""" Authors: Peter Mawhorter Consulted: Date: 2021-10-28 Purpose: CS 111 files lab exercises SOLUTION """ def showTop(filename): """ Given a filename, prints out the top 3 lines in that file. """ with open(filename, 'r') as fin: top3 = fin.readlines()[:3] # slice first 3 for line in top3: print(line[:-1]) # trim off the newline at the end to avoid blanks def showBottom(filename): """ Given a filename, prints out the bottom 3 lines in that file. """ with open(filename, 'r') as fin: bot3 = fin.readlines()[-3:] # slice last 3 for line in bot3: print(line[:-1]) # trims the newline at the end def listLines(filename): """ Given a filename, print each line of that file, preceded by a line number and a space. Line numbers start from 1. """ with open(filename, 'r') as fin: counter = 1 for line in fin: print(counter, line, end='') # this "end=''" part means that we don't add the usual extra # newline, since line itself already contains a newline. counter += 1 def copyFile(fromFile, toFile): """ Given two filenames, reads the first file, then opens the second file and writes a copy of the first file there. """ with open(fromFile, 'r') as fin: data = fin.read() with open(toFile, 'w') as fout: fout.write(data) def writeReport(data, filename): """ Given a list of tuples containing strings paired with numbers, writes each entry to the given file on a separate line, with a colon and a space between the parts of the tuple. """ with open(filename, 'w') as fout: # Multiple loop variables pull apart the tuple automatically for name, num in data: # A format string makes it easy to create our output fout.write(f"{name}: {num}") def readReport(filename): """ Reads data in the same format written by writeReport, returning a list of tuples containing strings and (floating-point) numbers. """ result = [] with open(filename, 'r') as fin: for line in fin: # Split where the ': ' is, removing it in the process name, numstr = line.split(": ") # Convert number to a float num = float(numstr) # Append to our result. # Note that the inner parentheses create a tuple result.append((name, num)) return result def fractionalHours(hour, minute): """ Converts hour and minute integers into a fractional hours number. So for example, 15 hours and 30 minutes would become 15.5. """ fraction = minute / 60 return hour + fraction def hourMinuteString(hours): """ Converts a number of fractional hours into a string representing hours and minutes, with a colon between them. Rounds to the nearest minute. """ hour = int(hours) minutes = round((hours - hour) * 60) # Deal with special cases if minutes == 60: # rounding up to 60 means we need to add an hour hour += 1 minutes = "00" else: minutes = str(minutes) if len(minutes) == 1: # a one-digit result needs an extra 0 minutes = '0' + minutes return f"{hour}:{minutes}" def swapFiles(fileA, fileB): """ Swaps the contents of two files. Have to be careful not to erase one before we've read both. """ # Read the first file with open(fileA, 'r') as fin: dataA = fin.read() # Read the second file with open(fileB, 'r') as fin: dataB = fin.read() # Write the first file with open(fileA, 'w') as fout: fout.write(dataB) # Write the second file with open(fileB, 'w') as fout: fout.write(dataA) def showCalendar(filename): """ Reads in a calendar file where each line specifies an event, with three comma-separated parts: a name, a start time (as hours:minutes) and a duration (as fractional hours). Prints each events, listing start and end times in hours:minutes (24-hour clock). """ with open(filename, 'r') as fin: for line in fin: name, start, duration = line.split(',') hours, minutes = start.split(':') # Convert to numbers hours = int(hours) minutes = int(minutes) # this works even with a leading zero duration = float(duration) # Convert to fractional hours and compute end startHours = fractionalHours(hours, minutes) endHours = startHours + duration # Convert to hour:minute strings and display startTime = hourMinuteString(startHours) endTime = hourMinuteString(endHours) print(f"{name} ({startTime}-{endTime})") def test(): """ Testing code for the functions above. """ # showTop('nums.txt') # showBottom('nums.txt') listLines('nums.txt')