python-hard-way/Codecademy.md

675 lines
15 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 weve 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)
```