# Codecademy's Python 2 Course https://www.codecademy.com/courses/learn-python/lessons/python-syntax/ It's gratis and accepts Python 3 syntax. # Object-oriented "The main goal of an object oriented language is to make code reusable – we do this through the use of classes and objects. If we want to design a new type of car, we can start with what they all have in common: wheels, seats, a frame. Now that we’ve determined what cars have in common, we can more easily implement any type of car we want by starting from that basic blueprint." https://discuss.codecademy.com/t/what-does-it-mean-that-python-is-an-object-oriented-language/297314 # Errors (ex6, CH1, P3) "SyntaxError means there is something wrong with the way your program is written — punctuation that does not belong, a command where it is not expected, or a missing parenthesis can all trigger a SyntaxError. A NameError occurs when the Python interpreter sees a word it does not recognize. Code that contains something that looks like a variable but was never defined will throw a NameError." SyntaxError example: `SyntaxError: EOL while scanning string literal` # Linear Regression One of the projects in my Python 3 course on Codecademy was to calculate the linear regression of any given line in a set. This is my journey of doing just that, following their instructions. The goal, is to calculate the bounciness of different balls with the least error possible. Starting with `y = m*x + b` We can determine the y of a point pretty easily if we have the slope of the line (m) and the intercept (b). Thus, we can write a basic function to calculate the y: ``` def get_y(m, b, x): y = m*x + b return y print(get_y(1, 0, 7) == 7) print(get_y(5, 10, 3) == 25) ``` We can then use that to calculate the linear regression of a line: ``` def calculate_error(m, b, point): x_point = point[0] y_point = point[1] y2 = get_y(m, b, x_point) y_diff = y_point - y2 y_diff = abs(y_diff) return y_diff ``` To get a more accurate result, we need a function that will parse several points at a time: ``` def calculate_all_error(m, b, points): totalerror = 0 for point in points: totalerror += calculate_error(m, b, point) return abs(totalerror) ``` We can test it using their examples: ``` #every point in this dataset lies upon y=x, so the total error should be zero: datapoints = [(1, 1), (3, 3), (5, 5), (-1, -1)] print(calculate_all_error(1, 0, datapoints)) #every point in this dataset is 1 unit away from y = x + 1, so the total error should be 4: datapoints = [(1, 1), (3, 3), (5, 5), (-1, -1)] print(calculate_all_error(1, 1, datapoints)) #every point in this dataset is 1 unit away from y = x - 1, so the total error should be 4: datapoints = [(1, 1), (3, 3), (5, 5), (-1, -1)] print(calculate_all_error(1, -1, datapoints)) #the points in this dataset are 1, 5, 9, and 3 units away from y = -x + 1, respectively, so total error should be # 1 + 5 + 9 + 3 = 18 datapoints = [(1, 1), (3, 3), (5, 5), (-1, -1)] print(calculate_all_error(-1, 1, datapoints)) ``` You can save all possible m and b values between -10 and 10 (m values), as well as -20 and 20 (b values) using: ``` possible_ms = [mv * 0.1 for mv in range(-100, 100)] #your list comprehension here possible_bs = [bv * 0.1 for bv in range(-200, 200)] #your list comprehension here ``` We can find the combination that produces the least error, which is: ``` m = 0.3 b = 1.7 x = 6 ``` The goal was to calculate the bounciness of different balls with the least error possible. With this data, we can calculate how far a given ball would bounce. For example, a 6 cm ball would bounce 3.5 cm. We know this because we can plug in the numbers like this: ``` get_y(0.3, 1.7, 6) ``` # Math (ex6) ``` mirthful_addition = 12381 + 91817 amazing_subtraction = 981 - 312 trippy_multiplication = 38 * 902 happy_division = 540 / 45 sassy_combinations = 129 * 1345 + 120 / 6 - 12 exponents = (16 ** 0.5) # 16 to the 1/2th power. (4) remainder = (15 % 2) # The remainder (and thus the result) equals 1 ``` ## Find the remainder of a number using % ``` is_this_number_odd = 15 % 2 is_this_number_divisible_by_seven = 133 % 7 ``` # Updating variables / operators. ``` sandwich_price += sales_tax ``` is the same as: ``` sandwich_price = sandwich_price + sales_tax ``` but is much shorter. ## Comments Are indicated by # or """This is not for running""" # Numbers An integer is like `5`, a float is a number with a decimal point like `5.0`. They can also be in scientific notation like `2.3e7` In Python 2, you need to make sure math like `7/2` = `3.5` is correct is by inputting it into Python like `7./2.` or `float(7)/2` ## Limitations of floats Floats are limited by the number of digits. For example `1/3 = 0.3` ``` >>> format(math.pi, '.12g') # give 12 significant digits '3.14159265359' >>> format(math.pi, '.2f') # give 2 digits after the point '3.14' ``` # Strings Multi-line strings are marked by ```""" Mulit- line strings""" ``` # Booleans (True/False) True = int(1) False = int(0) ## Boolean Expressions `and` evaluates true if both are true. `or` evaluates true if either are true. `not` return the opposite boolean value. ## Relational Operators (ch.4, ex. 3) `==` returns `True` if is is equal `!=` returns `True` if is is NOT equal Here are more of he same kind of operator: `>` greater than `<` less than `>=` greater than or equal to `<=` less than or equal to # if, else, if else `elif` = if else # Datatypes Force treating as a string: str(7) Force treating as an integer: int("7") Force treating as a float: float(7) ## Check Datatypes Check datatypes using type(var) # Escaping Characters Simply add a `\` to escape a character that would otherwise cause issues. # Arrays / Indexes `cows = "cows"[0]` This sets the variable `cows` to the 0th letter of the string `"cows"` which is `c`. These indexes start at 0, not 1. # Strings ## String Methods `len(var)` Get length of string. `var.lower()` Force lowercase `var.upper()` Force uppercase `str(var)` Force treating variable as a string. If it uses dot notation like `.lower()`, it works exclusively on strings. ## Concatenation `"Ten times a cow is equal to " + result + " with 10 times as many breeding opportunities."` or `print(var, var2, var3)` or `string1 += string2` ## String Formatting with % `"%s %s - 2020" % (month, day) # Replace %s with a variable. First the month, then the day.` `Add %03d to specify a signed integer padded 2 places with zeros. For example, 2 becomes 02.` This is super useful for displaying dates like this: `print("%02d-%02d-%02d") % (now.month, now.day, now.year)` or time like this: `print '%02d:%02d:%04d' % (now.hour, now.minute, now.second)` (Ch3, Ex. 4) ## Date and Time (Ch3) Grab the current time: ``` from datetime import datetime now = datetime.now() year = now.year month = now.month day = now.day ``` # Function P3 Ch.2 ## Defining a Function ``` def greet_customer(): print("Welcome!") ``` ## Calling Functions ``` greet_customer() ``` or if it has parameters: ``` greet_customer(1,ten) ``` # Passing Arguments ``` greet_customer(special_item): print(special_item) greet_customer(beef) ``` Result: ``` beef ``` ## Using Keyword Arguments Keyword arguments are nice for specifying a default but changeable argument. Here's an example from P3, Ch2, ex7 ``` def create_spreadsheet(title, row_count = 1000): row_count = str(row_count) print("Creating a spreadsheet called " + title + " with " + row_count +" rows.") create_spreadsheet("Applications", row_count = 10) ``` ``` row_count = 1000 ``` is the default ``` row_count = 10 ``` is the passed argument and thus what is used for a result: ``` Creating a spreadsheet called Applications with 10 rows. ``` ## Returning Stuff You can return stuff like this to store for later: ``` def addfour(number, cow): addedfour = number + 4 cat = number - 4 return addedfour, cat # All returned arguments must be on the same return call. ``` I'll make it add four to 456 ``` yo, cow = addfour(456) print ("456 + 4 equals " + str(yo) ) ``` ``` 460 ``` You can also do this with multiple arguments: ``` x_squared, y_squared = square_point(1, 3) ``` # Lists You can put either strings, integers or other lists in a list, probably other things too. `heights = [['Jenny', 61], ['Alexus', 70], ['Sam', 67], ['Grace', 64]]` Use zip to combine elements from two lists: `zip(names, dogs_names)` would match dogs and their owners. But don't forget to turn it into a list before printing `print(list(zipvar))` You can append values to lists like this: ``` orders = ['daisies', 'periwinkle'] orders.append('tulips') ``` You can add lists like this: `['list1', 'stuff'] + ['list2', 'stuff']` but need to use `lst1 + lst2` and not `[lst1] + [lst2]` # List Comprehensions Say you only want to allow people over the height of 161 to ride your roller coaster for safety reasons. You could do this to create a list of only those heights about 161. ``` heights = [161, 164, 156, 144, 158, 170, 163, 163, 157] can_ride_coaster = [] can_ride_coaster = [height for height in heights if height > 161] print(can_ride_coaster) ``` You can manipulate lists with list comprehensions as well: ``` fahrenheit = [celsius * (9 / 5) + 32 for celsius in celsius] ``` ### Print every other element ``` odd = [odd for odd in lst if lst.index(odd) % 2 == 1] return odd ``` ### Print manipulated numbers in for loop ``` single_digits = range(10) squares = [] cubes = [(num ** 3) for num in single_digits] for single_digits in single_digits: print(single_digits) squares.append(single_digits ** 2) print(squares) print(cubes) ``` # For example, printing all cuts under $30 ``` cuts_under_30 = [hairstyles[i] for i in range(0, (len(hairstyles) - 1)) if new_prices[i] < 30] ``` ### Another example ``` [lst.append("hi, " + name)] ``` ## Make sure starting number is uneven ``` def delete_starting_evens(lst): while len(lst) > 0 and lst[0] % 2 == 0: lst.remove(lst[0]) return lst #Uncomment the lines below when your function is done print(delete_starting_evens([4, 8, 10, 11, 12, 15])) print(delete_starting_evens([4, 8, 10])) ``` ## Ranges You can get a range of numbers using `range()` It will give you all numbers under the number you input. For example, `range(8)` would give you 0-7, `range(1, 8)` would give you 1-7, and `range(1, 8, 2)` would give you 1,3,5,7 (2 is the interval and needs no padding) Use `print(list(var))` when printing. ### Ranges and list manipulation You can combine `range()` with list manipulation like this: ``` for index in range(1, len(lst), 2): new_list.append(lst[index]) ``` ## length Grab length with `len(list)` # Selecting List elements Use: `listname[indexnumber]` The index starts at 0. Grab the last in an index using `list[-1]` ## Giving values to list elements `lst[index] = indexlst` ## Cutting the middle of a list (ex3, functions + lists, ch.4) ``` def remove_middle(lst, start, end): end = end + 1 return lst[:start] + lst[end:] print(remove_middle([4, 8, 15, 16, 23, 42], 1, 3)) ``` This prints `[4, 23, 42]` removing the index 1-3. # If something occurs more than N times, return True ``` def more_than_n(lst, item, n): if lst.count(item) > n: return True else: return False print(more_than_n([2, 4, 6, 2, 3, 2, 1, 2], 2, 3)) ``` ## More frequency analysis ``` def more_frequent_item(lst, item1, item2): if (lst.count(item1)) > (lst.count(item2)): return item1 if lst.count(item2) > lst.count(item1): return item2 if lst.count(item1) == lst.count(item2): return item1 #Uncomment the line below when your function is done print(more_frequent_item([2, 3, 3, 2, 3, 2, 3, 2, 3], 2, 3)) ``` ## A creative original solution to grabbing the middle of an index (solving their problem with their names) ``` def middle_element(lst): if len(lst) % 2 > 0: rounded = round(len(lst) / 2) rounded = int(rounded) print(rounded) return lst[rounded] elif len(lst) % 2 == 0: position = int((len(lst) / 2) - 1) position2 = int(len(lst) / 2) both = (lst[position] + lst[position2]) / 2 return both print(middle_element([5, 2, -10, -4, 4, 5, 7])) ``` ### Add the last two elements, append them. (Ex.8) ``` def append_sum(lst): trip = 0 while trip < 3: lasttwo = lst[-2:] added = lasttwo[0] + lasttwo[1] print(added) lst.append(added) trip = trip + 1 return lst #Uncomment the line below when your function is done print(append_sum([1, 1, 2])) ``` ### Sublists Grab a subset of a list using `sublist = letters[1:6]` This would give you index **1-5**. You can also do `[:5]` for all up to index 4, and `[5:]` for all after index 5. And, you can do `[-3:]` for the last 3 in an index. ## Counting frequency of elements in a list. `var.count('stringtofind')` ## Sorting strings alphabetically ``` var.sort() print(var) ``` or use ``` sortedvar = sorted(var) ``` to produce a new list with sorted contents without changing the original variable. ## Sorting strings based on an element in a sublist Replace 1 with the index you want to sort by. `pizzas.sort(key=lambda x: x[1])`` # Catch Errors ``` try: command_may_cause_error except NameOfError: print("Nice little message to user.") ``` # Loops The following assigns an arbitrary name to a temporary variable (tempvar) to the number of elements in `sport_games` For every element in `sport_games`, it will print `print(tempvar)` ``` for tempvar in sport_games: print(tempvar) ``` You can use `range()` to get lists of arbitrary lengths. You can also add lists like this: ``` students_period_A = ["Alex", "Briana", "Cheri", "Daniele"] students_period_B = ["Dora", "Minerva", "Alexa", "Obie"] for student in students_period_A: students_period_B.append(student) ``` ## Iterating until we find something ``` for thing in stuff: if thing == thing_I_want: print("Found it!") break # Stops the loop, executes code outside. ``` ## Skip a value in a list. Ex.5 ``` for age in ages: if age < 21: continue else: print(age) ``` ## Move from list to list Ex.7 ``` while len(students_in_poetry) < 6: student = all_students.pop(-1) # Remove last element students_in_poetry.append(student) # Add it to students_in_poetry print(students_in_poetry) ``` # Nested Loops ``` for location in sales_data: print(location) for sub in location: scoops_sold += sub ``` # Fun Projects Design a shop using Ex7 and Ex9 as a frame: 7: ``` money_in_wallet = 40 sandwich_price = 7.50 sales_tax = .08 * sandwich_price sandwich_price += sales_tax money_in_wallet -= sandwich_price ``` 9: ``` cucumbers = 1 price_per_cucumber = 3.25 total_cost = cucumbers * price_per_cucumber print(total_cost) ``` `total_price += nice_sweater` Cool concept from Ch2 Ex15: ``` name = raw_input("What is your name? ") quest = raw_input("What is your quest? ") color = raw_input("What is your favorite color? ") print "Ah, so your name is %s, your quest is %s, " \ "and your favorite color is %s." % (name, quest, color) ```