282 lines
7.1 KiB
Plaintext
282 lines
7.1 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Reminder\n",
|
|
"\n",
|
|
"Do you need to register for \"Studienleistung\" in HisInOne?"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Speedrun: command line interface (CLI) treasure hunt (schnitzeljagd)\n",
|
|
"\n",
|
|
"We will do a quick speedrun of the schnitzeljagd exercise starting with `ssh your-user-name@python-course.strawlab.org`.\n",
|
|
"\n",
|
|
"Discussion: why CLI Python?"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Classes\n",
|
|
"\n",
|
|
"Here is an example of a simple class:"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 1,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"class MyClass:\n",
|
|
" def my_method(self):\n",
|
|
" print(\"This was printed from a method inside the class.\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"We'll discuss the \"self\" parameter below. First, let's create an instance of this class:"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"x = MyClass()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 3,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"This was printed from a method inside the class.\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"x.my_method()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 4,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"y = MyClass()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 5,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"This was printed from a method inside the class.\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"y.my_method()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Why classes?\n",
|
|
"\n",
|
|
"The great benefit of classes is that they keep data and functions organized togther. The functions within a class are called \"methods\" and always take the first parameter, \"self\".\n",
|
|
"\n",
|
|
"With small pieces of code, this is not so important, but as the size of software grows larger, this is handy for keeping things organized. Most Python libraries make extensive use of classes.\n",
|
|
"\n",
|
|
"A class is like a template and multiple instances of this template can be created.\n",
|
|
"\n",
|
|
"## Creating an instance of a class\n",
|
|
"\n",
|
|
"Class definitions can have a special method caled `__init__()`. This initialization method, also called constructor, is called when an instance of a class is created. It is used to store variables and perform other setup."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 6,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"My variable is foo.\n",
|
|
"My variable is bar.\n",
|
|
"My variable is zzz.\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"class MyClass:\n",
|
|
" def __init__(self):\n",
|
|
" self.my_variable = \"foo\"\n",
|
|
" def my_method(self):\n",
|
|
" print(\"My variable is {}.\".format(self.my_variable))\n",
|
|
" def set_var(self,new_value):\n",
|
|
" self.my_variable = new_value\n",
|
|
" \n",
|
|
"x = MyClass()\n",
|
|
"x.my_method()\n",
|
|
"\n",
|
|
"x.set_var(\"bar\")\n",
|
|
"x.my_method()\n",
|
|
"\n",
|
|
"x.my_variable = \"zzz\"\n",
|
|
"x.my_method()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## What is this `self` thing?\n",
|
|
"\n",
|
|
"As mentioned, `self` is always the first argument of any method. It contains the data (variables) for a specific instance of a class."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 7,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"The insect (species Bombus terrestris) has a mass of 200 milligrams.\n",
|
|
"The insect (species Bombus terrestris) has a mass of 205 milligrams.\n",
|
|
"The insect (species Apis mellifera) has a mass of 100 milligrams.\n",
|
|
"The insect (species Tarantula gigantus) has a mass of 10 grams.\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"class Insect:\n",
|
|
" def __init__(self, species_name, mass, mass_units='milligrams'):\n",
|
|
" self.species_name = species_name\n",
|
|
" self.mass = mass\n",
|
|
" self.mass_units = mass_units\n",
|
|
" def print_description(self):\n",
|
|
" print(\"The insect (species {}) has a mass of {} {}.\".format(\n",
|
|
" self.species_name, self.mass, self.mass_units))\n",
|
|
" def eat(self,amount):\n",
|
|
" # (This could alternatively be done with `self.mass += amount`.)\n",
|
|
" self.mass = self.mass + amount\n",
|
|
" def exercise(self,amount):\n",
|
|
" self.mass = self.mass - amount\n",
|
|
" \n",
|
|
"x = Insect(\"Bombus terrestris\", 200)\n",
|
|
"x.print_description()\n",
|
|
"x.eat(10)\n",
|
|
"x.exercise(5)\n",
|
|
"x.print_description()\n",
|
|
"\n",
|
|
"y = Insect(\"Apis mellifera\", 100)\n",
|
|
"y.print_description()\n",
|
|
"# y.eat(10)\n",
|
|
"# y.print_description()\n",
|
|
"\n",
|
|
"z = Insect(\"Tarantula gigantus\", 10, mass_units=\"grams\") # yes, it's not really an insect...\n",
|
|
"z.print_description()\n",
|
|
"\n",
|
|
"# print(x.species_name,x.mass)\n",
|
|
"# print(y.species_name,y.mass)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"You can see we access the value of a variable within a method using `self.variable_name`. Outside the function, we can also access the \"instance variables\" but we need to use the instance name and a dot:"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 8,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Bombus terrestris\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"print(x.species_name)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 9,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Apis mellifera\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"print(y.species_name)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"As mentioned, most Python libraries make use of classes to organize their code. All objects in Python act a lot like instances of classes. For example, the string methods `.strip()` and `.format()` could be defined on a hypothetical `String` class exactly like the methods above. (In reality, they are likely implemented differently for performance reasons.)"
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "Python 3 (ipykernel)",
|
|
"language": "python",
|
|
"name": "python3"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": {
|
|
"name": "ipython",
|
|
"version": 3
|
|
},
|
|
"file_extension": ".py",
|
|
"mimetype": "text/x-python",
|
|
"name": "python",
|
|
"nbconvert_exporter": "python",
|
|
"pygments_lexer": "ipython3",
|
|
"version": "3.11.10"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 4
|
|
}
|