|
6c1cd5e1-c1ba-4c19-a221-e3e2ddb87851
|
8684964a-bab1-4235-93a8-5fd5e24a1d0a
|
Advanced_Programming_with_Python.pdf
|
{"name": "Advanced_Programming_with_Py {"name": "Advanced_Programming_with_Python.pdf", "content_type": "application/pdf", "size": 309695, "data": {"additionalProp1": {}}, "collection_name": "file-6c1cd5e1-c1ba-4c19-a221-e3e2ddb87851"}...
|
1769077888
|
55c5aee2f971594476d3a95a0c4ddb104a3f5d0b9b5f8cd7fb 55c5aee2f971594476d3a95a0c4ddb104a3f5d0b9b5f8cd7fbf3e857379eb17d...
|
{"status": "completed", "conte {"status": "completed", "content": "Advanced Programming with Python\nDISCLAIMER: The presented material relies heavily on Python Advance course carried out at CERN. The material is also available freely at\nthe website: \nhttps://www.python-course.eu\n (https://www.python-course.eu)\n1\n. \nWhat is a variable\n2\n. \nBasic types\nstring\nenum\n3\n. \nContainers\nlists\ntuples\nsets\ndictionaries\n4\n. \nFunctions\narguments\nrecursion\nstatic variables\ndecorators\ngenerators\ncontext managers\n5\n. \nException Handling\nNot included\n:\n6\n. \nObject Oriented Programming\n7\n. \nPackaging\n8\n. \nDocumentation\n9\n. \nUnit testing\n10\n. \nContinuous Integration\nIn 1999, Guido Van Rossum submitted a funding proposal to DARPA called \"Computer Programming for Everybody\", in which he further\ndefined his goals for Python:\nAn easy and intuitive language just as powerful as major competitors\nOpen source, so anyone can contribute to its development\nCode that is as understandable as plain English\nSuitability for everyday tasks, allowing for short development times\n0. Hello world\nIn [1]:\nprint\n(\n'Hello world!'\n)\n0.1. Zen of Python\nHello world! In [2]:\nimport\n \nthis\n1. What is a variable?\nVariable in python is always a reference to an object as in python everything, even a function, is an object.\nIn [3]:\nx\n \n=\n \n3\ny\n \n=\n \nx\ny\n,\n \nx\nIn [4]:\nx\n \n=\n \n2\nIn [5]:\ny\n,\n \nx\nConditional statement to assign a value\nIn [6]:\nx\n \n=\n \n-\n5\nif\n \nx\n \n>\n \n0\n:\n \nlabel\n \n=\n \n'Pos'\nelse\n:\n \nlabel\n \n=\n \n'Neg'\nprint\n(\nlabel\n)\nThe Zen of Python, by Tim Peters\nBeautiful is better than ugly.\nExplicit is better than implicit.\nSimple is better than complex.\nComplex is better than complicated.\nFlat is better than nested.\nSparse is better than dense.\nReadability counts.\nSpecial cases aren't special enough to break the rules.\nAlthough practicality beats purity.\nErrors should never pass silently.\nUnless explicitly silenced.\nIn the face of ambiguity, refuse the temptation to guess.\nThere should be one-- and preferably only one --obvious way to do it.\nAlthough that way may not be obvious at first unless you're Dutch.\nNow is better than never.\nAlthough never is often better than *right* now.\nIf the implementation is hard to explain, it's a bad idea.\nIf the implementation is easy to explain, it may be a good idea.\nNamespaces are one honking great idea -- let's do more of those!\nOut[3]:\n(3, 3)\nOut[5]:\n(3, 2)\nNeg In [7]:\nx\n \n=\n \n-\n5\nlabel\n \n=\n \n'Pos'\n \nif\n \nx\n \n>\n \n0\n \nelse\n \n'Neg'\nprint\n(\nlabel\n)\nIn [28]:\nprint\n(\n'Pos'\n \nif\n \nx\n \n>\n \n0\n \nelse\n \n'Neg'\n)\n2. Basic types\n2.1. String\nStrings in python are immutable\nIn [14]:\nstring\n \n=\n \n'My string'\nstring\n[\n0\n]\n \n=\n \n'T'\nIn [15]:\nstring\n.\nreplace\n(\n'M'\n,\n \n'T'\n)\nIn [16]:\nstring\nString is iterable\nIn [17]:\nfor\n \ns\n \nin\n \n'My string'\n:\n \nprint\n(\ns\n)\nFormating of strings\nNeg\nNeg\n---------------------------------------------------------------------------\nTypeError\n Traceback (most recent call last)\n<ipython-input-14-9c1867d9b2ff>\n in \n<module>\n 1\n string \n=\n \n'My string'\n----> 2\n \nstring\n[\n0\n]\n \n=\n \n'T'\nTypeError\n: 'str' object does not support item assignment\nOut[15]:\n'Ty string'\nOut[16]:\n'My string'\nM\ny\n \ns\nt\nr\ni\nn\ng In [18]:\nfrom\n \ndatetime\n \nimport\n \ndate\n'Today is '\n \n+\n \nstr\n(\ndate\n.\ntoday\n())\n \n+\n \n'.'\nIn [23]:\n'Today is \n{}\n and number \n{}\n.'\n.\nformat\n(\ndate\n.\ntoday\n(),\n \n[\n1\n,\n \n2\n,\n \n3\n])\nf-strings have been introduced in Python 3.6\nIn [21]:\nprint\n(\nf\n'Today is {date.today()}'\n)\nCheck if a substring is in a string\nIn [25]:\nif\n \n'sub'\n \nin\n \n'substring'\n:\n \nprint\n(\n'True'\n)\nThere are already many built-in functions for handling strings in Python\nIn [29]:\ndir\n(\nlist\n)\nOut[18]:\n'Today is 2019-11-28.'\nOut[23]:\n'Today is 2019-11-28 and number [1, 2, 3].'\nToday is 2019-11-28\nTrue In [26]:\ndir\n(\nstr\n)\nOut[29]:\n['__add__',\n '__class__',\n '__contains__',\n '__delattr__',\n '__delitem__',\n '__dir__',\n '__doc__',\n '__eq__',\n '__format__',\n '__ge__',\n '__getattribute__',\n '__getitem__',\n '__gt__',\n '__hash__',\n '__iadd__',\n '__imul__',\n '__init__',\n '__init_subclass__',\n '__iter__',\n '__le__',\n '__len__',\n '__lt__',\n '__mul__',\n '__ne__',\n '__new__',\n '__reduce__',\n '__reduce_ex__',\n '__repr__',\n '__reversed__',\n '__rmul__',\n '__setattr__',\n '__setitem__',\n '__sizeof__',\n '__str__',\n '__subclasshook__',\n 'append',\n 'clear',\n 'copy',\n 'count',\n 'extend',\n 'index',\n 'insert',\n 'pop',\n 'remove',\n 'reverse',\n 'sort']\nOut[26]:\n['__add__',\n '__class__',\n '__contains__',\n '__delattr__',\n '__dir__',\n '__doc__',\n '__eq__',\n '__format__',\n '__ge__',\n '__getattribute__',\n '__getitem__',\n '__getnewargs__',\n '__gt__',\n '__hash__',\n '__init__',\n '__init_subclass__',\n '__iter__',\n '__le__', In [32]:\n'my first sentence'\n.\nupper\n()\n '__le__',\n '__len__',\n '__lt__',\n '__mod__',\n '__mul__',\n '__ne__',\n '__new__',\n '__reduce__',\n '__reduce_ex__',\n '__repr__',\n '__rmod__',\n '__rmul__',\n '__setattr__',\n '__sizeof__',\n '__str__',\n '__subclasshook__',\n 'capitalize',\n 'casefold',\n 'center',\n 'count',\n 'encode',\n 'endswith',\n 'expandtabs',\n 'find',\n 'format',\n 'format_map',\n 'index',\n 'isalnum',\n 'isalpha',\n 'isdecimal',\n 'isdigit',\n 'isidentifier',\n 'islower',\n 'isnumeric',\n 'isprintable',\n 'isspace',\n 'istitle',\n 'isupper',\n 'join',\n 'ljust',\n 'lower',\n 'lstrip',\n 'maketrans',\n 'partition',\n 'replace',\n 'rfind',\n 'rindex',\n 'rjust',\n 'rpartition',\n 'rsplit',\n 'rstrip',\n 'split',\n 'splitlines',\n 'startswith',\n 'strip',\n 'swapcase',\n 'title',\n 'translate',\n 'upper',\n 'zfill']\nOut[32]:\n'MY FIRST SENTENCE' 2.2. Enum\nEnum is a data type which links a name to an index. They are useful to represent a closed set of options\nIn [33]:\nfrom\n \nenum\n \nimport\n \nEnum\nclass\n \nQhBrowserAction\n(\nEnum\n):\n \nQUERY_BUTTON_CLICKED\n \n=\n \n1\n \nSAVE_BUTTON_CLICKED\n \n=\n \n2\n \nDATE_CHANGED\n \n=\n \n3\n \nQH_NAME_CHANGED\n \n=\n \n4\n \nSLIDER_MOVED\n \n=\n \n5\na\n \n=\n \nQhBrowserAction\n.\nDATE_CHANGED\na\n.\nname\n,\n \na\n.\nvalue\nIn [36]:\na_next\n \n=\n \nQhBrowserAction\n(\na\n.\nvalue\n+\n1\n)\na_next\nIn [38]:\nif\n \na_next\n \n==\n \nQhBrowserAction\n.\nQH_NAME_CHANGED\n:\n \nprint\n(\n'In state \n{}\n'\n.\nformat\n(\na_next\n.\nvalue\n))\n3. Containers\nContainer data types in Python are dedicated to store multiple variables of a various type. The basic container types are: lists, tuples, sets,\ndictionaries.\n3.1. Lists\nIn [39]:\nmy_list\n \n=\n \n[\n1\n,\n \n'b'\n,\n \nTrue\n]\nmy_list\nLists are 0-indexed and elements are accessed by a square bracket\nIn [40]:\nmy_list\n[\n0\n]\nLists are mutable\nOut[33]:\n('DATE_CHANGED', 3)\nOut[36]:\n<QhBrowserAction.QH_NAME_CHANGED: 4>\nIn state 4\nOut[39]:\n[1, 'b', True]\nOut[40]:\n1 In [42]:\nmy_list\n[\n1\n]\n \n=\n \n0\nmy_list\nIn order to extend a list one can either append...\nIn [44]:\nmy_list\n.\nappend\n(\n3\n)\nmy_list\nOr simply\nIn [45]:\nmy_list\n \n+\n \n[\n1\n,\n \n'b'\n]\n...or append elements\nIn [ ]:\nmy_list\n \n+=\n \n[\n3\n]\nmy_list\nIn [ ]:\nmy_list\n \n=\n \nmy_list\n \n+\n \n[\n3\n]\n \n# One shall not do that\nmy_list\nBe careful with the last assignment, this creates a new list, so a need to perfom a copy - very inefficient for large lists.\nHow to append a list at the end?\nIn [47]:\nmy_list\n.\nappend\n([\n1\n,\n \n'a'\n])\nmy_list\nThis adds a list as an element, which is not quite what we wanted.\nIn [58]:\nmy_list\n.\nextend\n([\n5\n])\nmy_list\nOut[42]:\n[0, 0, True]\nOut[44]:\n[0, 0, True, 3, 3]\nOut[45]:\n[0, 0, True, 3, 3, 1, 'b']\nOut[47]:\n[0, 0, True, 3, 3, 3, [1, 'a']]\nOut[58]:\n[0, 0, True, 3, 3, 3, [1, 'a'], 1, 'a', 1, 'a', [1, 2], '5', 5] In [53]:\nimport\n \nitertools\nlist2d\n \n=\n \n[[\n1\n,\n2\n,\n3\n],\n \n[\n4\n,\n5\n,\n6\n],\n \n[\n7\n],\n \n[\n8\n,\n9\n]]\nmerged\n \n=\n \nlist\n(\nitertools\n.\nchain\n(\n*\nlist2d\n))\nmerged\nWhich one to choose in order to add elements efficiently?\nhttps://stackoverflow.com/questions/252703/what-is-the-difference-between-pythons-list-methods-append-and-extend\n(https://stackoverflow.com/questions/252703/what-is-the-difference-between-pythons-list-methods-append-and-extend)\n3.1.1. List comprehension\nOld-fashioned way\nIn [59]:\nmy_list\n \n=\n \n[]\nfor\n \ni\n \nin\n \nrange\n(\n10\n):\n \nmy_list\n.\nappend\n(\ni\n)\nmy_list\nOne-line list comprehension\nIn [75]:\nabs\n(\n0.1\n \n-\n \n(\n1.1\n-\n1\n))\n \n<\n \n1e-16\nIn [65]:\nmy_list\n \n=\n \n[\n1\n/\n(\ni\n+\n1\n)\n \nfor\n \ni\n \nin\n \nrange\n(\n10\n)]\nmy_list\nIn [66]:\nmy_list\n \n=\n \n[\ni\n \nfor\n \ni\n \nin\n \nrange\n(\n10\n)\n \nif\n \ni\n \n>\n \n4\n]\nmy_list\nGenerator comprehension\nOut[53]:\n[[1, 2, 3], [4, 5, 6], [7], [8, 9]]\nOut[59]:\n[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\nOut[75]:\nTrue\nOut[65]:\n[1.0,\n 0.5,\n 0.3333333333333333,\n 0.25,\n 0.2,\n 0.16666666666666666,\n 0.14285714285714285,\n 0.125,\n 0.1111111111111111,\n 0.1]\nOut[66]:\n[5, 6, 7, 8, 9] In [76]:\nx\n \n=\n \n(\nx\n**\n2\n \nfor\n \nx\n \nin\n \nrange\n(\n10\n))\nprint\n(\nx\n)\nIn [87]:\nnext\n(\nx\n)\nIn [93]:\nimport\n \ndatetime\nstr\n(\ndatetime\n.\ndatetime\n.\nnow\n())\nIn [103]:\nprint\n(\ndatetime\n.\ndatetime\n.\nnow\n())\nfor\n \nx\n \nin\n \n((\nx\n+\n1\n)\n**\n2\n \nfor\n \nx\n \nin\n \nrange\n(\nint\n(\n1e7\n))):\n \nx\n**\n(\n-\n1\n/\n2\n)\nprint\n(\ndatetime\n.\ndatetime\n.\nnow\n())\nIn [104]:\nprint\n(\ndatetime\n.\ndatetime\n.\nnow\n())\nlst\n \n=\n \n[(\nx\n+\n1\n)\n**\n2\n \nfor\n \nx\n \nin\n \nrange\n(\nint\n(\n1e7\n))]\nfor\n \nx\n \nin\n \nlst\n:\n \nx\n**\n(\n-\n1\n/\n2\n)\nprint\n(\ndatetime\n.\ndatetime\n.\nnow\n())\nGenerator returns values on demand - no need to create a table and than iterate over it\nIn [111]:\nx\n \n=\n \niter\n(\nrange\n(\n10\n))\nnext\n(\nx\n)\nIn [ ]:\nx\n \n=\n \n(\nx\n**\n2\n \nfor\n \nx\n \nin\n \nrange\n(\n10\n))\nlist\n(\nx\n)\n3.1.2. Filter, map, reduce\n<generator object <genexpr> at 0x7faceb983468>\n---------------------------------------------------------------------------\nStopIteration\n Traceback (most recent call last)\n<ipython-input-87-92de4e9f6b1e>\n in \n<module>\n----> 1\n \nnext\n(\nx\n)\nStopIteration\n:\n \nOut[93]:\n'2019-11-28 11:24:28.029777'\n2019-11-28 11:27:55.759043\n2019-11-28 11:28:01.770323\n2019-11-28 11:28:09.839305\n2019-11-28 11:28:15.530292\nOut[111]:\n0 In [105]:\nmy_list\n \n=\n \n[\n-\n5\n,\n \n-\n4\n,\n \n-\n3\n,\n \n-\n2\n,\n \n-\n1\n,\n \n0\n,\n \n1\n,\n \n2\n,\n \n3\n,\n \n4\n,\n \n5\n]\nfilter\n(\nlambda\n \nx\n:\n \nx\n>\n0\n,\n \nmy_list\n)\nFilter returns an iterable generator. Generator is a very important concept in Python!\nIn [106]:\nfor\n \nel\n \nin\n \nfilter\n(\nlambda\n \nx\n:\n \nx\n>\n0\n,\nmy_list\n):\n \nprint\n(\nel\n)\nIn [112]:\nlist\n(\nfilter\n(\nlambda\n \nx\n:\n \nx\n>\n0\n,\n \nmy_list\n))\nMap\nIn [113]:\nprint\n(\nmy_list\n)\nlist\n(\nmap\n(\nlambda\n \nx\n:\n \nabs\n(\nx\n),\n \nmy_list\n))\nMap can be applied to many lists\nIn [114]:\nlst1\n \n=\n \n[\n0\n,\n1\n,\n2\n,\n3\n,\n4\n]\nlst2\n \n=\n \n[\n5\n,\n6\n,\n7\n,\n8\n]\nlist\n(\nmap\n(\nlambda\n \nx\n,\n \ny\n:\n \nx\n+\ny\n,\n \nlst1\n,\n \nlst2\n))\nReduce\nIn [115]:\nsum\n([\n0\n,\n1\n,\n2\n,\n3\n,\n4\n,\n5\n,\n6\n,\n7\n,\n8\n,\n9\n,\n10\n])\nOut[105]:\n<filter at 0x7face70b88d0>\n1\n2\n3\n4\n5\nOut[112]:\n[1, 2, 3, 4, 5]\n[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]\nOut[113]:\n[5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5]\nOut[114]:\n[5, 7, 9, 11]\nOut[115]:\n55 In [116]:\nfrom\n \nfunctools\n \nimport\n \nreduce\nreduce\n(\nlambda\n \nx\n,\n \ny\n:\n \nx\n+\ny\n,\n \n[\n0\n,\n1\n,\n2\n,\n3\n,\n4\n,\n5\n,\n6\n,\n7\n,\n8\n,\n9\n,\n10\n])\n$0+1+...+n = \\frac{n(n+1)}{2}$\n3.1.3. Iterating over lists\nIn [119]:\ni\n \n=\n \n0\nfor\n \nel\n \nin\n \n[\n-\n5\n,\n \n-\n4\n,\n \n-\n3\n,\n \n-\n2\n,\n \n-\n1\n,\n \n0\n,\n \n1\n,\n \n2\n,\n \n3\n,\n \n4\n,\n \n5\n]:\n \nprint\n(\ni\n,\n \nel\n)\n \ni\n \n+=\n \n1\nIterating with index\nIn [118]:\nfor\n \nindex\n,\n \nel\n \nin\n \nenumerate\n([\n-\n5\n,\n \n-\n4\n,\n \n-\n3\n,\n \n-\n2\n,\n \n-\n1\n,\n \n0\n,\n \n1\n,\n \n2\n,\n \n3\n,\n \n4\n,\n \n5\n]):\n \nprint\n(\nindex\n,\n \nel\n)\nIterating over two (many) lists\nIn [120]:\nletters\n \n=\n \n[\n'a'\n,\n \n'b'\n,\n \n'c'\n,\n \n'd'\n]\nnumbers\n \n=\n \n[\n1\n,\n \n2\n,\n \n3\n,\n \n4\n,\n \n5\n]\nfor\n \nl\n,\n \nn\n \nin\n \nzip\n(\nletters\n,\n \nnumbers\n):\n \nprint\n(\nl\n,\n \nn\n)\nOut[116]:\n55\n0 -5\n1 -4\n2 -3\n3 -2\n4 -1\n5 0\n6 1\n7 2\n8 3\n9 4\n10 5\n0 -5\n1 -4\n2 -3\n3 -2\n4 -1\n5 0\n6 1\n7 2\n8 3\n9 4\n10 5\na 1\nb 2\nc 3\nd 4 In [122]:\nlist\n(\nzip\n(\nletters\n,\n \nnumbers\n))\nIn [124]:\ndict\n(\nzip\n(\nletters\n,\n \nnumbers\n))\nIn [125]:\nhelp\n(\nzip\n)\n3.1.4. Copying lists\nIn [126]:\nx\n \n=\n \n[\n1\n,\n \n2\n,\n \n3\n,\n \n4\n]\ny\n \n=\n \nx\ny\n[\n0\n]\n \n=\n \n'a'\nprint\n(\nx\n,\n \ny\n)\nIn [128]:\nx\n.\ncopy\n()\nOut[122]:\n[('a', 1), ('b', 2), ('c', 3), ('d', 4)]\nOut[124]:\n{'a': 1, 'b': 2, 'c': 3, 'd': 4}\nHelp on class zip in module builtins:\nclass zip(object)\n | zip(iter1 [,iter2 [...]]) --> zip object\n | \n | Return a zip object whose .__next__() method returns a tuple where\n | the i-th element comes from the i-th iterable argument. The .__next__()\n | method continues until the shortest iterable in the argument sequence\n | is exhausted and then it raises StopIteration.\n | \n | Methods defined here:\n | \n | __getattribute__(self, name, /)\n | Return getattr(self, name).\n | \n | __iter__(self, /)\n | Implement iter(self).\n | \n | __new__(*args, **kwargs) from builtins.type\n | Create and return a new object. See help(type) for accurate signature.\n | \n | __next__(self, /)\n | Implement next(self).\n | \n | __reduce__(...)\n | Return state information for pickling.\n['a', 2, 3, 4] ['a', 2, 3, 4]\nOut[128]:\n[1, 2, 3, 4] In [127]:\nx\n \n=\n \n[\n1\n,\n \n2\n,\n \n3\n,\n \n4\n]\ny\n \n=\n \nx\n.\ncopy\n()\ny\n[\n0\n]\n \n=\n \n'a'\nprint\n(\nx\n,\n \ny\n)\nIn [129]:\nx\n \n=\n \n[[\n1\n,\n \n'a'\n],\n \n2\n,\n \n3\n,\n \n4\n]\ny\n \n=\n \nx\n.\ncopy\n()\n \n# equivalent to x[:]\ny\n[\n0\n]\n \n=\n \n'a'\nprint\n(\nx\n,\n \ny\n)\nIn [131]:\nx\n \n=\n \n[[\n1\n,\n \n'a'\n],\n \n2\n,\n \n3\n,\n \n4\n]\ny\n \n=\n \nx\n.\ncopy\n()\ny\n[\n0\n][\n0\n]\n \n=\n \n'b'\nprint\n(\nx\n,\n \ny\n)\nThe reason for this behavior is that Python performs a shallow copy.\nIn [132]:\nfrom\n \ncopy\n \nimport\n \ndeepcopy\nx\n \n=\n \n[[\n1\n,\n \n'a'\n],\n \n2\n,\n \n3\n,\n \n4\n]\ny\n \n=\n \ndeepcopy\n(\nx\n)\ny\n[\n0\n][\n0\n]\n \n=\n \n'b'\nprint\n(\nx\n,\n \ny\n)\n3.1.5. Sorting lists - inplace operations\nIn [133]:\nx\n \n=\n \n[\n1\n,\n \n10\n,\n \n2\n,\n \n9\n,\n \n3\n,\n \n8\n,\n \n4\n,\n \n6\n,\n \n5\n]\nx\n \n=\n \nx\n.\nsort\n()\nprint\n(\nx\n)\nlist.sort() is an inplace operation. In general, inplace operations are efficient as they do not create a new copy in memory\nIn [134]:\nx\n \n=\n \n[\n1\n,\n \n10\n,\n \n2\n,\n \n9\n,\n \n3\n,\n \n8\n,\n \n4\n,\n \n6\n,\n \n5\n]\nx\n.\nsort\n()\nprint\n(\nx\n)\nlist.sorted does create a new variable\nIn [135]:\nx\n \n=\n \n[\n1\n,\n \n10\n,\n \n2\n,\n \n9\n,\n \n3\n,\n \n8\n,\n \n4\n,\n \n6\n,\n \n5\n]\nsorted\n(\nx\n)\nprint\n(\nx\n)\n[1, 2, 3, 4] ['a', 2, 3, 4]\n[[1, 'a'], 2, 3, 4] ['a', 2, 3, 4]\n[['b', 'a'], 2, 3, 4] [['b', 'a'], 2, 3, 4]\n[[1, 'a'], 2, 3, 4] [['b', 'a'], 2, 3, 4]\nNone\n[1, 2, 3, 4, 5, 6, 8, 9, 10]\n[1, 10, 2, 9, 3, 8, 4, 6, 5] In [136]:\nx\n \n=\n \n[\n1\n,\n \n10\n,\n \n2\n,\n \n9\n,\n \n3\n,\n \n8\n,\n \n4\n,\n \n6\n,\n \n5\n]\nx\n \n=\n \nsorted\n(\nx\n)\nprint\n(\nx\n)\nIn [137]:\nx\n \n=\n \n[\n1\n,\n \n10\n,\n \n2\n,\n \n9\n,\n \n3\n,\n \n8\n,\n \n4\n,\n \n6\n,\n \n5\n]\nx\n \nis\n \nsorted\n(\nx\n)\nHow to sort in a reverted order\nIn [139]:\nx\n \n=\n \n[\n1\n,\n \n10\n,\n \n2\n,\n \n9\n,\n \n3\n,\n \n8\n,\n \n4\n,\n \n6\n,\n \n5\n]\nx\n.\nsort\n(\nreverse\n=\nTrue\n)\nprint\n(\nx\n)\nSort nested lists\nIn [140]:\nemployees\n \n=\n \n[(\n111\n,\n \n'John'\n),\n \n(\n123\n,\n \n'Emily'\n),\n \n(\n232\n,\n \n'David'\n),\n \n(\n100\n,\n \n'Mark'\n),\n \n(\n1\n,\n \n'Andrew'\n)]\nemployees\n.\nsort\n(\nkey\n=\nlambda\n \nx\n:\n \nx\n[\n0\n])\nemployees\nIn [141]:\nemployees\n \n=\n \n[(\n111\n,\n \n'John'\n),\n \n(\n123\n,\n \n'Emily'\n),\n \n(\n232\n,\n \n'David'\n),\n \n(\n100\n,\n \n'Mark'\n),\n \n(\n1\n,\n \n'Andrew'\n)]\nemployees\n.\nsort\n(\nkey\n=\nlambda\n \nx\n:\n \nx\n[\n1\n])\nemployees\nAlso with reversed order\nIn [142]:\nemployees\n \n=\n \n[(\n111\n,\n \n'John'\n),\n \n(\n123\n,\n \n'Emily'\n),\n \n(\n232\n,\n \n'David'\n),\n \n(\n100\n,\n \n'Mark'\n),\n \n(\n1\n,\n \n'Andrew'\n)]\nemployees\n.\nsort\n(\nkey\n=\nlambda\n \nx\n:\n \nx\n[\n0\n],\n \nreverse\n=\nTrue\n)\nemployees\n3.1.6. List extras\n[1, 2, 3, 4, 5, 6, 8, 9, 10]\nOut[137]:\nFalse\n[10, 9, 8, 6, 5, 4, 3, 2, 1]\nOut[140]:\n[(1, 'Andrew'), (100, 'Mark'), (111, 'John'), (123, 'Emily'), (232, 'David')]\nOut[141]:\n[(1, 'Andrew'), (232, 'David'), (123, 'Emily'), (111, 'John'), (100, 'Mark')]\nOut[142]:\n[(232, 'David'), (123, 'Emily'), (111, 'John'), (100, 'Mark'), (1, 'Andrew')] In [143]:\nmy_list\n \n=\n \n5\n*\n[\n'a'\n]\nmy_list\nIn [144]:\n3\n \nin\n \n[\n1\n,\n2\n,\n3\n,\n4\n,\n5\n]\nIn [149]:\nx\n \n=\n \n[\n'a'\n]\ny\n \n=\n \n[\n'a'\n]\nx\n \n==\n \ny\nIn [150]:\nx\n \n=\n \n(\n'a'\n)\ny\n \n=\n \n(\n'a'\n)\nx\n \nis\n \ny\n3.2. Tuples\nTuples, similarly to lists can stores elements of different types.\nIn [152]:\nmy_tuple\n \n=\n \n(\n1\n,\n2\n,\n3\n)\nmy_tuple\nIn [153]:\nmy_tuple\n[\n0\n]\nUnlike the lists, tuples are immutable.\nIn [154]:\nmy_tuple\n[\n0\n]\n=\n0\nOut[143]:\n['a', 'a', 'a', 'a', 'a']\nOut[144]:\nTrue\nOut[149]:\nTrue\nOut[150]:\nTrue\nOut[152]:\n(1, 2, 3)\nOut[153]:\n1\n---------------------------------------------------------------------------\nTypeError\n Traceback (most recent call last)\n<ipython-input-154-a0c25be542d6>\n in \n<module>\n----> 1\n \nmy_tuple\n[\n0\n]\n=\n0\nTypeError\n: 'tuple' object does not support item assignment In [159]:\ntuple\n([\n1\n,\n2\n,\n3\n])\n3.3. Sets\nSets are immutable and contain only unique elements\nIn [155]:\n{\n1\n,\n2\n,\n3\n,\n4\n}\nIn [156]:\n{\n1\n,\n2\n,\n3\n,\n4\n,\n4\n}\nSo this is a neat way for obtaining unique elements in a list\nIn [157]:\nmy_list\n \n=\n \n[\n1\n,\n \n2\n,\n \n3\n,\n \n4\n,\n \n4\n,\n \n5\n,\n \n5\n,\n \n5\n]\nset\n(\nmy_list\n)\nor a tuple\nIn [158]:\nmy_tuple\n \n=\n \n(\n1\n,\n \n2\n,\n \n3\n,\n \n4\n,\n \n4\n,\n \n5\n,\n \n5\n,\n \n5\n)\nset\n(\nmy_tuple\n)\nOne can perform set operations on sets ;-)\nIn [160]:\nA\n \n=\n \n{\n1\n,\n2\n,\n3\n}\nB\n \n=\n \n{\n3\n,\n4\n,\n5\n}\nprint\n(\nf\n'A+B={A.union(B)}'\n)\nprint\n(\nf\n'A-B={A-B}'\n)\nprint\n(\nf\n'A*B={A.intersection(B)}'\n)\nprint\n(\nf\n'A*0={A.intersection(\n{}\n)}'\n)\nOut[159]:\n(1, 2, 3)\nOut[155]:\n{1, 2, 3, 4}\nOut[156]:\n{1, 2, 3, 4}\nOut[157]:\n{1, 2, 3, 4, 5}\nOut[158]:\n{1, 2, 3, 4, 5}\nA+B={1, 2, 3, 4, 5}\nA-B={1, 2}\nA*B={3}\nA*0=set() In [165]:\npm\n \n=\n \n{\n'system'\n,\n \n'source'\n,\n \n'I_MEAS'\n,\n \n'I_REF'\n}\nsignals\n \n=\n \npm\n \n-\n \n{\n'system'\n,\n \n'source'\n}\nsignals\nIn [174]:\nfor\n \ns\n \nin\n \nsignals\n:\n \nprint\n(\ns\n)\nIn [175]:\nhelp\n(\nset\n)\nOut[165]:\n{'I_MEAS', 'I_REF'}\nI_MEAS\nI_REF\nHelp on class set in module builtins:\nclass set(object)\n | set() -> new empty set object\n | set(iterable) -> new set object\n | \n | Build an unordered collection of unique elements.\n | \n | Methods defined here:\n | \n | __and__(self, value, /)\n | Return self&value.\n | \n | __contains__(...)\n | x.__contains__(y) <==> y in x.\n | \n | __eq__(self, value, /)\n | Return self==value.\n | \n | __ge__(self, value, /)\n | Return self>=value.\n | \n | __getattribute__(self, name, /)\n | Return getattr(self, name).\n | \n | __gt__(self, value, /)\n | Return self>value.\n | \n | __iand__(self, value, /)\n | Return self&=value.\n | \n | __init__(self, /, *args, **kwargs)\n | Initialize self. See help(type(self)) for accurate signature.\n | \n | __ior__(self, value, /)\n | Return self|=value.\n | \n | __isub__(self, value, /)\n | Return self-=value.\n | \n | __iter__(self, /)\n | Implement iter(self).\n | \n | __ixor__(self, value, /)\n | Return self^=value.\n | \n | __le__(self, value, /)\n | Return self<=value.\n | \n | __len__(self, /)\n | Return len(self). | Return len(self).\n | \n | __lt__(self, value, /)\n | Return self<value.\n | \n | __ne__(self, value, /)\n | Return self!=value.\n | \n | __new__(*args, **kwargs) from builtins.type\n | Create and return a new object. See help(type) for accurate signature.\n | \n | __or__(self, value, /)\n | Return self|value.\n | \n | __rand__(self, value, /)\n | Return value&self.\n | \n | __reduce__(...)\n | Return state information for pickling.\n | \n | __repr__(self, /)\n | Return repr(self).\n | \n | __ror__(self, value, /)\n | Return value|self.\n | \n | __rsub__(self, value, /)\n | Return value-self.\n | \n | __rxor__(self, value, /)\n | Return value^self.\n | \n | __sizeof__(...)\n | S.__sizeof__() -> size of S in memory, in bytes\n | \n | __sub__(self, value, /)\n | Return self-value.\n | \n | __xor__(self, value, /)\n | Return self^value.\n | \n | add(...)\n | Add an element to a set.\n | \n | This has no effect if the element is already present.\n | \n | clear(...)\n | Remove all elements from this set.\n | \n | copy(...)\n | Return a shallow copy of a set.\n | \n | difference(...)\n | Return the difference of two or more sets as a new set.\n | \n | (i.e. all elements that are in this set but not the others.)\n | \n | difference_update(...)\n | Remove all elements of another set from this set.\n | \n | discard(...)\n | Remove an element from a set if it is a member.\n | \n | If the element is not a member, do nothing.\n | \n | intersection(...)\n | Return the intersection of two sets as a new set.\n | \n | (i.e. all elements that are in both sets.)\n | \n | intersection_update(...)\n | Update a set with the intersection of itself and another.\n | In [177]:\nsignals\n[\n0\n]\nIn [180]:\nnext\n(\niter\n(\nsignals\n))\nIn [173]:\nlist\n(\nsignals\n)[\n0\n]\nUnpacking variables\n | \n | isdisjoint(...)\n | Return True if two sets have a null intersection.\n | \n | issubset(...)\n | Report whether another set contains this set.\n | \n | issuperset(...)\n | Report whether this set contains another set.\n | \n | pop(...)\n | Remove and return an arbitrary set element.\n | Raises KeyError if the set is empty.\n | \n | remove(...)\n | Remove an element from a set; it must be a member.\n | \n | If the element is not a member, raise a KeyError.\n | \n | symmetric_difference(...)\n | Return the symmetric difference of two sets as a new set.\n | \n | (i.e. all elements that are in exactly one of the sets.)\n | \n | symmetric_difference_update(...)\n | Update a set with the symmetric difference of itself and another.\n | \n | union(...)\n | Return the union of sets as a new set.\n | \n | (i.e. all elements that are in either set.)\n | \n | update(...)\n | Update a set with the union of itself and others.\n | \n | ----------------------------------------------------------------------\n | Data and other attributes defined here:\n | \n | __hash__ = None\n---------------------------------------------------------------------------\nTypeError\n Traceback (most recent call last)\n<ipython-input-177-6c9ebb69209b>\n in \n<module>\n----> 1\n \nsignals\n[\n0\n]\nTypeError\n: 'set' object does not support indexing\nOut[180]:\n'I_MEAS'\nOut[173]:\n'I_MEAS' In [182]:\nfirst\n,\n \nsecond\n \n=\n \n[\n1\n,\n \n2\n]\nprint\n(\nfirst\n,\n \nsecond\n)\nIn [183]:\nfirst\n,\n \nsecond\n \n=\n \n(\n1\n,\n \n2\n)\nprint\n(\nfirst\n,\n \nsecond\n)\nIn [184]:\nfirst\n,\n \nsecond\n \n=\n \n{\n1\n,\n \n2\n}\nprint\n(\nfirst\n,\n \nsecond\n)\nIn [185]:\nemployees\n \n=\n \n[(\n111\n,\n \n'John'\n),\n \n(\n123\n,\n \n'Emily'\n),\n \n(\n232\n,\n \n'David'\n),\n \n(\n100\n,\n \n'Mark'\n),\n \n(\n1\n,\n \n'Andrew'\n)]\nfor\n \nemployee_id\n,\n \nemployee_name\n \nin\n \nemployees\n:\n \nprint\n(\nemployee_id\n,\n \nemployee_name\n)\n3.4. Dictionaries\nIn [186]:\nempty_set\n \n=\n \n{}\ntype\n(\nempty_set\n)\nIn [187]:\nempty_set\n \n=\n \nset\n()\ntype\n(\nempty_set\n)\nIn [188]:\nmy_dict\n \n=\n \n{\n'a'\n:\n \n1\n,\n \n'b'\n:\n \n2\n,\n \n'c'\n:\n \n3\n,\n \n'd'\n:\n \n4\n}\nmy_dict\n---------------------------------------------------------------------------\nValueError\n Traceback (most recent call last)\n<ipython-input-182-07dd77cb2d66>\n in \n<module>\n----> 1\n \nfirst\n,\n second \n=\n \n[\n1\n,\n \n2\n,\n \n3\n]\n 2\n print\n(\nfirst\n,\n second\n)\nValueError\n: too many values to unpack (expected 2)\n1 2\n1 2\n111 John\n123 Emily\n232 David\n100 Mark\n1 Andrew\nOut[186]:\ndict\nOut[187]:\nset\nOut[188]:\n{'a': 1, 'b': 2, 'c': 3, 'd': 4} In [189]:\nmy_dict\n[\n'a'\n]\nIn [190]:\nfor\n \nkey\n \nin\n \nmy_dict\n:\n \nprint\n(\nkey\n)\nIn [191]:\nfor\n \nkey\n,\n \nvalue\n \nin\n \nmy_dict\n.\nitems\n():\n \nprint\n(\nkey\n,\n \nvalue\n)\nSummary of Python Containers\nFeature\nlist\ntuple\ndict\nset\nPurpose\nan ordered collection of variables\nan ordered collection of variables\nan ordered collection of key,value pairs\na collection of variables\nDuplication of values\nyes\nyes\nunique keys, duplicate values\nno\nMutability\nyes\nno\nyes\nno\nCreation\n[1,2,3]\n(1,2,3)\n{'a':1}\n{1,2,3}\nEmpty container\n[]\n()\n{}\nset()\nComprehension\n[x for x in range(5)]\ntuple((x for x in range(5)))\n{k: v for k,v in zip(['a'], [1])}\n{x for x in range(5)}\nAccessing element\nlst[0]\ntpl[0]\ndct['key']\nnot possible\n4. Functions\nIn [1]:\n# lambda functions\nf\n \n=\n \nlambda\n \nx\n:\n \nx\n**\n2\nf\n(\n2\n)\nIn [31]:\ndef\n \nf\n(\nx\n):\n \nreturn\n \nx\n**\n2\nf\n(\n2\n)\n4.1. Arguments\nOut[189]:\n1\na\nb\nc\nd\na 1\nb 2\nc 3\nd 4\nOut[1]:\n4\nOut[31]:\n4 In [2]:\ndef\n \nf\n(\na\n,\n \nb\n,\n \nc\n=\n3\n):\n \nreturn\n \na\n+\nb\n+\nc\nf\n(\n1\n,\n2\n)\nIn [3]:\nf\n(\n1\n,\n2\n,\n \n4\n)\nIf the number of arguments matches, one can pass a list\nIn [5]:\nlst\n \n=\n \n[\n1\n,\n2\n,\n3\n]\nf\n(\n*\nlst\n)\nor a dictionary (provided that key names match the argument names) - very useful for methods with multiple arguments, e.g., plotting,\nquerying databases, etc.\nIn [6]:\ndct\n \n=\n \n{\n'a'\n:\n \n1\n,\n \n'b'\n:\n \n2\n,\n \n'c'\n:\n \n3\n}\nf\n(\n**\ndct\n)\nIn [ ]:\nquery_params\n \n=\n \n{\n'db'\n:\n \n\"NXCALS\"\n,\n \n\"signal\"\n:\n \n\"I_MEAS\"\n,\n \n\"t_start\"\n:\n \n\"today\"\n,\n \n\"t_end\"\n:\n \n\"tomorrow\"\n}\ncall_db\n(\n**\nquery_params\n)\nquery_params\n[\n'db'\n]\n \n=\n \n'PM'\ncall_db\n(\n**\nquery_params\n)\nDefault argument values\nIn [8]:\ndef\n \nf\n(\na\n,\n \nb\n,\n \nd\n,\n \nc\n=\n3\n):\n \nreturn\n \na\n+\nb\n+\nc\n+\nd\nIn [15]:\ndef\n \nf\n(\n*\nargs\n):\n \nprint\n(\nlen\n(\nargs\n))\n \nreturn\n \nargs\n[\n0\n]\n*\nargs\n[\n1\n]\n*\nargs\n[\n2\n]\nf\n(\n1\n,\n \n10\n,\n \n'a'\n)\nOut[2]:\n6\nOut[3]:\n7\nOut[5]:\n6\nOut[6]:\n6\n3\nOut[15]:\n'aaaaaaaaaa' In [38]:\ndef\n \nf\n(\n**\nkwargs\n):\n \nreturn\n \nkwargs\n[\n'a'\n]\n \n+\n \nkwargs\n[\n'b'\n]\nf\n(\na\n=\n1\n,\n \nb\n=\n2\n,\n \nc\n=\n3\n)\nIn [17]:\ndef\n \nf\n(\narg\n,\n \n*\nargs\n,\n \n**\nkwargs\n):\n \nreturn\n \narg\n \n+\n \nsum\n(\nargs\n)\n \n+\n \nkwargs\n[\n'f'\n]\nf\n(\n1\n,\n \n2\n,\n \n3\n,\n \n4\n,\n \n5\n,\n \nf\n=\n6\n)\nIn [18]:\ndef\n \nf\n(\na\n,\n \nb\n,\n \n*\n,\n \nc\n):\n \nreturn\n \na\n+\nb\n+\nc\nf\n(\n1\n,\n2\n,\n3\n)\nIn [19]:\nf\n(\n1\n,\n2\n,\nscaling\n=\n3\n)\nA function passed as an argument\nIn [20]:\ndef\n \nf\n(\nx\n):\n \nreturn\n \nx\n**\n2\ndef\n \ng\n(\nfunc\n,\n \nx\n):\n \nreturn\n \nfunc\n(\nx\n)\ng\n(\nf\n,\n2\n)\nA function can return multiple values, in fact it returns a tuple\nIn [23]:\ndef\n \nf\n():\n \nreturn\n \n'a'\n,\n \n'b'\n,\n \n's'\nf\n()\nOut[38]:\n3\nOut[17]:\n21\n---------------------------------------------------------------------------\nTypeError\n Traceback (most recent call last)\n<ipython-input-18-ff89bb262ade>\n in \n<module>\n 1\n \ndef\n f\n(\na\n,\n b\n,\n \n*\n,\n c\n)\n:\n 2\n \nreturn\n a\n+\nb\n+\nc\n----> 3\n \nf\n(\n1\n,\n2\n,\n3\n)\nTypeError\n: f() takes 2 positional arguments but 3 were given\nOut[19]:\n6\nOut[20]:\n4\nOut[23]:\n('a', 'b', 's') In [32]:\nfirst\n \n=\n \nlist\n(\nf\n())\n# print(first)\n# print(second)\nIn [33]:\nfirst\n[\n1\n]\n \n=\n \n2\nIn [34]:\nfirst\n4.2. Recursion\nFactorial of an integer $n$ is given as: \\begin{equation} n! = n*(n-1)*(n-2)*(n-3)* ... * 3 * 2 * 1 \n\\end{equation} For example: \\begin{equation}\n5! = 5 * 4 * 3 * 2 * 1 = 120 \\end{equation}\nIn [37]:\ndef\n \nfactorial\n(\nn\n):\n \nif\n \nn\n \n==\n \n1\n:\n \nreturn\n \n1\n \nelse\n:\n \nreturn\n \nn\n*\nfactorial\n(\nn\n-\n1\n)\nfactorial\n(\n3\n)\nIn [38]:\nfactorial\n(\n5\n)\nIn [39]:\nfactorial\n(\n-\n1\n)\nOut[34]:\n['a', 2, 's']\nOut[37]:\n6\nOut[38]:\n120\nERROR:root:Internal Python error in the inspect module.\nBelow is the traceback from this internal error. In [42]:\ndef\n \nfactorial\n(\nn\n):\n \nif\n \nnot\n \nisinstance\n(\nn\n,\n \nint\n)\n \nor\n \nn\n \n<=\n \n0\n:\n \nraise\n \nValueError\n(\n\"Argument is not a positive integer\"\n)\n \n \nif\n \nn\n \n==\n \n1\n:\n \nreturn\n \n1\n \nelse\n:\n \nreturn\n \nn\n*\nfactorial\n(\nn\n-\n1\n)\nfactorial\n(\n5\n)\nTraceback (most recent call last):\n File \"/usr/local/lib/swan/IPython/core/interactiveshell.py\", line 3326, in run_code\n exec(code_obj, self.user_global_ns, self.user_ns)\n File \"<ipython-input-39-5aae425d6a8b>\", line 1, in <module>\n factorial(-1)\n File \"<ipython-input-37-0017e71e028e>\", line 5, in factorial\n return n*factorial(n-1)\n File \"<ipython-input-37-0017e71e028e>\", line 5, in factorial\n return n*factorial(n-1)\n File \"<ipython-input-37-0017e71e028e>\", line 5, in factorial\n return n*factorial(n-1)\n [Previous line repeated 2967 more times]\n File \"<ipython-input-37-0017e71e028e>\", line 2, in factorial\n if n == 1:\nRecursionError: maximum recursion depth exceeded in comparison\nDuring handling of the above exception, another exception occurred:\nTraceback (most recent call last):\n File \"/usr/local/lib/swan/IPython/core/interactiveshell.py\", line 2040, in showtraceback\n stb = value._render_traceback_()\nAttributeError: 'RecursionError' object has no attribute '_render_traceback_'\nDuring handling of the above exception, another exception occurred:\nTraceback (most recent call last):\n File \"/cvmfs/sft.cern.ch/lcg/releases/Python/3.6.5-f74f0/x86_64-centos7-gcc8-opt/lib/python3.6/genericpath.p\ny\", line 19, in exists\n os.stat(path)\nFileNotFoundError: [Errno 2] No such file or directory: '<ipython-input-37-0017e71e028e>'\nDuring handling of the above exception, another exception occurred:\nTraceback (most recent call last):\n File \"/usr/local/lib/swan/IPython/core/ultratb.py\", line 1101, in get_records\n return _fixed_getinnerframes(etb, number_of_lines_of_context, tb_offset)\n File \"/usr/local/lib/swan/IPython/core/ultratb.py\", line 319, in wrapped\n return f(*args, **kwargs)\n File \"/usr/local/lib/swan/IPython/core/ultratb.py\", line 353, in _fixed_getinnerframes\n records = fix_frame_records_filenames(inspect.getinnerframes(etb, context))\n File \"/cvmfs/sft.cern.ch/lcg/releases/Python/3.6.5-f74f0/x86_64-centos7-gcc8-opt/lib/python3.6/inspect.py\",\n \nline 1483, in getinnerframes\n frameinfo = (tb.tb_frame,) + getframeinfo(tb, context)\n File \"/cvmfs/sft.cern.ch/lcg/releases/Python/3.6.5-f74f0/x86_64-centos7-gcc8-opt/lib/python3.6/inspect.py\",\n \nline 1441, in getframeinfo\n filename = getsourcefile(frame) or getfile(frame)\n File \"/cvmfs/sft.cern.ch/lcg/releases/Python/3.6.5-f74f0/x86_64-centos7-gcc8-opt/lib/python3.6/inspect.py\",\n \nline 693, in getsourcefile\n if os.path.exists(filename):\n File \"/cvmfs/sft.cern.ch/lcg/releases/Python/3.6.5-f74f0/x86_64-centos7-gcc8-opt/lib/python3.6/genericpath.p\ny\", line 19, in exists\n os.stat(path)\nKeyboardInterrupt\n---------------------------------------------------------------------------\nOut[42]:\n120 Flattening a nested list\nIn [50]:\ndef\n \nflatten_nested_lists\n(\nx\n):\n \nresult\n \n=\n \n[]\n \nfor\n \nel\n \nin\n \nx\n:\n \nif\n \nisinstance\n(\nel\n,\n \n(\nlist\n,\n \ntuple\n)):\n \nresult\n.\nextend\n(\nflatten_nested_lists\n(\nel\n))\n \nelse\n:\n \nresult\n.\nappend\n(\nel\n)\n \nreturn\n \nresult\nIn [51]:\nlst1\n \n=\n \n[\n1\n]\nlst2\n \n=\n \n[\n1\n,\n \n2\n]\nlst1\n.\nappend\n(\nlst2\n)\nlst1\nIn [51]:\nlst\n \n=\n \n[\n1\n,\n \n2\n,\n \n[\n3\n,\n4\n],\n \n[\n5\n,\n \n[\n6\n,\n \n7\n]]]\nflatten_nested_lists\n(\nlst\n)\nFibonacci\nIn [52]:\ndef\n \nfib\n(\nn\n):\n \nif\n \nn\n \n==\n \n0\n:\n \nreturn\n \n0\n \nelif\n \nn\n \n==\n \n1\n:\n \nreturn\n \n1\n \nelse\n:\n \nreturn\n \nfib\n(\nn\n-\n1\n)\n \n+\n \nfib\n(\nn\n-\n2\n)\n[\nfib\n(\ni\n)\n \nfor\n \ni\n \nin\n \nrange\n(\n6\n)]\nHow many times do we calculate fib(3)?\n---------------------------------------------------------------------------\nTypeError\n Traceback (most recent call last)\n<ipython-input-51-d821110e9bc8>\n in \n<module>\n 1\n lst1 \n=\n \n[\n1\n]\n 2\n lst2 \n=\n \n[\n1\n,\n \n2\n]\n----> 3\n \nlst1\n.\nappend\n(\n*\nlst2\n)\n 4\n lst1\nTypeError\n: append() takes exactly one argument (2 given)\nOut[51]:\n[1, 2, 3, 4, 5, 6, 7]\nOut[52]:\n[0, 1, 1, 2, 3, 5] In [56]:\narguments\n \n=\n \n[]\ndef\n \nfib\n(\nn\n):\n \narguments\n.\nappend\n(\nn\n)\n \nif\n \nn\n \n==\n \n0\n:\n \nreturn\n \n0\n \nelif\n \nn\n \n==\n \n1\n:\n \nreturn\n \n1\n \nelse\n:\n \nreturn\n \nfib\n(\nn\n-\n1\n)\n \n+\n \nfib\n(\nn\n-\n2\n)\nx\n \n=\n \n[\nfib\n(\ni\n)\n \nfor\n \ni\n \nin\n \nrange\n(\n6\n)]\nprint\n(\nx\n)\nIn [58]:\ncounts\n \n=\n \n{\ni\n:\n \narguments\n.\ncount\n(\ni\n)\n \nfor\n \ni\n \nin\n \nrange\n(\nmax\n(\narguments\n)\n+\n1\n)}\ncounts\nIn [59]:\nsum\n(\ncounts\n.\nvalues\n())\n4.3. Memoization\nIn computing, memoization or memoisation is an optimization technique used primarily to speed up computer programs by storing the results\nof expensive function calls and returning the cached result when the same inputs occur again.\nsource: \nhttps://en.wikipedia.org/wiki/Memoization\n (https://en.wikipedia.org/wiki/Memoization)\nIn [60]:\n# Memoization for Fibonacci\n# Fibonacci\nmemo\n \n=\n \n{\n0\n:\n0\n,\n \n1\n:\n1\n}\narguments\n \n=\n \n[]\ndef\n \nfib\n(\nn\n):\n \narguments\n.\nappend\n(\nn\n)\n \nif\n \nn\n \nnot\n \nin\n \nmemo\n:\n \nmemo\n[\nn\n]\n \n=\n \nfib\n(\nn\n-\n1\n)\n \n+\n \nfib\n(\nn\n-\n2\n)\n \nreturn\n \nmemo\n[\nn\n]\n[\nfib\n(\ni\n)\n \nfor\n \ni\n \nin\n \nrange\n(\n6\n)]\nIn [63]:\ncounts\n \n=\n \n{\ni\n:\n \narguments\n.\ncount\n(\ni\n)\n \nfor\n \ni\n \nin\n \nrange\n(\nmax\n(\narguments\n)\n+\n1\n)}\ncounts\n[0, 1, 1, 2, 3, 5]\nOut[58]:\n{0: 8, 1: 12, 2: 7, 3: 4, 4: 2, 5: 1}\nOut[59]:\n34\nOut[60]:\n[0, 1, 1, 2, 3, 5]\nOut[63]:\n{0: 2, 1: 3, 2: 3, 3: 3, 4: 2, 5: 1} In [62]:\nsum\n(\ncounts\n.\nvalues\n())\n4.5. Decorators\nDecorators are functions dedicated to enhance functionality of a given function, e.g., check parameter inputs, format input\nIn [59]:\ndef\n \nargument_test_natural_number\n(\nf\n):\n \ndef\n \nhelper\n(\nx\n):\n \nif\n \ntype\n(\nx\n)\n \nis\n \nint\n \nand\n \nx\n \n>\n \n0\n:\n \nreturn\n \nf\n(\nx\n)\n \nelse\n:\n \nraise\n \nException\n(\n\"Argument is not an integer\"\n)\n \nreturn\n \nhelper\ndef\n \nfactorial\n(\nn\n):\n \nif\n \nn\n \n==\n \n1\n:\n \nreturn\n \n1\n \nelse\n:\n \nreturn\n \nn\n*\nfactorial\n(\nn\n-\n1\n)\n \nfactorial\n \n=\n \nargument_test_natural_number\n(\nfactorial\n)\nfactorial\n(\n3\n)\nIn [60]:\nfactorial\n(\n-\n1\n)\nOut[62]:\n14\nOut[59]:\n6\n---------------------------------------------------------------------------\nException\n Traceback (most recent call last)\n<ipython-input-60-5aae425d6a8b>\n in \n<module>\n----> 1\n \nfactorial\n(\n-\n1\n)\n<ipython-input-59-74d7cacc5284>\n in \nhelper\n(x)\n 4\n \nreturn\n f\n(\nx\n)\n 5\n \nelse\n:\n----> 6\n \nraise\n Exception\n(\n\"Argument is not an integer\"\n)\n 7\n \nreturn\n helper\n 8\n \nException\n: Argument is not an integer In [64]:\ndef\n \nargument_test_natural_number\n(\nf\n):\n \ndef\n \nhelper\n(\nx\n):\n \nif\n \ntype\n(\nx\n)\n \nis\n \nint\n \nand\n \nx\n \n>\n \n0\n:\n \nreturn\n \nf\n(\nx\n)\n \nelse\n:\n \nraise\n \nException\n(\n\"Argument is not an integer\"\n)\n \nreturn\n \nhelper\n@argument_test_natural_number\ndef\n \nfactorial\n(\nn\n):\n \nif\n \nn\n \n==\n \n1\n:\n \nreturn\n \n1\n \nelse\n:\n \nreturn\n \nn\n*\nfactorial\n(\nn\n-\n1\n)\n \nfactorial\n(\n3\n)\nIn [65]:\nfactorial\n(\n-\n1\n)\nIn [66]:\ndef\n \nsum_aritmetic_series\n(\nn\n):\n \nreturn\n \nn\n*\n(\nn\n+\n1\n)\n/\n2\nsum_aritmetic_series\n(\n2\n)\nIn [67]:\nsum_aritmetic_series\n(\n1.5\n)\nIn [68]:\n@argument_test_natural_number\ndef\n \nsum_aritmetic_series\n(\nn\n):\n \nreturn\n \nn\n*\n(\nn\n-\n1\n)\n/\n2\nsum_aritmetic_series\n(\n2\n)\nOut[64]:\n6\n---------------------------------------------------------------------------\nException\n Traceback (most recent call last)\n<ipython-input-65-5aae425d6a8b>\n in \n<module>\n----> 1\n \nfactorial\n(\n-\n1\n)\n<ipython-input-64-61c7137e6453>\n in \nhelper\n(x)\n 4\n \nreturn\n f\n(\nx\n)\n 5\n \nelse\n:\n----> 6\n \nraise\n Exception\n(\n\"Argument is not an integer\"\n)\n 7\n \nreturn\n helper\n 8\n \nException\n: Argument is not an integer\nOut[66]:\n3.0\nOut[67]:\n1.875\nOut[68]:\n1.0 In [69]:\nsum_aritmetic_series\n(\n1.5\n)\nFixing the Fibonacci series\nIn [70]:\ndef\n \nmemoize\n(\nf\n):\n \nmemo\n \n=\n \n{}\n \ndef\n \nhelper\n(\nn\n):\n \nif\n \nn\n \nnot\n \nin\n \nmemo\n:\n \nmemo\n[\nn\n]\n \n=\n \nf\n(\nn\n)\n \nreturn\n \nmemo\n[\nn\n]\n \nreturn\n \nhelper\narguments\n \n=\n \n[]\n@memoize\ndef\n \nfib\n(\nn\n):\n \narguments\n.\nappend\n(\nn\n)\n \nif\n \nn\n \n==\n \n0\n:\n \nreturn\n \n0\n \nelif\n \nn\n \n==\n \n1\n:\n \nreturn\n \n1\n \nelse\n:\n \nreturn\n \nfib\n(\nn\n-\n1\n)\n \n+\n \nfib\n(\nn\n-\n2\n)\n[\nfib\n(\ni\n)\n \nfor\n \ni\n \nin\n \nrange\n(\n6\n)]\nIn [71]:\ncounts\n \n=\n \n{\ni\n:\n \narguments\n.\ncount\n(\ni\n)\n \nfor\n \ni\n \nin\n \nrange\n(\nmax\n(\narguments\n)\n+\n1\n)}\ncounts\nIn [72]:\nsum\n(\ncounts\n.\nvalues\n())\nThere is a built-in cache decorator\n---------------------------------------------------------------------------\nException\n Traceback (most recent call last)\n<ipython-input-69-16581ed0c766>\n in \n<module>\n----> 1\n \nsum_aritmetic_series\n(\n1.5\n)\n<ipython-input-64-61c7137e6453>\n in \nhelper\n(x)\n 4\n \nreturn\n f\n(\nx\n)\n 5\n \nelse\n:\n----> 6\n \nraise\n Exception\n(\n\"Argument is not an integer\"\n)\n 7\n \nreturn\n helper\n 8\n \nException\n: Argument is not an integer\nOut[70]:\n[0, 1, 1, 2, 3, 5]\nOut[71]:\n{0: 1, 1: 1, 2: 1, 3: 1, 4: 1, 5: 1}\nOut[72]:\n6 In [ ]:\n# built-in least-recently used cache decorator\nimport\n \nfunctools\n@functools\n.\nlru_cache\n(\nmaxsize\n=\n128\n,\n \ntyped\n=\nFalse\n)\ndef\n \nfib\n(\nn\n):\n \nif\n \nn\n \n<\n \n2\n:\n \nreturn\n \nelse\n:\n \nreturn\n \nfib\n(\nn\n-\n1\n)\n \n+\n \nfib\n(\nn\n-\n2\n)\n4.4. Static variables\nIn [73]:\n# Exercise\n# - write a decorator counting the number of times a function was called\n# - the same but for a varying number of parameters and keyword-arguments\ndef\n \ncounter\n(\nfunc\n):\n \n# first define function\n \ndef\n \nhelper\n(\nx\n,\n \n*\nargs\n,\n \n**\nkwargs\n):\n \nhelper\n.\ncount\n \n+=\n \n1\n \nreturn\n \nfunc\n(\nx\n,\n \n*\nargs\n,\n \n**\nkwargs\n)\n \n# return function as it is\n \n# then, define an attribute to be incremented with every call\n \n# this attribute behaves like a static variable\n \n# helper exist only after the function definition. Once defined, then we can attach an attribute\n \nhelper\n.\ncount\n \n=\n \n0\n \n \nreturn\n \nhelper\n@counter\ndef\n \nfun\n(\nx\n):\n \nreturn\n \nx\nfun\n(\n1\n)\nfun\n(\n2\n)\nfun\n(\n3\n)\nfun\n.\ncount\n4.6. Generators\nIn [74]:\ns\n \n=\n \n\"Python\"\nitero\n \n=\n \niter\n(\ns\n)\nitero\n# what I write is:\n# for char in s:\n# what python does:\n# for char in iter(s)\n# in fact it is a while loop until stop is reached\nIn [75]:\nnext\n(\nitero\n)\nOut[73]:\n3\nOut[74]:\n<str_iterator at 0x7f4675fb7f28>\nOut[75]:\n'P' In [76]:\nnext\n(\nitero\n)\nIn [77]:\nnext\n(\nitero\n)\nIn [78]:\nnext\n(\nitero\n)\nIn [79]:\nnext\n(\nitero\n)\nIn [80]:\nnext\n(\nitero\n)\nIn [81]:\nnext\n(\nitero\n)\nOwn generator\nIn [87]:\ndef\n \nabc_generator\n():\n \nyield\n \n\"a\"\n \nyield\n \n\"b\"\n \nyield\n \n\"c\"\n \nx\n \n=\n \nabc_generator\n()\n \n# we call like a function. A function returns an object\n \nfor\n \ni\n \nin\n \nx\n:\n \nprint\n(\ni\n)\nOut[76]:\n'y'\nOut[77]:\n't'\nOut[78]:\n'h'\nOut[79]:\n'o'\nOut[80]:\n'n'\n---------------------------------------------------------------------------\nStopIteration\n Traceback (most recent call last)\n<ipython-input-81-bc7ed7acd9c9>\n in \n<module>\n----> 1\n \nnext\n(\nitero\n)\nStopIteration\n:\n \na\nb\nc In [86]:\nnext\n(\nx\n)\nIn [80]:\n# print(next(x)) <-- yield \"a\"\n# print(next(x)) <-- yield \"b\"\n# print(next(x)) <-- yield \"c\"\n# this is a co-process. This function creates a code waiting to be executed, when we assign x = abc_generator(\n)\n# after it reaches a yield, it returns value and stops. Then next is positioned fter the yield.x\nx\n \n=\n \nabc_generator\n()\nprint\n(\nnext\n(\nx\n))\nprint\n(\nnext\n(\nx\n))\nprint\n(\nnext\n(\nx\n))\nprint\n(\nnext\n(\nx\n))\nA function is also a single-value generator\nIn [88]:\ndef\n \nabc_generator\n():\n \nreturn\n \n\"a\"\nx\n \n=\n \nabc_generator\n()\nfor\n \ni\n \nin\n \nx\n:\n \nprint\n(\ni\n)\n# works, because the returned value is iterable\nIn [82]:\ntype\n(\nabc_generator\n())\nIn [83]:\ndef\n \nabc_generator\n():\n \nfor\n \nchar\n \nin\n \n[\n\"a\"\n,\n \n\"b\"\n,\n \n\"c\"\n]:\n \nyield\n \nchar\nfor\n \ni\n \nin\n \nabc_generator\n():\n \nprint\n(\ni\n)\n---------------------------------------------------------------------------\nStopIteration\n Traceback (most recent call last)\n<ipython-input-86-92de4e9f6b1e>\n in \n<module>\n----> 1\n \nnext\n(\nx\n)\nStopIteration\n:\n \na\nb\nc\n---------------------------------------------------------------------------\nStopIteration\n Traceback (most recent call last)\n<ipython-input-80-e58ce091c0f7>\n in \n<module>\n 8\n print\n(\nnext\n(\nx\n)\n)\n 9\n print\n(\nnext\n(\nx\n)\n)\n---> 10\n \nprint\n(\nnext\n(\nx\n)\n)\nStopIteration\n:\n \na\nOut[82]:\nstr\na\nb\nc In [85]:\ntype\n(\nabc_generator\n())\nIn [ ]:\n# Generate a pi value\n# pi/4 = 1 - 1/3 + 1/5 - 1/7\ndef\n \npi_series\n():\n \nsum\n \n=\n \n0\n \ni\n \n=\n \n1.0\n \nj\n \n=\n \n1\n \nwhile\n \nTrue\n:\n \nsum\n \n=\n \nsum\n \n+\n \nj\n/\ni\n \nyield\n \n4\n*\nsum\n \ni\n \n=\n \ni\n \n+\n \n2\n \nj\n \n=\n \nj\n \n*\n \n-\n1\n# runs forever\n# we can break with a counter, but it is not a good idea\nfor\n \ni\n \nin\n \npi_series\n():\n \nprint\n(\ni\n)\nIn [ ]:\ndef\n \nfirstn\n(\ng\n,\n \nn\n):\n \nfor\n \ni\n \nin\n \nrange\n(\nn\n):\n \nyield\n \nnext\n(\ng\n)\n \nprint\n(\nlist\n(\nfirstn\n(\npi_series\n(),\n \n8\n)))\n4.7. Context Manager\nIs used to allocate and release some sort of resource when we need it.\nWhich means that before we start a block we open e.g. a file, and when we are going out, the file is automatically released.\nIf we don't close, it remains open in a file system. Closing a program, it would close. A good practice is to always close.\nWith context managers, the benefit is no need to close.\nThe issue is with the exceptions. With with, the exception is caught and handled.\nContext manager is a general concept. The concept is as follows.\nwith device():\nbefore:\n1. check device\n2. start device\nwe enter the block:\n1. we do something\nafter:\n1. we execute stop block\nin case of exceptions we are sure that the after part will be executed.\nIn [ ]:\nimport\n \ncsv\nwith\n \nopen\n(\n'example.txt'\n,\n \n'w'\n)\n \nas\n \nout\n:\n \ncsv_out\n \n=\n \ncsv\n.\nwriter\n(\nout\n)\n \ncsv_out\n.\nwriterow\n([\n'date'\n,\n \n'# events'\n])\nOut[85]:\ngenerator In [ ]:\nfrom\n \ncontextlib\n \nimport\n \ncontextmanager\n@contextmanager\ndef\n \ndevice\n():\n \nprint\n(\n\"Check device\"\n)\n \ndevice_state\n \n=\n \nTrue\n \nprint\n(\n\"Start device\"\n)\n \nyield\n \ndevice_state\n \n# the block after with is executed\n \nprint\n(\n\"Stop device\"\n)\nwith\n \ndevice\n()\n \nas\n \nstate\n:\n \nprint\n(\n\"State is \"\n,\n \nstate\n)\n \nprint\n(\n\"Device is running!\"\n)\n5. Exception handling\nException handling\nIt is easier to ask for forgiveness than for permission\nE.g.\nif fileexisits(file_name):\n txt = open(file_name).read()\nWe first check if the file exists, then in the next step we fetch the file - two operations (asking for permission)\nWe can try to read, if it is there we are good, otherwise it raises an exception - single operation (asking for forgiveness)\ntry:\n txt = open(file_name)\nexcept Exception as e:\n txt = \"\"\nIn [ ]:\nwhile\n \nTrue\n:\n \ntry\n:\n \nx\n \n=\n \nint\n(\ninput\n(\n\"Please enter a number: \"\n))\n \nbreak\n \nexcept\n \nValueError\n \nas\n \nerr\n:\n \nprint\n(\n\"Error message: \"\n,\n \nerr\n)\n \nprint\n(\n\"No valid number. Try again\"\n)\ntry:\n some code\nexcept ZeroDivisionError:\n some code\n there could be a raise here\nexcept FooError:\n some code\nexcept BarError:\n some code\nfinally:\n some code executed always In [ ]:\n# Finally is executed always\ntry\n:\n \nx\n \n=\n \nfloat\n(\ninput\n(\n\"Your number: \"\n))\n \ninverse\n \n=\n \n10\n/\nx\nexcept\n \nValueError\n \nas\n \nerr\n:\n \nprint\n(\n\"Error message: \"\n,\n \nerr\n)\n \nprint\n(\n\"No valid number. Try again\"\n)\nfinally\n:\n \nprint\n(\n\"There may or may not have been an exception.\"\n)\nprint\n(\n\"The inverse: \"\n,\n \ninverse\n)\nIn [ ]:\n# assert\nx\n \n=\n \n5\ny\n \n=\n \n6\nassert\n \nx\n \n<\n \ny\n,\n \n\"x has to be smaller than y\""}...
|
1769077888
|
/home/sid/xevyo/open-webui-dev/backend/data/upload /home/sid/xevyo/open-webui-dev/backend/data/uploads/6c1cd5e1-c1ba-4c19-a221-e3e2ddb87851_Advanced_Programming_with_Python.pdf...
|
null
|
Edit
Delete
|
|
0f3f6321-0d56-49a0-99a0-b006c54b5780
|
8684964a-bab1-4235-93a8-5fd5e24a1d0a
|
Advanced_Programming_with_Python.pdf
|
{"name": "Advanced_Programming_with_Py {"name": "Advanced_Programming_with_Python.pdf", "content_type": "application/pdf", "size": 309695, "data": {"additionalProp1": {}}, "collection_name": "file-0f3f6321-0d56-49a0-99a0-b006c54b5780"}...
|
1770016499
|
55c5aee2f971594476d3a95a0c4ddb104a3f5d0b9b5f8cd7fb 55c5aee2f971594476d3a95a0c4ddb104a3f5d0b9b5f8cd7fbf3e857379eb17d...
|
{"status": "completed", "conte {"status": "completed", "content": "Advanced Programming with Python\nDISCLAIMER: The presented material relies heavily on Python Advance course carried out at CERN. The material is also available freely at\nthe website: \nhttps://www.python-course.eu\n (https://www.python-course.eu)\n1\n. \nWhat is a variable\n2\n. \nBasic types\nstring\nenum\n3\n. \nContainers\nlists\ntuples\nsets\ndictionaries\n4\n. \nFunctions\narguments\nrecursion\nstatic variables\ndecorators\ngenerators\ncontext managers\n5\n. \nException Handling\nNot included\n:\n6\n. \nObject Oriented Programming\n7\n. \nPackaging\n8\n. \nDocumentation\n9\n. \nUnit testing\n10\n. \nContinuous Integration\nIn 1999, Guido Van Rossum submitted a funding proposal to DARPA called \"Computer Programming for Everybody\", in which he further\ndefined his goals for Python:\nAn easy and intuitive language just as powerful as major competitors\nOpen source, so anyone can contribute to its development\nCode that is as understandable as plain English\nSuitability for everyday tasks, allowing for short development times\n0. Hello world\nIn [1]:\nprint\n(\n'Hello world!'\n)\n0.1. Zen of Python\nHello world! In [2]:\nimport\n \nthis\n1. What is a variable?\nVariable in python is always a reference to an object as in python everything, even a function, is an object.\nIn [3]:\nx\n \n=\n \n3\ny\n \n=\n \nx\ny\n,\n \nx\nIn [4]:\nx\n \n=\n \n2\nIn [5]:\ny\n,\n \nx\nConditional statement to assign a value\nIn [6]:\nx\n \n=\n \n-\n5\nif\n \nx\n \n>\n \n0\n:\n \nlabel\n \n=\n \n'Pos'\nelse\n:\n \nlabel\n \n=\n \n'Neg'\nprint\n(\nlabel\n)\nThe Zen of Python, by Tim Peters\nBeautiful is better than ugly.\nExplicit is better than implicit.\nSimple is better than complex.\nComplex is better than complicated.\nFlat is better than nested.\nSparse is better than dense.\nReadability counts.\nSpecial cases aren't special enough to break the rules.\nAlthough practicality beats purity.\nErrors should never pass silently.\nUnless explicitly silenced.\nIn the face of ambiguity, refuse the temptation to guess.\nThere should be one-- and preferably only one --obvious way to do it.\nAlthough that way may not be obvious at first unless you're Dutch.\nNow is better than never.\nAlthough never is often better than *right* now.\nIf the implementation is hard to explain, it's a bad idea.\nIf the implementation is easy to explain, it may be a good idea.\nNamespaces are one honking great idea -- let's do more of those!\nOut[3]:\n(3, 3)\nOut[5]:\n(3, 2)\nNeg In [7]:\nx\n \n=\n \n-\n5\nlabel\n \n=\n \n'Pos'\n \nif\n \nx\n \n>\n \n0\n \nelse\n \n'Neg'\nprint\n(\nlabel\n)\nIn [28]:\nprint\n(\n'Pos'\n \nif\n \nx\n \n>\n \n0\n \nelse\n \n'Neg'\n)\n2. Basic types\n2.1. String\nStrings in python are immutable\nIn [14]:\nstring\n \n=\n \n'My string'\nstring\n[\n0\n]\n \n=\n \n'T'\nIn [15]:\nstring\n.\nreplace\n(\n'M'\n,\n \n'T'\n)\nIn [16]:\nstring\nString is iterable\nIn [17]:\nfor\n \ns\n \nin\n \n'My string'\n:\n \nprint\n(\ns\n)\nFormating of strings\nNeg\nNeg\n---------------------------------------------------------------------------\nTypeError\n Traceback (most recent call last)\n<ipython-input-14-9c1867d9b2ff>\n in \n<module>\n 1\n string \n=\n \n'My string'\n----> 2\n \nstring\n[\n0\n]\n \n=\n \n'T'\nTypeError\n: 'str' object does not support item assignment\nOut[15]:\n'Ty string'\nOut[16]:\n'My string'\nM\ny\n \ns\nt\nr\ni\nn\ng In [18]:\nfrom\n \ndatetime\n \nimport\n \ndate\n'Today is '\n \n+\n \nstr\n(\ndate\n.\ntoday\n())\n \n+\n \n'.'\nIn [23]:\n'Today is \n{}\n and number \n{}\n.'\n.\nformat\n(\ndate\n.\ntoday\n(),\n \n[\n1\n,\n \n2\n,\n \n3\n])\nf-strings have been introduced in Python 3.6\nIn [21]:\nprint\n(\nf\n'Today is {date.today()}'\n)\nCheck if a substring is in a string\nIn [25]:\nif\n \n'sub'\n \nin\n \n'substring'\n:\n \nprint\n(\n'True'\n)\nThere are already many built-in functions for handling strings in Python\nIn [29]:\ndir\n(\nlist\n)\nOut[18]:\n'Today is 2019-11-28.'\nOut[23]:\n'Today is 2019-11-28 and number [1, 2, 3].'\nToday is 2019-11-28\nTrue In [26]:\ndir\n(\nstr\n)\nOut[29]:\n['__add__',\n '__class__',\n '__contains__',\n '__delattr__',\n '__delitem__',\n '__dir__',\n '__doc__',\n '__eq__',\n '__format__',\n '__ge__',\n '__getattribute__',\n '__getitem__',\n '__gt__',\n '__hash__',\n '__iadd__',\n '__imul__',\n '__init__',\n '__init_subclass__',\n '__iter__',\n '__le__',\n '__len__',\n '__lt__',\n '__mul__',\n '__ne__',\n '__new__',\n '__reduce__',\n '__reduce_ex__',\n '__repr__',\n '__reversed__',\n '__rmul__',\n '__setattr__',\n '__setitem__',\n '__sizeof__',\n '__str__',\n '__subclasshook__',\n 'append',\n 'clear',\n 'copy',\n 'count',\n 'extend',\n 'index',\n 'insert',\n 'pop',\n 'remove',\n 'reverse',\n 'sort']\nOut[26]:\n['__add__',\n '__class__',\n '__contains__',\n '__delattr__',\n '__dir__',\n '__doc__',\n '__eq__',\n '__format__',\n '__ge__',\n '__getattribute__',\n '__getitem__',\n '__getnewargs__',\n '__gt__',\n '__hash__',\n '__init__',\n '__init_subclass__',\n '__iter__',\n '__le__', In [32]:\n'my first sentence'\n.\nupper\n()\n '__le__',\n '__len__',\n '__lt__',\n '__mod__',\n '__mul__',\n '__ne__',\n '__new__',\n '__reduce__',\n '__reduce_ex__',\n '__repr__',\n '__rmod__',\n '__rmul__',\n '__setattr__',\n '__sizeof__',\n '__str__',\n '__subclasshook__',\n 'capitalize',\n 'casefold',\n 'center',\n 'count',\n 'encode',\n 'endswith',\n 'expandtabs',\n 'find',\n 'format',\n 'format_map',\n 'index',\n 'isalnum',\n 'isalpha',\n 'isdecimal',\n 'isdigit',\n 'isidentifier',\n 'islower',\n 'isnumeric',\n 'isprintable',\n 'isspace',\n 'istitle',\n 'isupper',\n 'join',\n 'ljust',\n 'lower',\n 'lstrip',\n 'maketrans',\n 'partition',\n 'replace',\n 'rfind',\n 'rindex',\n 'rjust',\n 'rpartition',\n 'rsplit',\n 'rstrip',\n 'split',\n 'splitlines',\n 'startswith',\n 'strip',\n 'swapcase',\n 'title',\n 'translate',\n 'upper',\n 'zfill']\nOut[32]:\n'MY FIRST SENTENCE' 2.2. Enum\nEnum is a data type which links a name to an index. They are useful to represent a closed set of options\nIn [33]:\nfrom\n \nenum\n \nimport\n \nEnum\nclass\n \nQhBrowserAction\n(\nEnum\n):\n \nQUERY_BUTTON_CLICKED\n \n=\n \n1\n \nSAVE_BUTTON_CLICKED\n \n=\n \n2\n \nDATE_CHANGED\n \n=\n \n3\n \nQH_NAME_CHANGED\n \n=\n \n4\n \nSLIDER_MOVED\n \n=\n \n5\na\n \n=\n \nQhBrowserAction\n.\nDATE_CHANGED\na\n.\nname\n,\n \na\n.\nvalue\nIn [36]:\na_next\n \n=\n \nQhBrowserAction\n(\na\n.\nvalue\n+\n1\n)\na_next\nIn [38]:\nif\n \na_next\n \n==\n \nQhBrowserAction\n.\nQH_NAME_CHANGED\n:\n \nprint\n(\n'In state \n{}\n'\n.\nformat\n(\na_next\n.\nvalue\n))\n3. Containers\nContainer data types in Python are dedicated to store multiple variables of a various type. The basic container types are: lists, tuples, sets,\ndictionaries.\n3.1. Lists\nIn [39]:\nmy_list\n \n=\n \n[\n1\n,\n \n'b'\n,\n \nTrue\n]\nmy_list\nLists are 0-indexed and elements are accessed by a square bracket\nIn [40]:\nmy_list\n[\n0\n]\nLists are mutable\nOut[33]:\n('DATE_CHANGED', 3)\nOut[36]:\n<QhBrowserAction.QH_NAME_CHANGED: 4>\nIn state 4\nOut[39]:\n[1, 'b', True]\nOut[40]:\n1 In [42]:\nmy_list\n[\n1\n]\n \n=\n \n0\nmy_list\nIn order to extend a list one can either append...\nIn [44]:\nmy_list\n.\nappend\n(\n3\n)\nmy_list\nOr simply\nIn [45]:\nmy_list\n \n+\n \n[\n1\n,\n \n'b'\n]\n...or append elements\nIn [ ]:\nmy_list\n \n+=\n \n[\n3\n]\nmy_list\nIn [ ]:\nmy_list\n \n=\n \nmy_list\n \n+\n \n[\n3\n]\n \n# One shall not do that\nmy_list\nBe careful with the last assignment, this creates a new list, so a need to perfom a copy - very inefficient for large lists.\nHow to append a list at the end?\nIn [47]:\nmy_list\n.\nappend\n([\n1\n,\n \n'a'\n])\nmy_list\nThis adds a list as an element, which is not quite what we wanted.\nIn [58]:\nmy_list\n.\nextend\n([\n5\n])\nmy_list\nOut[42]:\n[0, 0, True]\nOut[44]:\n[0, 0, True, 3, 3]\nOut[45]:\n[0, 0, True, 3, 3, 1, 'b']\nOut[47]:\n[0, 0, True, 3, 3, 3, [1, 'a']]\nOut[58]:\n[0, 0, True, 3, 3, 3, [1, 'a'], 1, 'a', 1, 'a', [1, 2], '5', 5] In [53]:\nimport\n \nitertools\nlist2d\n \n=\n \n[[\n1\n,\n2\n,\n3\n],\n \n[\n4\n,\n5\n,\n6\n],\n \n[\n7\n],\n \n[\n8\n,\n9\n]]\nmerged\n \n=\n \nlist\n(\nitertools\n.\nchain\n(\n*\nlist2d\n))\nmerged\nWhich one to choose in order to add elements efficiently?\nhttps://stackoverflow.com/questions/252703/what-is-the-difference-between-pythons-list-methods-append-and-extend\n(https://stackoverflow.com/questions/252703/what-is-the-difference-between-pythons-list-methods-append-and-extend)\n3.1.1. List comprehension\nOld-fashioned way\nIn [59]:\nmy_list\n \n=\n \n[]\nfor\n \ni\n \nin\n \nrange\n(\n10\n):\n \nmy_list\n.\nappend\n(\ni\n)\nmy_list\nOne-line list comprehension\nIn [75]:\nabs\n(\n0.1\n \n-\n \n(\n1.1\n-\n1\n))\n \n<\n \n1e-16\nIn [65]:\nmy_list\n \n=\n \n[\n1\n/\n(\ni\n+\n1\n)\n \nfor\n \ni\n \nin\n \nrange\n(\n10\n)]\nmy_list\nIn [66]:\nmy_list\n \n=\n \n[\ni\n \nfor\n \ni\n \nin\n \nrange\n(\n10\n)\n \nif\n \ni\n \n>\n \n4\n]\nmy_list\nGenerator comprehension\nOut[53]:\n[[1, 2, 3], [4, 5, 6], [7], [8, 9]]\nOut[59]:\n[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\nOut[75]:\nTrue\nOut[65]:\n[1.0,\n 0.5,\n 0.3333333333333333,\n 0.25,\n 0.2,\n 0.16666666666666666,\n 0.14285714285714285,\n 0.125,\n 0.1111111111111111,\n 0.1]\nOut[66]:\n[5, 6, 7, 8, 9] In [76]:\nx\n \n=\n \n(\nx\n**\n2\n \nfor\n \nx\n \nin\n \nrange\n(\n10\n))\nprint\n(\nx\n)\nIn [87]:\nnext\n(\nx\n)\nIn [93]:\nimport\n \ndatetime\nstr\n(\ndatetime\n.\ndatetime\n.\nnow\n())\nIn [103]:\nprint\n(\ndatetime\n.\ndatetime\n.\nnow\n())\nfor\n \nx\n \nin\n \n((\nx\n+\n1\n)\n**\n2\n \nfor\n \nx\n \nin\n \nrange\n(\nint\n(\n1e7\n))):\n \nx\n**\n(\n-\n1\n/\n2\n)\nprint\n(\ndatetime\n.\ndatetime\n.\nnow\n())\nIn [104]:\nprint\n(\ndatetime\n.\ndatetime\n.\nnow\n())\nlst\n \n=\n \n[(\nx\n+\n1\n)\n**\n2\n \nfor\n \nx\n \nin\n \nrange\n(\nint\n(\n1e7\n))]\nfor\n \nx\n \nin\n \nlst\n:\n \nx\n**\n(\n-\n1\n/\n2\n)\nprint\n(\ndatetime\n.\ndatetime\n.\nnow\n())\nGenerator returns values on demand - no need to create a table and than iterate over it\nIn [111]:\nx\n \n=\n \niter\n(\nrange\n(\n10\n))\nnext\n(\nx\n)\nIn [ ]:\nx\n \n=\n \n(\nx\n**\n2\n \nfor\n \nx\n \nin\n \nrange\n(\n10\n))\nlist\n(\nx\n)\n3.1.2. Filter, map, reduce\n<generator object <genexpr> at 0x7faceb983468>\n---------------------------------------------------------------------------\nStopIteration\n Traceback (most recent call last)\n<ipython-input-87-92de4e9f6b1e>\n in \n<module>\n----> 1\n \nnext\n(\nx\n)\nStopIteration\n:\n \nOut[93]:\n'2019-11-28 11:24:28.029777'\n2019-11-28 11:27:55.759043\n2019-11-28 11:28:01.770323\n2019-11-28 11:28:09.839305\n2019-11-28 11:28:15.530292\nOut[111]:\n0 In [105]:\nmy_list\n \n=\n \n[\n-\n5\n,\n \n-\n4\n,\n \n-\n3\n,\n \n-\n2\n,\n \n-\n1\n,\n \n0\n,\n \n1\n,\n \n2\n,\n \n3\n,\n \n4\n,\n \n5\n]\nfilter\n(\nlambda\n \nx\n:\n \nx\n>\n0\n,\n \nmy_list\n)\nFilter returns an iterable generator. Generator is a very important concept in Python!\nIn [106]:\nfor\n \nel\n \nin\n \nfilter\n(\nlambda\n \nx\n:\n \nx\n>\n0\n,\nmy_list\n):\n \nprint\n(\nel\n)\nIn [112]:\nlist\n(\nfilter\n(\nlambda\n \nx\n:\n \nx\n>\n0\n,\n \nmy_list\n))\nMap\nIn [113]:\nprint\n(\nmy_list\n)\nlist\n(\nmap\n(\nlambda\n \nx\n:\n \nabs\n(\nx\n),\n \nmy_list\n))\nMap can be applied to many lists\nIn [114]:\nlst1\n \n=\n \n[\n0\n,\n1\n,\n2\n,\n3\n,\n4\n]\nlst2\n \n=\n \n[\n5\n,\n6\n,\n7\n,\n8\n]\nlist\n(\nmap\n(\nlambda\n \nx\n,\n \ny\n:\n \nx\n+\ny\n,\n \nlst1\n,\n \nlst2\n))\nReduce\nIn [115]:\nsum\n([\n0\n,\n1\n,\n2\n,\n3\n,\n4\n,\n5\n,\n6\n,\n7\n,\n8\n,\n9\n,\n10\n])\nOut[105]:\n<filter at 0x7face70b88d0>\n1\n2\n3\n4\n5\nOut[112]:\n[1, 2, 3, 4, 5]\n[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]\nOut[113]:\n[5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5]\nOut[114]:\n[5, 7, 9, 11]\nOut[115]:\n55 In [116]:\nfrom\n \nfunctools\n \nimport\n \nreduce\nreduce\n(\nlambda\n \nx\n,\n \ny\n:\n \nx\n+\ny\n,\n \n[\n0\n,\n1\n,\n2\n,\n3\n,\n4\n,\n5\n,\n6\n,\n7\n,\n8\n,\n9\n,\n10\n])\n$0+1+...+n = \\frac{n(n+1)}{2}$\n3.1.3. Iterating over lists\nIn [119]:\ni\n \n=\n \n0\nfor\n \nel\n \nin\n \n[\n-\n5\n,\n \n-\n4\n,\n \n-\n3\n,\n \n-\n2\n,\n \n-\n1\n,\n \n0\n,\n \n1\n,\n \n2\n,\n \n3\n,\n \n4\n,\n \n5\n]:\n \nprint\n(\ni\n,\n \nel\n)\n \ni\n \n+=\n \n1\nIterating with index\nIn [118]:\nfor\n \nindex\n,\n \nel\n \nin\n \nenumerate\n([\n-\n5\n,\n \n-\n4\n,\n \n-\n3\n,\n \n-\n2\n,\n \n-\n1\n,\n \n0\n,\n \n1\n,\n \n2\n,\n \n3\n,\n \n4\n,\n \n5\n]):\n \nprint\n(\nindex\n,\n \nel\n)\nIterating over two (many) lists\nIn [120]:\nletters\n \n=\n \n[\n'a'\n,\n \n'b'\n,\n \n'c'\n,\n \n'd'\n]\nnumbers\n \n=\n \n[\n1\n,\n \n2\n,\n \n3\n,\n \n4\n,\n \n5\n]\nfor\n \nl\n,\n \nn\n \nin\n \nzip\n(\nletters\n,\n \nnumbers\n):\n \nprint\n(\nl\n,\n \nn\n)\nOut[116]:\n55\n0 -5\n1 -4\n2 -3\n3 -2\n4 -1\n5 0\n6 1\n7 2\n8 3\n9 4\n10 5\n0 -5\n1 -4\n2 -3\n3 -2\n4 -1\n5 0\n6 1\n7 2\n8 3\n9 4\n10 5\na 1\nb 2\nc 3\nd 4 In [122]:\nlist\n(\nzip\n(\nletters\n,\n \nnumbers\n))\nIn [124]:\ndict\n(\nzip\n(\nletters\n,\n \nnumbers\n))\nIn [125]:\nhelp\n(\nzip\n)\n3.1.4. Copying lists\nIn [126]:\nx\n \n=\n \n[\n1\n,\n \n2\n,\n \n3\n,\n \n4\n]\ny\n \n=\n \nx\ny\n[\n0\n]\n \n=\n \n'a'\nprint\n(\nx\n,\n \ny\n)\nIn [128]:\nx\n.\ncopy\n()\nOut[122]:\n[('a', 1), ('b', 2), ('c', 3), ('d', 4)]\nOut[124]:\n{'a': 1, 'b': 2, 'c': 3, 'd': 4}\nHelp on class zip in module builtins:\nclass zip(object)\n | zip(iter1 [,iter2 [...]]) --> zip object\n | \n | Return a zip object whose .__next__() method returns a tuple where\n | the i-th element comes from the i-th iterable argument. The .__next__()\n | method continues until the shortest iterable in the argument sequence\n | is exhausted and then it raises StopIteration.\n | \n | Methods defined here:\n | \n | __getattribute__(self, name, /)\n | Return getattr(self, name).\n | \n | __iter__(self, /)\n | Implement iter(self).\n | \n | __new__(*args, **kwargs) from builtins.type\n | Create and return a new object. See help(type) for accurate signature.\n | \n | __next__(self, /)\n | Implement next(self).\n | \n | __reduce__(...)\n | Return state information for pickling.\n['a', 2, 3, 4] ['a', 2, 3, 4]\nOut[128]:\n[1, 2, 3, 4] In [127]:\nx\n \n=\n \n[\n1\n,\n \n2\n,\n \n3\n,\n \n4\n]\ny\n \n=\n \nx\n.\ncopy\n()\ny\n[\n0\n]\n \n=\n \n'a'\nprint\n(\nx\n,\n \ny\n)\nIn [129]:\nx\n \n=\n \n[[\n1\n,\n \n'a'\n],\n \n2\n,\n \n3\n,\n \n4\n]\ny\n \n=\n \nx\n.\ncopy\n()\n \n# equivalent to x[:]\ny\n[\n0\n]\n \n=\n \n'a'\nprint\n(\nx\n,\n \ny\n)\nIn [131]:\nx\n \n=\n \n[[\n1\n,\n \n'a'\n],\n \n2\n,\n \n3\n,\n \n4\n]\ny\n \n=\n \nx\n.\ncopy\n()\ny\n[\n0\n][\n0\n]\n \n=\n \n'b'\nprint\n(\nx\n,\n \ny\n)\nThe reason for this behavior is that Python performs a shallow copy.\nIn [132]:\nfrom\n \ncopy\n \nimport\n \ndeepcopy\nx\n \n=\n \n[[\n1\n,\n \n'a'\n],\n \n2\n,\n \n3\n,\n \n4\n]\ny\n \n=\n \ndeepcopy\n(\nx\n)\ny\n[\n0\n][\n0\n]\n \n=\n \n'b'\nprint\n(\nx\n,\n \ny\n)\n3.1.5. Sorting lists - inplace operations\nIn [133]:\nx\n \n=\n \n[\n1\n,\n \n10\n,\n \n2\n,\n \n9\n,\n \n3\n,\n \n8\n,\n \n4\n,\n \n6\n,\n \n5\n]\nx\n \n=\n \nx\n.\nsort\n()\nprint\n(\nx\n)\nlist.sort() is an inplace operation. In general, inplace operations are efficient as they do not create a new copy in memory\nIn [134]:\nx\n \n=\n \n[\n1\n,\n \n10\n,\n \n2\n,\n \n9\n,\n \n3\n,\n \n8\n,\n \n4\n,\n \n6\n,\n \n5\n]\nx\n.\nsort\n()\nprint\n(\nx\n)\nlist.sorted does create a new variable\nIn [135]:\nx\n \n=\n \n[\n1\n,\n \n10\n,\n \n2\n,\n \n9\n,\n \n3\n,\n \n8\n,\n \n4\n,\n \n6\n,\n \n5\n]\nsorted\n(\nx\n)\nprint\n(\nx\n)\n[1, 2, 3, 4] ['a', 2, 3, 4]\n[[1, 'a'], 2, 3, 4] ['a', 2, 3, 4]\n[['b', 'a'], 2, 3, 4] [['b', 'a'], 2, 3, 4]\n[[1, 'a'], 2, 3, 4] [['b', 'a'], 2, 3, 4]\nNone\n[1, 2, 3, 4, 5, 6, 8, 9, 10]\n[1, 10, 2, 9, 3, 8, 4, 6, 5] In [136]:\nx\n \n=\n \n[\n1\n,\n \n10\n,\n \n2\n,\n \n9\n,\n \n3\n,\n \n8\n,\n \n4\n,\n \n6\n,\n \n5\n]\nx\n \n=\n \nsorted\n(\nx\n)\nprint\n(\nx\n)\nIn [137]:\nx\n \n=\n \n[\n1\n,\n \n10\n,\n \n2\n,\n \n9\n,\n \n3\n,\n \n8\n,\n \n4\n,\n \n6\n,\n \n5\n]\nx\n \nis\n \nsorted\n(\nx\n)\nHow to sort in a reverted order\nIn [139]:\nx\n \n=\n \n[\n1\n,\n \n10\n,\n \n2\n,\n \n9\n,\n \n3\n,\n \n8\n,\n \n4\n,\n \n6\n,\n \n5\n]\nx\n.\nsort\n(\nreverse\n=\nTrue\n)\nprint\n(\nx\n)\nSort nested lists\nIn [140]:\nemployees\n \n=\n \n[(\n111\n,\n \n'John'\n),\n \n(\n123\n,\n \n'Emily'\n),\n \n(\n232\n,\n \n'David'\n),\n \n(\n100\n,\n \n'Mark'\n),\n \n(\n1\n,\n \n'Andrew'\n)]\nemployees\n.\nsort\n(\nkey\n=\nlambda\n \nx\n:\n \nx\n[\n0\n])\nemployees\nIn [141]:\nemployees\n \n=\n \n[(\n111\n,\n \n'John'\n),\n \n(\n123\n,\n \n'Emily'\n),\n \n(\n232\n,\n \n'David'\n),\n \n(\n100\n,\n \n'Mark'\n),\n \n(\n1\n,\n \n'Andrew'\n)]\nemployees\n.\nsort\n(\nkey\n=\nlambda\n \nx\n:\n \nx\n[\n1\n])\nemployees\nAlso with reversed order\nIn [142]:\nemployees\n \n=\n \n[(\n111\n,\n \n'John'\n),\n \n(\n123\n,\n \n'Emily'\n),\n \n(\n232\n,\n \n'David'\n),\n \n(\n100\n,\n \n'Mark'\n),\n \n(\n1\n,\n \n'Andrew'\n)]\nemployees\n.\nsort\n(\nkey\n=\nlambda\n \nx\n:\n \nx\n[\n0\n],\n \nreverse\n=\nTrue\n)\nemployees\n3.1.6. List extras\n[1, 2, 3, 4, 5, 6, 8, 9, 10]\nOut[137]:\nFalse\n[10, 9, 8, 6, 5, 4, 3, 2, 1]\nOut[140]:\n[(1, 'Andrew'), (100, 'Mark'), (111, 'John'), (123, 'Emily'), (232, 'David')]\nOut[141]:\n[(1, 'Andrew'), (232, 'David'), (123, 'Emily'), (111, 'John'), (100, 'Mark')]\nOut[142]:\n[(232, 'David'), (123, 'Emily'), (111, 'John'), (100, 'Mark'), (1, 'Andrew')] In [143]:\nmy_list\n \n=\n \n5\n*\n[\n'a'\n]\nmy_list\nIn [144]:\n3\n \nin\n \n[\n1\n,\n2\n,\n3\n,\n4\n,\n5\n]\nIn [149]:\nx\n \n=\n \n[\n'a'\n]\ny\n \n=\n \n[\n'a'\n]\nx\n \n==\n \ny\nIn [150]:\nx\n \n=\n \n(\n'a'\n)\ny\n \n=\n \n(\n'a'\n)\nx\n \nis\n \ny\n3.2. Tuples\nTuples, similarly to lists can stores elements of different types.\nIn [152]:\nmy_tuple\n \n=\n \n(\n1\n,\n2\n,\n3\n)\nmy_tuple\nIn [153]:\nmy_tuple\n[\n0\n]\nUnlike the lists, tuples are immutable.\nIn [154]:\nmy_tuple\n[\n0\n]\n=\n0\nOut[143]:\n['a', 'a', 'a', 'a', 'a']\nOut[144]:\nTrue\nOut[149]:\nTrue\nOut[150]:\nTrue\nOut[152]:\n(1, 2, 3)\nOut[153]:\n1\n---------------------------------------------------------------------------\nTypeError\n Traceback (most recent call last)\n<ipython-input-154-a0c25be542d6>\n in \n<module>\n----> 1\n \nmy_tuple\n[\n0\n]\n=\n0\nTypeError\n: 'tuple' object does not support item assignment In [159]:\ntuple\n([\n1\n,\n2\n,\n3\n])\n3.3. Sets\nSets are immutable and contain only unique elements\nIn [155]:\n{\n1\n,\n2\n,\n3\n,\n4\n}\nIn [156]:\n{\n1\n,\n2\n,\n3\n,\n4\n,\n4\n}\nSo this is a neat way for obtaining unique elements in a list\nIn [157]:\nmy_list\n \n=\n \n[\n1\n,\n \n2\n,\n \n3\n,\n \n4\n,\n \n4\n,\n \n5\n,\n \n5\n,\n \n5\n]\nset\n(\nmy_list\n)\nor a tuple\nIn [158]:\nmy_tuple\n \n=\n \n(\n1\n,\n \n2\n,\n \n3\n,\n \n4\n,\n \n4\n,\n \n5\n,\n \n5\n,\n \n5\n)\nset\n(\nmy_tuple\n)\nOne can perform set operations on sets ;-)\nIn [160]:\nA\n \n=\n \n{\n1\n,\n2\n,\n3\n}\nB\n \n=\n \n{\n3\n,\n4\n,\n5\n}\nprint\n(\nf\n'A+B={A.union(B)}'\n)\nprint\n(\nf\n'A-B={A-B}'\n)\nprint\n(\nf\n'A*B={A.intersection(B)}'\n)\nprint\n(\nf\n'A*0={A.intersection(\n{}\n)}'\n)\nOut[159]:\n(1, 2, 3)\nOut[155]:\n{1, 2, 3, 4}\nOut[156]:\n{1, 2, 3, 4}\nOut[157]:\n{1, 2, 3, 4, 5}\nOut[158]:\n{1, 2, 3, 4, 5}\nA+B={1, 2, 3, 4, 5}\nA-B={1, 2}\nA*B={3}\nA*0=set() In [165]:\npm\n \n=\n \n{\n'system'\n,\n \n'source'\n,\n \n'I_MEAS'\n,\n \n'I_REF'\n}\nsignals\n \n=\n \npm\n \n-\n \n{\n'system'\n,\n \n'source'\n}\nsignals\nIn [174]:\nfor\n \ns\n \nin\n \nsignals\n:\n \nprint\n(\ns\n)\nIn [175]:\nhelp\n(\nset\n)\nOut[165]:\n{'I_MEAS', 'I_REF'}\nI_MEAS\nI_REF\nHelp on class set in module builtins:\nclass set(object)\n | set() -> new empty set object\n | set(iterable) -> new set object\n | \n | Build an unordered collection of unique elements.\n | \n | Methods defined here:\n | \n | __and__(self, value, /)\n | Return self&value.\n | \n | __contains__(...)\n | x.__contains__(y) <==> y in x.\n | \n | __eq__(self, value, /)\n | Return self==value.\n | \n | __ge__(self, value, /)\n | Return self>=value.\n | \n | __getattribute__(self, name, /)\n | Return getattr(self, name).\n | \n | __gt__(self, value, /)\n | Return self>value.\n | \n | __iand__(self, value, /)\n | Return self&=value.\n | \n | __init__(self, /, *args, **kwargs)\n | Initialize self. See help(type(self)) for accurate signature.\n | \n | __ior__(self, value, /)\n | Return self|=value.\n | \n | __isub__(self, value, /)\n | Return self-=value.\n | \n | __iter__(self, /)\n | Implement iter(self).\n | \n | __ixor__(self, value, /)\n | Return self^=value.\n | \n | __le__(self, value, /)\n | Return self<=value.\n | \n | __len__(self, /)\n | Return len(self). | Return len(self).\n | \n | __lt__(self, value, /)\n | Return self<value.\n | \n | __ne__(self, value, /)\n | Return self!=value.\n | \n | __new__(*args, **kwargs) from builtins.type\n | Create and return a new object. See help(type) for accurate signature.\n | \n | __or__(self, value, /)\n | Return self|value.\n | \n | __rand__(self, value, /)\n | Return value&self.\n | \n | __reduce__(...)\n | Return state information for pickling.\n | \n | __repr__(self, /)\n | Return repr(self).\n | \n | __ror__(self, value, /)\n | Return value|self.\n | \n | __rsub__(self, value, /)\n | Return value-self.\n | \n | __rxor__(self, value, /)\n | Return value^self.\n | \n | __sizeof__(...)\n | S.__sizeof__() -> size of S in memory, in bytes\n | \n | __sub__(self, value, /)\n | Return self-value.\n | \n | __xor__(self, value, /)\n | Return self^value.\n | \n | add(...)\n | Add an element to a set.\n | \n | This has no effect if the element is already present.\n | \n | clear(...)\n | Remove all elements from this set.\n | \n | copy(...)\n | Return a shallow copy of a set.\n | \n | difference(...)\n | Return the difference of two or more sets as a new set.\n | \n | (i.e. all elements that are in this set but not the others.)\n | \n | difference_update(...)\n | Remove all elements of another set from this set.\n | \n | discard(...)\n | Remove an element from a set if it is a member.\n | \n | If the element is not a member, do nothing.\n | \n | intersection(...)\n | Return the intersection of two sets as a new set.\n | \n | (i.e. all elements that are in both sets.)\n | \n | intersection_update(...)\n | Update a set with the intersection of itself and another.\n | In [177]:\nsignals\n[\n0\n]\nIn [180]:\nnext\n(\niter\n(\nsignals\n))\nIn [173]:\nlist\n(\nsignals\n)[\n0\n]\nUnpacking variables\n | \n | isdisjoint(...)\n | Return True if two sets have a null intersection.\n | \n | issubset(...)\n | Report whether another set contains this set.\n | \n | issuperset(...)\n | Report whether this set contains another set.\n | \n | pop(...)\n | Remove and return an arbitrary set element.\n | Raises KeyError if the set is empty.\n | \n | remove(...)\n | Remove an element from a set; it must be a member.\n | \n | If the element is not a member, raise a KeyError.\n | \n | symmetric_difference(...)\n | Return the symmetric difference of two sets as a new set.\n | \n | (i.e. all elements that are in exactly one of the sets.)\n | \n | symmetric_difference_update(...)\n | Update a set with the symmetric difference of itself and another.\n | \n | union(...)\n | Return the union of sets as a new set.\n | \n | (i.e. all elements that are in either set.)\n | \n | update(...)\n | Update a set with the union of itself and others.\n | \n | ----------------------------------------------------------------------\n | Data and other attributes defined here:\n | \n | __hash__ = None\n---------------------------------------------------------------------------\nTypeError\n Traceback (most recent call last)\n<ipython-input-177-6c9ebb69209b>\n in \n<module>\n----> 1\n \nsignals\n[\n0\n]\nTypeError\n: 'set' object does not support indexing\nOut[180]:\n'I_MEAS'\nOut[173]:\n'I_MEAS' In [182]:\nfirst\n,\n \nsecond\n \n=\n \n[\n1\n,\n \n2\n]\nprint\n(\nfirst\n,\n \nsecond\n)\nIn [183]:\nfirst\n,\n \nsecond\n \n=\n \n(\n1\n,\n \n2\n)\nprint\n(\nfirst\n,\n \nsecond\n)\nIn [184]:\nfirst\n,\n \nsecond\n \n=\n \n{\n1\n,\n \n2\n}\nprint\n(\nfirst\n,\n \nsecond\n)\nIn [185]:\nemployees\n \n=\n \n[(\n111\n,\n \n'John'\n),\n \n(\n123\n,\n \n'Emily'\n),\n \n(\n232\n,\n \n'David'\n),\n \n(\n100\n,\n \n'Mark'\n),\n \n(\n1\n,\n \n'Andrew'\n)]\nfor\n \nemployee_id\n,\n \nemployee_name\n \nin\n \nemployees\n:\n \nprint\n(\nemployee_id\n,\n \nemployee_name\n)\n3.4. Dictionaries\nIn [186]:\nempty_set\n \n=\n \n{}\ntype\n(\nempty_set\n)\nIn [187]:\nempty_set\n \n=\n \nset\n()\ntype\n(\nempty_set\n)\nIn [188]:\nmy_dict\n \n=\n \n{\n'a'\n:\n \n1\n,\n \n'b'\n:\n \n2\n,\n \n'c'\n:\n \n3\n,\n \n'd'\n:\n \n4\n}\nmy_dict\n---------------------------------------------------------------------------\nValueError\n Traceback (most recent call last)\n<ipython-input-182-07dd77cb2d66>\n in \n<module>\n----> 1\n \nfirst\n,\n second \n=\n \n[\n1\n,\n \n2\n,\n \n3\n]\n 2\n print\n(\nfirst\n,\n second\n)\nValueError\n: too many values to unpack (expected 2)\n1 2\n1 2\n111 John\n123 Emily\n232 David\n100 Mark\n1 Andrew\nOut[186]:\ndict\nOut[187]:\nset\nOut[188]:\n{'a': 1, 'b': 2, 'c': 3, 'd': 4} In [189]:\nmy_dict\n[\n'a'\n]\nIn [190]:\nfor\n \nkey\n \nin\n \nmy_dict\n:\n \nprint\n(\nkey\n)\nIn [191]:\nfor\n \nkey\n,\n \nvalue\n \nin\n \nmy_dict\n.\nitems\n():\n \nprint\n(\nkey\n,\n \nvalue\n)\nSummary of Python Containers\nFeature\nlist\ntuple\ndict\nset\nPurpose\nan ordered collection of variables\nan ordered collection of variables\nan ordered collection of key,value pairs\na collection of variables\nDuplication of values\nyes\nyes\nunique keys, duplicate values\nno\nMutability\nyes\nno\nyes\nno\nCreation\n[1,2,3]\n(1,2,3)\n{'a':1}\n{1,2,3}\nEmpty container\n[]\n()\n{}\nset()\nComprehension\n[x for x in range(5)]\ntuple((x for x in range(5)))\n{k: v for k,v in zip(['a'], [1])}\n{x for x in range(5)}\nAccessing element\nlst[0]\ntpl[0]\ndct['key']\nnot possible\n4. Functions\nIn [1]:\n# lambda functions\nf\n \n=\n \nlambda\n \nx\n:\n \nx\n**\n2\nf\n(\n2\n)\nIn [31]:\ndef\n \nf\n(\nx\n):\n \nreturn\n \nx\n**\n2\nf\n(\n2\n)\n4.1. Arguments\nOut[189]:\n1\na\nb\nc\nd\na 1\nb 2\nc 3\nd 4\nOut[1]:\n4\nOut[31]:\n4 In [2]:\ndef\n \nf\n(\na\n,\n \nb\n,\n \nc\n=\n3\n):\n \nreturn\n \na\n+\nb\n+\nc\nf\n(\n1\n,\n2\n)\nIn [3]:\nf\n(\n1\n,\n2\n,\n \n4\n)\nIf the number of arguments matches, one can pass a list\nIn [5]:\nlst\n \n=\n \n[\n1\n,\n2\n,\n3\n]\nf\n(\n*\nlst\n)\nor a dictionary (provided that key names match the argument names) - very useful for methods with multiple arguments, e.g., plotting,\nquerying databases, etc.\nIn [6]:\ndct\n \n=\n \n{\n'a'\n:\n \n1\n,\n \n'b'\n:\n \n2\n,\n \n'c'\n:\n \n3\n}\nf\n(\n**\ndct\n)\nIn [ ]:\nquery_params\n \n=\n \n{\n'db'\n:\n \n\"NXCALS\"\n,\n \n\"signal\"\n:\n \n\"I_MEAS\"\n,\n \n\"t_start\"\n:\n \n\"today\"\n,\n \n\"t_end\"\n:\n \n\"tomorrow\"\n}\ncall_db\n(\n**\nquery_params\n)\nquery_params\n[\n'db'\n]\n \n=\n \n'PM'\ncall_db\n(\n**\nquery_params\n)\nDefault argument values\nIn [8]:\ndef\n \nf\n(\na\n,\n \nb\n,\n \nd\n,\n \nc\n=\n3\n):\n \nreturn\n \na\n+\nb\n+\nc\n+\nd\nIn [15]:\ndef\n \nf\n(\n*\nargs\n):\n \nprint\n(\nlen\n(\nargs\n))\n \nreturn\n \nargs\n[\n0\n]\n*\nargs\n[\n1\n]\n*\nargs\n[\n2\n]\nf\n(\n1\n,\n \n10\n,\n \n'a'\n)\nOut[2]:\n6\nOut[3]:\n7\nOut[5]:\n6\nOut[6]:\n6\n3\nOut[15]:\n'aaaaaaaaaa' In [38]:\ndef\n \nf\n(\n**\nkwargs\n):\n \nreturn\n \nkwargs\n[\n'a'\n]\n \n+\n \nkwargs\n[\n'b'\n]\nf\n(\na\n=\n1\n,\n \nb\n=\n2\n,\n \nc\n=\n3\n)\nIn [17]:\ndef\n \nf\n(\narg\n,\n \n*\nargs\n,\n \n**\nkwargs\n):\n \nreturn\n \narg\n \n+\n \nsum\n(\nargs\n)\n \n+\n \nkwargs\n[\n'f'\n]\nf\n(\n1\n,\n \n2\n,\n \n3\n,\n \n4\n,\n \n5\n,\n \nf\n=\n6\n)\nIn [18]:\ndef\n \nf\n(\na\n,\n \nb\n,\n \n*\n,\n \nc\n):\n \nreturn\n \na\n+\nb\n+\nc\nf\n(\n1\n,\n2\n,\n3\n)\nIn [19]:\nf\n(\n1\n,\n2\n,\nscaling\n=\n3\n)\nA function passed as an argument\nIn [20]:\ndef\n \nf\n(\nx\n):\n \nreturn\n \nx\n**\n2\ndef\n \ng\n(\nfunc\n,\n \nx\n):\n \nreturn\n \nfunc\n(\nx\n)\ng\n(\nf\n,\n2\n)\nA function can return multiple values, in fact it returns a tuple\nIn [23]:\ndef\n \nf\n():\n \nreturn\n \n'a'\n,\n \n'b'\n,\n \n's'\nf\n()\nOut[38]:\n3\nOut[17]:\n21\n---------------------------------------------------------------------------\nTypeError\n Traceback (most recent call last)\n<ipython-input-18-ff89bb262ade>\n in \n<module>\n 1\n \ndef\n f\n(\na\n,\n b\n,\n \n*\n,\n c\n)\n:\n 2\n \nreturn\n a\n+\nb\n+\nc\n----> 3\n \nf\n(\n1\n,\n2\n,\n3\n)\nTypeError\n: f() takes 2 positional arguments but 3 were given\nOut[19]:\n6\nOut[20]:\n4\nOut[23]:\n('a', 'b', 's') In [32]:\nfirst\n \n=\n \nlist\n(\nf\n())\n# print(first)\n# print(second)\nIn [33]:\nfirst\n[\n1\n]\n \n=\n \n2\nIn [34]:\nfirst\n4.2. Recursion\nFactorial of an integer $n$ is given as: \\begin{equation} n! = n*(n-1)*(n-2)*(n-3)* ... * 3 * 2 * 1 \n\\end{equation} For example: \\begin{equation}\n5! = 5 * 4 * 3 * 2 * 1 = 120 \\end{equation}\nIn [37]:\ndef\n \nfactorial\n(\nn\n):\n \nif\n \nn\n \n==\n \n1\n:\n \nreturn\n \n1\n \nelse\n:\n \nreturn\n \nn\n*\nfactorial\n(\nn\n-\n1\n)\nfactorial\n(\n3\n)\nIn [38]:\nfactorial\n(\n5\n)\nIn [39]:\nfactorial\n(\n-\n1\n)\nOut[34]:\n['a', 2, 's']\nOut[37]:\n6\nOut[38]:\n120\nERROR:root:Internal Python error in the inspect module.\nBelow is the traceback from this internal error. In [42]:\ndef\n \nfactorial\n(\nn\n):\n \nif\n \nnot\n \nisinstance\n(\nn\n,\n \nint\n)\n \nor\n \nn\n \n<=\n \n0\n:\n \nraise\n \nValueError\n(\n\"Argument is not a positive integer\"\n)\n \n \nif\n \nn\n \n==\n \n1\n:\n \nreturn\n \n1\n \nelse\n:\n \nreturn\n \nn\n*\nfactorial\n(\nn\n-\n1\n)\nfactorial\n(\n5\n)\nTraceback (most recent call last):\n File \"/usr/local/lib/swan/IPython/core/interactiveshell.py\", line 3326, in run_code\n exec(code_obj, self.user_global_ns, self.user_ns)\n File \"<ipython-input-39-5aae425d6a8b>\", line 1, in <module>\n factorial(-1)\n File \"<ipython-input-37-0017e71e028e>\", line 5, in factorial\n return n*factorial(n-1)\n File \"<ipython-input-37-0017e71e028e>\", line 5, in factorial\n return n*factorial(n-1)\n File \"<ipython-input-37-0017e71e028e>\", line 5, in factorial\n return n*factorial(n-1)\n [Previous line repeated 2967 more times]\n File \"<ipython-input-37-0017e71e028e>\", line 2, in factorial\n if n == 1:\nRecursionError: maximum recursion depth exceeded in comparison\nDuring handling of the above exception, another exception occurred:\nTraceback (most recent call last):\n File \"/usr/local/lib/swan/IPython/core/interactiveshell.py\", line 2040, in showtraceback\n stb = value._render_traceback_()\nAttributeError: 'RecursionError' object has no attribute '_render_traceback_'\nDuring handling of the above exception, another exception occurred:\nTraceback (most recent call last):\n File \"/cvmfs/sft.cern.ch/lcg/releases/Python/3.6.5-f74f0/x86_64-centos7-gcc8-opt/lib/python3.6/genericpath.p\ny\", line 19, in exists\n os.stat(path)\nFileNotFoundError: [Errno 2] No such file or directory: '<ipython-input-37-0017e71e028e>'\nDuring handling of the above exception, another exception occurred:\nTraceback (most recent call last):\n File \"/usr/local/lib/swan/IPython/core/ultratb.py\", line 1101, in get_records\n return _fixed_getinnerframes(etb, number_of_lines_of_context, tb_offset)\n File \"/usr/local/lib/swan/IPython/core/ultratb.py\", line 319, in wrapped\n return f(*args, **kwargs)\n File \"/usr/local/lib/swan/IPython/core/ultratb.py\", line 353, in _fixed_getinnerframes\n records = fix_frame_records_filenames(inspect.getinnerframes(etb, context))\n File \"/cvmfs/sft.cern.ch/lcg/releases/Python/3.6.5-f74f0/x86_64-centos7-gcc8-opt/lib/python3.6/inspect.py\",\n \nline 1483, in getinnerframes\n frameinfo = (tb.tb_frame,) + getframeinfo(tb, context)\n File \"/cvmfs/sft.cern.ch/lcg/releases/Python/3.6.5-f74f0/x86_64-centos7-gcc8-opt/lib/python3.6/inspect.py\",\n \nline 1441, in getframeinfo\n filename = getsourcefile(frame) or getfile(frame)\n File \"/cvmfs/sft.cern.ch/lcg/releases/Python/3.6.5-f74f0/x86_64-centos7-gcc8-opt/lib/python3.6/inspect.py\",\n \nline 693, in getsourcefile\n if os.path.exists(filename):\n File \"/cvmfs/sft.cern.ch/lcg/releases/Python/3.6.5-f74f0/x86_64-centos7-gcc8-opt/lib/python3.6/genericpath.p\ny\", line 19, in exists\n os.stat(path)\nKeyboardInterrupt\n---------------------------------------------------------------------------\nOut[42]:\n120 Flattening a nested list\nIn [50]:\ndef\n \nflatten_nested_lists\n(\nx\n):\n \nresult\n \n=\n \n[]\n \nfor\n \nel\n \nin\n \nx\n:\n \nif\n \nisinstance\n(\nel\n,\n \n(\nlist\n,\n \ntuple\n)):\n \nresult\n.\nextend\n(\nflatten_nested_lists\n(\nel\n))\n \nelse\n:\n \nresult\n.\nappend\n(\nel\n)\n \nreturn\n \nresult\nIn [51]:\nlst1\n \n=\n \n[\n1\n]\nlst2\n \n=\n \n[\n1\n,\n \n2\n]\nlst1\n.\nappend\n(\nlst2\n)\nlst1\nIn [51]:\nlst\n \n=\n \n[\n1\n,\n \n2\n,\n \n[\n3\n,\n4\n],\n \n[\n5\n,\n \n[\n6\n,\n \n7\n]]]\nflatten_nested_lists\n(\nlst\n)\nFibonacci\nIn [52]:\ndef\n \nfib\n(\nn\n):\n \nif\n \nn\n \n==\n \n0\n:\n \nreturn\n \n0\n \nelif\n \nn\n \n==\n \n1\n:\n \nreturn\n \n1\n \nelse\n:\n \nreturn\n \nfib\n(\nn\n-\n1\n)\n \n+\n \nfib\n(\nn\n-\n2\n)\n[\nfib\n(\ni\n)\n \nfor\n \ni\n \nin\n \nrange\n(\n6\n)]\nHow many times do we calculate fib(3)?\n---------------------------------------------------------------------------\nTypeError\n Traceback (most recent call last)\n<ipython-input-51-d821110e9bc8>\n in \n<module>\n 1\n lst1 \n=\n \n[\n1\n]\n 2\n lst2 \n=\n \n[\n1\n,\n \n2\n]\n----> 3\n \nlst1\n.\nappend\n(\n*\nlst2\n)\n 4\n lst1\nTypeError\n: append() takes exactly one argument (2 given)\nOut[51]:\n[1, 2, 3, 4, 5, 6, 7]\nOut[52]:\n[0, 1, 1, 2, 3, 5] In [56]:\narguments\n \n=\n \n[]\ndef\n \nfib\n(\nn\n):\n \narguments\n.\nappend\n(\nn\n)\n \nif\n \nn\n \n==\n \n0\n:\n \nreturn\n \n0\n \nelif\n \nn\n \n==\n \n1\n:\n \nreturn\n \n1\n \nelse\n:\n \nreturn\n \nfib\n(\nn\n-\n1\n)\n \n+\n \nfib\n(\nn\n-\n2\n)\nx\n \n=\n \n[\nfib\n(\ni\n)\n \nfor\n \ni\n \nin\n \nrange\n(\n6\n)]\nprint\n(\nx\n)\nIn [58]:\ncounts\n \n=\n \n{\ni\n:\n \narguments\n.\ncount\n(\ni\n)\n \nfor\n \ni\n \nin\n \nrange\n(\nmax\n(\narguments\n)\n+\n1\n)}\ncounts\nIn [59]:\nsum\n(\ncounts\n.\nvalues\n())\n4.3. Memoization\nIn computing, memoization or memoisation is an optimization technique used primarily to speed up computer programs by storing the results\nof expensive function calls and returning the cached result when the same inputs occur again.\nsource: \nhttps://en.wikipedia.org/wiki/Memoization\n (https://en.wikipedia.org/wiki/Memoization)\nIn [60]:\n# Memoization for Fibonacci\n# Fibonacci\nmemo\n \n=\n \n{\n0\n:\n0\n,\n \n1\n:\n1\n}\narguments\n \n=\n \n[]\ndef\n \nfib\n(\nn\n):\n \narguments\n.\nappend\n(\nn\n)\n \nif\n \nn\n \nnot\n \nin\n \nmemo\n:\n \nmemo\n[\nn\n]\n \n=\n \nfib\n(\nn\n-\n1\n)\n \n+\n \nfib\n(\nn\n-\n2\n)\n \nreturn\n \nmemo\n[\nn\n]\n[\nfib\n(\ni\n)\n \nfor\n \ni\n \nin\n \nrange\n(\n6\n)]\nIn [63]:\ncounts\n \n=\n \n{\ni\n:\n \narguments\n.\ncount\n(\ni\n)\n \nfor\n \ni\n \nin\n \nrange\n(\nmax\n(\narguments\n)\n+\n1\n)}\ncounts\n[0, 1, 1, 2, 3, 5]\nOut[58]:\n{0: 8, 1: 12, 2: 7, 3: 4, 4: 2, 5: 1}\nOut[59]:\n34\nOut[60]:\n[0, 1, 1, 2, 3, 5]\nOut[63]:\n{0: 2, 1: 3, 2: 3, 3: 3, 4: 2, 5: 1} In [62]:\nsum\n(\ncounts\n.\nvalues\n())\n4.5. Decorators\nDecorators are functions dedicated to enhance functionality of a given function, e.g., check parameter inputs, format input\nIn [59]:\ndef\n \nargument_test_natural_number\n(\nf\n):\n \ndef\n \nhelper\n(\nx\n):\n \nif\n \ntype\n(\nx\n)\n \nis\n \nint\n \nand\n \nx\n \n>\n \n0\n:\n \nreturn\n \nf\n(\nx\n)\n \nelse\n:\n \nraise\n \nException\n(\n\"Argument is not an integer\"\n)\n \nreturn\n \nhelper\ndef\n \nfactorial\n(\nn\n):\n \nif\n \nn\n \n==\n \n1\n:\n \nreturn\n \n1\n \nelse\n:\n \nreturn\n \nn\n*\nfactorial\n(\nn\n-\n1\n)\n \nfactorial\n \n=\n \nargument_test_natural_number\n(\nfactorial\n)\nfactorial\n(\n3\n)\nIn [60]:\nfactorial\n(\n-\n1\n)\nOut[62]:\n14\nOut[59]:\n6\n---------------------------------------------------------------------------\nException\n Traceback (most recent call last)\n<ipython-input-60-5aae425d6a8b>\n in \n<module>\n----> 1\n \nfactorial\n(\n-\n1\n)\n<ipython-input-59-74d7cacc5284>\n in \nhelper\n(x)\n 4\n \nreturn\n f\n(\nx\n)\n 5\n \nelse\n:\n----> 6\n \nraise\n Exception\n(\n\"Argument is not an integer\"\n)\n 7\n \nreturn\n helper\n 8\n \nException\n: Argument is not an integer In [64]:\ndef\n \nargument_test_natural_number\n(\nf\n):\n \ndef\n \nhelper\n(\nx\n):\n \nif\n \ntype\n(\nx\n)\n \nis\n \nint\n \nand\n \nx\n \n>\n \n0\n:\n \nreturn\n \nf\n(\nx\n)\n \nelse\n:\n \nraise\n \nException\n(\n\"Argument is not an integer\"\n)\n \nreturn\n \nhelper\n@argument_test_natural_number\ndef\n \nfactorial\n(\nn\n):\n \nif\n \nn\n \n==\n \n1\n:\n \nreturn\n \n1\n \nelse\n:\n \nreturn\n \nn\n*\nfactorial\n(\nn\n-\n1\n)\n \nfactorial\n(\n3\n)\nIn [65]:\nfactorial\n(\n-\n1\n)\nIn [66]:\ndef\n \nsum_aritmetic_series\n(\nn\n):\n \nreturn\n \nn\n*\n(\nn\n+\n1\n)\n/\n2\nsum_aritmetic_series\n(\n2\n)\nIn [67]:\nsum_aritmetic_series\n(\n1.5\n)\nIn [68]:\n@argument_test_natural_number\ndef\n \nsum_aritmetic_series\n(\nn\n):\n \nreturn\n \nn\n*\n(\nn\n-\n1\n)\n/\n2\nsum_aritmetic_series\n(\n2\n)\nOut[64]:\n6\n---------------------------------------------------------------------------\nException\n Traceback (most recent call last)\n<ipython-input-65-5aae425d6a8b>\n in \n<module>\n----> 1\n \nfactorial\n(\n-\n1\n)\n<ipython-input-64-61c7137e6453>\n in \nhelper\n(x)\n 4\n \nreturn\n f\n(\nx\n)\n 5\n \nelse\n:\n----> 6\n \nraise\n Exception\n(\n\"Argument is not an integer\"\n)\n 7\n \nreturn\n helper\n 8\n \nException\n: Argument is not an integer\nOut[66]:\n3.0\nOut[67]:\n1.875\nOut[68]:\n1.0 In [69]:\nsum_aritmetic_series\n(\n1.5\n)\nFixing the Fibonacci series\nIn [70]:\ndef\n \nmemoize\n(\nf\n):\n \nmemo\n \n=\n \n{}\n \ndef\n \nhelper\n(\nn\n):\n \nif\n \nn\n \nnot\n \nin\n \nmemo\n:\n \nmemo\n[\nn\n]\n \n=\n \nf\n(\nn\n)\n \nreturn\n \nmemo\n[\nn\n]\n \nreturn\n \nhelper\narguments\n \n=\n \n[]\n@memoize\ndef\n \nfib\n(\nn\n):\n \narguments\n.\nappend\n(\nn\n)\n \nif\n \nn\n \n==\n \n0\n:\n \nreturn\n \n0\n \nelif\n \nn\n \n==\n \n1\n:\n \nreturn\n \n1\n \nelse\n:\n \nreturn\n \nfib\n(\nn\n-\n1\n)\n \n+\n \nfib\n(\nn\n-\n2\n)\n[\nfib\n(\ni\n)\n \nfor\n \ni\n \nin\n \nrange\n(\n6\n)]\nIn [71]:\ncounts\n \n=\n \n{\ni\n:\n \narguments\n.\ncount\n(\ni\n)\n \nfor\n \ni\n \nin\n \nrange\n(\nmax\n(\narguments\n)\n+\n1\n)}\ncounts\nIn [72]:\nsum\n(\ncounts\n.\nvalues\n())\nThere is a built-in cache decorator\n---------------------------------------------------------------------------\nException\n Traceback (most recent call last)\n<ipython-input-69-16581ed0c766>\n in \n<module>\n----> 1\n \nsum_aritmetic_series\n(\n1.5\n)\n<ipython-input-64-61c7137e6453>\n in \nhelper\n(x)\n 4\n \nreturn\n f\n(\nx\n)\n 5\n \nelse\n:\n----> 6\n \nraise\n Exception\n(\n\"Argument is not an integer\"\n)\n 7\n \nreturn\n helper\n 8\n \nException\n: Argument is not an integer\nOut[70]:\n[0, 1, 1, 2, 3, 5]\nOut[71]:\n{0: 1, 1: 1, 2: 1, 3: 1, 4: 1, 5: 1}\nOut[72]:\n6 In [ ]:\n# built-in least-recently used cache decorator\nimport\n \nfunctools\n@functools\n.\nlru_cache\n(\nmaxsize\n=\n128\n,\n \ntyped\n=\nFalse\n)\ndef\n \nfib\n(\nn\n):\n \nif\n \nn\n \n<\n \n2\n:\n \nreturn\n \nelse\n:\n \nreturn\n \nfib\n(\nn\n-\n1\n)\n \n+\n \nfib\n(\nn\n-\n2\n)\n4.4. Static variables\nIn [73]:\n# Exercise\n# - write a decorator counting the number of times a function was called\n# - the same but for a varying number of parameters and keyword-arguments\ndef\n \ncounter\n(\nfunc\n):\n \n# first define function\n \ndef\n \nhelper\n(\nx\n,\n \n*\nargs\n,\n \n**\nkwargs\n):\n \nhelper\n.\ncount\n \n+=\n \n1\n \nreturn\n \nfunc\n(\nx\n,\n \n*\nargs\n,\n \n**\nkwargs\n)\n \n# return function as it is\n \n# then, define an attribute to be incremented with every call\n \n# this attribute behaves like a static variable\n \n# helper exist only after the function definition. Once defined, then we can attach an attribute\n \nhelper\n.\ncount\n \n=\n \n0\n \n \nreturn\n \nhelper\n@counter\ndef\n \nfun\n(\nx\n):\n \nreturn\n \nx\nfun\n(\n1\n)\nfun\n(\n2\n)\nfun\n(\n3\n)\nfun\n.\ncount\n4.6. Generators\nIn [74]:\ns\n \n=\n \n\"Python\"\nitero\n \n=\n \niter\n(\ns\n)\nitero\n# what I write is:\n# for char in s:\n# what python does:\n# for char in iter(s)\n# in fact it is a while loop until stop is reached\nIn [75]:\nnext\n(\nitero\n)\nOut[73]:\n3\nOut[74]:\n<str_iterator at 0x7f4675fb7f28>\nOut[75]:\n'P' In [76]:\nnext\n(\nitero\n)\nIn [77]:\nnext\n(\nitero\n)\nIn [78]:\nnext\n(\nitero\n)\nIn [79]:\nnext\n(\nitero\n)\nIn [80]:\nnext\n(\nitero\n)\nIn [81]:\nnext\n(\nitero\n)\nOwn generator\nIn [87]:\ndef\n \nabc_generator\n():\n \nyield\n \n\"a\"\n \nyield\n \n\"b\"\n \nyield\n \n\"c\"\n \nx\n \n=\n \nabc_generator\n()\n \n# we call like a function. A function returns an object\n \nfor\n \ni\n \nin\n \nx\n:\n \nprint\n(\ni\n)\nOut[76]:\n'y'\nOut[77]:\n't'\nOut[78]:\n'h'\nOut[79]:\n'o'\nOut[80]:\n'n'\n---------------------------------------------------------------------------\nStopIteration\n Traceback (most recent call last)\n<ipython-input-81-bc7ed7acd9c9>\n in \n<module>\n----> 1\n \nnext\n(\nitero\n)\nStopIteration\n:\n \na\nb\nc In [86]:\nnext\n(\nx\n)\nIn [80]:\n# print(next(x)) <-- yield \"a\"\n# print(next(x)) <-- yield \"b\"\n# print(next(x)) <-- yield \"c\"\n# this is a co-process. This function creates a code waiting to be executed, when we assign x = abc_generator(\n)\n# after it reaches a yield, it returns value and stops. Then next is positioned fter the yield.x\nx\n \n=\n \nabc_generator\n()\nprint\n(\nnext\n(\nx\n))\nprint\n(\nnext\n(\nx\n))\nprint\n(\nnext\n(\nx\n))\nprint\n(\nnext\n(\nx\n))\nA function is also a single-value generator\nIn [88]:\ndef\n \nabc_generator\n():\n \nreturn\n \n\"a\"\nx\n \n=\n \nabc_generator\n()\nfor\n \ni\n \nin\n \nx\n:\n \nprint\n(\ni\n)\n# works, because the returned value is iterable\nIn [82]:\ntype\n(\nabc_generator\n())\nIn [83]:\ndef\n \nabc_generator\n():\n \nfor\n \nchar\n \nin\n \n[\n\"a\"\n,\n \n\"b\"\n,\n \n\"c\"\n]:\n \nyield\n \nchar\nfor\n \ni\n \nin\n \nabc_generator\n():\n \nprint\n(\ni\n)\n---------------------------------------------------------------------------\nStopIteration\n Traceback (most recent call last)\n<ipython-input-86-92de4e9f6b1e>\n in \n<module>\n----> 1\n \nnext\n(\nx\n)\nStopIteration\n:\n \na\nb\nc\n---------------------------------------------------------------------------\nStopIteration\n Traceback (most recent call last)\n<ipython-input-80-e58ce091c0f7>\n in \n<module>\n 8\n print\n(\nnext\n(\nx\n)\n)\n 9\n print\n(\nnext\n(\nx\n)\n)\n---> 10\n \nprint\n(\nnext\n(\nx\n)\n)\nStopIteration\n:\n \na\nOut[82]:\nstr\na\nb\nc In [85]:\ntype\n(\nabc_generator\n())\nIn [ ]:\n# Generate a pi value\n# pi/4 = 1 - 1/3 + 1/5 - 1/7\ndef\n \npi_series\n():\n \nsum\n \n=\n \n0\n \ni\n \n=\n \n1.0\n \nj\n \n=\n \n1\n \nwhile\n \nTrue\n:\n \nsum\n \n=\n \nsum\n \n+\n \nj\n/\ni\n \nyield\n \n4\n*\nsum\n \ni\n \n=\n \ni\n \n+\n \n2\n \nj\n \n=\n \nj\n \n*\n \n-\n1\n# runs forever\n# we can break with a counter, but it is not a good idea\nfor\n \ni\n \nin\n \npi_series\n():\n \nprint\n(\ni\n)\nIn [ ]:\ndef\n \nfirstn\n(\ng\n,\n \nn\n):\n \nfor\n \ni\n \nin\n \nrange\n(\nn\n):\n \nyield\n \nnext\n(\ng\n)\n \nprint\n(\nlist\n(\nfirstn\n(\npi_series\n(),\n \n8\n)))\n4.7. Context Manager\nIs used to allocate and release some sort of resource when we need it.\nWhich means that before we start a block we open e.g. a file, and when we are going out, the file is automatically released.\nIf we don't close, it remains open in a file system. Closing a program, it would close. A good practice is to always close.\nWith context managers, the benefit is no need to close.\nThe issue is with the exceptions. With with, the exception is caught and handled.\nContext manager is a general concept. The concept is as follows.\nwith device():\nbefore:\n1. check device\n2. start device\nwe enter the block:\n1. we do something\nafter:\n1. we execute stop block\nin case of exceptions we are sure that the after part will be executed.\nIn [ ]:\nimport\n \ncsv\nwith\n \nopen\n(\n'example.txt'\n,\n \n'w'\n)\n \nas\n \nout\n:\n \ncsv_out\n \n=\n \ncsv\n.\nwriter\n(\nout\n)\n \ncsv_out\n.\nwriterow\n([\n'date'\n,\n \n'# events'\n])\nOut[85]:\ngenerator In [ ]:\nfrom\n \ncontextlib\n \nimport\n \ncontextmanager\n@contextmanager\ndef\n \ndevice\n():\n \nprint\n(\n\"Check device\"\n)\n \ndevice_state\n \n=\n \nTrue\n \nprint\n(\n\"Start device\"\n)\n \nyield\n \ndevice_state\n \n# the block after with is executed\n \nprint\n(\n\"Stop device\"\n)\nwith\n \ndevice\n()\n \nas\n \nstate\n:\n \nprint\n(\n\"State is \"\n,\n \nstate\n)\n \nprint\n(\n\"Device is running!\"\n)\n5. Exception handling\nException handling\nIt is easier to ask for forgiveness than for permission\nE.g.\nif fileexisits(file_name):\n txt = open(file_name).read()\nWe first check if the file exists, then in the next step we fetch the file - two operations (asking for permission)\nWe can try to read, if it is there we are good, otherwise it raises an exception - single operation (asking for forgiveness)\ntry:\n txt = open(file_name)\nexcept Exception as e:\n txt = \"\"\nIn [ ]:\nwhile\n \nTrue\n:\n \ntry\n:\n \nx\n \n=\n \nint\n(\ninput\n(\n\"Please enter a number: \"\n))\n \nbreak\n \nexcept\n \nValueError\n \nas\n \nerr\n:\n \nprint\n(\n\"Error message: \"\n,\n \nerr\n)\n \nprint\n(\n\"No valid number. Try again\"\n)\ntry:\n some code\nexcept ZeroDivisionError:\n some code\n there could be a raise here\nexcept FooError:\n some code\nexcept BarError:\n some code\nfinally:\n some code executed always In [ ]:\n# Finally is executed always\ntry\n:\n \nx\n \n=\n \nfloat\n(\ninput\n(\n\"Your number: \"\n))\n \ninverse\n \n=\n \n10\n/\nx\nexcept\n \nValueError\n \nas\n \nerr\n:\n \nprint\n(\n\"Error message: \"\n,\n \nerr\n)\n \nprint\n(\n\"No valid number. Try again\"\n)\nfinally\n:\n \nprint\n(\n\"There may or may not have been an exception.\"\n)\nprint\n(\n\"The inverse: \"\n,\n \ninverse\n)\nIn [ ]:\n# assert\nx\n \n=\n \n5\ny\n \n=\n \n6\nassert\n \nx\n \n<\n \ny\n,\n \n\"x has to be smaller than y\""}...
|
1770016499
|
/home/sid/xevyo/open-webui-dev/backend/data/upload /home/sid/xevyo/open-webui-dev/backend/data/uploads/0f3f6321-0d56-49a0-99a0-b006c54b5780_Advanced_Programming_with_Python.pdf...
|
null
|
Edit
Delete
|