admin 0Comment

Zabieramy się za kolejne zadanie praktyczne z kursu Automate the Boring Stuff with Python.

Jeśli nie znasz kursu lub nie czytałeś tekstu wyjaśniającego pierwsze zadanie, powinieneś zrobić to tutaj.
Dzisiejsze zadanie pochodzi z rozdziału czwartego i brzmi:

Comma Code
Say you have a list value like this:
spam = [‚apples’, ‚bananas’, ‚tofu’, ‚cats’]
Write 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. For example, passing the previous spam list to the function would return ‚apples, bananas, tofu, and cats’. But your function should be able to work with any list value passed to it.

Mocno namawiam do próby samodzielnego rozwiązania zadania zanim przeczytacie dalszą część mojego tekstu.

Opis rozwiązania:
Przede wszystkim, ważna kwestia – nie ma jednego prawidłowego rozwiązania. Można to zrobić na wiele sposobów, a te będą się różnić między sobą długością, zastosowanymi metodami czy też generalną elegancją (lub jej brakiem) i klarownością kodu.
Zamiast od razu główkować nad całością, rozbijmy polecenie na mniejsze problemy – skoro mamy napisać funkcję, której argumentem będzie lista, możemy zacząć w ten sposób:

def convertsToString(list):

Jedziemy dalej: funkcja ma zwrócić string – oznacza to, że takie koszmarki, mimo, że wyświetlają porządany wynik, nie są akceptowane:

def convertsToString(list):
    newList = list[-1]
    del list[-1]
    for i in range(len(list)):
        print(list[i], end=', ')
    print('and ', end='')
    print(newList)

spam = ['apples', 'bananas', 'tofu', 'cats']
convertsToString(spam)

To jedno z moich pierwszych podejść do tego zadania, przekombinowane tak bardzo, jak tylko się da. Co tutaj robię? Tworzę nową listę (newList), zawierającą jeden element, będący ostatnim elementem pierwotnej listy (tej, która podana jest jako argument funkcji). Następnie z pierwotnej listy usuwam ten, ostatni, element. Potem dla każdego elementu w pierwotnej liście wyświetlam go w tej samej linii, dodając za nim przecinek, osobno wyświetlam (nadal w tej samej linii, dzięki end=’’) słowo ‘and’ a na koniec wyświetlam jedyny element newList czyli ten, który był ostatnim elementem pierwotnej listy.

Jest to niepotrzebnie skomplikowany sposób i przede wszystkim, wyświetla (poprzez funkcję print) wynik zamiast go zwracać (poprzez funkcję return). Zdecydowanie nie idźcie tą drogą.
Wracamy do sensownego rozwiązania. Z dalszej części tekstu zadania możemy wywnioskować, że będziemy musieli po kolei zajmować się poszczególnymi elementami funkcji (czyli iterować) z tym, że co innego będziemy musieli zrobić w odniesieniu do elementów przed ostatnim, a co innego – w odniesieniu do ostatniego.
Zanim przejdziemy do iteracji, skupmy się na tym, co dokładnie funkcja ma zwracać. Zgodnie z tekstem zadania, zwrócony ma być string, może więc warto na początku, stworzyć pusty string, który zostanie (już po uzupełnieniu) ostatecznie zwrócony przez funkcję:

def convertsToString(list):
    newString = ''

Wracamy do iteracji, ale pamiętamy, że działanie na ostatnim elemencie w liście będzie się różnić od działań na poprzednich elementach, właściwe więc jest ograniczenie iteracji tylko do nich. Efektem działania ma być uzupełnienie newString o elementy funkcji (poza ostatnim) z dodanymi przecinkami po każdym:

def convertsToString(list):
    newString = ''
    for i in range(len(list)-1):
        newString += list[i] + ', '

Skoro tę część, mamy już zakończoną, możemy (poza iteracją) przejść do dodania do newString ostatniego elementu listy (odnosimy się do niego w prosty sposób, niezależnie od długości listy – jest to po prostu list[-1]), poprzedzonego ‘and’. Całość zwracamy (czyli korzystamy z return, a nie funkcji print) jako newString. Tak wygląda cały program, spełniający wymagania zadania:

def convertsToString(list):
    newString = ''
    for i in range(len(list)-1):
        newString += list[i] + ', '
    newString += 'and ' + list[-1]
    return newString

spam = ['apples', 'bananas', 'tofu', 'cats']
print(convertsToString(spam))

Dodaj komentarz