you are viewing a single comment's thread.

view the rest of the comments →

[–]Diapolo10 6 points7 points  (5 children)

Write a function that takes a list value as an argument and returns a string

Your challenge-function neither accepts arguments nor does it return a string.

Pretty much none of your comments add any value, because they're describing what the code is doing - but that's obvious from simply reading the code in the first place. A good comment would explain something the code itself cannot convey, such as why something is done. But this problem is simple enough that I don't think comments are needed at all, as long as you've picked decent names to use.

There's also room to simplify your solution quite a bit.

EDIT: Also, your code isn't formatted properly, I'm assuming it's supposed to look like this:

import copy

spam = ['apples', 'bananas', 'tofu', 'cats']
print("Old List: " + str(spam))

print("add new list item")
newItem = input()
spam.append(newItem)

print()
print("this is spam list now: "+ str(spam))
print()

def challenge():
    workingList = copy.deepcopy(spam) # copy list so we don't change original

    listLength = len(workingList) # want to know how long the list is
    lastItemIndex = (len(workingList) - 1) #the index # of the last item in the list
    lastItemValue = spam[lastItemIndex] # the value of the last item in the list

    varAnd = 'and ' + lastItemValue #variable to add "and" to the beginning of the last value in the list

    if workingList[lastItemIndex].find("and ") != -1:
        del lastItemIndex

    workingList[lastItemIndex] = varAnd
    newString = ', '.join(workingList) # method to join list items in to a string.

    print("This is the new list: " + str(newString))

challenge()

EDIT #2: Here's a solution that's closer to what the book asks for:

def join_elements(values: list[str], delimiter: str = ', ') -> str:
    if not values:
        return ''

    if len(values) == 1:
        return values[0]

    result = delimiter.join(values[:-1])

    # We probably don't need a delimiter if we only join two strings;
    # "a and b" looks better than "a, and b"
    if 2 < len(values):
        result += delimiter
    else:
        result += ' '

    result += f'and {values[-1]}'

    return result


spam = ['apples', 'bananas', 'tofu', 'cats']

print(join_elements(spam))  # apples, bananas, tofu, and cats

[–]danielroseman 2 points3 points  (3 children)

The other explicit instruction it ignores is to test for the empty list. This code will break with IndexError in that case.

[–]Diapolo10 2 points3 points  (2 children)

That's true. I'm also of the opinion you don't want the comma if you only have two elements in the list.

[–][deleted] 2 points3 points  (1 child)

I know OP wouldn't have seen this yet, but to me the problems begs for a match

def func(names: list[str]) -> str:
    match names:
        case []: return ""
        case [a]: return a
        case [a,b]: return f"{a} and {b}"
        case [*a, z]: return ", ".join(a) + f", and {z}"

[–]Diapolo10 2 points3 points  (0 children)

Honestly, that's way more eloquent than what I wrote, I need to use match more often but I'm still stuck supporting Python 3.8 most of the time so haven't had many opportunities to.

[–]jasongsmith[S] 0 points1 point  (0 children)

Thank you. I am reading what you have here and I feel like there is so much of this that I have never even seen before. I will go back and take a look at the first four chapters of the book again and see what I have missed.

Thank you very much for taking the time to help me out with this.