Day 6: While and String Manipulation
CMSC 201: While and Strings
Agenda:
Goal: Get familiar with while loops and some string operations, maybe have some fun :)
My email is: sdonahue@umbc.edu (Shane Donahue), office hours Tu/Th ITE 373 2-3PM
HW3
HW3 questions? HW2 questions? HW1 is almost done being graded :)
Let's look at HW3! (due Sep 27 2024 at 11:59PM)First exam is week of October 7th (Oct 9th for M/W and Oct 10th for Tu/Th)! We will be taking it in this room during your section time. TAs will be here to proctor, I unfortunately will not be here :(
If you have SDS accomodations (e.g., extra time or reduced distractions), please book that room and let them know you plan to take the test there! The room here will be very quiet though, so there won't be many auditory distractions.
"Fun": ascii art programs
You may have seen me using programs to make fun animations (matrix animation, fishtank, bonsai tree). These are all called ASCII art! The same ASCII we were using to make a list of letters. Most aren't available on GL :(
You can make ASCII art! All you need is a text editor and a lot of free time.
Who cares (about while loops and string manipulations)?
Let's make a (very quick and very text based) turn based combat! Goal: while either HP is above 0, collect turns. Use a list to store moves.
Review: Multi-dimensional lists
You can nest for loops! This is helpful for instantiating multi-dimensional lists.
Challenge: Make a 2D (two dimensional) array with 8 rows and 8 columns.
board = []
for x in range(8):
new_list = []
for y in range(8):
new_list.append("")
board.append(new_list)
We want to write to every element in this 2D list. What's the difference between these programs? Which one works?
for i in board:
for j in i:
j = "X"
print("The board element is", j)
for i in range(len(board)):
for j in range(len(board[i])):
board[i][j] = "X"
print('The board at', i, j, 'is', board[i][j])
The top one is a for-each loop, using a copy of the list elements (pass by value), and the bottom one is a for loop, referencing the original lists. To do that, the bottom one needs the list indicies (indexes).
While loops
For loops are cool and all, if you have a list or iterator (like range
) to go through. But what if you want to test for a boolean condition?
While loops are the answer!
while input() != "y": print("please type y")
Challenge: Ask the user for a word that has "pizza" in it, until they give one. (While the word does not contain pizza, ask for input.)
user_input = ""
while "pizza" not in user_input:
user_input = input("Pizza please: ")
print("Nice pizza:", user_input)
Infinite loops
While loops can run forever :)
while True: print("forever and ", end="")
Press CTRL-c to interrupt it!
This is more dangerous than with for loops, because there is no finite list you can iterate through. (You can do an infinite loop with for lists if your list never ends, but that's less common than messing up a boolean value!)
Which one exits?
index = 100
while index < 1000:
print("decrementing", index)
index -= 1
index = 1500
while index > 1000:
print("decrementing", index)
index -= 1
Challenge: Calculate user input multipied by index until it is exactly 100.
index = 1
while index != 100:
user_num = float(input("Give number: "))
index = index * user_num
# index *= user_num
print("Index is", index)
print("Done!")
Loop that never execute
While loops can run, never :)
while False: print("never executed")
This is handy if you want a loop to execute only if some condition was false.
choice = input("What type of soup: ")
while "soup" not in choice:
choice = input("What type of soup?! ")
Sentinel Values
"Sentinel" values are values that cause a loop to quit.
SENTINEL = "DONE"
new_num = input("Enter an integer, 'DONE' to exit: ")
integer_list = []
while new_num != SENTINEL:
integer_list.append(int(new_num))
print("Added", new_num)
new_num = input("Enter an integer: "")
Magic values and constants
"Magic" values or "magic numbers": random numbers in your code that have no meaning
days = int(input("How many days since you last washed your car: "))
next_wash = (days / 44) * 127 # <-- WHAT ARE THESE NUMBERS?
print("Your next wash will be in", next_wash, "days")
If you have a number that will never change, you should label it, using all caps so people know it's a CONSTANT.
AVERAGE_WASH_DAYS = 127
DAY_COMPRESSION_FACTOR = 44
days = int(input("How many days since you last washed your car: "))
next_wash = (days / DAY_COMPRESSION_FACTOR) * AVERAGE_WASH_DAYS # <-- much more clear, at least
print("Your next wash will be in", next_wash, "days")
While we call these constants, they are just variables. You can still modify them, but you never should.
Some Strings
Semi-preview for next time: strings! Methods that operate on strings:
Challenge: Ask for a comma-delimited list of the places that make up the DMV. Keep asking until they get them all. When they do, print them all back.
Turn-based battle
Let's make knock-off pokemon! Two entities, keep going until one has zero HP. Choose moves from list with string input.
# initial variables, names, hp, movelist
PK_1 = "pikachu"
PK_1_MOVES = ["thunderbolt", "surf"]
PK_1_DAMAGES = [9, 8]
PK_2 = "magikarp"
PK_2_MOVES = ["splash", "celebrate"]
PK_2_DAMAGES = [4, 1]
pk_1_hp = 16
pk_2_hp = 24
MOVE_NOT_FOUND = -1
print("Dododododod... battle commence!", PK_1, "versus", PK_2)
# while loop --> player1 moves, player2 moves, etc
while pk_2_hp > 0 and pk_1_hp > 0:
print("======================")
print(PK_1, "turn!", "hp:", pk_1_hp, "and knows moves", PK_1_MOVES)
pk_1_choice = input("What move? ")
# Select index and compare value
choice_index = MOVE_NOT_FOUND
index = 0
for x in PK_1_MOVES:
if x == pk_1_choice.strip():
choice_index = index
index += 1
if choice_index > MOVE_NOT_FOUND:
print("Wow,", PK_1, "used", PK_1_MOVES[choice_index] + "!")
pk_2_hp -= PK_1_DAMAGES[choice_index]
else:
print(PK_1, "does not know", pk_1_choice)
if pk_2_hp >= 0:
print(PK_2, "turn!", "hp:", pk_2_hp, " and knows moves", PK_2_MOVES)
pk_2_choice = input("What move? ")
choice_index = MOVE_NOT_FOUND
index = 0
for x in PK_2_MOVES:
if x == pk_2_choice.strip():
choice_index = index
index += 1
if choice_index > MOVE_NOT_FOUND:
print("Wow,", PK_2, "used", PK_2_MOVES[choice_index] + "!")
pk_1_hp -= PK_2_DAMAGES[choice_index]
else:
print(PK_2, "does not know", pk_2_choice)
if pk_1_hp <= 0:
print(PK_1, "fainted!")
else:
print(PK_2, "fainted!")