# Lab 09. Nested loop practice
# Task 1A.
def printCalendarDays(monthLengthsList):
"""Prints a vertical calendar, given a list of month lengths."""
for index in range(len(monthLengthsList)):
monthLength = monthLengthsList[index]
print()
print('Month is', (index + 1))
for day in range(1,monthLength + 1):
print(day)
# Extra 2
def printCalendarWeeks(monthLengthsList):
"""
Prints a calendar with each (7-day) week on a row, given a list of
the lengths of each month.
"""
for index in range(len(monthLengthsList)):
monthNum = index + 1
monthLength = monthLengthsList[index]
print()
print ('Month is', monthNum)
weekCounter = 0 # keeps track of each week
for day in range(1, monthLength + 1):
if weekCounter == 7:
# hit the end of the week
print() # next week starts on new line
weekCounter = 0 # re-initialize counter back to 0
printSpacedNumber(day, 2)
weekCounter += 1
print()
# Optional Task 5D
def printCalendarFancy(monthLengthsList, startColumn):
"""
Given a list of the length of each month, prints a calendar where
days are grouped into 7-day weeks, and horizontal placement is
maintained across months when a month doesn't line up with the end of
a 7-day week. The first day of the first week starts in the given
starting column (numbered from 0), and each day is printed to take up
2 spaces, so the numbers align into columns.
"""
weekCounter = startColumn # this counter is now across months
for index in range(len(monthLengthsList)):
monthNum = index + 1
monthLength = monthLengthsList[index]
print()
print ('Month is', monthNum)
# Print spaces at the start of the new month
print(weekCounter * ' ', end='')
for day in range(1, monthLength + 1):
if weekCounter == 7:
# hit the end of the week
print() # next week starts on new line
weekCounter = 0 # re-initialize counter back to 0
# Add a space before the date number if we need to:
if len(str(day)) == 1:
dayStr = ' ' + str(day)
else:
dayStr = str(day)
# Print the day number with a trailing space, and increment
# the week counter:
printSpacedNumber(day, 2)
weekCounter += 1
print()
# Task 2A
def triangle(height):
"""Draws a left-aligned triangle of asterisks, small to large"""
for row in range(1,height+1):
for col in range(1,row+1):
print ('*', end=" ")
print()
# Task 2B
def triangleWithNumbers(height):
"""Draws a left-aligned triangle of numbers, each num indicating the row"""
for row in range(1,height+1):
width = height - (row - 1)
for col in range(1,width+1):
print (col, end=" ") # changed '*' to col
print()
# Task 2C
def invertedTriangleWithNumbers(height):
"""Draws a left-aligned triangle of numbers, large to small"""
for row in range(height,0,-1): # range with three args (start, stop, step)
for col in range(1,row+1):
print(col, end=" ")
print()
def invertedTriangleWithNumbersAlt(height):
"""Another solution using a clever range"""
for row in range(height,0,-1): # range with three args (start, stop, step)
for col in range(1,row+1):
print(col, end=" ")
print()
# Task 3A Grid Sum
def gridSum(grid):
"""
listOfLsits should be a list of lists containing numbers. This
function returns the sum of all of the numbers in each row (i.e., the
sum of the entire grid).
"""
result = 0
for row in grid:
# Each row is itself a list of numbers
for number in row:
result += number
return result
# Task 3B Coverage
def gridNoZeroes(grid):
"""
Returns True if the grid has no zeroes in it.
"""
for row in grid:
for number in row:
if number == 0:
return False # we found a zero, we can return immediately
# We survived the entire loop without finding a zero, so there must
# not be any in the whole grid!
return True
# Task 3B Max Cell
def maxCell(grid):
"""
Returns the row, column coordinates of the cell in the grid with the
largest value, as a pair of numbers. Both row and column are counted
starting from 0, not 1. If there are multiple cells tied for largest,
this implementation returns the coordinates of the first such cell in
top-to-bottom left-to-right order.
"""
# First find the maximum value of the whole grid:
gridMax = None
for row in grid:
for num in row:
# Update our max if we didn't have one or if this num is greater
if gridMax == None or num > gridMax:
gridMax = num
# Next look through the grid until we find an entry that equals the
# max, and return the coordinates of that entry:
for r in range(len(grid)):
for c in range(len(row)):
# We index twice here, using row and column indices
if grid[r][c] == gridMax:
return (r, c)
# The loop above should always be able to find a max value!
print("ARGGHH. THIS SHOULDN'T BE POSSIBLE!")
def maxCellAlt(grid):
"""
An alternate implementation of maxCell that only uses a single nested
loop instead of a nested loop plus a follow-up loop.
"""
maxSoFar = None
bestCoords = None
for r in range(len(grid)):
# We iterate using numerical indices ('r' for row index),
# but immediately make a 'row' variable that holds the same value
# we'd get if our loop was `for row in grid`:
row = grid[r]
for c in range(len(row)):
# Likewise, we iterate by indices but grab the value
# immediately, as if we were doing `for num in row`:
num = row[c]
# If we didn't have a max yet, or if we did and this number
# is greater than that max, we'll update our max and record
# these coordinates as the best ones.
if maxSoFar == None or num > maxSoFar:
maxSoFar = num
bestCoords = (r, c)
# After the entire loop, bestCoords should hold the coordinate of a
# cell that's at least tied for maximum value.
return bestCoords
# Task 4
def flatten(nestedList):
"""
Flattens a nested list into one simple list, using nested loops.
Returns a new list (does not modify the original list).
"""
result = []
for inner in nestedList:
for element in inner:
result.append(element)
return result
# Task 5A
def printSpacedNumberSimple(n):
"""
Simplified printSpacedNumber that only works for 2-digit numbers.
"""
strN = str(n)
if len(strN) == 1:
print(' ' + strN, end=' ')
else:
print(strN, end=' ')
def printSpacedNumber(n, width):
"""
Prints a number (n) using extra spaces to make sure it has the given
width. Extra spaces are added on the left. No newline is printed, but
one extra space (beyond the given width) is added at the end of the
printed output.
"""
strN = str(n)
aligned = ' '*(width - len(strN)) + strN
print(aligned, end=' ') # adds an extra space afterward
def multTableSpaced(rows, cols):
"""
Prints a multiplication table, with alignment of numbers using spaces
up to the width of the largest number in the table.
"""
largestResult = rows * cols
spacing = len(str(largestResult))
for row in range(rows):
rowN = row + 1 # the number we'll be multiplying
for col in range(cols):
colN = col + 1 # the number we'll be multiplying
printSpacedNumber(rowN * colN, spacing)
print()