0% found this document useful (0 votes)
24 views64 pages

Recursive Structures in Programming

Uploaded by

camccain2
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
24 views64 pages

Recursive Structures in Programming

Uploaded by

camccain2
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

LS28 - Recursive structures

● Recursion
○ When a process (function) or structure (data type) is defined in terms of itself
○ Example
■ File system
■ Tree branches
○ Things that are defined in terms of other versions of itself
○ Recursion needs to terminate → base case
○ Made of
■ Base case
● Where recursion ends
■ Recursive step
● Structures
○ Recursive data type
■ Contains itself as an attribute/part of an attribute
● Linked lists vs lists


○ Classic list has one object made up of elements
○ Linked lists have node objects that point to other node objects
■ When you want to end list object have it end with none
■ Next is the arrow pointing to next node in list of nodes
● Recursive structures vs functions
○ Base case is in recursive is last function call where we return final function
○ Base case in linked list is last element in list that points to none
○ Once you find node that points to one, you have reached the base case, where
linked list ends
● VS Code

● Ending recursion
○ Terminates on a base case
○ Recursive attribute replaced with None type
● In memory

CL19 - Classes in Memory and Magic Methods


● When I call print(x), Python calls what magic method on x before printing?
○ __str__
■ x: Point = Point(1.0, 2.0)
● Arithmetic Operator Overloads

● Comparison Operator Overloads


● For each magic method call, what is self and (if applicable) what is other?
○ A and b are arguments
○ Self and other are parameters


■ Point object must be on left hand side
■ You can call x * 2.0 but not 2.0 * x

y

LS27 - Operator Overloads


● In Python, when you design a class you are able to define what it means when
objects of your class are multiplied, added, and so on to other values.
● In Python, to define how objects of a class behave with respect to arithmetic
operations like addition (+), you need to implement special methods like __add__.
When you write a + b, Python looks for the __add__ method in the class of a. If it's
not found, Python looks in the class of b and its superclasses. The method
signature for __add__ should have two parameters: self and other, where self
refers to the instance on which the method is called, and other refers to the
object being added. It's not required that the second parameter be of type
Fraction, but the __add__ method should be able to handle addition with any
compatible type.

LS26 - Magic Methods


● Function you define that Python already has built in functionality for
○ Example - print, __init__
● Will have two underscores before and after for magic method
● When you print an object whose class does not have a __str__ method defined, the
default string representation of an object looks something cryptic, like:
○ <__main__.ClassName at 0x000238492>
■ Where ClassName above is the name of the class of the object.
● The __str__ method is automatically called when Python attempts to convert an object to
a str and the object's class has a __str__ method defined in it.
● Magic methods are called automatically when certain events occur, such as creating an
object or performing arithmetic operations.

RD02 - Man vs Machine or Man + Machine


● The article discusses the ongoing debate regarding the role of humans and machines in
decision-making processes, particularly in complex systems involving automation. It
highlights the challenge of balancing the allocation of roles and functions between
humans and computers, emphasizing the need for collaboration and clear design
criteria.
● The historical perspective on human-computer interaction (HCI) is discussed, noting the
attempts to characterize the strengths and limitations of humans and computers in
various tasks. The concept of Levels of Automation (LOAs) is introduced, which range
from fully manual systems to fully automated systems, with different degrees of human
involvement in decision-making.
● The article argues that while automation is often seen as superior and desirable in many
systems, especially for skill-based tasks, there are limitations. Automation is less
effective in handling uncertainty and complex decision-making, which are areas where
human judgment and intuition excel.
● A modified Skills, Rules, Knowledge framework is proposed to understand the allocation
of roles and functions between humans and computers. Skill-based tasks, which are
highly automatic and routine, are considered suitable for automation. Rule-based tasks,
which require following predefined procedures, can benefit from human-computer
collaboration. Knowledge-based tasks, which involve decision-making based on
experience and intuition, are challenging for automation and often require human
expertise.
● The article concludes by advocating for a collaborative approach between humans and
computers, especially in knowledge-based domains, where humans can leverage the
computational power of computers while applying their judgment and intuition to handle
uncertainty. It emphasizes the need for a new breed of engineers and computer
scientists who understand both human psychology and control theory to design effective
human-machine systems.
● In the article, written in 2014, Mary Cummings discusses the “slow” progress of utilizing
computers for knowledge-based tasks (this may include tasks such as understanding the
sentiment of a phrase, describing the contents of a picture, or even giving a relevant
response to a question). Do you believe computer scientists have accelerated this
progress since then? Give examples of 2 advancements in the last decade in which
humans can use computers for knowledge-based tasks.
○ I believe that computer scientists have definitely accelerated progress since then.
The first example of an advancement in the last decade would be generative AI
platforms like ChatGPT. Since its launch in 2022, ChatGPT has excelled in tasks
such as sentiment and literary analysis, developing varied responses to
questions, and even creative writing that is yet to exist. These platforms like
ChatGPT use intensive, large-scale pre-training with large amounts of data to
develop a complex understanding of language and information that allows them
to perform knowledge-based tasks extremely effectively and efficiently. Another
example of a recent technological advancement is Amazon’s Alexa and voice
recognition. Alexa works by using voice recognition technology to analyze and
respond to spoken commands. Similar to ChatGPT, though continuously
approving, it uses large-scale pre-training to access a wide range of information
and services to provide users with relevant responses and perform requested
tasks. Not only can Alexa perform specific tasks, but it has the power to have a
conversation the same way a human would. Thus, though in 2014, there may
have been an issue of slow processing in technology, the new generation of
technology truly has a mind like a human and will have no issues with knowledge
based processing and true human operation.
● There is an on-going discussion of whether humans or machines should get the
decisional authority within new computer technology. Do you foresee a world in which
everything can be automated, especially with the advancements in unsupervised
learning. Do you believe there are any ethical concerns with trying to automate as many
aspects of life as possible?
○ In my opinion, I do not see a world in which this is possible. My first reason is that
although machines can process nearly infinite amounts of data, allowing it to
perform in human functions like Alexa, I don't think that you can ever fully
accurately replicate human reactions, responses, and reflexes, as they are ever
changing. Given this, I don’t think that machines will ever get to the point in which
they can fully replicate a human. Another reason I have is that I do not think you
can teach a machine to have true emotions and emotional judgement. Emotions
and emotional judgement are unique to each individual, and making these
decisions is too subjective to program.
○ In my view, reaching a world where everything can be fully automated, especially
with advancements in unsupervised learning, seems unlikely. While machines
can process vast amounts of data and perform human-like functions, such as
those seen in virtual assistants like Alexa, accurately replicating human
reactions, responses, and reflexes poses a significant challenge. Human
behaviors and responses are complex and dynamic, influenced by various
factors that are difficult to simulate artificially.
○ Moreover, teaching machines to possess genuine emotions and exercise
emotional judgment is what I see as an impossible task. Emotions and their
interpretation are highly subjective and vary widely among individuals.
Programming machines to make decisions based on emotional factors may lead
to ethical concerns and unintended consequences, especially in situations where
empathy, compassion, or moral reasoning are required.
○ While automation can enhance efficiency and convenience in certain tasks, there
are ethical considerations regarding the extent to which automation should be
pursued. Striking a balance between automation and human decision-making is
crucial to address these concerns and ensure that technology serves humanity's
best interests. Finally, though jobs can be made through the creation of
automated machines and devices, I do not see it as ethical nor possible to
replace human work with machines.

CL18 - Class Writing Practice


LS 25 - Introduction to Object Oriented Programming
● Object oriented programming
○ Lets you create new objects in program
○ “Type” → “Class”
○ “Data/Variables” → “attributes”
○ “Functions” → “Methods”
■ A method of a class is a special kind of function that all objects
(instances) of the class will have available for calling.

● Class
○ Name class w capital letter
○ A class defines groupings of related variables called attributes. Each
object, or instance, of a class has those attributes.
○ A class definition introduces a new data type, or type of object, in your
program.
● Example: Pizza
○ Attributes
■ Size: large
■ Toppings: 1
■ Gluten free: yes


● Attributes
○ Variables that belong to each instantiation of the object
○ Syntax
■ <attribute name> : <type>
■ Gluten_free : bool

● Constructor
○ Method that defines what happens when new object is created
○ Signature syntax:
■ Def __init__(self, <other parameters>): *Essentially returns self
○ Instantiation:
■ <class name>(<arguments>)
● Methods
○ Functions that belong to an object
○ The first parameter of a method is self and it is given a reference to the
object the method was called on.
○ Calling a method
■ price(my_pizza) → my_pizza.price()
○ Defining a method:
■ Def <method_name>(self, <other parameters>) → <return type>:
■ Def price(self) → float
● Example


■ Attributes appear on line 3 and 4.
■ Parameters appear on line 6.
■ Arguments appear on lines 16 and 17.
■ The __init__ constructor is called on lines 16 and 17.
■ If you were to call [Link](), the output would be "Woof!".

CL16 - Reverse Engineering a Recursive Definition


● Goal for today
○ Start with a recursive python program and find out the standard function
representation that it is describing.



● Today: Do it in Reverse -
○ Start with recursive Python function
○ From that, get the recursive definition
○ From that, get the sequence representation
○ From that, get the standard definition


○ Start with recursive Python function
○ From that, get the recursive definition
■ Base case:
● If n = 0 → mystery(n) = 1
■ Recursive step
● If n > 0 → mystery(n) = 2 x mystery(n-1)
○ From that, get the sequence representation

n 0 1 2 3 4 …

F(n) 1 2 4 8 16

○ From that, get the standard definition
■ F(n) = 2n
■ Given n, how do I get to F(n)
■ Answer
● Def mystery(n:int) → int:
○ Return 2n


LS24 - Intro to Recursion
● Motivation
○ Why recursion?
■ Some programming languages are built entirely around recursive
structures
■ Some functions, sets, or sequences are best represented via recursion
■ Helpful representation for proving things about your functions
● Function in python is called a partial function


○ Representing a function as sequence of outputs
● Recursive definition of a function
○ Calling a function within itself, typically with a smaller input.
■ f(n) = f(n/2)
○ Two components:
■ Base case(s)
● Where recursion ends
● Often smallest input(s)
● Prevent infinite loops!
● Ex
○ When n>=0, base case is n=0
■ Recursive Rule
● Definition to handle all inputs that aren’t base case.
● Expresses function in terms of smaller calls to the function.
○ (e.g. expressing f(n) in terms of f(n-1))
○ Finding recursive rule

● Looking at how you get from one output to the next
○ Finding base case


● Base case will typically be first or first couple outputs
● Base case is where the recursive rule does not apply
○ See bottom right, cannot do this because we are focused on
integers equal to or above 0
● When in doubt, make base case the first element in sequence
○ Writing recursive in python

○ Memory diagram


● More on recursion


■ Recursion rule - n>0 → f(n,b) = f(n-1,b) + 1
■ Base case - n=0 → f(0,b) = b

CL14 - More on Big O Notation


● Common Runtimes
○ O(1) - Constant
○ O(n) - Linear
○ O(n^2) - Quadratic
○ O(x^n) - Exponential (BAD)
● Dictionaries vs. Lists
○ There are runtime considerations for dictionaries/hash tables and lists!
○ Dictionaries:
■ Faster lookup: “x in d” ~ O(1)
■ Slower iteration (theoretically)
○ Lists:
■ Slower lookup: “x in l” ~ O(n)
■ Faster iteration (theoretically)
○ There are many other pros/cons to dictionaries vs. lists, which you will see in
other languages/future courses.
● Search Algorithms
○ Selection Sort Outer loop:
■ Loop over list (everything up to pointer is sorted, everything else is not).
Once you reach the end of the list, you’re done!
■ Inner loop: Loop over list to find minimum. Swap the object at outer
pointer with the minimum.


○ Insertion Sort Outer loop:
■ Loop over list (everything up to pointer is sorted, everything else is not).
Once you reach the end of the list, you’re done!
■ Inner loop: Swap the object at the pointer backwards until it’s in the
correct position


RD01

One of the main models I see in my life is algorithms and cookies in social media and
technology. I would classify these as informal models, as they likely do not rely on true
mathematical calculations or symbolic representations. These models are meant to help the user,
as they cater your media and advertisements to content related to what you may have looked at
or used or purchased before. On one hand, this can be super helpful, as most of the media I
consume is catered to my interests, and I do not have to watch media I am not interested in. On
the other hand, however, this model can make me feel as if I am being watched and my personal
privacy is being violated.
Another model that I have seen in my friends’ lives is the predictions made in sports
betting. The entirety of sports betting is reliant on statistical models of previous games and
player statistics. Without these models, there would be no way of having odds for people to bet
on, and people would not be able to view statistics to base their bets, or future predictions, on.
Thus, these models are very useful for people in the world of sports betting.

In order for an algorithm or model to not cause harm, the algorithm or model should be
fully transparent and clear to those whom it may affect. In the example from the reading, for
example, there is no reason for the ten rows to be blocked off without that being clear and
understood by people at the concert what its purpose is. Not only are unclear models frustrating,
but they are often unnecessary and can avoid potential harms through simple explanation.
To continue, an algorithm or method should be able to be applied across all populations
consistently and fairly. What I mean by this is, no model or algorithm should discriminate or
negatively impact individuals or groups on the basis of their identity. These models are unfair
and will always cause harm so should avoid not being scalable.
Finally, in order to avoid harm, models and algorithms should always avoid any types of
biases that could harm an individual or a group, and they instead should focus on benefiting all
people at all times.
The first paragraph focuses on the idea of limiting opacity, the second focuses on
promoting scalability, and the final paragraph focuses on limiting damages and maximizing
benefits.

​ Opacity: The algorithm should be transparent and understandable to those


affected by its decisions. Users should be able to understand how the algorithm
works, what data it uses, and how it makes decisions. This transparency helps
prevent the algorithm from being misused or producing unintended
consequences.
​ Scale: The algorithm should be designed to be scalable, meaning that it can be
applied consistently and fairly across different contexts and populations. It
should not disproportionately impact certain groups or individuals based on
factors such as race, gender, or socioeconomic status.
​ Damage: The algorithm should be designed to minimize harm and maximize
benefit. It should not result in unjust outcomes or perpetuate existing
inequalities. Instead, it should aim to improve fairness, accuracy, and efficiency in
decision-making.

CL13 - Big O Notation


● Recall: Algorithms
○ Input is data given to an algorithm
○ An algorithm is a series of steps
○ An algorithm returns some result
○ An algorithm may be influenced by its environment and it may produce
side-effects which influence its environment.
● What is an algorithm?
○ A set of steps to solve a general problem
○ Finite
○ Can handle a problem of arbitrary size
● How do we measure how “good” an algorithm is?
○ Is it correct?
○ How long does it take to implement?
○ How much computer memory does it take?
● Why do we care about computation speed?
○ Security: Cryptography works because encrypted information takes too long to
decipher!
○ User Experience: Users don’t want to work with a slow application!
○ Big Data: We want to be able to feed as much data as possible into our systems,
but we need a way to efficiently do that!
● Measurements we use
○ O “Big O”: upper bound (worst case runtime)
○ “Big Omega”: lower bound (best case runtime)
○ “Big Theta”: average runtime
● Looking for lowest card
○ 4 actions for input of 4 cards
○ N actions for an input of size n
○ In this approach, we always have to check every card in the deck, so our runtime
will always be approximately n where n is the size of the deck.

■ This will take at the maximum n actions for an input of size n
■ You take the number of actions for the number of input size
● Speed vs. Memory
○ Sometimes you can make a tradeoff between speed and memory.
■ E.g. storing a value rather than computing it repeatedly.
○ First one is



LS22 Mutable and Immutable Objects


● Mutable vs immutable
○ Immutable: can’t be mutated (changed) after creation
■ Immutable types: int, float, bool, string, and tuple
■ Can be re-assigned, but not changed
○ Mutable: can be mutated after creation
■ Mutable types: list and dict
■ Can be both reassigned and changed
■ Can be mutated directly, but also with functions
● Practice
○ Write three functions that take a list[str] as an argument
■ remove_first removes the first element of the input list
■ get_first returns the first element of the input list WITHOUT mutating
■ get_and_remove_first removes the first element of the input list AND
returns it
LS23 - More Unit Tests

#Function name: lookup_by_kind_and_date


#Parameters: dict[str, list[str]], dict[str, list[str]], str, str
#Return Type: str
def lookup_by_kind_and_date(plants_by_kind: dict[str, list[str]], plants_by_date:
dict[str, list[str]], kind, month) -> str:
"""Return string with list of plants of a specific kind to plant in a specific
month."""
assert kind in plants_by_kind # makes it so only uses kind if in plants by kind
assert month in plants_by_date #
# get a list of all plants of the specific kind input
kind_list: list[str] = plants_by_kind[kind]
# get a list of all plants planted in a specific month
month_list: list[str] = plants_by_date[month]
# go through both lists and find elements that apper in both
# kind_list = ["marigold", "daisy"]
# month_list = ["daisy", "rose"]
combined_list: list[str] = []
for plant in kind_list:
for other_plant in month_list:
if plant == other_plant: #plant is in both kind_list and month_list
combined_list.append(plant) # can also be (other_plant)
# "<kind>s to plant in <month>: <combined_list>"
if len(combined_list) > 0:
return f"{kind} to plant in {month}: {combined_list}"
else: # 'no {kind}s to plant in {month}.'
return f"no {kind}s to plant in {month}"

LS21 - Unit Tests


● Unit testing
○ Writing functions to test other functions
○ Using pytest (other frameworks exist)
● Syntax
○ Def test_name -> None:
● Assert <boolean expression>
○ Command line: python -m pytest path/to/[Link]
○ Test file names: end with _test.py
○ Test function names: always begin with test_
● Testing
○ Use case: testing properties for how we expect our program to be used
○ Edge case: testing instances outside “typical” usage

CL11 - Dictionaries and for loops


● Dictionary syntax
○ Create empty dict
■ <name>:dict[<key type>,<value type>] = {} or
■ <name>:dict[<key type>,<value type>] = dict()
○ Create populated dict
■ <name>: dict[<key type>,<value type> ] = {key_0: val_0, key_1:
val_1,...}
○ Add/Change Elements:
■ <name>[<key>] = <value>
○ Remove Elements:
■ <name>.pop(<key>)
○ Check if key in dictionary:
■ <key> in <dict name>
● “For “ loops
○ “for” loops iterate over the keys by default

● Practice
○ in_stock: dict[str, bool] = {“carrots”: True, “beets”: False, “apples”: True}
○ Print all keys that have the value “True”.

LS20 - Dictionaries in memory


LS19 - Dictionaries
● Dictionaries
○ In lists indexes are keys, values are the values
○ Values can be different types
○ Also called maps, hashmaps, key value stores
● Syntax
○ Data type:
■ Data type: name: dict[<key type>,<value type> ]
■ Ice_cream: dict[str, int]
○ Constructor
■ dict()
● Or
■ ice_cream: dict[str, int] = {"chocolate": 12, "vanilla": 8, "strawberry": 5}
● Can also use single quote
● Dictionary operations
○ Adding elements
■ We use subscription notation
■ <dict name>[<key>] = <value>
■ Ice_cream[“chocolate”] = 12
■ Ice_cream[“mint”] = 3
○ Removing elements
■ Similar to lists, we use pop()
■ <dict name>.pop(<key>)
■ ice_cream.pop(“mint”)
○ Access and modify
■ To access a value, use subscription notation:
● <dict name>[<key>]
● Ice_cream[“vanilla”]
■ To modify, also use subscription notation
● <dict name>[<key>] = new_value
● Ice_cream[“vanilla”] = 9 or ice_cream[“vanilla”] += 1
○ Length of dictionary
■ len(ice_cream)
○ Check if key in dictionary
■ <key> in <dict name>
■ “Mint” in ice_cream
○ Important: cannot have multiple of the same key! Can have duplicates of the same
value

CL10 - for loops + range ()


● Range
○ Includes start point, does not include end point, and steps through every point in
between
○ Constructor: range(start, end, [step = 1])
○ Examples:
■ range(1, 5) stops at numbers 1, 2, 3, 4
■ range(1, 6, 2) stops at numbers 1, 3, 5


○ Using range() in a for … in … loop.
■ names: list[str] = [“Alyssa”, “Janet”, “Vrinda”]
■ Print every element’s index and value:
● 0: Alyssa
● 1: Janet
● 2: Vrinda
○ """Demonstrates range in a for loop."""

○ names: list[str] = ["Alyssa", "Virinda", "Janet"]

○ for index in range(0,len(names)):

○ print(f"{index}:{names[index]}")

CL09 - for loops and sequences


● Sequences
○ What is a Sequence?
○ An Abstract Data Type that is an ordered, 0-indexed set of values.
○ There are many specific types of sequences with their own properties. Common,
built-in sequence types in Python include:
■ str: a sequence of character data
■ list: a dynamically sized sequence of values of a specific type
■ tuple: a fixed size sequence of values of any types
■ range: a sequence of integers at intervals between a start and end
● Tuples
○ Tuples types are made of a specific, fixed-length sequence of any mixed type(s).
○ Example
■ 3d_coordinate: tuple[float, float, float] = (1.0, 1.0, 1.0)
■ Other example:
● Player = tuple[str, int]
● lebron : Player = ("James", 6) mj: Player = ("Jordan", 23)
○ This is pretty much everything you need to know about tuples for this class, I just
want you to familiar with them!
● Looping through sequences
○ You can use a loop to iterate over every element in a sequence!
○ x: str = “hello
○ idx: int = 0
○ While idx < len(x)
■ Print (x[idx])
■ Idx =+ 1
● for…in…loops
○ xs: list[str] = [“w”, “x”, “y”, “z”]
○ We want to print every element of xs
○ While
■ Idx: int = 0
■ While idx < len(xs):
● Print (xs[idx])
● Idx += 1
○ for…in…
■ for elem in xs:
● print(elem) ← behavior we want in loop
○ These both do the same!
○ For _____ in ____, Python knows by syntax we are creating a new variable



● for…in…loops in memory



● Writing Code for for in loops
○ pets: list[str] = [“Louie”, “Bo”, “Bear”]
○ Using a for … in … loop, write code to tell each pet they’re a good boy!
○ Challenge: call each elem something other than “elem”
○ Output should be:
■ Good boy, Louie!
■ Good boy, Bo!
■ Good boy, Bear!
○ Answer
■ pets: list[str] = ["Louie", "Bo", "Bear"]

■ for baby in pets:

■ print(f"Good boy, {baby}!")

LS18 - Importing Modules


● Files in python are called modules

● We use the if name == main because if we are in my_functions, we want that to run but
only that
● We do that so in imports if you run that it'll only run what is in imports
● Syntax
○ From <package name> import <module name>
○ Can also import certain functions or variables
■ From lessons.my_functions import add
■ From lessons.my_functions import my_variable
● Using an import
○ Function: <module name> . <function name> (arguments)
○ Variable: <module name> . <variable name>

LS17 - Lists in Memory


● Example
○ Lists are stored on the heap

■ Now that we have x and y as reference to same object, if u modify x you
modify y as well
● Comparing Lists and Strings
○ Left column of heap is index number


■ In the strings, we only add the 6 to a
■ In lists, since b and a are references to same object on heap, we modify
both
● Lists and Functions

■ Defining a function on the heap
■ Because we call on course, that is the argument. We then relate it to the
parameter which is xs, which is why course and xs are both id:1


■ First step is writing odds list as id:0 in the stack and the lines in occupies
in the heap
■ Then we go down to line 11 and look at global odds which calls us back to
line one, and we create odds_list own section
■ We use values of 2 and 10 as the min and max and line 11 as the RA
■ We give odds an empty list with nothing
■ We then go through the while loop and add to id:1 as we go until done
then write id:1 as return value
■ We then print the list of integers for global odds as a list
● Lists and Functions

CL08 - Lists and Functions


● Modifying lists with functions
● First function has a string parameter and adds an exclamation point, string input does not
get modified,
● Second function has a list as parameter and appending an exclamation point, with list
when we cal emphasize with b as argument we do get the exclamation point

CL07 - Intro to Lists


● Lists
○ A list is a data structure- something that lets you reason about multiple items
○ Examples
■ To do list
■ Grocery list
○ Not a fixed number of items
● Initializing an empty list
○ <list name>: list[<item type>] = list()
○ Grocery_list: list[str] = list() ← list constructor
○ Grocery_list: list[str] = [] ← literal
● Adding an item to list
○ <list name>.append(<item>)
○ Grocery_list.append(“bananas”)
○ Append is a method
■ A function that belongs to the list class
■ Like calling append(grocery_list, “bananas”)
● Initializing An Already Populated List
○ <list name>: list[<item type>] = [<item 0>,<item 1> , … ,<item n> ]
○ grocery_list: list[str] = [“bananas”, “milk”, “bread”]
● Indexing
○ grocery_list: list[str] = [“bananas”, “milk”, “bread”]
○ Grocery_list[0]
● Modify by index
○ grocery_list: list[str] = [“bananas”, “milk”, “bread”]
○ Grocery_list[1] = almond milk
■ Will make element 1 (milk) into almond milk
● Before change:
● ['bananas', 'milk', 'bread']
● After change:
● ['bananas', 'almond milk', 'bread']
● Length of a list
○ grocery_list: list[str] = [“eggs”, “milk”, “bread”]
○ len(grocery_list)
● Remove an item from a list
○ grocery_list: list[str] = [“eggs”, “milk”, “bread”]
○ grocery_list.pop(2)
■ Number is the index of item you want to remove
● Lists + Functions
○ Functions can:
■ Take lists as arguments
■ Return or create lists
■ Modify lists
● Example
○ # Function name: display
○ # Parameter: list[str]

○ # Return nothing!

○ # Print out the list!

○ print("~*~ Functions ~*~")

○ def display(word: list[str]):

○ print(word)

○ display(["Charles", "Ty", "Jojo", "Will"])



■ X is none because the original display function does not return to anything
● Which of the following is a list access via the subscription operator?
○ List[str]
○ names[0]
○ ["Kris", "Kaki", "Alyssa"][1]
○ list()

CL06 - Practice with Functions


● Practice Writing Functions
○ Write a mimic function: you input a string and it returns the same string back to
you
■ Function name: mimic
■ Parameters: my_words: str
■ Return type: str
■ Doc string: """Given the string my_words, outputs the same string"""
○ Try calling it!
● Memory diagrams: Change!
○ We will be replacing arrows with id numbers
○ Why
■ Every object in python has an id number associated with their location in
memory (also called an “address”)
■ We use arrows to represent variables that are references to locations in
memory on the heap.
■ Using id is a cleaner and more literal representation of this.
○ When objects stored on the heap (e.g. functions) are initialized, label them with a
heap id, starting with id:0 and counting up
○ When referring to an object on the heap, instead of drawing an arrow, state their
id number (id: 0).
○ When accessing a variable name that holds a heap id, look at its associated id on
the heap (if variable x has id:0 as its value, look at the object on the heap with
id:0)
○ When objects stored on the



● Practice Writing Functions
○ Write a different mimic function: you input a string and an index and it returns the
letter at that index. If the index is too high for the string length, return “Index too
high”
■ E.g. mimic_letter(“hello”,0) returns “h”, mimic_letter(“howdy”,2) returns
“w”, mimic_letter(“hi”,3) returns “Index too high”
○ Function name: mimic_letter
■ Parameters: my_words: str, letter_idx: int
■ Return type: str
■ Doc string: """Outputs the character of my_words at index letter_idx"""

LS15 - function semantics



○ Use heap after definition to show which lines you are skipping
○ After you write heap, skip those lines
○ Create new frames in stack for everytime we call a function
○ Immediately write RA - return address
■ Where we are coming back to code when we step through function
○ Identify corresponding arguments
■ num1 corresponds with argument 1
■ num2 corresponds with argument 12
■ Write these in new my_max frame
○ Then go back to line 3 and begin stepping through
○ RV - return value, write what is returned from lines 3-8
○ Then go back to return address which is line 10
○ Assign value of line 10 (max) from the RV
○ Write new variable in global stack
○ Create a new frame with my_max
○ Write RA - 11
○ Reassign values for num1 and 2 based on correspondence
■ num1 = 13
■ num2 = 3
○ RV is 13
○ Soon as you reach return statement, you exit fuction and return to RA
○ other_max is 13
○ Write output as 13
● Function Call steps
○ Always make sure functions being called have already been defined in earlier line
○ Are arguments fully evaluated?
○ Do parameters and arguments agree?
■ 1 and 12 as inputs must match types
■ Number of arguments matches number of parameters
● Establish frame for function call
○ Frame on stack labeled with function name
○ Write down return address
○ Copy down arguments
● Global variables are accessible throughout entire file
● Variables within call frame are only available in call frame

LS14 - Function Syntax


● How we write a function in python
○ function_name(<argument list>)
■ print(“hello”) → one argument
■ randint(1,7) → two arguments, one and seven
○ Arguments are considered expressions
● Syntax for defining a function
○ Def function_name(<parameter list>) -> <return type>:
■ Must always begin with def when defining
○ Def function_name(<parameter list>) -> <return type>:
■ Indenting tells us we are working inside function definition
■ “““Docstring describing function”””
■ <what your function does>


■ Function name → my_max
■ Parameter list → number1: int, number2: int
■ Return type → int
■ Signature → def my_max(number1: int, number2: int) -> int:
● Call vs signature
○ Call (for calling a function):
■ function_name(<argument list>)
■ my_max(11,3)
○ Signature (for defining a function):
■ Def function_name(<parameter list>) -> <return type>:
■ def my_max(number1: int, number2: int) -> int:
○ Return type should match
○ Function name should match
○ Arguments need to correspond with parameters

LS13 - Introducing Functions


● Functions
○ Let you generalize problems for different problems
○ Allow you to take solutions you defined in one place of your program and reuse
them in other places of your program file…and even in other program files!
○ Help you abstract away from certain processes
● Abstraction
○ Ordering a pizza
■ You order a large cheese pizza
■ You dont think ab how they got the ingredients, Made the crust, etc
■ You are abstracting away from specificity of specific processes
○ round(x)
■ Can round 10.25 down to 10 by calling round(10.25)
■ Not thinking line by line how the program is making rounding decision
● Calling a function
○ Function call: expressions that result in (“return”) a specific type
○ Common expressions
■ “Making a function call”
■ “Using a function”
■ “Invoking a function”
○ Looks like function_name(<inputs>)
■ print(“hello”)
■ round(10.25)
● A function returns something but doesn't always print something
○ round(10.25)
■ This will never print anything, but it will return 10
■ Must activate print to print it
● Print function prints something but does not return anything
● Defining functions
○ function definitions are sub-programs that define what happens when a function is
called
○ Can be:
■ Built-in
● Print, round
■ Imported in libraries
● From radom import randint
■ DIY - define your own in python file

CL04- Practice with While Loops


● Practice with While Loops
○ “Iteration” - one pass through a while loop
○ Often “i” (or “idx”) is used as the counter to track the loop




○ Enter while loop if condition is true
○ With while loops, once the condition becomes false, finish the operations then
stop

LS12 - counters
● Something you want to keep track or count of

LS11 - elif
● Combines else and if
○ Allows you to Combine else and if
○ Used between else and if statements

LS10 - while loop statements


● Loops
○ Used to carry out statements in a program repeatedly an arbitrary number of times
○ If condition is true you repeat block
● While loop
○ Repeat the block “while” the condition is true
○ Conditionals located inside a “while” loop
○ Syntax
■ While <condition>:
■ <repeat action>
● The while statement is called a loop, because the control of your program jumps back up
to a point earlier in the program than the end of the repeat block.
● The condition in the while statement's syntax must be a bool expression.
● If the condition in a while statement evaluates to False, the program exits the
repeat block and continues to the next statement at the same level of indentation
as the while keyword.
● You can write any statements you'd like inside of the repeat block, such as other
print statements, variable declaration and assignment statements, conditional
if-else statements, while loop statements, and so on.
● To avoid an infinite loop which of the following should be true, choose all that
apply:
○ Something must change in the repeat block that causes the while loop's
condition to change
○ Forward progress must be made toward the while loop condition
becoming False
● When iterating through a collection using the index/subscription operator, such as
with a string, it is common to use your counter variable as the index operator's
int value in order to access individual items in the collection one-by-one.
● You can use a while loop to iterate through each item in a collection. For
example, a str is a collection of characters, and you can use a while loop to
reason about each character one-by-one.
● The big, valuable idea of a loop is that it allows you to write a fixed number of
lines of code that can process arbitrarily sized amounts of data and/or
computations.

CL03 - Practice with Memory Diagrams and Conditionals


● len() function
○ Function you can use on strings!
○ len(“Hello”) → 5
○ Tells the length of a string
● Conditionals practice
○ 1. 2 , 2. 4, 3. 7, 4. none, 5. +-3, 6. none


● Relative Reassignment
○ Reassigning a variable relative to its current value: i = i+ 1
○ Addition re-assignment operator shorthand has the same effect: i += 1
○ Since you will use meaningfully descriptive variable names, this is a big
improvement!
○ total_dollars= total_dollars + next_donation vs total_dollars += next_donation


○ 2nd to last line doesn’t matter

LS08 - Unicode, Emoji, Escape Sequences, and f-Strings


● Strings are sequences of characters
● Use the ord function to find a character’s int code
○ every character has a corresponding int value.
■ Python’s built-in function ord, short for “ordinal” which is the order in
which characters are defined, takes a single-character string as an input
parameter and returns the int representation of the character’s binary code.
● ord(“A”) → 65
○ The ord of lowercase letters is higher than uppercase letters in ASCII
■ “duke” > “UNC” → true
● Use the chr function to convert an int to a character
○ The chr function is built-in to Python, takes an int parameter, and returns the
single character representation as a string.
■ chr(65) → ‘A’
● Putting a hex on large integers
○ Consider the base-10 value 90. It can be interpretted in a binary, a base-2 numeral
system as 01011010. Binary is base 2 and has only 2 digits: 0 and 1. It can also be
represented in a hexademical, a base-16 numeral system, with 5A. Hexadecimal is
base 16 and has 16 digits, 0-9 followed by A-F which correspond to the decimal
values of 10-15. Computer scientists love hexadecimal because each single digit
corresponds to four binary digits. Notice that in the example: 01011010, which is
8 binary digits, is equivalent to 5A.
○ Python has a built-in hex function for converting to its representation. The 0x in
front of the hexadecimal notation can be ignored and is case insensitive.
■ hex(90) → 0x5A
○ U+ tells you this is Unicode, a more modern international character encoding
standard than ASCII. The 1F920 is a hexadecimal representation of the code for
the cowboy emoji.


■ The leading backslash begins an escape sequence
■ The U is an indication that what will follow is an 8-digit hex
representation of a unicode character. Then, to encode 1F920, we must add
three leading 0s for padding because 8 hex digits are expected.


● String escape sequences
○ the backslashes in the string "\U0001F920\U0001F40E" are signalling something
special is about to follow the backslash. In this case, what follows is a U which
hints “8 hexidecimal digits encoding a single unicode character” will follow the
\U “escape sequence”
○ Common string sequences

○ How can you use a double quote character in a string surrounded in double
quotes?
■ With the first escape sequence above! For example, the string literal "The
computer said, \"Hello, world.\"" will evaluate to the characters The
computer said, "Hello, world." The \" escape sequence, when evaluated,
results in a quotation character.
○ f-strings “format” strings
■ A key distinction between a regular string and an f-string is that it begins
with the letter f preceeding its quotes.


■ Inside of an f-string you can write an expression inside of curly braces and
it will get substituted with the expression’s value when the string literal is
evaluated. Spaces inside of the curly braces are ignored



LS07 - Memory Diagrams
● Representing what is happening in memory as you step through code
● Will have two boxes - stack and output
○ Everything for now for stack is global
● Example 1
○ Name: str = “Alyssa”
○ Stack is used for name
○ Output is used for the result of the code/things printed


● Example 2


■ Can put 2 and 4 in quotes because python prints as a string
● CQ00



● CQ01


■ Even though it becomes 2.0, do not print line 5 because we work top to
bottom and we only arrived at 2.0 from line 7

LSO6
● Boolean
○ Something that evaluates to True or False
○ Typically shown with relational operator and/or boolean operator
■ Weather == “rainy”
■ x>=2
● Boolean operators
○ Not, and, or
○ Can be used to express more with booleans
■ It is not rainy: weather != “rain
■ It is not rainy: not (weather!= “rain”)
■ It is rainy and it is cold: (weather == “rain”) and (temperature == “cold”)
● Both statements need to be true for statement to be True
■ It is rainy or it is snowy: (weather == “rain”) or (weather == “snow”)
● Only one has to be true for it to be True
○ Not
■ Not inverts the value of boolean

B (normal boolean like temp == Not b
rain

True False

False True
● Weather = “rainy”
○ Weather == rainy
■ True if b
○ Not (weather == rainy)
■ False
○ And
■ Booleans combined with and evaluate to True if and only if both booleans
are True

a b a and b

T T T

T F F

F T F

F F F
○ And
■ Booleans combined with or evaluate to True if at least one is True

a b a or b

T T F

T F T
F T T

F F F
○ Ordering
■ P
■ E
■ MD
■ A
■ S
■ Not
■ And
■ Or

LS05 - Conditionals
● Conditional statement card example
○ If current card < low card, make it the low card
● Conditional statements
○ If <something>:
○ <do something>
○ <rest of program>
● Can also add an else statement
○ If <something>:
○ <do something>
○ else:
○ <do something else>
○ <rest of program>



○ Line 1 → docstring note to self what program is doing
○ Line 3 → user input function, evaluates user input as a string, user will input a
number but whatever the input is it will be interpreted as a string, string with 5
inside the string
○ Line 4 → print the type of the user input
○ Line 5 → make user number, call it an integer, now changes value into an integer
○ Line 6 → will print out the type of user number, which will be an integer
■ User input is a string, user number will be an int
○ Line 8 → use hashtags to make a comment to yourself, NOT a line of code
○ Line 9 → the beginning of our conditional, if user number is less than 10
○ Line 10 → if it’s less than 10, print the word small
○ Line 11 → else function, if the user number is greater than or equal to 10
■ Basically if line 9 isnt true than do this
○ Line 12 →if the user number is less than or equal to 10, print the word big
○ Line 14 → print back the user input/number given


○ Code is same as above except lines 9-12
○ We are trying to see if it is even or odd, so we must use remainder function (%)
○ Line 9 → if the user number has a remainder of 0, it will be even
○ Line 10→ if user number has 0 remainder, print even
○ Line 11 → if the user number has a remainder of 1, it will be odd
○ Line 12→ if user number has 1 remainder, print odd

LS04 - Variables and Input User


● """Demonstrates asking the user for input"""


● user_name: str = input("What is your name? ")

● print("Hello, " + user_name + ", good morning!")

● print("You are the best programmer ever," + user_name)

● Basically storing a username so you dont type it twice


● The generic format of a variable declaration and initialization statement is the following:
A: B = C
○ A = The name of the variable being declared
○ B= The data type of the variable being declared
○ C= The initial value of the variable being declared

LS03 - Expressions
● There are two big ideas behind expressions:
○ Every expression evaluates to a typed value at runtime
■ Every expression evaluates to a specific, concrete type
■ The evaluation of an expression only occurs when the program is running
or when you ask the interactive Python interpreter to evaluate it
○ Anywhere you can write an expression, you can substitute any other expression
of the same type and still have a validly typed program (though it may have
bugs!)
● Literal Expressions
○ When a literal expression is evaluated, it results in an object guided by what was
literally written in code
○ constant values expressed directly in code by providing a concrete, hardcoded
number or string value
● Operator Expressions
○ operators are special symbols, combinations of symbols, or keywords that
designate some type of computation
■ Addition, mult, etc
● Numerical operators
○ Addition, subs, etc
○ Doing a computation with numbers
● Relational operators
○ The evaluation of relational operators always results in a bool value.
○ For example, if you visit a website regarding alcoholic beverages, you will be
asked for your date of birth. The website needs to compare your age with 21 in
order to determine whether to let you into the website, or not. This kind of
comparison tests a relationship, “true or false: 18 is greater than or equal to 21?”
False!
○ True, false, greater than, equal to, etc
● Variable Access
○ A variable access will evaluate to the last value bound to the variable’s name.
○ Basically just writing a line of what x, for example, is equal to then swapping x in
later lines


● Constructor Expressions for Type Conversions
○ For types of data that do not have built-in literal syntax, meaning types other than
str, int, and so on, you need a way to construct a new object of that type. Each
type is defined by a class that has a constructor. By convention, the name of the
constructor is the same as the class.
○ Although types such as str and int have literal syntax, they also have constructor
functions. Each of the primitive types’ constructor functions can be used to
convert a value from another type to it. This is best explored through following
along:

○ Notice the names, or identifiers, int and str are defined as classes which you can
think of as classifications of a type of data. Each class has a constructor we can
make use of as shown. In the example of int("110"), notice the int constructor
function is able to take in a str and evaluate to an int object. Similarly with the str
constructor, notice we gave it an integer and it evaluated to a str. Often you will
have data in one type and need to convert it to another type for a different
purpose and, in Python, this is how you can.
○ When a constructor call expression evaluates, it always evaluates to the type of
the object it created (and thus it’s name!). So str(123) evaluates to a str typed
object.
● Function Call Expressions
○ Programs tend to be broken down into smaller “subprograms” called functions.
○ A function can often be thought of as a procedure, or a named algorithm, which
you can use to carry out some complex operation more simply.


■ In the first examples, the built in round function rounded a float up or
down based on common rounding rules.
■ Next we imported a function named randint from the random package.
■ many functions and types are organized into their own packages to keep
related concepts separate from unrelated concepts. In this case, the
randint function took two inputs in the form of two int values, and when
the randint function evaluated it returned a random int value between
those two numbers.
● Method call expressions
○ Some types of objects have built-in capabilities called methods.


○ Each of the expressions you wrote that involved a str, or variable access that
evaluated to a str, followed by a . and then what looks similar to a function call
was a method call expression. As another foreshadowing, the use of a str
variable named msg was included.
● Summary
○ types are fundamentally important to the practice of programming. All of the data
your programs will process, which you can think of as objects in your computer’s
memory, have a specific type. That type is important because it guides the kinds
of expressions you can form and thus the steps of computation you can carry out.
[Link]

LS02 - Objects + Data Types


● Expressions
○ Something that evaluates at runtime
○ Every expression evaluates to a specific typed value
○ Examples
■ 1+2*3
■ 1
■ 1.0 * 2.0
■ “Hello” + “World!”
■ 1>3
● Numerical Operators
○ Addition (+)
■ If numerical objects, adds the values together
● 1+1→2
■ If strings, concatenate them
● “Comp” + “110” → “Comp 110”
■ The result type depends on the operands
● Float + float → float
● Int + int → int
● Float + int → float
● int + float → float
● str + str → str
○ Subtraction/Negation (-)
■ Meant strictly for numerical types
● 3-2→1
● 4.0 - 2.0 → 2.0
● 4.0 - 2 → 2.0
● - (1 + 1) → -2
■ The result type depends on the operands
● float - float → float
● int - int → int
● float - int → float
● int - float → float
○ Multiplication (*)
■ If numerical objects, multiply the values
● 1*1→1
● 1.0 * 2.0 → 2.0
■ If string and int, repeat the string
● “Hello” * 3 → “HelloHelloHello”
■ The result type depends on the operands
● float * float → float
● int * int → int
● float * int → float
● int * float → float
● str + int → str
○ Division (/)
■ Meant strictly for numerical types
● 3 / 2 → 1.5
● 4.0 / 2.0 → 2.0
● 4 / 2 → 2.0
■ Division results in a float
● float / float → float
● int / int → float
● float / int → float
● int / float → float
○ Integer Division (//)
■ Division resulting in an integer
■ 7//5 → 1
○ Exponentiation (**)
■ Meant strictly for numerical types
● 2 ** 2 → 4
● 2.0 ** 2.0 → 4.0
■ The result type depends on the operands
● float ** float → float
● int ** int → int
● float ** int → float
● int ** float → float
○ Remainder “modulo”
■ Calculates the remainder when you divide two numbers
■ Meant strictly for numerical types
● 5%2→1
● 6%3→0
■ The result type depends on the operands
● int % int → int
● float % float → float
● float % int → float
● int % float → float
● Note:
○ If x is even, x % 2 → 0
○ If x is odd, x % 2 → 1
● Order of operations
○ P () E ** MD * / % AS + - Tie? Evaluate Left to Right
● Relational Operators

Operator Name Symbol

Equal? ==
Less than? <

Greater than? >

Less than or equal to? (At most) <=

Greater than or equal to? (At least) >=

Not equal? !=

○ Always result in a bool (True or False)
○ Equals (==) and Not Equal (!=)
■ Can be used for all primitive types we’ve learned so far! (bool, int, float,
str)
○ Every other type
■ Just use on floats and ints
■ (Can technically use on all primitive types)
● Example
○ 220>= int((“1”+”1”+”0”)*2)
■ 220>= int(“11”+ “0”)*2)
■ 220>= int(“110”*2)
■ 220>= int(“110110”)
■ 220>= 110110
● FALSE
○ 7%2=1
○ 8%4=0
○ 7%4=3
○ 2+4/2*2
■ 2+2.0*2
■ 2+4.0
■ 6.0
● Variables
○ Declaration of a variable
■ <name>: <type> = <value>
■ students: int = 300
■ message: str = “Howdy!”
○ Update a variable
■ <name> = <new value>
■ students = 325
■ message = “See ya!”

Notes 1/12
● Objects and types
○ Typed unit of data in memory
○ The object’s type ifies it to help the computer know how it should be interpreted
and represented.
● Numerical Built-In Types
○ Integers
■ Int
■ Zero or non-zero digit followed by zero or more integers (e.g. 100 is an int
but 0100 is not)
■ Integers are useful for counting
○ Decimals (Or floats)
■ Float
■ Not the only way to represent decimal numbers, but a very precise way
■ use float for numbers with decimal points
● Textual Built in Type
○ Strings
■ Str
■ A sequence (or string) of characters
■ Can be denoted using “ ”
● Indexing
○ Your way of counting
○ Subscription syntax uses square brackets and allows you to access an item in a
sequence
○ Index numbering starts from 0
■ “12345”[0] → 1
● Docstrings
○ A string written at the top of every file to describe its purpose
○ Denoted with three quotations “““ ”””
● Booleans
○ Bool
○ Evaluates to True or False
● Check an Object’s Type
○ type()
● Change an Object’s Type
○ float()
○ str()
○ int()
Notes 1/12
● Computational Thinking
○ Strategic thought and problem-solving
○ Can help perform a task better, faster, cheaper, etc.
○ Examples:
■ Meal prepping
■ Making your class schedule
■ “Life Hacks
● Algorithms
○ Input is data given to an algorithm
○ An algorithm is a series of steps
○ An algorithm returns some result
○ An algorithm may be influenced by its environment and it may produce
side-effects which influence its environment.
■ Example: planning walk to class
● Input: what the weather is, what the conditions are
● Algorithm: planning out outfit that matches
○ What is an algorithm
■ A set of steps to solve a general problem
■ Finite
■ Can handle a problem of arbitrary size
● Pseudocode
○ Looks like code, but simplified and readable
○ Not meant to run on a computer
○ Helps you outline what your algorithm is going to look like
○ You should be able to expand on your pseudocode to help you write actual code!
○ Pseudocode for cards
■ lowest_card = first card in deck Repeatedly until end of deck: if
current_card < lowest_card: lowest_card = current_card
● Pseudocode
○ simple and readable version of algorithm that resembles code
● Assignment Operator
○ Assigns a variable some value
● Relational Operator
○ Compares two values
● Conditional Statement
○ A statement that only performs an action under certain conditions
● Loop Statement
○ repeat a portion of code a set number of times until the desired process is
complete
● Conditional
○ expressions that evaluate to either true or false
● Function
○ a block of organized, reusable code that is used to perform a single, related action
● Always command S to execute python functions

You might also like