1
\$\begingroup\$

This is an exercise in the Automate The Boring Stuff book. I am supposed to create a function that takes a list value as an argument and returns a string with all the items separated by a comma and a space, with 'and' inserted before the last item. My code also includes a loop for the user to create their list.

def add_and(alist):
 if ((alist != []) & (len(alist) > 2)):
 for item in alist[:-1]:
 print(item + ", ",end="")
 print("and", alist[-1])
 elif ((alist != []) & (len(alist) == 2)):
 print(alist[0], "and", alist[1])
 elif ((alist != []) & (len(alist) == 1)):
 print(alist[0])
 else: 
 print("")
 
your_list = []
while True:
 print("Enter An Item or nothing")
 item = input()
 if ((item) == ""):
 print("")
 break
 else:
 your_list.append(item)
 continue
add_and(your_list)

I know that the code works, but I was wondering if there were any faux-pas that I am implementing, or if there is anything I could obviously do to make it cleaner. Thanks!

asked Dec 11, 2020 at 19:34
\$\endgroup\$
5
  • \$\begingroup\$ You've not implemented the correct solution for the question. Your task is to "create a function that ... returns a string". The function you wrote prints the result but returns nothing. \$\endgroup\$ Commented Dec 11, 2020 at 21:08
  • \$\begingroup\$ If I replace my "print" with "return", would it be correct? \$\endgroup\$ Commented Dec 11, 2020 at 21:26
  • \$\begingroup\$ The last two in the function could be replaced by return, the middle one would need modification, but could also be replaced. But the first two cannot be. You can only return from a function once, not multiple time in a loop; the first return executed terminates the function. \$\endgroup\$ Commented Dec 12, 2020 at 1:23
  • \$\begingroup\$ You can edit the question to match what the code does, and then we can review what you have written, or we can attempt to migrate the code to Stack Overflow, where you might get assistance with fixing the code to do what the problem asks. Which would you prefer? \$\endgroup\$ Commented Dec 12, 2020 at 1:27
  • \$\begingroup\$ Given the original intent of the post I'm leaning toward the former. \$\endgroup\$ Commented Dec 12, 2020 at 15:35

1 Answer 1

2
\$\begingroup\$
  • Don't surround sub-predicates or predicates with parens when that isn't needed
  • Use logical and rather than binary &
  • Use join rather than a for-and-concatenate
  • Factor out common sub-predicates for your list emptiness checks into an outer if
  • Don't else-after-break
  • No need to continue
  • Gather your input in a separate function
  • Do not leave the input prompt blank

Suggested:

def and_add(alist):
 if len(alist) > 1:
 print(', '.join(alist[:-1]), 'and', alist[-1])
 elif len(alist) == 1:
 print(alist[0])
 else:
 print('')
def get_input():
 while True:
 item = input('Enter an item or nothing: ')
 if not item:
 return
 yield item
and_add(list(get_input())) 
answered Dec 12, 2020 at 15:52
\$\endgroup\$
2
  • \$\begingroup\$ Thanks! Why can't you else-after-break? \$\endgroup\$ Commented Dec 12, 2020 at 20:45
  • 2
    \$\begingroup\$ You can, it's just redundant. \$\endgroup\$ Commented Dec 12, 2020 at 20:45

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.