890 likes | 927 Views
Advanced T opics in Functional and Reactive Programming: Python 3. Majeed Kassis. Agenda. Basic Python Advanced Python Python Functional Programming Good Programming Practices. Python. An open-sourced programming language Interpreted – No compilation needed
E N D
Advanced Topics in Functional and Reactive Programming:Python 3 MajeedKassis
Agenda • Basic Python • Advanced Python • Python Functional Programming • Good Programming Practices
Python • An open-sourced programming language • Interpreted – • No compilation needed • Python uses an interpreter to translate and run its code! • The interpreter reads and executes each line of code one at a time • Memory managed – • manages creation and deletion of objects • Object oriented – • objects, inheritance • Functional oriented – • pure functions, lambda, map, filer, reduce, list comprehensions • Dynamically typed – • Type check is done during runtime • Strongly typed – • once the type is detected, operations can be executed only for the detected type
Python: Types • Dynamically Typed: • This works! • Strongly Typed: • This fails - combining string with integer! • In python objects have a type, it is just not visible, and can be changed on the go.
Python: type() • Dynamically-typed: declared without an explicit type
Python: Numbers • Python has two numeric types: int and float
Python: Booleans • bool is a subtype of int, where: • True == 1 and False == 0
Python: Strings • No char in Python! • Both ' and " create string literals.
Indexing & Negative Indexing • Strings are index accessible! • Substring returned is also a String. Even if its length is 1.
Python: Lists • Line 7, 8: • Python lists are objects with overloaded operations such as operator+, and operator* • How to multiply each element by 2? • How to add 1 to each element? • Syntax: li = [x * 2 for x in li] li = [x + 1for x in li]
Checking for Empty Lists • How should we check for an empty list? • Never use if expr == True/False • Example: • Instead:
Python: Functions & Indentation • Instead of brackets, python uses indentation • And inner scope is indented using 4 spaces in comparison to the outer scope • Be sure to use spaces and not tabs! • Otherwise the interpreter will throw an error • Functions are defined using def keyword • Python is a scripting language, it does not require a main function to run!
Functions: Return Values • All functions return somevalue • Even if that value is None • No return statement or just return implicitly returns None • Functions can return multiple values • Example: return value1, value2, value3
Python: if-statements • Just like any other programming language, python has if-statements. • Instead of using else if, elif is used! • Acts exactly like other programming languages if-statements • Python has no switch statement.
Python: Slicing • Slicing in python is the ability to return a range of elements out of some defined container of elements • Containers: arrays, strings, lists, tuples, etc… • Python also supports string slicing: • String slicing is returning sub-string out of the original string • Strings in python are considered array of characters
Python: Tuples – Immutable Sequences • Tuples are hashable, while lists are not! • Tuples can be dictionary keys, but lists cannot • Tuples behave exactly like lists – only difference, immutable! • Any attempt to modify tuples, results in an error • Syntax:
Python: Objects • In python everything is an Object: • Objects have Identity: • "Identity" is unique and fixed during an object's lifetime • Objects are tagged with their type at runtime • Objects contain pointers to their data blob • This overhead means even small things take up a lot of space!
Python: Variables • Variables are references to objects • Assigning from a variable does not copy an object! • Instead, it adds another reference to the same object.
Swapping Variables • Temporary variables: [Avoid] • XOR: [Avoid] • Tuple Packing:
Python: Variable Unpacking • Let’s say a function takes 4 variables as arguments. • Instead of having four variables, we have a list of size 4. • Normally, one would need to extract the values at the indexes to be able to execute the function. • Solution: using unpacking.
Python: List Unpacking • Using an asterisk *, we unpack any list containers into its corresponding elements.
Python: Dictionaries • They are the hash maps – entries of key:value • Syntax:
Python: Dictionary Unpacking • Using a double asterisk **, we unpack any dictionary container into its corresponding items. • Example: • Output:
Python Functions: Arguments • Primitives by value: • Non-primitives by reference:
Python: Default Parameters • Default-value arguments: defreset(lis, default_val=None):del lis[:]if default_valis not None:lis.append(default_val)li = [5]print('original list:', li)reset(li, 2)print('reset default 2:', li)reset(li)print('reset no default:', li) original list: [5]reset default 2: [2]reset no default: []
Python: Variable Length Arguments • Variable-length arguments: defprint_info(first, *rest):print(first, end='')for one in rest:print(' ', one, end='')print('')print_info(1)print_info(1, 2, 3) 11 2 3
Python: Variable Length Named Arguments • Sent arguments dictate both the argument name, as well as the argument value. • They are saved as a dictionary in a variable prefixed with two asterisks.
Multiple Returns and Partial Returns • To return multiple elements we simple delimit the values using a comma ,. • To accept partial returns use underscore _ for each unneeded value.
Python: Iterating over data deffor_in_iteration(first, *rest):print(first, end='')for one in rest:print(' ', one, end='')print('') • defin_range(first, *rest):print(first, end='')for iin range(len(rest)):print(' ', rest[i], end='')print('') defwhile_iteration(first, *rest):print(first, end='')i = 0while i < len(rest):print(' ', rest[i], end='')i += 1print('') 1 2 3 4 51 2 3 4 51 2 3 4 5 for_in_iteration(1, 2, 3, 4, 5)in_range(1, 2, 3, 4, 5)while_iteration(1, 2, 3, 4, 5)
Reversed and Sorted Iterations • Iterating in a reversed order can be done by using reversed function: • Sorting a collection can be done using the sorted function:
Python: List Comprehensions letters = []for letter in 'human':letters.append(letter)print(letters) letters = [letter for letter in 'human']print(letters) nums = []for x in range(20):if x % 2 == 0:nums.append(x)print(nums) nums = [x for x in range(20) if x % 2 == 0]print(nums) li = []for i in range(10):if i % 2 == 0: li.append('even')else: li.append('odd')print(li) li = ["even" if i % 2 == 0 else "odd" for i in range(10)]print(li)
Python: More Comprehensions • More List Comprehensions: • Dictionary and Set Comprehensions:
Python Magic Methods • Magic methods in Python are the special methods which add "magic" to defined classes. • Magic methods are not meant to be invoked directly • The invocation happens internally from the class on a certain action. • Syntax: def __magicMethod__() • Example: • when you add two values using the + operator • Internally, the __add__() method will be called! • Complete List: • https://www.tutorialsteacher.com/python/magic-methods-in-python
Python: Class Example class Employee: # defining classemp_count = 0 def__init__(self, name, salary): # declare class 'constructor'self.name = name # access object instance variableself.salary = salary # self acts like 'this'Employee.emp_count += 1 # access static variable@staticmethod# declare display_count as a static functiondefdisplay_count():print("total employees %d" % Employee.emp_count)defdisplay_employee(self):# using 'self' is mandatory - unlike 'this' # one cannot access 'salary' without 'self'print("name : ", self.name, ", salary: ", self.salary)
Class: Usage Example Employee.display_count()e1 = Employee('mark', 1000)Employee.display_count()e2 = Employee('joe', 2000)Employee.display_count()e1.display_employee()e2.display_employee() total employees 0total employees 1total employees 2name : mark , salary: 1000name : joe , salary: 2000
Python: delcommand class Employee: def__init__(self):class_name = self.__class__.__name__print(class_name, "created")def__del__(self):class_name = self.__class__.__name__print(class_name, "destroyed") • Reminder: All python objects are automatically deleted once there are no references to them e = Employee()del e Employee createdEmployee destroyed
Python: del command • del removes the reference e1 – reducing the reference count by 1 • If the reference count reaches zero, then the garbage collector removes it • del does not delete the object instance • The garbage collector does that! • del deletes the referenceitself • The garbage collections comes in if the count reached zero due to this deletion e1 = Employee()e2 = e1print('e1 id=', id(e1))print('e2 id=', id(e2))del e1print('e2 id=', id(e2)) # what happens here?del e2 Employee createde1 id= 2257554491936e2 id= 2257554491936e2 id= 2257554491936Employee destroyed
Python: Inheritance p = Person("Marge", "Simpson")e = Employee("Homer", "Simpson", "1007")print(p.name())print(e.get_employee()) class Person:def__init__(self, first, last):self.first_name = firstself.last_name = lastdefname(self):return self.first_name + " " + self.last_nameclass Employee(Person): # inheritance!def__init__(self, first, last, staff_number):# must execute super explicitlyPerson.__init__(self, first, last) self.staff_number = staff_numberdefget_employee(self):return self.name() + ", " + self.staff_number Marge SimpsonHomer Simpson, 1007
Python: Setting main Function • No formal notion of a main function in Python! • By running: python file.py • Execution begins at the beginning of the file • All statements are executed in order until the end of the file is reached • However, a special variable __name__ is set to __main__ • Using this, we can implement our ‘main’ function • Example: defmain():# this is the 'main' method if __name__ == '__main__': main()
Python: Command Line Arguments • To be able to fetch arguments from the command line: • Use sys library: python -m file.py arg1 arg2 import sysdefmain(args):# this is the 'main' methodprint(args)if __name__ == '__main__': main(sys.argv)
Functional Programming • Primary entity is a "function" • "Pure" functions are mathematical: • Output depends only on input • No side effects that modify internal state • print() and file.write() are side effects! • Strict functional programming: • (Haskell): no assignments, variables, or state • Flexible functional programming: • (Python): encourage low-interference functions • Functional-looking interface but usevariables and state, internally.
Advantages of Functional Approach • By avoiding the use of objects and side effects we achieve: • Formal Provability: • Line-by-line invariants • Modularity: • Encourages small independent functions • Composability: • Arrange existing functions for new goals • Easy Debugging: • Since function behavior depends only on input • Each function is an independent entity!
Python Functions: First Class Objects • Functions are the first class objects in python: • They act like objects • They act like variables • Functions act like objects: • They can be referenced to by another function as a variable • They can be passed to another function as a variable • They can be returned to another function as variable • Functions act like variables: • Functions can be defined inside another function • Functions can be passed as argumentsto another function • Functions can be returned as values from another function
Functions as Arguments • Functions can be sent as an argument!