19
What's in a Software Dev degree anyway? Course 1 - Information Structures
This is a continuation of What's in a Software Dev degree anyway?. Again, expect examples with no math and no crappy names
Okay, I did it. First class of this degree is done. This post is just a cumulative of topics and concepts that were covered in my 1st course of my Software Dev degree.
As of now, I'd still consider myself self-taught. It's rough not knowing what you should learn next. I have a lot of gaps in my knowledge. That's why I decided to go to school. And also why I'm hoping sharing this will help someone else.
MET CS 521 O1 Information Structures with Python (2021 Fall 1)
Jump to:
Wait! I just wanna test myself on the exercises you had in class. Glad you asked, here's the repo: Exercises for first class
- Data Types
- primitives vs collections
- primitives:
int
bool
float
complex
char
- collections:
list
tuple
set
dictionary
string
- Namespaces
- Input/Output
- Variable Scopes (legb)
- Importing modules
- statements
dog_age = 6
vs expressionsdog_age + 1
- statement returns nothing
- expression returns something, also called a side effect
- Functions that can be applied to different data types are polymorphic
Unrelated to the curriculum, I also learned:
- the professor has a preference for explaining Python in relation to C++ instead of explaining in ways everyone can understand.
- use RateMyProfessors.com to look up before registering for future courses. I was watching Netflix series “The Chair” and learned about this.
- Data Types
- complex numbers
- totally new to me. Guess they’re used in things like electromagnetics, chemistry, and economics.
- complex numbers
- fractions module is super neat
- Hashing
hash()
for quick comparisons (still confused on this) - Mutability
- Python Ranges
- Copying Objects
- shallow copy makes copy but points to other object
-
deepcopy()
makes new object
-
==
vsis
-
==
checks values -
is
checksid
to see if same exact object
-
- UTF - 8 numbering for alphanumeric characters
-
chr()
andord()
-
- Strings
- immutable, but there are work arounds
range(start, stop, step)
- half-open range: does not include
stop
number - slicing
[start:stop:jump]
- string reversal
string[-1]
- out of bound slicing will not error, but give you whatever is in bounds
- string formatting
{:[alignment][width][decimal precision][type descriptor]}
- immutable, but there are work arounds
- Control Flow
- if-elif-else
- try - except
- Iterations
-
while
andfor
-
- Files
-
open
,read
,readlines
,write
,writelines
- importance of
close
-
- Lists
- list comprehensions
- can have multiple conditions
- works for mutable objects (lists & sets, not tuples & strings)
- list comprehensions
numbers = [13, 72, 11, 43, 66, 82]
# iterate to get even numbers
evens_from_nums = []
for num in numbers:
if num % 2 == 0:
evens_from_nums.append(num)
# list comprehension to get even numbers
# same as above, just shorthand
odds_from_nums_again = [num for num in numbers if num % 2 == 0]
- list reversal with slicing or
.reverse()
-
enumerate()
for indexed collections- returns a list with an index number
-
sort()
vssorted()
-
sort()
changes things in place -
sorted()
orders things and creates a new list
-
-
Lists
- See above, went over some list stuff in week 3
- indexing a nested list
list[1][2]
would give index 1 of main list then index 2 of the nested list - sorting list of list sorts on the index [0] of nested lists
- some methods that modify a list:
append()
pop()
extend()
insert()
remove()
sort()
reverse()
- reversing a list
list[::-1]
(gives no start or stop and a-1
step) - Exercise: check if words are anagrams
- create a copy slice using
[:]
(shallow copy?) - when list appends itself as an element, infinite regress occurs
-
Tuples
- single element tuple
tuple = ("cat",)
note the trailing comma, otherwise this would not be a tuple - can use the same set up for a list comprehension
- immutable but can contain mutable objects
- tuples use most of the same methods as lists, except the ones that would change a list (eg
append()
)
- single element tuple
-
Dictionaries
- can use a similar set up for a list comprehension
- keys are not arranged in a specific order, they are in an order to efficiently search
- Exercise: count words or letters in a string
- namespaces are implemented with dictionaries
-
items()
all key-value pairs as a list of tuples -
keys()
all keys as a list of list -
values()
all values as a list of list -
zip()
2 or more lists together. Tuples by default - can merge dicts with
update()
(note: for keys that already exist, values will be replaced)
-
Sets
- mutable, not ordered, only unique values
- subset
small_set <= big_set
vs supersetbig_set >= small_set
- frozen sets are possible to make sets immutable
- Methods
-
&
orintersection()
creates new set of all elements that are the same -
|
orunion()
creates new set of all elements of both lists -
-
ordifference()
creates new set of all elements in 1st set but not 2nd set -
^
orsymmetric_difference()
creates new set of all elements that are different - Link to Python Tutor with examples (with animals) of these set methods
-
-
split()
returns a list - data type is the actual use of data structures, where data structures are more the theory or idea of
- efficiency refers to time, space, and algorithm
- Implementing other data structures with the types we have
-
stacks
can be made with lists - Ternary if basically an if-else but jammed onto one line
true_thing if condition else false_thing # ternary syntax
throw_ball() if dog_wants_play else pet_dog() # ternary example
-
Error Handling
- interupts vs Exceptions
- Allows us to watch code for errors
- useful for things like user inputs ("All user input is evil")
- Try - Except
- can handle multiple exceptions
- can do
except IndexError as e
to later usee
(the error) - If you use
finally
it runs every time, not required though
-
Functions
- functions are objects and have their own namespace (reminder: everything is an object)
- function docstring can include inputs, outputs, what the function does
- Parameters != arguments
- parameters are in the function definition
def feed_dog(dog_weight):
- arguments are in the function call/invocation
feed_dog(25.5)
- parameters are in the function definition
- functions return
None
if there is no return statement - can pass functions as arguments
- possible to have different function "signatures". same name === same function
- default parameters
def pet_cat(time="now"):
if you don't give a different time, cat will be petnow
- variable positional args
def func(*args):
this requires a tuple as input - Mutable parameters as args/params, avoid if possible. Can cause issues
- parameter names as keywords
feed_dog(dog_age=5, dog_weight = 25.5)
- annotation of params to document/suggest what type the param should be
def feed_dog(dog_weight: float, dog_age: int):
#syntax
def function_name(param1, param2):
'''what it does, inputs, and outputs'''
# code for your function to do
function_name(arg1, arg2)
# example
def feed_dog(dog_weight: float, dog_age: int):
'''calculate/output how much to feed dog with given dog weight arg'''
pass
feed_dog(25.5, 5)
# -----other ways to call/invoke-----
# how to invoke with out of order args
feed_dog(dog_age=5, dog_weight = 25.5) # also useful when there are a lot of params
# use a dictionary for function args
dog_dict = {"dog_weight":25.5, "dog_age":5} # same names as params
feed_dog(**dog_dict) # using ** to pass a dict
- generators functions
- use
yield
instead ofreturn
- allows you to start where you pick up as opposed to the beginning like a
return
-
yield
give results and wait until next time function is called -
__iter__()
__next__()
- use
-
Lambda Function
lambda args: expression
map()
filter()
reduce()
-
Recursion
- must have a base case and the base case must be first in the function
- can be slower than a non-recursive function
- Advantage: less code, may be easier for some problems
- Disadvantage: inefficient on memory and processing time, harder to read and follow
- Calls by...
- if you pass a mutable param -> call by reference
- create a new object -> call by values
- if you pass a immutable param -> call by value ### Week 6
-
Classes
- can be used to make new data structures. (Classes were used to build
dict()
,set()
,list()
etc) - defining a class:
-
self
allows an object to keep it's own data (likethis
in js/c++/java)
- can be used to make new data structures. (Classes were used to build
import copy
class Dog():
__stomach = 1 # a static variable w/ name mangling
# define a constructor
def __init__(self, name):
self.__name = name # w/ name mangling
def __copy__(self): # shallow copy
return Dog(self.__name) # w/ name mangling
def __str__(self):
'''give a string when you print(instance_variable)'''
return 'dog with name: ' + str(self.__name) # w/ name mangling
def add(a,b): #
return Dog(a.__name + b.__name)
def get_stomachs(self): # getter/accessor
return self.__stomach
def eat_dinner(self): # self is like `this` in js/c++/java
'''a class method for the dog to eat dinner'''
# use Class_Name.variable to get the static variable
print(f"{name} reports for dinner with their {Dog.stomach} stomach")
dog_one = Dog("wiley") # makes a Dog just like list() makes a list
dog_one_come = dog_one.eat_dinner()
dog_copy = copy.copy(dog_one)
print(dog_one) # prints return of __str__
-
Static vs. Instance Variables
- better to have static variables vs instance variables
- better to have 1 copy of a variable as opposed to 1 copy per instance
- static vars are before the methods defined in a class
- instance var or non-static would have the var in a method and each instance would have it's own copy of the var making it not so efficient
-
__repr__()
"official" object description (example:<__main__.Dog object at 0x7f545b6db8d0>
)
-
Data Encapsulation
- no private like java
- all methods and variables are public
- name mangling provides minimum protection
- give
__
before name like__stomach
to prevent accidental changing. - Though you could still change
Dog._Dog__stomach = 4
it would just be less of a chance to do it by accident
- give
-
Overloading
- Could write a method to use
+
,-
,<
,>
,==
,!=
,&
,!
in a way they weren't already built to do by using "magic methods" - magic methods are just overwritten methods that overload operators?
- Could write a method to use
def add(self, other): #
return Dog(self.__name + other.__name)
-
Inheritance and Polymorphism
- can derive classes from new classes.
- In real life, mammals could be a parent class and cats could be a child class. Cat has some similarities, but some stuff is different
- if child class doesn't have a str() defined, python will look in the parent class
- functions like
print()
andlen()
can be used across different classes and functions - if inheriting a parent class, include in the constructor/
__init__
-
Multiple Inheritance
- python allows classes to have multiple parent classes. not all languages allow this (like Java and C)
- one problem
-
Abstract Classes
-
Unit Tests
- run your function and use
assert
statements to test the expected output
- run your function and use
The quiz had some ridiculous questions on it. Oh well.
Vicki Langer@vicki_langerBombed that first quiz.
Python is interactive? Sure. I guess that’s important enough to have 2 questions on it.
When are sytax errors given? On compile or runtime? Who cares? They’re automatic!
Now I’m being childish, I guess I missed these in the book 😩15:11 PM - 10 Sep 2021
15 questions and 30 minutes later.
Covered:
- generators
- nested list/tuple indexing
- function syntax
- slicing
- hashable and immutable data types
-
break
andcontinue
- classes and inheritance
19