Commit eee87f18 authored by christian.foerster's avatar christian.foerster

progress

parent 5b4930c2
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -12,7 +12,421 @@
"It's a different way of you thinking about your model/problem. Instead of thinking of a problem as a sequence of commands that need to be executed (procedural, **linear**), you identify single processes/actors and define their attributes and functionalities, so that they can interact with other actors (**nonlinear**).\n",
"\n",
"**Example Problem:\n",
"Create a plotting library**\n"
"Create a simple Notepad**\n",
"\n",
"You'll want to be able to add and delete notes. And for each note you want to be able to add, delete and mark (as done) entries. The Notepad should also have a memory of which Note is selected."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Procedural**\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"notes = {}\n",
"selectedNote = None\n",
"\n",
"def addNote(notes, noteName):\n",
" global selectedNote\n",
" selectedNote = noteName\n",
" notes[noteName]={}\n",
" return notes\n",
"\n",
"def deleteNote(notes,noteName):\n",
" global selectedNote\n",
" selectedNote = None\n",
" del notes[noteName]\n",
" return notes\n",
"\n",
"def _noteNameCheck(noteName):\n",
" global selectedNote\n",
" if noteName is None and selectedNote is None:\n",
" raise ValueError(\"Please provide a noteName.\")\n",
" elif noteName is None:\n",
" noteName = selectedNote\n",
" return noteName\n",
"\n",
"def addEntry(notes, entry, noteName = None):\n",
" noteName = _noteNameCheck(noteName)\n",
" notes[noteName][entry]=\"unmarked\"\n",
" return notes\n",
"\n",
"def deleteEntry(notes, entry, noteName = None):\n",
" noteName = _noteNameCheck(noteName)\n",
" del notes[noteName][entry]\n",
" return notes\n",
"\n",
"def markEntry(notes, entry, noteName = None):\n",
" noteName = _noteNameCheck(noteName)\n",
" notes[noteName][entry]=\"marked\"\n",
" return notes\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'ShoppingList': {'coffee': 'unmarked',\n",
" 'milk': 'unmarked',\n",
" 'bread': 'unmarked',\n",
" 'chocolate': 'marked'}}"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"addNote(notes, \"ShoppingList\")\n",
"addEntry(notes,\"coffee\")\n",
"addEntry(notes,\"milk\")\n",
"addEntry(notes,\"bread\")\n",
"addEntry(notes,\"chocolate\")\n",
"markEntry(notes,\"chocolate\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**OOP**"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"class Notepad():\n",
" def __init__(self):\n",
" self.notes = {}\n",
" self.selectedNote=None\n",
" return\n",
" \n",
" def _noteNameCheck(self,noteName):\n",
" if noteName is None and self.selectedNote is None:\n",
" raise ValueError(\"Please provide a noteName.\")\n",
" elif noteName is None:\n",
" noteName = self.selectedNote\n",
" return noteName\n",
" \n",
" def addNote(self, noteName):\n",
" self.selectedNote=noteName\n",
" self.notes[noteName] = {}\n",
" return self.notes\n",
" \n",
" def deleteNote(self, noteName=None):\n",
" noteName = self._noteNameCheck(noteName)\n",
" del self.notes[noteName]\n",
" self.selectedNote = None \n",
" return self.notes\n",
" \n",
" def addEntry(self, entry, noteName=None):\n",
" noteName = self._noteNameCheck(noteName)\n",
" self.notes[noteName][entry]=\"unmarked\"\n",
" return self.notes\n",
" \n",
" def deleteEntry(self, entry, noteName=None):\n",
" noteName = self._noteNameCheck(noteName)\n",
" del self.notes[noteName][entry]\n",
" return self.notes\n",
" \n",
" def markEntry(self, entry, noteName=None):\n",
" noteName = self._noteNameCheck(noteName)\n",
" self.notes[noteName][entry]=\"marked\"\n",
" return self.notes"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'Shopping': {'coffee': 'unmarked',\n",
" 'milk': 'unmarked',\n",
" 'break': 'unmarked',\n",
" 'chocolate': 'marked'}}"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"NotepadInstance = Notepad()\n",
"NotepadInstance.addNote(\"Shopping\")\n",
"NotepadInstance.addEntry(\"coffee\")\n",
"NotepadInstance.addEntry(\"milk\")\n",
"NotepadInstance.addEntry(\"break\")\n",
"NotepadInstance.addEntry(\"chocolate\")\n",
"NotepadInstance.markEntry(\"chocolate\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"So for simple programs, there is basically not difference between these programming styles. But as soon as it gets more complicated OOP shines, because different parts of the program can be seperated more clearly. Image you want to design a plottling library...\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 4 Pillars of OOP\n",
"- Inheritance (a way to reuse your code)\n",
"- Abstraction (showing only essential features hiding details)\n",
"- Encapsulation (bind data variables and functions together in a class)\n",
"- Polymorphism (create functions with same name and different arguments, redefine functions)\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"# Parent class\n",
"class Dog:\n",
" # Class attribute\n",
" species = 'mammal'\n",
"\n",
" # Initializer / Instance attributes\n",
" def __init__(self, name, age):\n",
" self.name = name\n",
" self.age = age\n",
"\n",
" # instance method\n",
" def description(self):\n",
" return \"{} is {} years old\".format(self.name, self.age)\n",
"\n",
" # instance method\n",
" def speak(self, sound):\n",
" return \"{} says {}\".format(self.name, sound)\n",
"\n",
" \n",
"# Child class (inherits from Dog() class)\n",
"class RussellTerrier(Dog):\n",
" def run(self, speed):\n",
" return \"{} runs {}\".format(self.name, speed)\n",
"\n",
"\n",
"# Child class (inherits from Dog() class)\n",
"class Bulldog(Dog):\n",
" def run(self, speed):\n",
" return \"{} runs {}\".format(self.name, speed)"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Jim is 12 years old\n",
"Jim runs slowly\n",
"True\n",
"True\n",
"False\n",
"False\n"
]
}
],
"source": [
"# Child classes inherit attributes and\n",
"# behaviors from the parent class\n",
"jim = Bulldog(\"Jim\", 12)\n",
"print(jim.description())\n",
"\n",
"# Child classes have specific attributes\n",
"# and behaviors as well\n",
"print(jim.run(\"slowly\"))\n",
"\n",
"# Is jim an instance of Dog()?\n",
"print(isinstance(jim, Dog))\n",
"\n",
"# Is julie an instance of Dog()?\n",
"julie = Dog(\"Julie\", 100)\n",
"print(isinstance(julie, Dog))\n",
"\n",
"# Is johnny walker an instance of Bulldog()\n",
"johnnywalker = RussellTerrier(\"Johnny Walker\", 4)\n",
"print(isinstance(johnnywalker, Bulldog))\n",
"\n",
"# Is julie and instance of jim?\n",
"print(isinstance(julie, RussellTerrier))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Useful Example**"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[2019-06-28 16:07:59 - OneOfMany] - Instance initiated with...\n",
" Arguments: ('Here', 'are', 'some', 'arguments', '.')\n",
" Kwarguments: {'ThisIsADictArgument': 'check me out'}\n",
"[2019-06-28 16:07:59 - VarMemory] - Checking if logfile exists.\n",
"[2019-06-28 16:07:59 - VarMemory] - Writing logfile.\n",
"[2019-06-28 16:07:59 - VarMemory] - Tracker logged ac:33\n",
"[2019-06-28 16:07:59 - VarMemory] - Writing logfile.\n",
"[2019-06-28 16:07:59 - VarMemory] - Tracker logged {'abc': [3, 4, 5], 'bcd': 44}\n"
]
}
],
"source": [
"import sys, time, json, os\n",
"\n",
"class VerboseHandler:\n",
" verboseFile = None\n",
" verbosePrint = True\n",
" \n",
" def __verbose(self,*args, **kwargs):\n",
" niceFormatString = \"[{} - {}]\".format(time.strftime(\"%Y-%m-%d %X\"),self.__class__.__name__ )\n",
" \n",
" # taking care of indentation\n",
" length = len(niceFormatString)+3\n",
" args_updated = [a.replace(\"\\n\",\"\\n\"+\" \"*length) for a in args]\n",
" \n",
" print(niceFormatString, end=\" - \")\n",
" print(*args_updated, **kwargs)\n",
" \n",
" def verbose(self, *args, **kwargs):\n",
" \"\"\"\n",
" this method has the same arguments as print()\n",
" \"\"\"\n",
" if self.verbosePrint:\n",
" self.__verbose(*args, **kwargs)\n",
"\n",
" if self.verboseFile is not None:\n",
"\n",
" original_stdout = sys.stdout\n",
"\n",
" with open(verboseFile, \"a+\") as stream:\n",
" sys.stdout = stream\n",
" self.__verbose(*args, **kwargs)\n",
" \n",
" sys.stdout = original_stdout\n",
" \n",
" return\n",
" \n",
"\n",
"class VarMemory(VerboseHandler):\n",
" logfile = \"variable.txt\"\n",
" \n",
" def __init__(self):\n",
" self.__vardict = {}\n",
" if self.__file_exists():\n",
" self.__read_dict()\n",
" return\n",
"\n",
" def __file_exists(self):\n",
" self.verbose(\"Checking if logfile exists.\")\n",
" return os.path.exists(self.logfile)\n",
"\n",
" def __write_dict(self):\n",
" self.verbose(\"Writing logfile.\")\n",
" with open(self.logfile, \"w\") as lfile:\n",
" json.dump(self.__vardict, lfile, indent=4)\n",
" return\n",
" \n",
" def __read_dict(self):\n",
" self.verbose(\"Reading logfile.\")\n",
" with open(self.logfile, \"r\") as lfile:\n",
" self.__vardict = json.load(lfile)\n",
" return\n",
"\n",
" def log(self, key, value):\n",
" self.__vardict[key] = value\n",
" self.__write_dict()\n",
" self.verbose(\"Tracker logged {}:{}\".format(str(key),str(value)))\n",
" return\n",
"\n",
" def log_from_dict(self, dictionary):\n",
" self.__vardict.update(dictionary)\n",
" self.__write_dict()\n",
" self.verbose(\"Tracker logged {}\".format(str(dictionary)))\n",
" return\n",
" \n",
" # magic method to enable indexing of instance\n",
" def __getitem__(self, key):\n",
" return self.__vardict[key]\n",
" \n",
" # magic method to enable deleting via indexing the instance\n",
" def __delitem__(self, key):\n",
" self.verbose(\"Deleting log varibles - {}:{}\".format(key,self.__vardict[key]))\n",
" del self.__vardict[key]\n",
" self.__write_dict()\n",
" return\n",
" \n",
" # magic method to enable iteration via the instance\n",
" def __iter__(self):\n",
" return iter(self.__vardict)\n",
"\n",
" \n",
"class OneOfMany(VerboseHandler):\n",
" def __init__(self,*args,**kwargs):\n",
" self.verbose(\"Instance initiated with...\\nArguments: {}\\nKwarguments: {}\".format(str(args),str(kwargs)))\n",
" \n",
" \n",
"oom=OneOfMany(\"Here\",\"are\",\"some\",\"arguments\",\".\",ThisIsADictArgument=\"check me out\")\n",
"\n",
"vr = VarMemory()\n",
"vr.log(\"ac\",33)\n",
"vr.log_from_dict({\"abc\":[3,4,5],\"bcd\":44})"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"33\n",
"[3, 4, 5]\n",
"44\n"
]
}
],
"source": [
"for entry in vr:\n",
" print(vr[entry])"
]
},
{
......@@ -29,11 +443,18 @@
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Structering your code"
"## Structuring your code"
]
},
{
......@@ -54,7 +475,11 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"## Performance"
"## Performance\n",
"\n",
"- Numpy is fast! Why?\n",
" - try to stick with one variable type. Don't use lists and arrays and mix it all up\n",
"- "
]
},
{
......@@ -86,6 +511,109 @@
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": 170,
"metadata": {},
"outputs": [],
"source": [
"class Tank:\n",
" def __init__(self, tank_id, level, rate, upstream_tanks=None):\n",
" self.tank_id = tank_id\n",
" self.level = level\n",
" self.rate = rate\n",
" self.upstream_tanks = upstream_tanks\n",
" \n",
" @property # allows use of the method without brackets \n",
" def Q(self):\n",
" tank_area = 1\n",
" return self.level * self.rate / tank_area\n",
" \n",
" def fill_tank(self):\n",
" if self.upstream_tanks is not None:\n",
" for uptank in self.upstream_tanks:\n",
" # recursion\n",
" uptank.fill_tank() \n",
" \n",
" uptank.level -= uptank.Q\n",
" self.level += uptank.Q\n",
" \n",
"def initiate_tanks(network_structure, attributes):\n",
" # init all tanks without upstream tanks\n",
" tanks = {}\n",
" for tank_id in attributes:\n",
" level = attributes[tank_id][0]\n",
" rate = attributes[tank_id][1]\n",
" tanks[tank_id] = Tank(tank_id, level, rate, upstream_tanks=None)\n",
" # add upstream tanks\n",
" for tank_id in network_structure:\n",
" tanks[tank_id].upstream_tanks = [tanks[tank_id_up] for tank_id_up in network_structure[tank_id]]\n",
" return tanks\n",
"\n",
"def get_levels_upstream(fill_dict,tank):\n",
" fill_dict[tank.tank_id].append(tank.level)\n",
" if tank.upstream_tanks is not None:\n",
" for uptank in tank.upstream_tanks:\n",
" get_levels_upstream(fill_dict, uptank)\n"
]
},
{
"cell_type": "code",
"execution_count": 171,
"metadata": {},
"outputs": [],
"source": [
"network_structure = {6:[4,5],4:[1,2],5:[3]}\n",
"attributes = {1:(10, 0.0),\n",
" 2:(20, 0.06),\n",
" 3:(15, 0.9),\n",
" 4:(8, 0.3),\n",
" 5:(44, 0.5),\n",
" 6:(2.5, 0)}"
]
},
{
"cell_type": "code",
"execution_count": 172,
"metadata": {},
"outputs": [],
"source": [
"final_tank = initiate_tanks(network_structure,attributes)[6]\n",
"levels = {k:[] for k in range(7)[1:]}\n",
"for dt in range(100):\n",
" get_levels_upstream(levels,final_tank)\n",
" final_tank.fill_tank()\n",
" "
]
},
{
"cell_type": "code",
"execution_count": 173,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 864x576 with 6 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"# plotting simulation\n",
"import matplotlib.pyplot as plt\n",
"fig, axis = plt.subplots(6,1,figsize = (12,8))\n",
"for idx, ax in enumerate(axis):\n",
" ax.plot(levels[idx+1])\n",
" ax.set_title(idx+1)\n",
"plt.tight_layout()"
]
},
{
"cell_type": "code",
"execution_count": null,
......@@ -138,7 +666,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.3"
"version": "3.6.8"
}
},
"nbformat": 4,
......
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Ein kurzes Intro zu Python\n",
"\n",
"\n",
"## Some nice-to-know's\n",
"* Die Indexierung von Python started bei 0\n",
"* Der Syntax wird vor allem über tabs (4 Leerzeichen) gesteuert.\n",
"\n",
"## Variablen"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"25.0\n",
"6.7\n",
"5\n",
"5.6\n",
"vdsfdsafdsaffsaf\n"
]
},
{
"data": {
"text/plain": [
"25"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Integer\n",
"a=25\n",
"\n",
"# Float\n",
"b=5.6\n",
"\n",
"# String\n",
"c=\"6.7\"\n",
"\n",
"#Boolean\n",
"d=True\n",
"\n",
"# Die Umrechnung der Variablentypen funktioniert so (der int() Befehl rundet immer ab)\n",
"print(float(a),float(c),int(b),str(b),sep=\"\\n\")\n",
"print(\"vdsfdsafdsaffsaf\")\n",
"a"
]
},
{
"cell_type": "code",
"execution_count": 4,