What's in a Software Dev degree anyway? Course 1 - Information Structures
Tags: codenewbie, python
Published: 2021-10-22 15:00:09

*This is a continuation of [What's in a Software Dev degree anyway?](https://dev.to/vickilanger/what-s-in-a-software-dev-degree-491o). 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:**
- [Input (Learning Objectives)](#input)
- [Output (Projects and Work)](#output)
- [Documentation (References)](#docs)

Wait! I just wanna test myself on the exercises you had in class. Glad you asked, here's the repo: [Exercises for first class](https://github.com/VickiLanger/MS-in-Software-Dev/tree/main/CS521-Info-Structures_Python)

## Input (Learning Objectives) <a name="input"></a>

### Week 1
 - 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 expressions `dog_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. 

{% twitter 1436092310966648836 %}

 - use [RateMyProfessors.com](ratemyprofessors.com) to look up before registering for future courses. I was watching Netflix series “The Chair” and learned about this.


### Week 2
 - Data Types
  - complex numbers
     - totally new to me. Guess they’re used in things like electromagnetics, chemistry, and economics.
 - 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
 - `==` vs `is`
   - `==` checks values
   - `is` checks `id` to see if same exact object

### Week 3
 - UTF - 8 numbering for alphanumeric characters
	  - `chr()` and `ord()`
 - 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]}`
 - Control Flow
	  - if-elif-else
	  - try - except
 - Iterations
   - `while` and `for`
 - 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)
```python
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()` vs `sorted()`
  - `sort()` changes things in place
  - `sorted()` orders things and creates a new list


### Week 4
 - **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()`)
 - **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 superset `big_set >= small_set`
   - frozen sets are possible to make sets immutable
   - Methods
	   - `&` or `intersection()` creates new set of all elements that are the same
	   - `|` or `union()` creates new set of all elements of both lists
	   - `-` or `difference()` creates new set of all elements in 1st set but not 2nd set
	   - `^` or `symmetric_difference()` creates new set of all elements that are different
	   - [Link to Python Tutor with examples (with animals) of these set methods](https://pythontutor.com/live.html#code=%27%27%27%0A%60&%60%20or%20%60intersection%28%29%60%20creates%20new%20set%20of%20all%20elements%20that%20are%20the%20same%0A%20%60%7C%60%20or%20%60union%28%29%60%20creates%20new%20set%20of%20all%20elements%20of%20both%20lists%0A%60-%60%20or%20%60difference%28%29%60%20creates%20new%20set%20of%20all%20elements%20in%201st%20set%20but%20not%202nd%20set%0A%60%5E%60%20or%20%60symmetric_difference%28%29%60%20creates%20new%20set%20of%20all%20elements%20that%20are%20different%0A%27%27%27%0Amy_pets%20=%20%7B%22cat%22,%20%22dog%22,%20%22fish%22,%20%22aquatic%20snails%22%7D%0Ayour_pets%20=%20%7B%22ball%20python%22,%20%22human%20child%22,%20%22parakeet%22,%20%22bearded%20dragon%22,%7D%0A%0Aour_pets_in_common%20=%20my_pets%20&%20your_pets%0Aprint%28our_pets_in_common%29%0A%0Aall_our_pets%20=%20my_pets.union%28your_pets%29%0Aprint%28all_our_pets%29%0A%0Ayour_unique_pets%20=%20my_pets.difference%28your_pets%29%20%20#%20your%20pets%20that%20I%20don%27t%20have%0Aprint%28your_unique_pets%29%0A%0Aour_unique_pets%20=%20my_pets.symmetric_difference%28your_pets%29%0Aprint%28our_unique_pets%29&cumulative=false&curInstr=11&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false)
- `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
```python
true_thing if condition else false_thing  # ternary syntax
throw_ball() if dog_wants_play else pet_dog()  # ternary example
```


### Week 5
 - **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 use `e` (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)`
	 - 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 pet `now`
	 - 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):`

 ```python
 #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 of `return`
	 - 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__()`
 - 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 (like `this` in js/c++/java)
```python 
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
- **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?
```python
	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()` and `len()` 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**
	 - [Link to Python Tutor with examples (with animals) of abstract classes](https://pythontutor.com/live.html#code=class%20Animal%28%29%3A%0A%20%20%20%20def%20__init__%28self,name%29%3A%0A%20%20%20%20%20%20%20%20self.name%20%3D%20name%0A%20%20%20%20def%20place%28self%29%3A%0A%20%20%20%20%20%20%20%20raise%20NotImplementedError%28%22left%20to%20subclass%22%29%0A%0Aclass%20Lion%28Animal%29%3A%0A%20%20%20%20def%20__str__%28self%29%3A%0A%20%20%20%20%20%20%20%20return%20%22My%20mom%20a%20lioness%20and%20dad%20a%20lion%22%0A%20%20%20%20def%20place%28self%29%3A%0A%20%20%20%20%20%20%20%20return%20%22I%20live%20in%20Africa%22%0Aclass%20Tiger%28Animal%29%3A%0A%20%20%20%20def%20__str__%28self%29%3A%0A%20%20%20%20%20%20%20%20return%20%22My%20mom%20a%20tigress%20and%20dad%20a%20tiger%22%0A%20%20%20%20def%20place%28self%29%3A%0A%20%20%20%20%20%20%20%20return%20%22I%20live%20in%20Asia%22%0A%0Aclass%20Liger%28Lion,%20Tiger%29%3A%0A%20%20%20%20def%20__str__%28self%29%3A%0A%20%20%20%20%20%20%20%20return%20%22My%20mom%20a%20tigress%20and%20dad%20a%20lion%22%0Aclass%20Tigon%28Tiger,%20Lion%29%3A%0A%20%20%20%20def%20__str__%28self%29%3A%0A%20%20%20%20%20%20%20%20return%20%22My%20mom%20a%20lioness%20and%20dad%20a%20tiger%22%0A%20%20%20%20%20%20%20%20%0Aanimals%20%3D%20%5BLion%28%22Scar%22%29,%20Tiger%28%22kitty%22%29,%20Liger%28%22skinny%22%29,%20Tigon%28%22tiny%22%29%5D%0Afor%20animal%20in%20animals%3A%0A%20%20%20%20print%28animal,%20animal.place%28%29%29&cumulative=false&curInstr=51&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false)

- **Unit Tests**
   - run your function and use `assert` statements to test the expected output

## Output (Projects and Work) <a name="output"></a>
### Week 1
#### assignment
![https://onlinecampus.bu.edu/bbcswebdav/pid-9329010-dt-content-rid-57804186_1/xid-57804186_1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lpcox898470fsrw5w92h.png)

#### quiz
The quiz had some ridiculous questions on it. Oh well. 
{% twitter 1436346483385720870 %}

### Week 2 (data types, casting, mutability)
#### assignment
[Homework 2 Assignment PDF](https://github.com/VickiLanger/MS-in-Software-Dev/blob/main/CS521-Info-Structures_Python/CS%20521%20Homework%202%20-%20Fall%201.pdf)
### Week 3 (strings, control flow, loops, files)
#### assignment
[Homework 3 Assignment PDF](https://github.com/VickiLanger/MS-in-Software-Dev/blob/main/CS521-Info-Structures_Python/CS%20521%20Homework%203%20-%20Fall%201.pdf)
### Week 4 (lists, tuples, dictionaries, sets)
#### assignment
[Homework 4 Assignment PDF](https://github.com/VickiLanger/MS-in-Software-Dev/blob/main/CS521-Info-Structures_Python/CS%20521%20Homework%204%20-%20Fall%201.pdf)
### Week 5 (error handling, functions, recursion, generators)
#### assignment
[Homework 5 Assignment PDF](https://github.com/VickiLanger/MS-in-Software-Dev/blob/main/CS521-Info-Structures_Python/CS%20521%20Homework%205%20-%20Fall%201.pdf)
### Week 6 (classes, overloading, ecapsulation)
#### assignment
[Homework 6 Assignment PDF](https://github.com/VickiLanger/MS-in-Software-Dev/blob/main/CS521-Info-Structures_Python/CS%20521%20Homework%206%20-%20Fall%201.pdf)
### Week 7
#### Final Project
[Final Project Requirements](https://github.com/VickiLanger/MS-in-Software-Dev/blob/main/CS521-Info-Structures_Python/final_project_guidelines_v3.pdf)
[Final Project](https://github.com/VickiLanger/MS-in-Software-Dev/tree/main/CS521-Info-Structures_Python/final_project)
#### Final Exam
15 questions and 30 minutes later. 
Covered:
 - generators
 - nested list/tuple indexing
 - function syntax
 - slicing
 - hashable and immutable data types
 - `break` and `continue`
 - classes and inheritance

## Documentation (References) <a name="docs"></a>
 - https://pythontutor.com/visualize.html#mode=edit
 - https://docs.continuum.io/anaconda/install/