python-hard-way/Codecademy.md

675 lines
15 KiB
Markdown
Raw Permalink Normal View History

2018-12-15 21:35:53 +00:00
# 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
2018-12-15 23:25:43 +00:00
# Errors (ex6, CH1, P3)
2018-12-15 21:35:53 +00:00
2018-12-15 23:25:43 +00:00
"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.
2018-12-15 21:35:53 +00:00
2018-12-15 23:25:43 +00:00
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."
2018-12-15 21:35:53 +00:00
2018-12-15 23:25:43 +00:00
SyntaxError example: `SyntaxError: EOL while scanning string literal`
2018-12-15 21:35:53 +00:00
2019-03-03 00:47:52 +00:00
# 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)
```
2018-12-15 21:35:53 +00:00
# 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
2018-12-15 23:25:43 +00:00
exponents = (16 ** 0.5) # 16 to the 1/2th power. (4)
remainder = (15 % 2) # The remainder (and thus the result) equals 1
2018-12-15 21:35:53 +00:00
```
## 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`
2018-12-15 23:25:43 +00:00
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'
```
2018-12-15 21:35:53 +00:00
# Strings
2018-12-15 23:25:43 +00:00
Multi-line strings are marked by
```"""
Mulit-
2018-12-15 21:35:53 +00:00
line
2018-12-15 23:25:43 +00:00
strings"""
```
2018-12-15 21:35:53 +00:00
# Booleans (True/False)
True = int(1)
False = int(0)
2018-12-28 02:50:35 +00:00
## Boolean Expressions
`and` evaluates true if both are true.
`or` evaluates true if either are true.
`not` return the opposite boolean value.
2018-12-28 01:03:18 +00:00
## Relational Operators (ch.4, ex. 3)
2018-12-28 02:50:35 +00:00
`==` returns `True` if is is equal
`!=` returns `True` if is is NOT equal
2018-12-28 01:03:18 +00:00
Here are more of he same kind of operator:
`>` greater than
`<` less than
`>=` greater than or equal to
`<=` less than or equal to
2018-12-28 02:50:35 +00:00
# if, else, if else
`elif` = if else
2018-12-28 01:03:18 +00:00
2018-12-15 23:25:43 +00:00
# Datatypes
Force treating as a string: str(7)
Force treating as an integer: int("7")
Force treating as a float: float(7)
2018-12-15 23:25:43 +00:00
2018-12-28 01:03:18 +00:00
## Check Datatypes
Check datatypes using type(var)
2018-12-15 23:25:43 +00:00
# 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."`
2018-12-15 23:50:20 +00:00
or
`print(var, var2, var3)`
or
`string1 += string2`
2018-12-15 23:25:43 +00:00
## 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
```
2018-12-20 20:23:18 +00:00
# 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)
```
2018-12-20 20:48:53 +00:00
# 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.
```
2018-12-21 00:31:30 +00:00
## 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')
```
2019-01-13 01:34:34 +00:00
You can add lists like this: `['list1', 'stuff'] + ['list2', 'stuff']` but need to use `lst1 + lst2` and not `[lst1] + [lst2]`
2019-01-27 04:05:56 +00:00
# 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]
```
2019-02-22 01:27:24 +00:00
### Print every other element
```
odd = [odd for odd in lst if lst.index(odd) % 2 == 1]
return odd
```
2019-01-31 04:12:24 +00:00
### 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)
```
2019-02-02 04:56:22 +00:00
# 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]
```
2019-02-06 02:38:29 +00:00
### 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()`
2019-01-25 01:20:10 +00:00
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.
2019-02-22 01:27:24 +00:00
### 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))
```
2019-01-12 06:55:22 +00:00
## 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.")
```
2019-01-25 01:20:10 +00:00
# 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
```
2018-12-15 21:35:53 +00:00
# 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
```
2018-12-15 21:35:53 +00:00
9:
2018-12-15 21:35:53 +00:00
```
cucumbers = 1
price_per_cucumber = 3.25
total_cost = cucumbers * price_per_cucumber
print(total_cost)
```
2018-12-15 23:25:43 +00:00
2018-12-15 23:50:20 +00:00
`total_price += nice_sweater`
2018-12-15 23:25:43 +00:00
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)
```