Skip to content

Latest commit

 

History

History
584 lines (484 loc) · 10.2 KB

lecture2.md

File metadata and controls

584 lines (484 loc) · 10.2 KB

CS50P W2 - Loops

While Loops

While the condition is true the loop keeps iterating. The only way to break the loop is for the condition to return false. If the condition stays true, the loop will be infinite:

i = 3
while i != 0:
    print("meow")

Use cmd + c to break out of a infinite loop


i = 3
while i != 0:
    print("meow")
    i = i - 1

i = 1
while i <= 3:
    print("meow")
    i = i + 1

i = 0
while i < 3:
    print("meow")
    i += 1		# i += 1 == i = i + 1

water.py

from soil import sample

def main():
    moisture = sample()
    print(f"Moisture is {moisture}%")

    while moisture > 20:
        moisture = sample()
        print(f"Moisture is {moisture}%")

    print("Time to water!")

main()

While moisture is more than 20% (condition is True), keep sampling the soil. When the condition becomes False (moisture less or equal to 20%), break the loop and print “Time to water!”.


def main():
    moisture = sample()
    days = 0
    print(f"Moisture is {moisture}%")

    while moisture > 20:
        moisture = sample()
        days += 1
        print(f"Day {days}: Moisture is {moisture}%")

    print("Time to water!")

While moisture is more than 20% (condition is True), keep sampling the soil and increase the day count by 1.


For Loops

A for loop iterates through a list of items. Python automatically initializes (to 0) and updates i

for i in [0, 1, 2]:
    print("meow")

for i in range(3):
    print("meow")

The range() built-in function takes one argument (the number of values you want back), starting at 0 up to (but not through) the specified value.


for _ in range(3):
    print("meow")

The "Pythonic" way is to represent i with an underscore _


print("meow" * 3)

This code will output meowmeowmeow


print("meow\n" * 3 end="")

Adding a \n after the string and removing the automatic one after the print will output :

meow
meow
meow

User Input

while True:
    n = int(input("What's n? "))
    if n < 0:
        continue
    else:
	    break

If the user enters a negative (< 0) number the loop keeps asking for input until entering a positive number breaks the loop.


while True:
    n = int(input("What's n? "))
    if n > 0:
        break

for _ in range(n):
    print("meow")

def main():
    meow(3)

def meow(n):
    for _ in range(n):
        print("meow")

main()

def main():
    number = get_number()
    meow(number)

def get_number():
    while True:
        n = int(input("What's n? "))
        if n > 0:
            break
    return n

def meow(n):
    for _ in range(n):
        print("meow")

main()

Lists

students = ["Hermione", "Harry", "Ron"]

print(students[0])
print(students[1])
print(students[2])
for student in students:
    	    print(student)
for i in range(len(students)):
    print(students[i])
for i in range(len(students)):
    print(i + 1, students[i])
1 Hermione
2  Harry
3 Ron

Append elements to a list

results = ["Mario", "Luigi"]

results.append("Princess")
results.append("Yoshi")
results.append("Koopa Troopa")
results.append("Toad")

print(results)

  1. Append multiple elements at a time
results.append(["Bowser", "Donkey Kong Jr."])

This will result in a separate sublist within the original list. The extend() method is better suited to append multiple elements to the list

results.remove(["Bowser", "Donkey Kong Jr."])
results.extend(["Bowser", "Donkey Kong Jr."])

Remove elements from a list

results = ["Mario", "Luigi", "Princess", "Yoshi", "Koopa Troopa",
    "Toad", "Bowser", "Donkey Kong Jr."
]

results.remove("Bowser")

Insert elements into a list in a specific index insert(index, element)

results = ["Mario", "Luigi", "Princess", "Yoshi", "Koopa Troopa",
    "Toad", "Donkey Kong Jr."
]

results.insert(0,"Bowser")

Reverse order of the elements of a list

results = ["Mario", "Luigi", "Princess", "Yoshi", "Koopa Troopa",
    "Toad", “Bowser”, "Donkey Kong Jr."
]

results.reverse()

Output:

["Donkey Kong Jr.", “Bowser”,"Toad", "Koopa Troopa",
"Yoshi", "Princess", "Luigi", "Mario"
]

Dictionaries

Data structure that allows us to associate keys with values.

students = {
    "Hermione": "Gryffindor",
    "Harry": "Gryffindor",
    "Ron": "Gryffindor",
    "Draco": "Slytherin"}

print(students["Hermione"])

We use the key as an index to retrieve the value associated with it.


for student in students:
    print(student)

Printing the iterator student will print the keys in the list:

Hermione
Harry
Ron
Draco

for student in students:
    print(student, students[student])

Prints the keys student, and the values students[student]:

Hermione Gryffindor,
Harry Gryffindor
Ron Gryffindor
Draco Slytherin

for student in students:
    print(student, students[student], sep=",")

Prints the keys student, and the values students[student]:

Hermione, Gryffindor
Harry, Gryffindor
Ron, Gryffindor
Draco, Slytherin

report.py

def main():
    spacecraft = {"name": "Voyager 1", "distance": 163}
    print(create_report(spacecraft))

def create_report(spacecraft):
    return f"""
    ========= REPORT =========

    Name: {spacecraft["name"]}
    Distance: {spacecraft["distance"]} AU

    ==========================
    """

Notice the capabilities of the f-strings


Adding Keys

spacecraft = {"name": "Voyager 1", "distance": 163}

spacecraft["distance"] = 0.01 

We can add a key-value pair to a dictionary by indexing into the key and assigning a new value.


spacecraft = {"name": "james Webb Space Telescope"}

spacecraft.update({“distance”: 0.01, “orbit”: “Sun”}) 

Error Checking

def create_report(spacecraft):
    return f"""
    ========= REPORT =========

    Name: {spacecraft.get("name", "Unknown")}
    Distance: {spacecraft.get("distance", "Unknown")} AU
    Orbit:  {spacecraft.get("orbit", "Unknown")}

    ==========================
    """

get(key, default_value): spacecraft.get("distance", "Unknown") will try to access the value associated with the "distance" key, if no value is found, it will default to returning "Unknown"


distances.py

distances = {
    "Voyager 1": 163,
    "Voyager 2": 136,
    "Pioneer 10": 80,
    "New Horizons": 58,
    "Pioneer 11": 44
}

Accessing keys

def main():
    for name in distances.keys():
        print(f"{name} is {distances[name]} AU from Earth")

If the keys in the dictionary are different, we can use the keys() method to access each of those keys. Notice the use of an f-string and the distances[name]


Accessing values

def main():
    for name in distances.values():
        print(f"{name} is {distances[name]} AU from Earth")

Converting values (AU to meters)

def main():
    for distance in distances.values():
        print(f"{distance} AU is {convert(distance)} AU from Earth")

def convert(au):
    return au * 149597870700

Lists of Dictionaries

students = [
    {"name": "Hermione", "house": "Gryffindor", "patronus": "Otter"},
    {"name": "Harry", "house": "Gryffindor", "patronus": "Stag"},
    {"name": "Ron", "house": "Gryffindor", "patronus": "Jack Russell terrier"},
    {"name": "Draco", "house": "Slytherin", "patronus": None}
]

The keyword None means there is no value associated with the "patronus" key in the last dictionary.


for student in students:
    print(student["name"])

The iterator student now represents the dictionaries in the list. It prints the values associated with "name" key in each dictionary


for student in students:
    print(student["name"], student["house"], student["patronus"], sep=",")

Prints the values associated with the "name", "house", and "patronus" keys (separated by a comma) in each dictionary:

Hermione, Gryffindor, Otter
Harry, Gryffindor, Stag
Ron, Gryffindor, Jack Russell terrier
Draco, Slytherin, None

mario.py

def print_column(height):
    for _ in range(height):
        print("#")

def print_column(height):
    print("#\n" * height, end="")

def print_row(width):
    print("?" * width)

Nested loops

def print_square(size):
    for i in range(size):
	    for j in range(size):
        	print("#")
	    print()
def print_square(size):
	# For each row in square
    for i in range(size):
	    # For each brick in row
	    for j in range(size):
		    # Print brick
        	print("#")
	# Add new line at the end of the row
	print()

def print_square(size):
    for i in range(size):
    	print("#" * size)

def print_square(size):
    for i in range(size):
        print_row(size)

def print_row(width):
    print("#" * width)

Letters.py

def main():
    print(write_letter("Mario", "Princess Peach"))
    print(write_letter("Luigi", "Princess Peach"))
    print(write_letter("Daisy", "Princess Peach"))
    print(write_letter("Yoshi", "Princess Peach"))


def write_letter(receiver, sender):
    return f"""
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Dear {receiver},

    You are cordially invited to a ball at
    Peach's Castle this evening, 7:00 PM.

    Sincerely,
    {sender}
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    """

main()

  1. Create a list and loop through it (using i as an iterator)
def main():
    names = ["Mario", "Luigi", "Daisy", "Yoshi"]

    for i in range(len(names)):
        print(write_letter(names[i], "Princess Peach"))

  1. Pythonic simplified alternative syntax (using name as an iterator)
def main():
    names = ["Mario", "Luigi", "Daisy", "Yoshi"]
    for name in names:
        print(write_letter(names, "Princess Peach"))