1
\$\begingroup\$

Beginning of program assignment has a bug collector input the amount of bugs collected each day of the week then outputs the total number of bugs in a print statement. My professor has forbid us from using 'while true' and 'break'. Assignment requires the loop finishes only when the user inputs 'done' so I wrote an input statement asking the user to affirm, otherwise the code loops. Did I appropriately write the body of the loop?

def bug_collector():

    myInput = 0

    while myInput != 'done':

        Monday = int(input('How many bugs did you collect on Monday?: '))
        Tuesday = int(input('How many bugs did you collect on Tuesday?: '))
        Wednesday = int(input('How many bugs did you collect on Wednesday?: '))
        Thursday = int(input('How many bugs did you collect on Thursday?: '))
        Friday = int(input('How many bugs did you collect on Friday?: '))
        Saturday = int(input('How many bugs did you collect on Saturday?: '))
        Sunday = int(input('How many bugs did you collect on Sunday?: '))

        weekTotal = Monday + Tuesday + Wednesday + Thursday + Friday + Saturday + Sunday

        myInput = input("If you're finished, enter 'done'. If not, enter 'no' to restart: ")

        if myInput == 'done':

            if weekTotal == 0:
                print('You did not collect any bugs this week...')

            elif weekTotal == 1:
                print('You collected only {} bug this week! '.format(weekTotal))

            elif weekTotal > 1:
                print('You collected {} bugs this week! '.format(weekTotal))

    if myInput == 'no':
          bug_collector()

    print('Done!')

#Main Code

bug_collector()
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Please refine the first sentence, I don't think the grammar is right. Also if it's an assignment, please provide the assignment statement (preferably in a block comment). \$\endgroup\$
    – lukstru
    Jun 22 at 9:47
  • 1
    \$\begingroup\$ Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking. \$\endgroup\$
    – Community Bot
    Jun 22 at 9:47

4 Answers 4

1
\$\begingroup\$

My professor has forbid us from using 'while true' and 'break'

That's weird and bad. Considering Python has no do/while, a while True is the most appropriate loop to use. Depending on if your prof cares about the letter of the rule versus the intent of the rule, this can be worked around.

Did I appropriately write the body of the loop?

Not really? It's not a good idea to have a loop whose first predicate evaluation is meaningless. And the moment you see a done, the loop should terminate, either with a break or a return. The if myInput == 'no' doesn't make sense for a number of reasons: first, I would expect for it to be inside the loop, but it's outside of the loop; second, it recurses into bug_collector when it should just continue; and third, that check doesn't really need to exist at all unless you have input validation, which you don't.

The only other major refactoring needed is to use calendar and loop over your weekday names instead of hard-coding them.

Suggested

This meets the letter of the (bad) rules, though perhaps not the spirit.

from calendar import day_name


def bug_collector_loop() -> int:
    while 1:
        total = 0
        for day in day_name:
            total += int(input(f'How many bugs did you collect on {day}? '))

        finished = input("If you're finished, enter 'done'. If not, enter 'no' to restart: ")
        if finished.lower() == 'done':
            return total


def bug_collector() -> None:
    total = bug_collector_loop()
    if total == 0:
        print('You did not collect any bugs this week...')
    elif total == 1:
        print('You collected only 1 bug this week!')
    elif total > 1:
        print(f'You collected {total} bugs this week!')
    print('Done!')


if __name__ == '__main__':
    bug_collector()
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Thank you for your time and feedback! This is my third week of my first coding course at school but I understand why you rewrote portions of it! Plus, the calendar import idea is a fantastic idea. \$\endgroup\$
    – Kirito
    Jun 22 at 21:31
1
\$\begingroup\$

Assignment requires the loop finishes only when the user inputs 'done' so I wrote an input statement asking the user to affirm, otherwise the code loops. Did I appropriately write the body of the loop?

if myInput == 'done':
    PRINT_BLOCK

The PRINT_BLOCK can be outside the loop to clean up the loop body. It's not a logical part of the loop, it's what happens afterwards, so it should be outside the loop. And this way the conditional can be removed completely.

if myInput == 'no':
    bug_collector()

This will never execute, so it can be removed.

\$\endgroup\$
4
  • \$\begingroup\$ I don't understand if myInput == 'done' can be outside the loop to clean up the loop body. How can that be true if that check is needed to terminate the loop from within? \$\endgroup\$
    – Reinderien
    Jun 22 at 13:52
  • \$\begingroup\$ That check does not terminate the loop. The loop condition terminates the loop. That check prints out data. @Reinderien \$\endgroup\$
    – lukstru
    Jun 22 at 14:43
  • \$\begingroup\$ I think I see where we've gotten scrambled. There does indeed need to be conditional loop termination, but the total printing doesn't need to be in the loop (and doesn't need to be conditional either). So you're half-right, but the done check should only terminate the loop, not be re-applied to the printing block. \$\endgroup\$
    – Reinderien
    Jun 22 at 15:28
  • 1
    \$\begingroup\$ Yes, you're right, I missed that as well. Teamwork! \$\endgroup\$
    – lukstru
    Jun 22 at 21:18
0
\$\begingroup\$

An alternative version to @Reinderiens solution that uses recursion instead of a while True: loop, because recursion overflow will probably not be a problem in this case:

def bug_collector_loop() -> int:
    total = 0
    for day in day_name:
        total += int(input(f'How many bugs did you collect on {day}? '))

    finished = input("If you're finished, enter 'done'. If not, enter 'no' to restart: ")
    if finished.lower() != 'done':
        return bug_collector_loop()

    return total
\$\endgroup\$
2
  • \$\begingroup\$ Why would recursion be better here? \$\endgroup\$
    – Mast
    Jun 23 at 10:32
  • \$\begingroup\$ Wouldn't necessarily be better, just a different approach. This method does not have a loop, that's it. @Mast \$\endgroup\$
    – lukstru
    Jun 23 at 10:51
0
\$\begingroup\$

I'm also currently studing python so someone else may feel free to tell me if im wrong, or my way isn't better etc

but i think it would be easier and quicker to assign:

'how many bug did you collect on' to a variable and then just call the variable instead of rewriting your query each time

my eg.

query = 'How many bugs did you collect on'

Monday = int(input(f'{query} Monday?: '))
Tuesday = int(input(f'{query} Tuesday?: '))
Wednesday = int(input(f'{query} Wednesday?: '))
Thursday = int(input(f'{query} Thursday?: '))
Friday = int(input(f'{query} Friday?: '))
Saturday = int(input(f'{query} Saturday?: '))
Sunday = int(input(f'{query} Sunday?: '))
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.