This task is part of project03 which is due at 23:00 EDT on 2024-09-24.
You have the option to work with a partner on this task if you wish. Working with a partner requires more work to coordinate schedules, but if you work together and make sure that you are both understanding the code you write, you will make progress faster and learn more.
You can download the starter code for this task using this link.
You can submit this task using this link.
Put all of your work for this task into the file
timeProfiler.py
(you will create this file from scratch)
Armed with Python knowledge from your first two problem sets, you've decided to form a software startup that provides your fellow students with useful programs.
Since time is important to all Wellesley students, you've decided your first program should be a time profiler that helps students calculate how they spend their time during a typical week. The program will ask the user to enter a few pieces of information, and then will display a few calculations about the time spent on various things every week:
When you call your timeProfile
function, it should prompt the user to
enter information about these activities and display a time profile. We
have provided three example
executions of the time profiling program that
show how your program should behave, and the test_timeProfiler.py
starter file can automatically report whether your output is correct, or
if not, where the first difference was detected. In each run, text in
black is displayed by the program, while text highlighted in blue is entered by the user.
Note that in the example output, each number of hours has been rounded to two decimal places (in some cases Python only shows one because the second is a zero).
Also note that your program should ask the user for the name of the category used to describe the 'everything else' category, and then use that name in the remainder of the program. In the examples below, Latanya chose to use the name 'organizing', Alex chose to use the label 'extracurricular', and Yuting chose to use the name 'fun'. The user of the program gets to decide which name to use to describe that category, and your program incorporates that name into the profile.
In this task, you will write a time profiling Python program timeProfiler.py
from scratch in Thonny that has the behavior indicated by the sample executions
above. You are also required to define several supporting functions and
use them within the timeProfile
function.
Your goal is to create a timeProfiler.py
program that behaves
exactly as indicated by the sample executions
provided, and works reasonably on other sample
inputs that might be used to test it.
It's possible to write all of your code inside a single timeProfile
function and match the example outputs we provided. But such a program
would not be elegant, because lots of code would need to be repeated.
Instead, you must define each of the following functions individually,
and then use them together to write timeProfile
.
inputFloat
You will notice that one task performed repeatedly in the examples is to
ask the user for some kind of number. However, as you may remember,
Python's built-in input
function always returns what the user types as
a string, and if we want a number, it must be converted. Since this
pattern of asking for input and converting it to a (floating point)
number happens several times, you must write a function to do that,
called inputFloat
. inputFloat
must
accept 1 argument to determine the prompt, and then must call
input
using that prompt to
retrieve a string from the user. Then it must convert that to a
floating-point number using
float
and return the
resulting number. These inputFloat
examples demonstrate how it should work.
formatHours
If you study the example output you will see that
when displaying information about the time spent on different activities,
there is a standard format used: a number of hours, rounded to two
decimal places, followed by a label like "work hours." As part of the
approach to indenting these messages, you must write a formatHours
function which has two parameters: a
number of hours (as a floating-point number) and a label (as a string).
As shown in these formatHours
examples, the
function must return a string
containing the number rounded to two decimal
places, plus the label,
separated by a single space.
By returning a string, this function will enable other code to call it and store the result in a variable, which will then enable things like measuring the length of that variable.
indentMessage
To get the indentation of the last four lines of output correct, so that
all of the bars line up and can be compared, you must define an
indentMessage
function which takes 2
parameters: a message string, and a
target length (an integer). This function will add spaces to the
left-hand side of the message it is given, returning a new message whose
length (including spaces) is equal to the target
length. If the message length
already meets or exceeds the target length, zero spaces will be added and
the message will be returned as-is.
In timeProfile
you will be able to line things up correctly by:
1. First computing a target length equal to the length of longest of your
five messages.
2. Then calling indentMessage
with that target length on each message
to create indented messages whose lengths are the same.
These indentMessage
examples demonstrate how
it must work.
createBar
The last component of the output that we need to assemble is the bars of
characters which appear after the colons. Because these bars can only
have a whole number of letters in them, we will need to round the amount
of time to the nearest integer using the round
function before using the *
operator to repeat the desired letter. Since this process needs to happen
once for each bar, you must create a createBar
function which takes
two parameters: a letter to repeat and
a length value (as a floating-point number). It must round off the
length value and then return a string consisting of that many copies of
the letter it was given. These
createBar
examples demonstrate how it must work.
timeProfile
Once you've defined all of the other required functions, you are ready to
define timeProfile
itself. It
will not take any arguments, and must call each of your other functions.
To ensure that you are not repeating work done by those other functions,
timeProfile
must call input
exactly
twice and it must NOT call
round
or
float
itself (the
formatHours
and createBar
functions will handle all of the necessary
rounding, and inputFloat
will handle type conversion).
It must read inputs from the user and then print out a time profile
showing how many hours per week are spent on various tasks, with bars of
repeated letters allowing a visual comparison of these
values. These timeProfile
examples show how it should work.
timeProfile
It's good practice to try to figure out timeProfile
without consulting
these hints, but if you're stuck on how to put things together, here are
some hints:
These are the general steps that timeProfile
will use:
input
and inputFloat
. Make sure you
ask the questions in exactly the order specified, or our automatic
tests won't work. You'll need to store the inputs that you gather
into variables.formatHours
function to build a message string for each
category. After you build these messages, you can measure their
lengths.max
, and then use that number and the
indentMessage
function to create indented message variables.createBar
, and finally put the bars together
with the indented messages and print them out.You may assume that inputs are sensible, and the behavior of your program for nonsensical inputs is unspecified. This means that your program can do anything if an input is nonsensical and still be considered correct. For example, if the number of classes specified is negative, the program could fail with an error message immediately, it could fail after reading in other inputs, it could fail after printing the first line of the output display, or it could even work correctly taking that into account, but all of these would be considered "correct" behavior, because we do not expect the number of classes taken to be negative.
Here are inputs that are sensible:
"work"
,
"sleep"
, "class"
, or "free"
). We've provided a test_timeProfile
file which has tests for each
individual helper function as well as tests of timeProfile
itself.
These tests will be skipped if you haven't yet defined one of the
functions, so you can (and should) run this file each time you finish one
of the required functions, and then fix any problems that it reports
before moving on to the next function.
While timeProfile
must call
print,
none
of
the
other required
functions may call print
. They must each be fruitful, returning
their results so that timeProfile
can actually use them.
Your program should not use any Python features that we have not
studied yet, including conditionals (i.e., if
statements) or
loops.
For a completely correct solution, things like spacing and the number of digits after a decimal point in a number are important. But you will receive most of the credit for solutions that are not exactly correct. In order to check whether your output is totally correct, see the section on testing above.
Make sure you double-check the rubric, including the procedure requirements and the style requirements. In particular, although the style requirements are extra goals, they represent principles which, if violated, often lead to incorrect code.
Also as usual, you must not waste fruit and you must not waste boxes.
inputFloat
Examples
These examples show how inputFloat should work.
In []:PrintsinputFloat('What is pie? ')
What is pie? 3.1415926Out[]:In []:3.1415926
PrintsinputFloat("What rhymes with 'heaven?' ")
What rhymes with 'heaven?' 7Out[]:In []:7.0
PrintsinputFloat("What's below one? ")
What's below one? 0.999Out[]:0.999
formatHours
Examples
These examples show how formatHours should work.
In []:Out[]:formatHours(10.0, 'work hours')
In []:'10.0 work hours'
Out[]:formatHours(1.111, 'fun hours')
In []:'1.11 fun hours'
Out[]:formatHours(9.999, 'free hours')
'10.0 free hours'
indentMessage
Examples
These examples show how indentMessage should work.
In []:Out[]:indentMessage('hello', 7)
In []:' hello'
Out[]:indentMessage('hello', 5)
In []:'hello'
Out[]:indentMessage('hi', 5)
' hi'
createBar
Examples
These examples show how createBar should work.
In []:Out[]:createBar('A', 7)
In []:'AAAAAAA'
Out[]:createBar('B', 2.111)
In []:'BB'
Out[]:createBar('C', 4.999)
'CCCCC'
timeProfile
Examples
These examples show how timeProfile should work.
In []:PrintstimeProfile()
What is your name? Latanya How many hours do you work each week? 5 How many hours per day do you sleep on average? 6.55 How many classes are you taking this semester? 4 For one class, what is the average time spent in the classroom per week? 3.2 What shall we call the 'everything else' category? organizing How many hours per week do you spend on 'organizing'? 24 Weekly time profile for Latanya: 5.0 work hours: WWWWW 45.85 sleep hours: SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS 38.4 class hours: CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 24.0 organizing hours: EEEEEEEEEEEEEEEEEEEEEEEE 54.75 free hours: FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFIn []:PrintstimeProfile()
What is your name? Alex How many hours do you work each week? 8.5 How many hours per day do you sleep on average? 6.75 How many classes are you taking this semester? 4 For one class, what is the average time spent in the classroom per week? 3.67 What shall we call the 'everything else' category? extracurricular How many hours per week do you spend on 'extracurricular'? 22.5 Weekly time profile for Alex: 8.5 work hours: WWWWWWWW 47.25 sleep hours: SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS 44.04 class hours: CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 22.5 extracurricular hours: EEEEEEEEEEEEEEEEEEEEEE 45.71 free hours: FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFIn []:PrintstimeProfile()
What is your name? Yuting How many hours do you work each week? 0 How many hours per day do you sleep on average? 8 How many classes are you taking this semester? 5 For one class, what is the average time spent in the classroom per week? 2.5 What shall we call the 'everything else' category? fun How many hours per week do you spend on 'fun'? 15 Weekly time profile for Yuting: 0.0 work hours: 56.0 sleep hours: SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS 37.5 class hours: CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 15.0 fun hours: EEEEEEEEEEEEEEE 59.5 free hours: FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
=
or by defining a parameter for a function) you must also later use that variable as part of another expression. If you need to create a variable that you won't use, it must have the name _
, but you should only do this if absolutely necessary.inputFloat
must return the correct result
inputFloat
function is run must match the solution result.formatHours
must return the correct result
formatHours
function is run must match the solution result.indentMessage
must return the correct result
indentMessage
function is run must match the solution result.createBar
must return the correct result
createBar
function is run must match the solution result.timeProfile
are approximately correct.
timeProfile
is run, given the example inputs for Latanya, Alex, and Yuting.timeProfile
which start with numbers closely match the correct output.inputFloat
must return the correct result
inputFloat
function is run must match the solution result.formatHours
must return the correct result
formatHours
function is run must match the solution result.indentMessage
must return the correct result
indentMessage
function is run must match the solution result.createBar
must return the correct result
createBar
function is run must match the solution result.timeProfile
is exactly correct (extra input)
timeProfile
code, given some new inputs. These inputs will obey the definition of 'sensible inputs' laid out in the instructions.inputFloat
with 1 parameter
def
to define inputFloat
with 1 parameterprint
inputFloat
with 1 parameter, do not call print
.inputFloat
with 1 parameter
def
to define inputFloat
with 1 parameterinput
inputFloat
with 1 parameter, call input
in exactly one place.float
inputFloat
with 1 parameter, call float
in at least one place.return
statement
inputFloat
with 1 parameter, use return _
in at least one place.formatHours
with 2 parameters
def
to define formatHours
with 2 parametersprint
formatHours
with 2 parameters, do not call print
.formatHours
with 2 parameters
def
to define formatHours
with 2 parametersround
formatHours
with 2 parameters, call round
in at least one place.return
statement
formatHours
with 2 parameters, use return _
in at least one place.indentMessage
with 2 parameters
def
to define indentMessage
with 2 parametersprint
indentMessage
with 2 parameters, do not call print
.indentMessage
with 2 parameters
def
to define indentMessage
with 2 parameterslen
indentMessage
with 2 parameters, call len
in at least one place.return
statement
indentMessage
with 2 parameters, use return _
in at least one place.createBar
with 2 parameters
def
to define createBar
with 2 parametersprint
createBar
with 2 parameters, do not call print
.createBar
with 2 parameters
def
to define createBar
with 2 parametersround
createBar
with 2 parameters, call round
in at least one place.return
statement
createBar
with 2 parameters, use return _
in at least one place.timeProfile
with 0 parameters
def
to define timeProfile
with 0 parametersround
timeProfile
with 0 parameters, do not call round
.float
timeProfile
with 0 parameters, do not call float
.timeProfile
with 0 parameters
def
to define timeProfile
with 0 parametersinput
timeProfile
with 0 parameters, call input
in exactly 2 places.inputFloat
timeProfile
with 0 parameters, call inputFloat
in exactly 5 places.formatHours
timeProfile
with 0 parameters, call formatHours
in at least one place.indentMessage
timeProfile
with 0 parameters, call indentMessage
in at least one place.createBar
timeProfile
with 0 parameters, call createBar
in at least one place.print
timeProfile
with 0 parameters, call print
in at least one place.if
statement (possibly accompanied by an elif
or else
block).