<style> .present { text-align: left; } </style> # Python Data Types & Basic Control Flow (lecture style) ## Week 17 Day 2 --- ## Part 1: Python Basics --- ### `print()` We can use `print` to write messages to the console terminal ```python= print("Hello world") ``` Equivalent to `console.log` in JavaScript ```javascript= console.log("Hello world") ``` --- ### Commenting code In Python, comments start with `#` ```python= # this is a comment print("Hello") # can also start in line ``` Just like the `//` in JavaScript ```javascript= // this is a comment console.log("Hello world") // can also start in line ``` --- ### Commenting code Longer comment blocks can use the `"""` syntax ```python= """ You can use three quotes in a row for multiline comments """ ``` Like in JavaScript, where `/* ... */` creates multiline comments ```javascript= /* longer comment more commenting here */ ``` --- ### Docstrings A docstring is a string literal that is used to document a function, class, or module. ```python= def my_function(): """ This is my function. It doesn't do anything special. It's just a function. """ return 1 ``` We can access docstrings in two ways: ```python= help(my_function) print(my_function.__doc__) ``` --- ### Number Data Types We'll mostly interact with `int` and `float` types - `int` (integers): counting numbers with no decimal points - `float` (floating point numbers): numbers with decimal places. - They may occasionally have rounding errors, just like JavaScript - see [documentation on floating point arithmetic](https://docs.python.org/3/tutorial/floatingpoint.html) - `complex`: complex numbers --- | Operator | Meaning | Example | | :------: | :--------------- | :--------------------- | | `+` | addition | `print(10+4) # 14` | | `-` | subtraction | `print(10-4) # 6` | | `*` | multiplication | `print(10*4) # 40` | | `/` | division | `print(10/4) # 2.25` | | `%` | modulo | `print(10%4) # 2` | | `**` | exponent | `print(10**4) # 10000` | | `//` | integer division | `print(10//4) # 2` | --- ### Number Operations - Plus operator (`+`) can be used for both numeric addition and string concatenation - But type conversion between strings and numbers won't happen automatically (unlike JavaScript) ```python= print("hello " + "world") # "hello world" print("hello " + 7) # TypeError # explicitly convert types print("hello" + str(7)) # "hello7" ``` --- ### Assignment operators We can use assignment operators (like in JavaScript) to concisely update values ```python= a = 2 a += 3 print(a) # 5 a *= 2 print(a) # 10 ``` But no more `++` or `--` ```python= a++ # SyntaxError: invalid syntax ``` --- ## Exercises (30 minutes) - Hello, Eggs and Spam (5:00) - Plus, Minus, More (5:00) - Adding Two Numbers (1:00) - Convert Minutes To Seconds (1:00) - Livestock Legs (5:00) - Return Next Number (1:00) - Remainder Of Two Numbers (1:00) - String To Integer (5:00) - By The Power Of... (1:00) --- ## Part 2: Strings --- ### String Data Type - Strings use single quotes (`'`) or double quotes (`"`) - Using three quotes in a row (either `"""` or `'''`) will open a multiline string ```python= my_long_string = ''' you can make longer strings over multiple lines individual quote characters ' " won't end the string ''' ``` --- ### String Interpolation In Python version 3.6, `f` strings were introduced as the preferred method of string interpolation. String formatting with `f` strings: ```python= word = "hi" num = 6 print(f"{word} and {num}") ``` Similar to interpolated strings in JavaScript: ```javascript= let word = "hi" let num = 6 console.log(`${word} and ${num}`) ``` You can read about more [traditional methods of string interpolation in the PEP 498 documentation](https://peps.python.org/pep-0498/)! --- ### String Arithmetic ```python= a = "a" b = "b" an = "an" print(b + an) print(b + a*7) print(b + an*2 + a) print("$1" + ",000"*3) ``` --- ### String indexing - Use square brackets (`[]`) - Index starts at 0 (like in JavaScript) ```python= print("Spaghetti"[0]) # S print("Spaghetti"[4]) # h ``` - Can use a negative index ```python= print("Spaghetti"[-1]) print("Spaghetti"[-4]) ``` --- ### String indexing with ranges Indexing with ranges: the start value is inclusive, the end value is skipped ```python= # indexing with ranges print("Spaghetti"[1:4]) # pag print("Spaghetti"[4:-1]) # hett print("Spaghetti"[4:4]) # (empty string) print("Spaghetti"[:-1]) # ? print("Spaghetti"[1:]) # ? ``` --- ### String indexing Out of range values will through errors if you try to access the single value, but they are valid as part of a range. ```python= print("Spaghetti"[15]) # IndexError: string index out of range print("Spaghetti"[:15]) # Spaghetti print("Spaghetti"[15:]) # ? print("Spaghetti"[15:20]) # ? ``` --- ### String methods: `.index()` Returns the first index where the substring is found ```python= print("kiwi".index("k")) # 0 print("kiwi".index("m")) # ValueError: substring not found ``` --- ### String methods: `.count()` Returns the number of times the substring is found ```python= print("kiwi".count("k")) # 1 print("kiwi".count("i")) # 2 print("kiwi".count("m")) # 0 ``` --- ### String methods: `.split()` Returns a list (array) of substrings, split on the character (or substring) passed - If no character is passed, a space is used to split ```python= print("Hello World".split()) # ["Hello", "World"] print("Hello World".split(" ")) # ["Hello", "World"] print("i-am-a-dog".split("-")) # ["i", "am", "a", "dog"] ``` --- ### String methods: `.join()` Use a given string to join all the substrings from the list argument - Works in reverse from what you may be used to with JavaScript ```python= print(" ".join(["Hello", "World"])) # "Hello World" # ["Hello", "World"].join(" ") JavaScript print("-".join(["i", "am", "a", "dog"])) # "i-am-a-dog" ``` --- ### String methods: `.upper()` & `.lower()` Transform a string to the specified case - these methods return an entirely new string - they do not mutate the original string ```python= a = 'Hello' print(a) # 'Hello' print(a.upper()) # 'HELLO' print(a) # 'Hello' ``` --- ## Exercises (15 min) - Fun With Strings (5:00) - Burrrrrp (5:00) - Concatenate Names (1:00) --- ## Part 3: Try/Except Statements --- #### Better to ask forgiveness than permission A pythonic principle & fundamental part of Python control flow --- ### Control flow with `try/except` blocks Keywords: - `try`: run this code until an exception occurs - `except`: run this code when an exception occurs - `else`: run this code only if no exception occurs - `finally`: run this code no matter what --- ### Control flow with `try/except` blocks ```python= num = 0 try: print("Trying now...") print(4/num) except ZeroDivisionError: print("oops i tried to divide by zero!") finally: print("this happens no matter what") ``` --- ### Control flow with `try/except` blocks Avoid using a bare `except`— you should specify the type of error in almost every case. Different exceptions should be handled differently because they indicate different types of issues. A bare `except` can even prevent a user from exiting a program: ```python= while True: try: num = int(input("say a number ")) print(num) break except: print("try again") ``` --- ## Part 4: Boolean Logic --- ### Truthiness vs. `True` The concept of "truthiness" refers to values that *evaluate* to `True` when typecast as a Boolean. "Truthy" values however are not necessarily *equal* to `True`. --- ### Falsiness Falsey values in Python are: - 0 (for any number type) - `0`, `0.0`, `0j` - any empty collection - `""`, `[]`, `set()`, `{}`, `range(0)` - `False` - `None` All other values are truthy! --- ### Logic Operators We use the keywords `and`, `or`, and `not` in Python instead of `&&`, `||`, and `!` ```python= print(True and False) # False print(True or False) # True print(True and not False) # True ``` --- ### Logical operators Parentheses can group our conditions, just like JavaScript ```python= print(False and (True or True)) # False print((False and True) or True) # True ``` --- ### Short circuiting If we can already determine the overall outcome of a conditional, Python won't bother evaluating the rest of the statement. (JavaScript also has short-circuiting) ```python= False and print("not printed") # does not print False or print("printed #1") # prints "printed #1" True and print("printed #2") # prints "printed #2" True or print("not printed") # does not print ``` --- ### If statements If statement structure resembles Javascript. In Python, the if statement keywords are: - `if` - `elif` - `else` ```python= if i < 4: print("i is less than 4") elif i == 4: print("i is equal to 4") else: print("i is neither less than nor equal to 4") ``` --- ### While loops While loops also follow a very similar structure to JavaScript. ```python= i = 0 while i < 5: print(f"{i}. Hello, world.") i += 1 print("You've printed 5 times. Goodbye.") ``` --- ### Loop keywords: `continue` and `break` - `continue`: goes to the next iteration of the loop - `break`: exits out of the loop completely ```python= i = 0 while True: print(f"{i}. Hello, world.") if i < 4: i += 1 continue print("You've printed 5 times. Goodbye.") break ``` --- ## Part 5: Identity & Equality --- ### Identity vs. Equality - in JavaScript, `==` is bad, `===` is good - in Python, `is` and `==` are both useful, just for different things - Equality is not about typechecking, it's just about whether the values are the same ```python= my_int = 4 my_float = 4.0 # check if the values are the same print(my_int == my_float) # True # check if the values are the same and check type print(my_int == my_float and isinstance(my_int, float)) # False ``` --- ### When to use `==` (equality): - Most of the time! - Whenever you are comparing two values to see if they are the same - strings, numbers, lists, dictionaries, etc ```javascript= // javascript version console.log([1, 2, 3] === [1, 2, 3]) // false ``` ```python= # python version print([1, 2, 3] == [1, 2, 3]) # True ``` --- ### The `is` operator What if we compared two lists of the same value with `is`? ```python= print([1, 2, 3] is [1, 2, 3]) # False ``` While these lists have the same *value*, they are two distinct objects in memory with different identities. --- ### When to use `is` (identity) [1/3]: 1. For checking if a value is not `None` ```python= a = [] if a is not None: print("a is not None") # prints "a is not None" else: print("a is None") ``` --- ### When to use `is` (identity) [2/3]: 2. For checking is `True` / `False` ```python= a = 1 print(a == True) # don't do this, in Python 1 is equal in value to True print(a is True) ``` --- ### When to use `is` (identity) [3/3]: 3. For checking whether variables reference the same object in memory ```python= print([] == []) # True print([] is []) # False a = [] b = a print(a is b) # True b.append(5) print(a) # [5] ``` --- ### Interned memory For many small, immutable (unchangeable) data types, Python stores only one distinct copy in memory. This is a space optimization mechanism called *interning*. ```python= # python version a = 5 b = 5 print(a is b) # True c = "hey" d = "hey" print(c is d) # True ``` Due to interning, these variables can share the same identity if they have equal value. --- ### What is the "identity" `id()` returns the “identity” of an object. - Integer which is guaranteed to be unique and constant for this object during its lifetime (i.e. while the program is running) ```python= print(id(None)) print(id(None)) a = None print(id(a)) ``` --- ## Practices (40 min) - Double That Penny (5:00) - Numeric Equality (1:00) - Using and (1:00) - Split On Capitals (10:00) - Count Characters In String (5:00) - Factorial (5:00) - Is Divisible By 5 (1:00) - Is The Last Character N? (5:00) - Same Number Of Characters? (1:00) --- ## Part 6: Functions --- ### Python Functions - We use the `def` keyword to define a function followed by: - The name of the function - The arguments that it accepts - A new block identified as `:` and indent the next line ```python= def is_even(num): return num % 2 == 0 print(is_even(5)) # False print(is_even(2)) # True ``` --- ### Lambda Functions - For simple one-line functions, we can also use a lambda, which takes in: - Arguments on left side of `:` - Returns the value resulting from the right side of the `:` - They return automatically and cannot contain an explicit `return` keyword ```python= is_even = lambda num: num % 2 == 0 print(is_even(8)) # True ``` --- ### PEP-8 Style Guidlines - The use case of lambdas is when you are going to use a function once without assigning it - Assigning a lambda to a variable essentially duplicates the purpose of the def keyword, hence it is not pythonic --- ### Functions Returning Functions ```python= def order_pizza(pizza_type): order = f"I would like a {pizza_type} pizza" print(pizza_type) return lambda topping_type: order + f" with {topping_type}." sausage_pizza = order_pizza("sausage") # prints from line 3: "sausage" print(sausage_pizza) # prints lambda function object print(sausage_pizza("bell pepper")) # "I would like a sausage pizza with bell pepper." ``` --- ### Python Scoping - Scoping is done at the function level - In JS, we had block scopes - In PY, our `if` statements do not create new scopes ```python= def make_a_five(): y = 5 return y if True: x = 10 print(x) #10 # `x` was created in the global scope print(y) # NameError: name 'y' is not defined # `y` was created in the scope of the make_a_five function ``` --- ### Lecture Videos (35 min) - The Meaning of Truth (13:22) - Identity vs. Equality Demo (10:50) - Functions in Python (8:28) - Functions Returning Functions (2:00) ### Summary Practices (1 hr) - Fun With Functions (5:00) - Valid Hex Code (10:00) - First Before Second (10:00) - Sequence of Numbers (30:00) ### Summary Quizzes (20 minutes) - Python Documentation Quiz (5:00) - Arithmetic Operators (5:00) - Strings? (5:00) - Short Circuit (5:00)
{"metaMigratedAt":"2023-06-16T03:42:39.921Z","metaMigratedFrom":"Content","title":"Python Data Types & Basic Control Flow (lecture style)","breaks":false,"contributors":"[{\"id\":\"a6f34c0b-3567-4ed5-ba81-c2299c2d9369\",\"add\":8184,\"del\":7442},{\"id\":\"b3d4b64b-bcb9-47ce-975c-f84011d6c2f4\",\"add\":13870,\"del\":0}]"}
    856 views
   Owned this note