diff --git a/README.rst b/README.rst index 7adfbc2..79b50a1 100644 --- a/README.rst +++ b/README.rst @@ -5,27 +5,32 @@ Python Tips Please clone or fork, the notebooks are meant to be interacted with. -------------------------------------------------------------------- -These files are .ipynb. It is a notebook document used by Jupyter Notebook, an interactive computational environment designed to help scientists work with the Python language. +Note that these were written in Python 3 (3.6) + +These files are .ipynb. It is a notebook document used by Jupyter Notebook, an interactive computational environment designed to help scientists work with the Python language (as well as Julia and R). I suggest downloading `Anaconda `_. Anaconda is a free and open source distribution of the Python and R programming languages that aims to simplify package management and deployment. Jupyter Notebook is included in Anaconda. -Tips 1 topics: +Please feel free to contribute, critique and comment. + +Python Tips topics: - Lambda functions - Enumerate - - List, set and dict comprehension + - Comprehension (list, set, dict) - Map - Filter - Zip - Print formatting - Args and kwargs + - Class Inheritance - Mutable parameters -Tips 2 topics (WIP): +Built-In Libraries Tips topics: + - Generators - Itertools (built-in library) - - Functools (built-in library) reduce, partial.. etc. - Collections (built-in library) - - Decorators - - Class Inheritance. - - Generators + - Decorators (Property decorators: getters, setters, deleters) + - Functools (built-in library) reduce, partials. - Datetime (built-in library) + \ No newline at end of file diff --git a/built_in_library_tips.ipynb b/built_in_library_tips.ipynb new file mode 100644 index 0000000..4adf718 --- /dev/null +++ b/built_in_library_tips.ipynb @@ -0,0 +1,3108 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# TABLE OF CONTENTS: \n", + "\n", + "These tips focus largely on built-in libraries that I think are good to know.\n", + "\n", + "I may not cover everything in each library.
\n", + "Please go through official documentation if you want more thorough examples.\n", + "\n", + "All functions are operating under their default parameters.\n", + "\n", + "[Great website](https://realpython.com)
\n", + "[Great youtuber](https://www.youtube.com/channel/UCCezIgC97PvUuR4_gbFUs5g)\n", + "\n", + "Topics:\n", + " - [Generators](#generators)\n", + " - [Itertools](#itertools)\n", + " - [Infinite itoratos](#infinite)\n", + " - [Iterators terminating on the shortest input sequence](#itotsis)\n", + " - [Combinatoric iterators](#combinatoric)\n", + " - [Collections](#collections)\n", + " - [Decorators](#decorators)\n", + " - [Property Decorators: Getter, Setter, Deleter](#gsd)\n", + " - [Functools](#functools)\n", + " - [Datetime](#dt)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Generators\n", + "[Return to table of contents](#toc)\n", + "\n", + "Most functions process a collection of data first before returning the finished result. Generators remove iteration and temporary collection to store results." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "# Non generator function returning an operation on a list\n", + "\n", + "def non_generator(list_of_nums):\n", + " product_list = []\n", + " for i in list_of_nums:\n", + " product_list.append(i**i)\n", + " return product_list" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[1, 4, 27, 256]" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Iterates, stores in product_list and returns product_list.\n", + "\n", + "non_generator([1,2,3,4])" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "# Now using a generator\n", + "\n", + "def generator(list_of_nums):\n", + " for i in list_of_nums:\n", + " yield i**i" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1\n", + "4\n", + "27\n", + "256\n" + ] + } + ], + "source": [ + "# Each time your generator is called upon using next, it will only then yield the result. \n", + "# This will continue until your generator is exhausted.\n", + "\n", + "my_gen = generator([1,2,3,4])\n", + "print(next(my_gen))\n", + "print(next(my_gen))\n", + "print(next(my_gen))\n", + "print(next(my_gen))\n", + "# print(next(my_gen)) This will raise a StopIteration uncomment to run." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1\n", + "4\n", + "27\n", + "256\n" + ] + } + ], + "source": [ + "# You can also iterate over your generator\n", + "\n", + "for i in generator([1,2,3,4]):\n", + " print(i)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Itertools \n", + "[Return to table of contents](#toc)\n", + "\n", + "Please learn about generators first.\n", + "\n", + "This module implements a number of iterator building blocks inspired by constructs from APL, Haskell, and SML. Each has been recast in a form suitable for Python.\n", + "\n", + "The module standardizes a core set of fast, memory efficient tools that are useful by themselves or in combination. Together, they form an “iterator algebra” making it possible to construct specialized tools succinctly and efficiently in pure Python.\n", + "\n", + "https://docs.python.org/3/library/itertools.html" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "from itertools import *" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Infinite itorators
" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Count" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0\n", + "5\n", + "10\n" + ] + } + ], + "source": [ + "'''count(start=0, step=1)\n", + "\n", + "This creates an iterable object that goes up by the step you specify.\n", + "This will continuously yield increments of 5 i.e. 0, 5, 10, 15, 20...\n", + "\n", + "Do not use as a list.\n", + "'''\n", + "\n", + "count_object = count(0, 5) # (start, step)\n", + "\n", + "print(next(count_object))\n", + "print(next(count_object))\n", + "print(next(count_object))\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Cycle" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "A\n", + "B\n", + "C\n", + "D\n", + "A\n" + ] + } + ], + "source": [ + "'''cycle(iterable)\n", + "\n", + "This creates an iterable object of what you pass in in an endless cycle.\n", + "This will continuously yield, A B C D A B C D A B C D ...\n", + "\n", + "Do not use as a list.\n", + "''' \n", + "\n", + "cycle_object = cycle('ABCD')\n", + "\n", + "print(next(cycle_object))\n", + "print(next(cycle_object))\n", + "print(next(cycle_object))\n", + "print(next(cycle_object))\n", + "print(next(cycle_object))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Repeat" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[10, 10, 10]\n", + "['hello', 'hello', 'hello', 'hello']\n" + ] + } + ], + "source": [ + "'''repeat(object, times=None)\n", + "\n", + "Used to repeat an element up to n times.\n", + "\n", + "Works as a generator.\n", + "'''\n", + "\n", + "print(list(repeat(10, 3)))\n", + "print(list(repeat('hello',4)))" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10\n" + ] + } + ], + "source": [ + "repeat_obj = repeat(10, 3)\n", + "\n", + "print(next(repeat_obj))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Iterators terminating on the shortest input sequence" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Accumulate" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[1, 3, 6, 10, 15]" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "'''accumulate(iterable, func=operator.add)\n", + "\n", + "Accumulate makes an iterator that returns accumulated sums.\n", + "Works similar to itertools.reduce() although only with addition\n", + "'''\n", + "\n", + "list(accumulate([1,2,3,4,5]))" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1\n" + ] + } + ], + "source": [ + "# Generator\n", + "\n", + "accu_onj = accumulate([1,2,3,4,5])\n", + "\n", + "print(next(accu_onj))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Chain" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['a', 'b', 'c', 'f', 'e', 'd', 'g', 'h', 'i', 'j', 'k', 'l']\n" + ] + } + ], + "source": [ + "'''chain(*iterables)\n", + "\n", + "Chain makes an iterator that returns elements from the first iterable until it is exhausted,\n", + "then proceeds to the next iterable, until all of the iterables are exhausted.\n", + "Used for treating consecutive sequences as a single sequence.\n", + "\n", + "You can chain together lists, tuples, sets and strings\n", + "'''\n", + "\n", + "print(list(chain(('a','b','c'), {'d','e','f'}, ['g','h','i'], 'jkl'))) " + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "a\n" + ] + } + ], + "source": [ + "# Generator\n", + "\n", + "chain_obj = chain(('a','b','c'), {'d','e','f'}, ['g','h','i'], 'jkl')\n", + "\n", + "print(next(chain_obj))" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['a', 'b', 'c', 'f', 'e', 'd', 'g', 'h', 'i', 'j', 'k', 'l']\n" + ] + } + ], + "source": [ + "'''chain.from_interable(iterables)\n", + "\n", + "Alternate constructor for chain(). Gets chained inputs from a single \n", + "iterable argument that is evaluated.\n", + "\n", + "Works as a generator\n", + "''' \n", + "\n", + "# Now with a single argument.\n", + "\n", + "print(list(chain.from_iterable([('a','b','c'), {'d','e','f'}, ['g','h','i'], 'jkl']))) # Now as a single argument" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "# This will raise a TypeError uncomment to run.\n", + "\n", + "# print(list(chain.from_iterable(\n", + "# ('a','b','c'), {'d','e','f'}, ['g','h','i'], 'jkl')\n", + "# ))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Compress" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['A', 'C', 'E', 'F']" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "'''compress(data, selectors)\n", + "\n", + "Compress makes an iterator that filters elements from data returning\n", + "only those that have a corresponding element in selectors that\n", + "evaluates to True. \n", + "\n", + "Stops when either the data or selectors iterables have been exhausted.\n", + "'''\n", + "\n", + "# A, C, E and F correspond to 1 or True to they will return\n", + "list(compress('ABCDEF', [1,0,1,0,1,1]))" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "A\n" + ] + } + ], + "source": [ + "# Generator\n", + "\n", + "compress_obj = compress('ABCDEF', [1,0,1,0,1,1])\n", + "\n", + "print(next(compress_obj))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Dropwhile" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[5, 6, 7, 8, 9]" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "'''dropwhile(predicate, iterable)\n", + "\n", + "Dropwhile makes an iterator that drops elements from the iterable\n", + "as long as the predicate is true; afterwards, returns every element.\n", + "\n", + "Works as a generator.\n", + "\n", + "1 < 5 True won't return\n", + "2 < 5 True won't return\n", + "3 < 5 True won't return\n", + "4 < 5 True won't return\n", + "5 !< 5 False will return \n", + "\n", + "Now will return 5 and everything after.\n", + "'''\n", + "\n", + "list(dropwhile(lambda x: x<5, [1,2,3,4,5,6,7,8,9]))" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "5\n" + ] + } + ], + "source": [ + "# Generator\n", + "\n", + "dropwhile_obj = dropwhile(lambda x: x<5, [1,2,3,4,5,6,7,8,9])\n", + "\n", + "print(next(dropwhile_obj))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Filterfalse" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[0, 2, 4, 6, 8]" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "'''filterfalse(predicate, iterable)\n", + "\n", + "Makes an iterator that filters elements from an iterable \n", + "returning only those for which the predicate is False (0)\n", + "\n", + "Works as a generator.\n", + "\n", + "0 % 2 = 0 False will return\n", + "1 % 2 = 1 True won't return\n", + "2 % 2 = 0 False will return\n", + "3 % 2 = 1 True won't return\n", + "etc...\n", + "'''\n", + "\n", + "list(filterfalse(lambda x: x%2, range(10)))" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0\n" + ] + } + ], + "source": [ + "# Generator\n", + "\n", + "filterfalse_obj = filterfalse(lambda x: x%2, range(10))\n", + "\n", + "print(next(filterfalse_obj))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Groupby" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['A', 'B', 'C', 'D', 'A', 'B']" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "'''groupby(iterable, key=None)\n", + "\n", + "Makes an iterator that returns consecutive keys\n", + "and groups from the iterable.\n", + "\n", + "The operation of groupby() is similar to the uniq filter in Unix.\n", + "It generates a break or new group every time the value of the key\n", + "function changes.\n", + "\n", + "Generally, the iterable needs to already be sorted on the same key function.\n", + "'''\n", + "\n", + "# Only returns the individual elements\n", + "\n", + "[k for k, g in groupby('AAAABBBCCDAABBB')]" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[['A', 'A', 'A', 'A'],\n", + " ['B', 'B', 'B'],\n", + " ['C', 'C'],\n", + " ['D'],\n", + " ['A', 'A'],\n", + " ['B', 'B', 'B']]" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Using groupby like this will return the groups\n", + "\n", + "[list(g) for k, g in groupby('AAAABBBCCDAABBB')]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Islice" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['A', 'B']\n", + "['A', 'B']\n" + ] + } + ], + "source": [ + "'''islice(iterable, *args)\n", + "\n", + "Very similar to calling the index in a string\n", + "'''\n", + "\n", + "print(list(islice('ABCDEFG', 2)))\n", + "\n", + "# similar to\n", + "\n", + "print(list('ABCDEFG'[0:2]))" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['C', 'D']\n", + "['C', 'D']\n" + ] + } + ], + "source": [ + "print(list(islice('ABCDEFG', 2, 4)))\n", + "\n", + "# similar to\n", + "\n", + "print(list('ABCDEFG'[2:4]))" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['C', 'D', 'E', 'F', 'G']\n", + "['C', 'D', 'E', 'F', 'G']\n" + ] + } + ], + "source": [ + "print(list(islice('ABCDEFG', 2, None)))\n", + "\n", + "# similar to\n", + "\n", + "print(list('ABCDEFG'[2:]))" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['A', 'C', 'E', 'G']\n", + "['A', 'C', 'E', 'G']\n" + ] + } + ], + "source": [ + "print(list(islice('ABCDEFG', 0, None, 2)))\n", + "\n", + "# similar to\n", + "\n", + "print(list('ABCDEFG'[::2]))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Starmap" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[32, 9, 1000]\n", + "[32, 9, 1000]\n" + ] + } + ], + "source": [ + "'''starmap(function, iterable)\n", + "\n", + "Makes an iterator that computes the function\n", + "using arguments obtained from the iterable.\n", + "\n", + "Works as a generator.\n", + "'''\n", + "\n", + "print(list(starmap(pow, [(2,5), (3,2), (10,3)])))\n", + "\n", + "# similar to\n", + "\n", + "starmap_equivalent = [2**5, 3**2, 10**3]\n", + "print(starmap_equivalent)" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "32\n" + ] + } + ], + "source": [ + "starmap_obj = starmap(pow, [(2,5), (3,2), (10,3)])\n", + "\n", + "print(next(starmap_obj))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Takewhile" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[1, 4]" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "'''takewhile(predicate, iterable)\n", + "\n", + "Makes an iterator that returns elements \n", + "from the iterable as long as the predicate is true.\n", + "'''\n", + "\n", + "list(takewhile(lambda x: x<5, [1,4,6,4,1]))" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1\n" + ] + } + ], + "source": [ + "takewhile_obj = takewhile(lambda x: x<5, [1,4,6,4,1])\n", + "\n", + "print(next(takewhile_obj))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Tee" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(, , )\n" + ] + } + ], + "source": [ + "'''tee(iterable, n=2)\n", + "\n", + "Tee will take the iterable that you give it \n", + "and return a tuple of n iterables, which you can then iterate through. \n", + "'''\n", + "b = tee((1,2,3,4), 3) # Created 3 iterable object with the same elements\n", + "print(b)" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1\n", + "2\n", + "3\n", + "4\n" + ] + } + ], + "source": [ + "for first in b[0]:\n", + " print(first)" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1\n", + "2\n", + "3\n", + "4\n" + ] + } + ], + "source": [ + "for second in b[1]:\n", + " print(second)" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1\n", + "2\n", + "3\n", + "4\n" + ] + } + ], + "source": [ + "for third in b[2]:\n", + " print(third)" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": {}, + "outputs": [], + "source": [ + "# Will raise IndexError uncomment to run.\n", + "\n", + "# for third in b[3]:\n", + "# print(third)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Zip Longest" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[('A', 'x'), ('B', 'y'), ('C', '-'), ('D', '-')]\n", + "[('A', 'x'), ('B', 'y'), ('C', 'z'), ('D', '-')]\n", + "[('A', 'x'), ('B', 'y'), ('C', 'z'), ('D', 'a'), ('-', 'b')]\n" + ] + } + ], + "source": [ + "'''zip_longest(*iterables, fillvalue=None)\n", + "\n", + "Makes an iterator that aggregates elements from each of the iterables.\n", + "If the iterables are of uneven length, missing values are filled-in \n", + "with the fillvalue.\n", + "\n", + "Iteration continues until the longest iterable is exhausted.\n", + "'''\n", + "\n", + "print(list(zip_longest('ABCD', 'xy', fillvalue='-')))\n", + "\n", + "print(list(zip_longest('ABCD', 'xyz', fillvalue='-')))\n", + "\n", + "print(list(zip_longest('ABCD', 'xyzab', fillvalue='-')))" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "('A', 'x')\n" + ] + } + ], + "source": [ + "zip_longest_obj = zip_longest('ABCD', 'xy', fillvalue='-')\n", + "\n", + "print(next(zip_longest_obj))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Combinatoric iterators" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Product" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[('A',), ('B',), ('C',), ('D',)]" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "'''Product (*iterables, repeat=1)\n", + "\n", + "Product is equivalent to for loops. \n", + "Repeat lets you choose how many times to nest.\n", + "\n", + "Works as a generator.\n", + "'''\n", + "\n", + "# Single for loop\n", + "list(product('ABCD', repeat=1))" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[('A', 'A'),\n", + " ('A', 'B'),\n", + " ('A', 'C'),\n", + " ('A', 'D'),\n", + " ('B', 'A'),\n", + " ('B', 'B'),\n", + " ('B', 'C'),\n", + " ('B', 'D'),\n", + " ('C', 'A'),\n", + " ('C', 'B'),\n", + " ('C', 'C'),\n", + " ('C', 'D'),\n", + " ('D', 'A'),\n", + " ('D', 'B'),\n", + " ('D', 'C'),\n", + " ('D', 'D')]" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "list(product('ABCD', repeat=2))" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "('A',)\n" + ] + } + ], + "source": [ + "product_object = product('ABCD', repeat=1)\n", + "\n", + "print(next(product_object))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Permuations" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[('A', 'B'),\n", + " ('A', 'C'),\n", + " ('A', 'D'),\n", + " ('B', 'A'),\n", + " ('B', 'C'),\n", + " ('B', 'D'),\n", + " ('C', 'A'),\n", + " ('C', 'B'),\n", + " ('C', 'D'),\n", + " ('D', 'A'),\n", + " ('D', 'B'),\n", + " ('D', 'C')]" + ] + }, + "execution_count": 43, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "'''permutations(iterable, r=None_\n", + "\n", + "Returns all permutations, no repeated elements\n", + "\n", + "Works as a generator.\n", + "'''\n", + "\n", + "list(permutations('ABCD', 2))" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "('A', 'B')\n" + ] + } + ], + "source": [ + "permutation_obj = permutations('ABCD', 2)\n", + "\n", + "print(next(permutation_obj))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Combinations" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[('A', 'B'), ('A', 'C'), ('A', 'D'), ('B', 'C'), ('B', 'D'), ('C', 'D')]" + ] + }, + "execution_count": 45, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "'''combinations(iterable, r)\n", + "\n", + "Returns all combinations results in sorted order,\n", + "no repeated elements.\n", + "\n", + "Works as a generator.\n", + "'''\n", + "\n", + "list(combinations('ABCD', 2))" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "('A', 'B')\n" + ] + } + ], + "source": [ + "combinations_obj = combinations('ABCD', 2)\n", + "\n", + "print(next(combinations_obj))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Combinations With Replacement" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[('A', 'A'),\n", + " ('A', 'B'),\n", + " ('A', 'C'),\n", + " ('A', 'D'),\n", + " ('B', 'B'),\n", + " ('B', 'C'),\n", + " ('B', 'D'),\n", + " ('C', 'C'),\n", + " ('C', 'D'),\n", + " ('D', 'D')]" + ] + }, + "execution_count": 47, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "'''combinations_with_replacement(iterable, r)\n", + "\n", + "Returns all combinations with replacements,\n", + "Results in sorted order\n", + "\n", + "The list should return with these additional elements:\n", + "[('A', 'A'), ('B', 'B'), ('C', 'C'), ('D', 'D')]\n", + "\n", + "Works as a generator.\n", + "'''\n", + "\n", + "list(combinations_with_replacement('ABCD', 2))" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "('A', 'A')\n" + ] + } + ], + "source": [ + "combinations_replace_obj = combinations_with_replacement('ABCD', 2)\n", + "\n", + "print(next(combinations_replace_obj))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Collections\n", + "[Return to table of contents](#toc)\n", + "\n", + "This module implements specialized container datatypes providing alternatives to Python’s general purpose built-in containers, dict, list, set, and tuple.\n", + "\n", + "NOTES:
\n", + "user(dict|list|string) have lost value moving from Python2 -> Python3.\n", + "I won't be covering them.\n", + "\n", + "https://docs.python.org/3/library/collections.html" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": {}, + "outputs": [], + "source": [ + "from collections import *" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Namedtuple" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Color(red=255, green=255, blue=224)\n" + ] + } + ], + "source": [ + "'''namedtuple(typename, field_names, verbose=False, rename=False)\n", + "\n", + "Used to create tuple-like objects that act like lists\n", + "dictionaries. Very good at being descriptive check.\n", + "\n", + "._make creates list like tuple\n", + "\n", + "._asdict() creates dict like tuple\n", + "\n", + "._replace Return a new instance of the named tuple \n", + " replacing specified fields with new values.\n", + "\n", + "._fields Tuple of strings listing the field names. \n", + "'''\n", + "\n", + "# Real world application\n", + "\n", + "Color = namedtuple('Color', ['red','green','blue'])\n", + "banana = Color(red=255, green=255, blue=224)\n", + "\n", + "print(banana)" + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": {}, + "outputs": [], + "source": [ + "# Functionality" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "255" + ] + }, + "execution_count": 52, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Indexable\n", + "\n", + "banana[0]" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "255" + ] + }, + "execution_count": 53, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Key accessable\n", + "\n", + "# ._asdict()\n", + "\n", + "banana_dict = banana._asdict()\n", + "\n", + "banana_dict['red']" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "descriptor(x=11, y=22)\n", + "descriptor(x=11, y=22)\n" + ] + } + ], + "source": [ + "# These create list like objects, iterable and indexable.\n", + "\n", + "# ._make\n", + "\n", + "something = namedtuple('descriptor', ['x', 'y'])\n", + "\n", + "print(something(11,22))\n", + "\n", + "# Similar to\n", + "\n", + "values = [11,22]\n", + "print(something._make(values))" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "descriptor(x=33, y=22)" + ] + }, + "execution_count": 55, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# ._replace \n", + "\n", + "p = something(x=11, y=22)\n", + "p._replace(x=33)" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "('x', 'y')" + ] + }, + "execution_count": 56, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# ._fields\n", + "\n", + "something._fields" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Deque" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "deque([1, 2, 3])\n" + ] + } + ], + "source": [ + "'''deque([iterable[, maxlen]])\n", + "\n", + "Deques are a generalization of stacks and queues\n", + "\n", + "The name is pronounced “deck” and is short for\n", + "“double-ended queue.\n", + "\n", + "Think of a deque as a list like container with \n", + "fast appends and pops on either end.\n", + "\n", + "\n", + "append(x) Add x to the right side of the deque.\n", + "\n", + "appendleft(x) Add x to the left side of the deque.\n", + "\n", + "clear() Remove all elements from the deque \n", + " leaving it with length 0.\n", + "\n", + "count(x) Count the number of deque elements equal to x.\n", + "\n", + "extend(iterable) Extend the right side of the deque \n", + " by appending elements from the iterable argument.\n", + "\n", + "extendleft(iterable) Extend the left side of the deque by appending\n", + " elements from iterable. Note, the series of \n", + " left appends results in reversing the order \n", + " of elements in the iterable argument.\n", + "\n", + "pop() Remove and return an element from the right \n", + " side of the deque. If no elements are present, \n", + " raises an IndexError.\n", + "\n", + "popleft() Remove and return an element from the left \n", + " side of the deque. If no elements are present,\n", + " raises an IndexError.\n", + "\n", + "remove(value) Removed the first occurrence of value.\n", + " If not found, raises a ValueError.\n", + "\n", + "reverse() Reverse the elements of the deque in-place\n", + " and then return None.\n", + "\n", + "rotate(n) Rotate the deque n steps to the right.\n", + " If n is negative, rotate to the left.\n", + " Rotating one step to the right is equivalent to:\n", + " d.appendleft(d.pop()).\n", + "'''\n", + "\n", + "d = deque([1,2,3])\n", + "\n", + "print(d)" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "deque([1, 2, 3, 4])\n" + ] + } + ], + "source": [ + "# append()\n", + "\n", + "d.append(4)\n", + "\n", + "print(d)" + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "deque([0, 1, 2, 3, 4])\n" + ] + } + ], + "source": [ + "# appendleft()\n", + "\n", + "d.appendleft(0) \n", + "\n", + "print(d)" + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "deque([])\n" + ] + } + ], + "source": [ + "# clear()\n", + "\n", + "d.clear()\n", + "\n", + "print(d)" + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "deque([1, 2, 3])\n" + ] + }, + { + "data": { + "text/plain": [ + "1" + ] + }, + "execution_count": 61, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# count()\n", + "d = deque([1,2,3])\n", + "\n", + "print(d)\n", + "\n", + "d.count(2)" + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "deque([1, 2, 3, 4, 5, 6])\n" + ] + } + ], + "source": [ + "# entend()\n", + "\n", + "d.extend([4,5,6])\n", + "\n", + "print(d)" + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "deque([-2, -1, 0, 1, 2, 3, 4, 5, 6])\n" + ] + } + ], + "source": [ + "# extendleft()\n", + "\n", + "d.extendleft([0,-1,-2])\n", + "\n", + "print(d)" + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "6\n", + "deque([-2, -1, 0, 1, 2, 3, 4, 5])\n" + ] + } + ], + "source": [ + "# pop()\n", + "\n", + "print(d.pop())\n", + "\n", + "print(d)" + ] + }, + { + "cell_type": "code", + "execution_count": 65, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "-2\n", + "deque([-1, 0, 1, 2, 3, 4, 5])\n" + ] + } + ], + "source": [ + "# popleft()\n", + "\n", + "print(d.popleft())\n", + "\n", + "print(d)" + ] + }, + { + "cell_type": "code", + "execution_count": 66, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "deque([-1, 0, 1, 2, 3, 4, 5])\n", + "deque([-1, 0, 1, 2, 3, 4])\n" + ] + } + ], + "source": [ + "# remove()\n", + "\n", + "print(d)\n", + "\n", + "d.remove(5)\n", + "\n", + "print(d)" + ] + }, + { + "cell_type": "code", + "execution_count": 67, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "deque([-1, 0, 1, 2, 3, 4])\n", + "deque([4, 3, 2, 1, 0, -1])\n" + ] + } + ], + "source": [ + "# reverse()\n", + "\n", + "print(d)\n", + "\n", + "d.reverse()\n", + "\n", + "print(d)" + ] + }, + { + "cell_type": "code", + "execution_count": 68, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "deque([4, 3, 2, 1, 0, -1])\n", + "deque([-1, 4, 3, 2, 1, 0])\n", + "deque([4, 3, 2, 1, 0, -1])\n" + ] + } + ], + "source": [ + "# rotate(n) # You can adjust n\n", + "\n", + "print(d)\n", + "\n", + "d.rotate() # Pushed the right most element to become the left most element.\n", + "\n", + "print(d)\n", + "\n", + "d.rotate(-1) # Pushed the left most element to become the right most element.\n", + "\n", + "print(d)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "ChainMap" + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "metadata": {}, + "outputs": [], + "source": [ + "'''ChainMap(*maps)\n", + "\n", + "A ChainMap class is provided for quickly linking\n", + "a number of mappings so they can be treated as a single unit.\n", + "\n", + "If there a key that is the same within the ChainMap object, \n", + "it will assign the value to the first instance of that key.\n", + "'''\n", + "\n", + "dict1 = {'a':1,'b':2,'c':3}\n", + "dict2 = {'c':4,'d':5,'e':6}\n", + "\n", + "chained = ChainMap(dict1,dict2)" + ] + }, + { + "cell_type": "code", + "execution_count": 70, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "2" + ] + }, + "execution_count": 70, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "chained['b']" + ] + }, + { + "cell_type": "code", + "execution_count": 71, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "3" + ] + }, + "execution_count": 71, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Assigned 3 not 4 because dict1 was paased first.\n", + "\n", + "chained['c']" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Counter" + ] + }, + { + "cell_type": "code", + "execution_count": 72, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Counter({1: 3, 2: 3, 3: 3, 5: 3, 7: 3, 4: 3, 9: 3})" + ] + }, + "execution_count": 72, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "'''Counter([iterable-or-mapping])\n", + "\n", + "It is an unordered collection where elements\n", + "are stored as dictionary keys and their counts\n", + "are stored as dictionary values.\n", + "\n", + "Keys are the elements in the list and \n", + "the values are the number of occurences\n", + "'''\n", + "\n", + "example_list = [1,1,1,2,2,2,3,3,3,5,5,5,7,7,7,4,4,4,9,9,9,]\n", + "\n", + "Counter(example_list)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "OrderedDict" + ] + }, + { + "cell_type": "code", + "execution_count": 73, + "metadata": {}, + "outputs": [], + "source": [ + "'''OrderedDict([items])\n", + "\n", + "An OrderedDict is a dict that remembers\n", + "the order that keys were first inserted.\n", + "'''\n", + "\n", + "ordered_dict = OrderedDict({'a':1, 'b':2, 'c':3, 'd':4})" + ] + }, + { + "cell_type": "code", + "execution_count": 74, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 4)])" + ] + }, + "execution_count": 74, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "ordered_dict" + ] + }, + { + "cell_type": "code", + "execution_count": 75, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "a 1\n", + "b 2\n", + "c 3\n", + "d 4\n" + ] + } + ], + "source": [ + "# Supports all dictionary functions.\n", + "\n", + "for k,v in ordered_dict.items():\n", + " print(k,v)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Defaultdict" + ] + }, + { + "cell_type": "code", + "execution_count": 76, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'m': 1, 'i': 4, 's': 4, 'p': 2}\n", + "[('m', 1), ('i', 4), ('s', 4), ('p', 2)]\n" + ] + } + ], + "source": [ + "'''defaultdict([default_factory[, ...]])\n", + "\n", + "When a key is encountered for the first time it is assigned\n", + "the default_factory value you assign.\n", + "\n", + "Great to use when you need to count individual elements within a collection\n", + "Similar to count, but with the ability to set that default_factory.\n", + "'''\n", + "\n", + "string = 'mississippi'\n", + "\n", + "d = {}\n", + "\n", + "for letter in string:\n", + " if letter not in d:\n", + " d[letter] = 1 # For every new key we give it a default value of 1\n", + " else:\n", + " d[letter] += 1\n", + " \n", + "print(d)\n", + " \n", + "# Similar to\n", + "\n", + "default_dict2 = defaultdict(int)\n", + "for k in string:\n", + " default_dict2[k] += 1\n", + "\n", + "print(list(default_dict2.items()))" + ] + }, + { + "cell_type": "code", + "execution_count": 77, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[('yellow', [1, 3]), ('blue', [2, 4]), ('red', [1])]" + ] + }, + "execution_count": 77, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Setting the default to a list.\n", + "\n", + "colors = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]\n", + "\n", + "colors_default_dict = defaultdict(list)\n", + "\n", + "for k, v in colors:\n", + " colors_default_dict[k].append(v)\n", + "\n", + "list(colors_default_dict.items())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Decorators\n", + "[Return to table of contents](#toc)\n", + "\n", + "A decorator in Python is any callable Python object that is used to modify a function or a class\n", + "\n", + "Decorators work like wrappers or first class function." + ] + }, + { + "cell_type": "code", + "execution_count": 78, + "metadata": {}, + "outputs": [], + "source": [ + "# Outer is the first class funcion.\n", + "def outer(x):\n", + " message = x\n", + " \n", + " def inner():\n", + " print(''+message+'')\n", + " \n", + " return inner()" + ] + }, + { + "cell_type": "code", + "execution_count": 79, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "hello\n" + ] + } + ], + "source": [ + "outer('hello')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now using as a decorator" + ] + }, + { + "cell_type": "code", + "execution_count": 80, + "metadata": {}, + "outputs": [], + "source": [ + "def html_wrapper(function):\n", + " def wrap(code):\n", + " print(f'

{code}

')\n", + " return wrap" + ] + }, + { + "cell_type": "code", + "execution_count": 81, + "metadata": {}, + "outputs": [], + "source": [ + "@html_wrapper\n", + "def need_to_wrap(code):\n", + " print(code)" + ] + }, + { + "cell_type": "code", + "execution_count": 82, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "

Wrap this paragraph

\n" + ] + } + ], + "source": [ + "need_to_wrap('Wrap this paragraph')" + ] + }, + { + "cell_type": "code", + "execution_count": 83, + "metadata": {}, + "outputs": [], + "source": [ + "@html_wrapper\n", + "def need_to_wrap(code):\n", + " print(code)" + ] + }, + { + "cell_type": "code", + "execution_count": 84, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "

Using it again

\n" + ] + } + ], + "source": [ + "need_to_wrap('Using it again')" + ] + }, + { + "cell_type": "code", + "execution_count": 85, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "128\n", + "32\n", + "243\n" + ] + } + ], + "source": [ + "'''Example from \n", + "https://realpython.com/inner-functions-what-are-they-good-for/\n", + "'''\n", + "\n", + "def generate_power(exponent):\n", + " def decorator(f):\n", + " def inner(*args):\n", + " result = f(*args)\n", + " return exponent**result\n", + " return inner\n", + " return decorator\n", + "\n", + "@generate_power(2)\n", + "def raise_two(n):\n", + " return n\n", + "\n", + "print(raise_two(7)) # 2**7\n", + "print(raise_two(5)) # 2**5\n", + "\n", + "@generate_power(3)\n", + "def raise_three(n):\n", + " return n\n", + "\n", + "print(raise_three(5)) # 3**5" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Property Decorators: Getters, Setters and Deleters \n", + "\n", + "[Video that helped me a lot](https://www.youtube.com/watch?v=jCzT9XFZ5bw&t=459s)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Property/Getter" + ] + }, + { + "cell_type": "code", + "execution_count": 86, + "metadata": {}, + "outputs": [], + "source": [ + "''' Property gives classes getter, setter and deleter functionality. \n", + "@property on its own will give getter funtionality\n", + "allowing class methods to be called like an attribute.\n", + "'''\n", + "\n", + "class Person:\n", + " def __init__(self, first, last):\n", + " self.first = first\n", + " self.last = last\n", + " \n", + " @property # This will allow me to call fullname as an attribute.\n", + " def fullname(self):\n", + " return f'{self.first} {self.last}'" + ] + }, + { + "cell_type": "code", + "execution_count": 87, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'Guy Fieri'" + ] + }, + "execution_count": 87, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Guy = Person('Guy', 'Fieri')\n", + "\n", + "Guy.fullname\n", + "\n", + "# Similar to\n", + "\n", + "# Guy.fullname()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Setters" + ] + }, + { + "cell_type": "code", + "execution_count": 88, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'Why are setters useful?\\n\\nThis gives us the ability to alter class attributes used by a certain class\\nmethod without forcing a method call.\\n'" + ] + }, + "execution_count": 88, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "'''Why are setters useful?\n", + "\n", + "This gives us the ability to alter class attributes used by a certain class\n", + "method without forcing a method call.\n", + "'''" + ] + }, + { + "cell_type": "code", + "execution_count": 89, + "metadata": {}, + "outputs": [], + "source": [ + "class Person:\n", + " def __init__(self, first, last):\n", + " self.first = first\n", + " self.last = last\n", + " self.email = f'{self.first}.{self.last}@flavortown.com'.lower()\n", + " \n", + " def fullname(self):\n", + " return f'{self.first} {self.last}'" + ] + }, + { + "cell_type": "code", + "execution_count": 90, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Guy\n", + "Guy Fieri\n", + "guy.fieri@flavortown.com\n" + ] + } + ], + "source": [ + "Guy = Person('Guy', 'Fieri')\n", + "\n", + "# Looks good.\n", + "print(Guy.first)\n", + "print(Guy.fullname())\n", + "print(Guy.email)" + ] + }, + { + "cell_type": "code", + "execution_count": 91, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "notguy\n", + "guy.fieri@flavortown.com\n" + ] + } + ], + "source": [ + "# But what if we change a first or last name?\n", + "Guy.first = 'notguy'\n", + "print(Guy.first)\n", + "print(Guy.email) # It doesn't change. So lets make it a method" + ] + }, + { + "cell_type": "code", + "execution_count": 92, + "metadata": {}, + "outputs": [], + "source": [ + "class Person:\n", + " def __init__(self, first, last):\n", + " self.first = first\n", + " self.last = last\n", + " \n", + " def email(self):\n", + " return f'{self.first}.{self.last}@flavortown.com'.lower()\n", + " \n", + " def fullname(self):\n", + " return f'{self.first} {self.last}'" + ] + }, + { + "cell_type": "code", + "execution_count": 93, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "notguy\n", + "notguy.fieri@flavortown.com\n" + ] + } + ], + "source": [ + "'''It worked!\n", + "\n", + "But, this would mean I would need to change all \n", + "instance of email into a method to update them if I \n", + "changed a first or last name.\n", + "\n", + "Now for the setters.\n", + "'''\n", + "\n", + "Guy = Person('Guy', 'Fieri')\n", + "Guy.first = 'notguy'\n", + "\n", + "print(Guy.first)\n", + "print(Guy.email()) " + ] + }, + { + "cell_type": "code", + "execution_count": 94, + "metadata": {}, + "outputs": [], + "source": [ + "class Person:\n", + " def __init__(self, first, last):\n", + " self.first = first\n", + " self.last = last\n", + " \n", + " @property\n", + " def email(self):\n", + " return f'{self.first}.{self.last}@flavortown.com'.lower()\n", + " \n", + " @property\n", + " def fullname(self):\n", + " return f'{self.first} {self.last}'\n", + " \n", + " @fullname.setter\n", + " def fullname(self, new_name):\n", + " first, last = new_name.split(' ')\n", + " self.first = first\n", + " self.last = last" + ] + }, + { + "cell_type": "code", + "execution_count": 95, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Guy Fieri\n", + "fieri.notguy@flavortown.com\n", + "Fieri\n" + ] + } + ], + "source": [ + "# We can now change attributes though setters from a class method.\n", + "\n", + "Guy = Person('Guy', 'Fieri')\n", + "print(Guy.fullname)\n", + "\n", + "Guy.fullname = 'Fieri Notguy'\n", + "print(Guy.email)\n", + "print(Guy.first)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Deleters" + ] + }, + { + "cell_type": "code", + "execution_count": 96, + "metadata": {}, + "outputs": [], + "source": [ + "'''Used when we want to delete things or default them to another value.\n", + "uses del\n", + "'''\n", + "\n", + "class Person:\n", + " def __init__(self, first, last):\n", + " self.first = first\n", + " self.last = last\n", + " \n", + " @property\n", + " def fullname(self):\n", + " return f'{self.first} {self.last}'\n", + " \n", + " @fullname.deleter\n", + " def fullname(self):\n", + " print('Deleted!')\n", + " self.first = None\n", + " self.last = None" + ] + }, + { + "cell_type": "code", + "execution_count": 97, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Guy Fieri\n", + "Deleted!\n", + "None\n" + ] + } + ], + "source": [ + "Guy = Person('Guy', 'Fieri')\n", + "print(Guy.fullname)\n", + "\n", + "del Guy.fullname # Deletes the values and sets them to None.\n", + "print(Guy.first)" + ] + }, + { + "cell_type": "code", + "execution_count": 98, + "metadata": {}, + "outputs": [], + "source": [ + "class Person:\n", + " def __init__(self, first, last):\n", + " self.first = first\n", + " self.last = last\n", + " \n", + " @property\n", + " def fullname(self):\n", + " return f'{self.first} {self.last}'\n", + " \n", + " @fullname.deleter # Reset to default\n", + " def fullname(self):\n", + " print('Deleted!')\n", + " self.first = 'Joe'\n", + " self.last = 'Smith'" + ] + }, + { + "cell_type": "code", + "execution_count": 99, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Guy Fieri\n", + "Deleted!\n", + "Joe\n", + "Smith\n" + ] + } + ], + "source": [ + "Guy = Person('Guy', 'Fieri')\n", + "print(Guy.fullname)\n", + "\n", + "del Guy.fullname # Reset to the defaults we specified.\n", + "\n", + "print(Guy.first)\n", + "print(Guy.last)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Functools\n", + "[Return to table of contents](#toc)\n", + "\n", + "The functools module is for higher-order functions: functions that act on or return other functions. In general, any callable object can be treated as a function for the purposes of this module.\n", + "\n", + "https://docs.python.org/3/library/functools.html#functools.partial" + ] + }, + { + "cell_type": "code", + "execution_count": 100, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'Functools has a lot of wrapper tools and functionality. \\nI may go over them at some point. For now I think partial and reduce\\nare very good to know.\\n'" + ] + }, + "execution_count": 100, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from functools import *\n", + "\n", + "'''Functools has a lot of wrapper tools and functionality. \n", + "I may go over them at some point. For now I think partial and reduce\n", + "are very good to know.\n", + "'''" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Partial" + ] + }, + { + "cell_type": "code", + "execution_count": 101, + "metadata": {}, + "outputs": [], + "source": [ + "'''Partial(func, *args, **keywords)\n", + "\n", + "Partial makes a new version of a function with one or more arguments already filled in. Used for quick access.\n", + "\n", + "Good resource https://www.pydanny.com/python-partials-are-fun.html\n", + "'''\n", + "\n", + "# Initial function\n", + "def student(first,last,grade):\n", + " print(first,last,grade)\n", + "\n", + "# Partial function\n", + "freshman = partial(student, grade=10)" + ] + }, + { + "cell_type": "code", + "execution_count": 102, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Joe Smith 10\n" + ] + } + ], + "source": [ + "freshman('Joe','Smith')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Partialmethod" + ] + }, + { + "cell_type": "code", + "execution_count": 103, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "False\n", + "True\n" + ] + } + ], + "source": [ + "'''partialmethod(func, *args, **keywords)\n", + "\n", + "Return a new partialmethod descriptor \n", + "which behaves like partial except that \n", + "it is designed to be used as a method \n", + "definition rather than being directly callable.\n", + "'''\n", + "\n", + "class Cell(object):\n", + " def __init__(self):\n", + " self._alive = False\n", + " @property\n", + " def alive(self):\n", + " return self._alive\n", + " def set_state(self, state):\n", + " self._alive = bool(state)\n", + " set_alive = partialmethod(set_state, True)\n", + " set_dead = partialmethod(set_state, False)\n", + "\n", + "c = Cell()\n", + "print(c.alive) # Calls `self._alive = False` via @property\n", + "\n", + "c.set_alive() # Partial method is callable and sets the state True\n", + "print(c.alive)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Reduce" + ] + }, + { + "cell_type": "code", + "execution_count": 104, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "3628800" + ] + }, + "execution_count": 104, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "'''reduce(function, iterable, initializer=None)\n", + "\n", + "Reduce needs to be imported in Python3.x\n", + "\n", + "Reduce is a really useful function for performing some computation on a list and returning the result.\n", + "It applies a rolling computation to sequential pairs of values in a list. This one is tricky.\n", + "\n", + "Easiest example to understnad is trying to multiply a whole list together i.e 1*2*3*4*5*6*7*8*9*10\n", + "'''\n", + "\n", + "list_1 = list(range(1,11))\n", + "\n", + "reduce((lambda x, y: x * y), list_1) " + ] + }, + { + "cell_type": "code", + "execution_count": 105, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "10" + ] + }, + "execution_count": 105, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Another great example is using reduce to compare elements in a list against each other.\n", + "\n", + "reduce(lambda x, y: y if y > x else x, list_1) # Finding the largest number in the list" + ] + }, + { + "cell_type": "code", + "execution_count": 106, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "1" + ] + }, + "execution_count": 106, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "reduce(lambda x, y: y if y < x else x, list_1) # Finding the smallest number in the list" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Datetime\n", + "[Return to table of contents](#toc)\n", + "\n", + "The datetime module helps when manipulating time and date in Python with ease. \n", + "\n", + "https://docs.python.org/3/library/datetime.html" + ] + }, + { + "cell_type": "code", + "execution_count": 107, + "metadata": {}, + "outputs": [], + "source": [ + "from datetime import *" + ] + }, + { + "cell_type": "code", + "execution_count": 108, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "datetime.datetime(2018, 10, 10, 13, 56, 15, 346320)" + ] + }, + "execution_count": 108, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "'''datetime()\n", + "\n", + "Display the current time and date of your machine.\n", + "A datetime object will return following attributes:\n", + "year, month, day, hour, minute, seconds, micro-seconds.\n", + "'''\n", + "\n", + "datetime.now()" + ] + }, + { + "cell_type": "code", + "execution_count": 109, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Today is the 10 day of month 10, and the year is 2018!\n" + ] + } + ], + "source": [ + "now = datetime.now()\n", + "\n", + "# We can also extract only certain data as desired.\n", + "\n", + "now_year = now.year\n", + "now_month = now.month\n", + "now_day = now.day\n", + "\n", + "print('Today is the {} day of month {}, and the year is {}!'\n", + " .format(now_day, now_month, now_year))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Strftime" + ] + }, + { + "cell_type": "code", + "execution_count": 110, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The current month is October.\n" + ] + } + ], + "source": [ + "'''strftime() \n", + "\n", + "Strftime formats datetime objects into readable strings\n", + "\n", + "The %B is how strftime knows to return the \n", + "string of the current month in full.\n", + "\n", + "Useful cheatsheet for how to use strftime:\n", + "https://devhints.io/strftime.\n", + "'''\n", + "\n", + "print('The current month is {}.'.format(now.strftime('%B')))" + ] + }, + { + "cell_type": "code", + "execution_count": 111, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Today's date is 10-10-2018. Be careful;\n", + "It's not a datetimeobject anymore it is a !\n" + ] + } + ], + "source": [ + "# strftime() can generally be used to format datetime objects.\n", + "\n", + "formatted = now.strftime('%d-%m-%Y')\n", + "print('''Today's date is {}. Be careful;\n", + "It's not a datetimeobject anymore it is a {}!'''\n", + " .format(formatted, type(formatted)))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Timedelta" + ] + }, + { + "cell_type": "code", + "execution_count": 112, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "I started studying in university back in 21-10-2015,and I'll finish in 17-10-2018\n" + ] + } + ], + "source": [ + "'''timedelta()\n", + "Used to get a date X days\\months\\etc from now.\n", + "\n", + "'''\n", + "from datetime import timedelta\n", + "\n", + "''' School lasts about three years, \n", + "so we calculate the time difference between\n", + "starting university time and three years \n", + "(or 3 * 52 weeks) from this time'''\n", + "\n", + "start_uni_time = datetime(2015, 10, 21)\n", + "end_uni_time = start_uni_time + timedelta(weeks=52 * 3)\n", + "\n", + "print('''I started studying in university back in {},and I'll finish in {}'''\n", + " .format(start_uni_time.strftime('%d-%m-%Y'), end_uni_time.strftime('%d-%m-%Y')))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.6" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/python_tips_1.ipynb b/python_tips.ipynb similarity index 92% rename from python_tips_1.ipynb rename to python_tips.ipynb index bf764d3..4abfe5c 100644 --- a/python_tips_1.ipynb +++ b/python_tips.ipynb @@ -6,8 +6,14 @@ "source": [ "# TABLE OF CONTENTS:\n", "\n", + "These tips are focused on topics I think every Python programmer should know.\n", + "\n", "Please go through official documentation if you want more thorough examples.\n", "\n", + "[Great website](https://realpython.com)
\n", + "[Great youtuber](https://www.youtube.com/channel/UCCezIgC97PvUuR4_gbFUs5g)\n", + "\n", + "\n", "Topics:\n", " - [Lambda functions](#lambda)\n", " - [Enumerate](#enum)\n", @@ -25,6 +31,7 @@ " - [Args](#args)\n", " - [Kwargs](#kwargs)\n", " - [Using Them Together](#together)\n", + " - [Class Inheritence](#class)\n", " - [Mutable parameters](#mparams)" ] }, @@ -636,7 +643,7 @@ { "data": { "text/plain": [ - "" + "" ] }, "execution_count": 24, @@ -982,8 +989,7 @@ "# These are use in documentation, specifically within in functions or class methods\n", "\n", "def documentation(x, y):\n", - " '''\n", - " This function takes two parameters\n", + " '''This function takes two parameters\n", " It will then sum x and y\n", " '''\n", " return(x+y)" @@ -1232,6 +1238,87 @@ "multiple('a','b',1,2,3,4,5,key1='item1',key2='item2')" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Class inheretance\n", + "[Return to table of contents](#toc)\n", + "\n", + "Simple overview of class inheretance. If you want to inherit instance variables from another clsss following this syntax:" + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": {}, + "outputs": [], + "source": [ + "# syntax\n", + "\n", + "'''\n", + "childclass(parentcall):\n", + " def __init__(self, parent_var, new_var):\n", + " super().__init__(parent_var)\n", + "'''\n", + "\n", + "# Class\n", + "\n", + "class Employee():\n", + " def __init__(self, name, job):\n", + " self.name = name\n", + " self.job = job\n", + " \n", + "# This class inherits name and job from the employee class using super().__init__\n", + "\n", + "class Manager(Employee):\n", + " def __init__(self, name, job, level):\n", + " super().__init__(name, job)\n", + " self.level = level" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'Todd'" + ] + }, + "execution_count": 52, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Todd = Employee('Todd','Developer')\n", + "Todd.name" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'Manager'" + ] + }, + "execution_count": 53, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Sharon = Manager('Sharon', 'Senior Developer', 'Manager')\n", + "Sharon.level" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -1242,7 +1329,7 @@ }, { "cell_type": "code", - "execution_count": 51, + "execution_count": 54, "metadata": {}, "outputs": [], "source": [ @@ -1256,7 +1343,7 @@ }, { "cell_type": "code", - "execution_count": 52, + "execution_count": 55, "metadata": { "scrolled": true }, @@ -1267,7 +1354,7 @@ "[5]" ] }, - "execution_count": 52, + "execution_count": 55, "metadata": {}, "output_type": "execute_result" } @@ -1278,7 +1365,7 @@ }, { "cell_type": "code", - "execution_count": 53, + "execution_count": 56, "metadata": {}, "outputs": [ { @@ -1287,7 +1374,7 @@ "[5, 7]" ] }, - "execution_count": 53, + "execution_count": 56, "metadata": {}, "output_type": "execute_result" } @@ -1298,7 +1385,7 @@ }, { "cell_type": "code", - "execution_count": 54, + "execution_count": 57, "metadata": {}, "outputs": [], "source": [ @@ -1313,7 +1400,7 @@ }, { "cell_type": "code", - "execution_count": 55, + "execution_count": 58, "metadata": {}, "outputs": [ { @@ -1322,7 +1409,7 @@ "[5]" ] }, - "execution_count": 55, + "execution_count": 58, "metadata": {}, "output_type": "execute_result" } @@ -1333,7 +1420,7 @@ }, { "cell_type": "code", - "execution_count": 56, + "execution_count": 59, "metadata": {}, "outputs": [ { @@ -1342,7 +1429,7 @@ "[7]" ] }, - "execution_count": 56, + "execution_count": 59, "metadata": {}, "output_type": "execute_result" } @@ -1368,7 +1455,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.5" + "version": "3.6.6" } }, "nbformat": 4, diff --git a/python_tips_2.ipynb b/python_tips_2.ipynb deleted file mode 100644 index 2460f1e..0000000 --- a/python_tips_2.ipynb +++ /dev/null @@ -1,857 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# TABLE OF CONTENTS: \n", - "\n", - "I may not cover everything in each library.
\n", - "Please go through official documentation if you want more thorough examples.\n", - "\n", - "Topics:\n", - " - [Generators](#generators)\n", - " - [Itertools](#itertools)\n", - " - [Infinite itoratos](#infinite)\n", - " - [Iterators terminating on the shortest input sequence](#itotsis)\n", - " - [Combinatoric iterators](#combinatoric)\n", - " - [Collections](#collections)\n", - " - [Functools](#functools)\n", - " - [Class Inheritence](#class)\n", - " - [Datetime](#dt)\n", - " - [Timedelta](#timedelta)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Generators\n", - "[Return to table of contents](#toc)\n", - "\n", - "Most functions process a collection of data first before returning the finished result. Generators remove iteration and temporary collection to store results." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Non generator function returning an operation on a list\n", - "\n", - "def non_generator(list_of_nums):\n", - " product_list = []\n", - " for i in list_of_nums:\n", - " product_list.append(i**i)\n", - " return product_list" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Iterates, stores in product_list and returns product_list.\n", - "\n", - "non_generator([1,2,3,4])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Now using a generator\n", - "\n", - "def generator(list_of_nums):\n", - " for i in list_of_nums:\n", - " yield i**i" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Each time your generator is called upon using next, it will only then yield the result. \n", - "# This will continue until your generator is exhausted.\n", - "\n", - "my_gen = generator([1,2,3,4])\n", - "print(next(my_gen))\n", - "print(next(my_gen))\n", - "print(next(my_gen))\n", - "print(next(my_gen))\n", - "print(next(my_gen))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# You can also iterate over your generator\n", - "\n", - "for i in generator([1,2,3,4]):\n", - " print(i)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Itertools \n", - "[Return to table of contents](#toc)\n", - "\n", - "This module implements a number of iterator building blocks inspired by constructs from APL, Haskell, and SML. Each has been recast in a form suitable for Python.\n", - "\n", - "The module standardizes a core set of fast, memory efficient tools that are useful by themselves or in combination. Together, they form an “iterator algebra” making it possible to construct specialized tools succinctly and efficiently in pure Python.\n", - "\n", - "https://docs.python.org/3/library/itertools.html" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "from itertools import *" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Infinite itorators
\n", - "Please learn about generators first. Do not use count() and cycle() to create a list." - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "0\n", - "5\n", - "10\n", - "15\n" - ] - } - ], - "source": [ - "'''\n", - "count()\n", - "\n", - "This creates an iterable object that goes up by the step you specify.\n", - "This will continuously yield increments of 5 i.e. 0, 5, 10, 15, 20...\n", - "'''\n", - "\n", - "count_object = count(0, 5) # (start, step)\n", - "\n", - "print(next(count_object))\n", - "print(next(count_object))\n", - "print(next(count_object))\n", - "print(next(count_object))" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "A\n", - "B\n", - "C\n", - "D\n", - "A\n" - ] - } - ], - "source": [ - "'''\n", - "cycle()\n", - "\n", - "This creates an iterable object of what you pass in in an endless cycle.\n", - "This will continuously yield, A B C D A B C D A B C D ...\n", - "''' \n", - "\n", - "cycle_object = cycle('ABCD')\n", - "\n", - "print(next(cycle_object))\n", - "print(next(cycle_object))\n", - "print(next(cycle_object))\n", - "print(next(cycle_object))\n", - "print(next(cycle_object))" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[10, 10, 10]\n", - "['hello', 'hello', 'hello', 'hello']\n" - ] - } - ], - "source": [ - "'''\n", - "repeat()\n", - "\n", - "Used to repeat an element up to n times.\n", - "'''\n", - "\n", - "print(list(repeat(10, 3)))\n", - "print(list(repeat('hello',4)))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Iterators terminating on the shortest input sequence" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "'''accumulate()'''" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "'''chain() and chain.from_iterable'''" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "'''compress()'''" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "'''dropwhile()'''" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "'''filterflase()'''" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "'''groupby()'''" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "'''islice()'''" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "'''starmap()'''" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "'''tee()'''" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "'''zip_longest()'''" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Combinatoric iterators" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Product is the equivalent for-loops. Repeat lets you choose how many times to nest." - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[('A',), ('B',), ('C',), ('D',)]" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Product ()\n", - "\n", - "#is equivalent for-loops. Repeat lets you choose how many times to nest.\n", - "\n", - "list(product('ABCD', repeat=1))" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[('A', 'B'), ('A', 'C'), ('A', 'D'), ('B', 'C'), ('B', 'D'), ('C', 'D')]" - ] - }, - "execution_count": 23, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "list(combinations('ABCD', 2))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "combinations_with_replacement()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "count()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "accumulate()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Collections\n", - "[Return to table of contents](#toc)\n", - "\n", - "This module implements specialized container datatypes providing alternatives to Python’s general purpose built-in containers, dict, list, set, and tuple.\n", - "\n", - "https://docs.python.org/3/library/collections.html" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Functools\n", - "[Return to table of contents](#toc)\n", - "\n", - "The functools module is for higher-order functions: functions that act on or return other functions. In general, any callable object can be treated as a function for the purposes of this module.\n", - "\n", - "https://docs.python.org/3/library/functools.html#functools.partial" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Partial makes a new version of a function with one or more arguments already filled in. Used for quick access." - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [], - "source": [ - "from functools import partial\n", - "# Good resource https://www.pydanny.com/python-partials-are-fun.html\n", - "\n", - "def student(first,last,grade):\n", - " print(first,last,grade)\n", - "\n", - "freshman = partial(student, grade=10)" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Joe Smith 10\n" - ] - } - ], - "source": [ - "freshman('Joe','Smith')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Reduce is a really useful function for performing some computation on a list and returning the result. It applies a rolling computation to sequential pairs of values in a list. This one is tricky." - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "3628800" - ] - }, - "execution_count": 20, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Reduce needs to be imported in Python3.x\n", - "from functools import reduce\n", - "\n", - "# Easiest example to understnad is trying to multiply a whole list together i.e 1*2*3*4*5*6*7*8*9*10\n", - "\n", - "list_1 = list(range(1,11))\n", - "\n", - "reduce((lambda x, y: x * y), list_1) " - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "10" - ] - }, - "execution_count": 21, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Another great example is using reduce to compare elements in a list against each other.\n", - "\n", - "reduce(lambda x, y: y if y > x else x, list_1) # Finding the largest number in the list" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "data": { - "text/plain": [ - "1" - ] - }, - "execution_count": 22, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "reduce(lambda x, y: y if y < x else x, list_1) # Finding the smallest number in the list" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Decorators\n", - "[Return to table of contents](#toc)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Class inheretance\n", - "[Return to table of contents](#toc)\n", - "\n", - "Simple overview of class inheretance. If you want to inherit instance variables from another clsss following this syntax:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# syntax\n", - "\n", - "'''\n", - "childclass(parentcall):\n", - " def __init__(self, parent_var, new_var):\n", - " super().__init__(parent_var)\n", - "'''" - ] - }, - { - "cell_type": "code", - "execution_count": 39, - "metadata": {}, - "outputs": [], - "source": [ - "# Class\n", - "\n", - "class employee():\n", - " def __init__(self, name, job):\n", - " self.name = name\n", - " self.job = job\n", - "\n", - " \n", - "# This class inherits name and job from the employee class using super().__init__\n", - "\n", - "class manager(employee):\n", - " def __init__(self, name, job, level):\n", - " super().__init__(name, job)\n", - " self.level = level" - ] - }, - { - "cell_type": "code", - "execution_count": 42, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'Todd'" - ] - }, - "execution_count": 42, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "Todd = employee('Todd','Developer')\n", - "Todd.name" - ] - }, - { - "cell_type": "code", - "execution_count": 44, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'Manager'" - ] - }, - "execution_count": 44, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "Sharon = manager('Sharon', 'Senior Developer', 'Manager')\n", - "Sharon.level" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Datetime\n", - "[Return to table of contents](#toc)\n", - "\n", - "The datetime module helps when manipulating time and date in Python with ease. \n", - "\n", - "https://docs.python.org/3/library/datetime.html" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "datetime.datetime(2018, 9, 28, 9, 54, 20, 815758)" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from datetime import datetime\n", - "\n", - "# A datetime object will return following attributes: year, month, day, hour, minute, seconds, micro-seconds.\n", - "\n", - "# Display the current time and date of your machine.\n", - "datetime.now()" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Today is the 28 day of month 9, and the year is 2018!\n" - ] - } - ], - "source": [ - "now_datetime_object = datetime.now()\n", - "\n", - "# We can also extract only certain data as desired.\n", - "\n", - "now_year = now_datetime_object.year\n", - "now_month = now_datetime_object.month\n", - "now_day = now_datetime_object.day\n", - "\n", - "print('Today is the {} day of month {}, and the year is {}!'.format(now_day, now_month, now_year))" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The current month is September.\n" - ] - } - ], - "source": [ - "# strftime() formats datetime objects into readable strings\n", - "# The %B is how strftime knows to return the string of the current month in full.\n", - "# Useful cheatsheet for how to use strftime: https://devhints.io/strftime.\n", - "\n", - "print('The current month is {}.'.format(now_datetime_object.strftime('%B')))" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Today's date is 28-09-2018, and be careful; now it is not a datetimeobject!\n", - " it is actually !\n" - ] - } - ], - "source": [ - "# strftime() can generally be used to format datetime objects.\n", - "\n", - "pretty_format = now_datetime_object.strftime('%d-%m-%Y')\n", - "print(\"Today's date is {}, and be careful; now it is not a datetimeobject!\\n \\\n", - " it is actually {}!\".format(pretty_format, type(pretty_format)))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Timedelta" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "I started studying in university back in 21-10-2015, and I'll finish in 17-10-2018\n" - ] - } - ], - "source": [ - "# To get a date X days\\months\\etc from now, we can use timedelta().\n", - "\n", - "from datetime import timedelta\n", - "\n", - "# School lasts about three years, so we calculate the time difference between starting university time and three years \n", - "# (or 3 * 52 weeks) from this time\n", - "\n", - "start_uni_time = datetime(2015, 10, 21)\n", - "end_uni_time = start_uni_time + timedelta(weeks=52 * 3)\n", - "print(\"I started studying in university back in {}, and I'll finish in {}\".format(\n", - " start_uni_time.strftime('%d-%m-%Y'), end_uni_time.strftime('%d-%m-%Y')))" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.6.5" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -}