## DEV Community

Vicki Langer

Posted on • Updated on

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

Wait! I just wanna test myself on the exercises you had in class. Glad you asked, here's the repo: Exercises for first class

## Input (Learning Objectives)

### 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.
• use 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)
``````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
• `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
``````

### 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):`
`````` #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)
``````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
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
• 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?
``````    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

• Unit Tests

• run your function and use `assert` statements to test the expected output

## Output (Projects and Work)

### Week 1

#### quiz

The quiz had some ridiculous questions on it. Oh well.

### Week 2 (data types, casting, mutability)

#### assignment

Homework 2 Assignment PDF

### Week 3 (strings, control flow, loops, files)

#### assignment

Homework 3 Assignment PDF

### Week 4 (lists, tuples, dictionaries, sets)

#### assignment

Homework 4 Assignment PDF

### Week 5 (error handling, functions, recursion, generators)

#### assignment

Homework 5 Assignment PDF

#### assignment

Homework 6 Assignment PDF

### Week 7

#### 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