Найти - Пользователи
Полная версия: Текстовый мини-квест "Уютный Магазинчик"
Начало » Python для новичков » Текстовый мини-квест "Уютный Магазинчик"
1
Palrom
Всем привет! Делюсь первой своей работой для фидбека и конструктивной критики. Перед вами маленький квест про поход в магазин, забытый кошелёк и попытку нашарить по карманам мелочь для оплаты покупок. Здесь активный упор на функции (до классов я ещё не дошёл, но думаю для проги такого размера они и не нужны пока). Доработка, оптимизация, дополнение - всё приветствуется!

  
import random
 
prices = {'мясо': 22, 'хлеб': 4, 'пиво': 10, 'вода': 1, 'рыба': 16}
more_goods = {'молоко': 14, 'рыба': 18, 'сало': 20, 'масло': 7}
prices.update(more_goods)  # Добавляет новые элементы и обновляет старые в словаре prices.
 
def coin_declension(number: int):  # Склоняет слово "монета" в соответствие с переданным в эту функцию числом.
    if 11 <= number <= 19:
        coins = f"{number} монет"
    elif number % 10 == 1:
        coins = f"{number} монета"
    elif 2 <= number % 10 <= 4:
        coins = f"{number} монеты"
    else:
        coins = f"{number} монет"
    return coins
 
def no_purse(price_to_pay=0):  # Разыгрывает сценку с кошельком. Принимает стоимость товаров из функции shopping.
    if price_to_pay == 0:      # Если из shopping пришёл 0 (юзер ничего не покупает), то просто выходит из программы.
        print('Всего доброго!')
        quit()
    print('Вас вдруг пронзает мысль, что вы забыли свой кошель с монетами дома!\n'
          'Отказаться от покупки или пошарить по карманам в поисках мелочи?')
    while True:
        decision = input('Введите "отказ" или "поиск"\n')
        if decision == 'отказ':
            print('Взгляд продавца делается осуждающим, впрочем, быстро сменяется улыбкой. Он отвечает:\n'
                  '"Забыли кошелёк? Ничего страшного, с кем не бывает? Возвращайтесь когда будете готовы!"\n'
                  'Всего доброго!')
            quit()
        elif decision == 'поиск':
            pockets = random.randint(1, 20)  # Генерирует число от 1 до 20 для монет, найденных в карманах.
            if pockets >= price_to_pay:
                much_more = pockets - 10       # Необязательная секция. Служит для вставки частицы "аж" в ввод can_pay
                even = ' '                     # Необязательная секция. Служит для вставки частицы "аж" в ввод can_pay
                if much_more >= price_to_pay:  # Необязательная секция. Служит для вставки частицы "аж" в ввод can_pay
                    even = ' аж '              # Необязательная секция. Служит для вставки частицы "аж" в ввод can_pay
                can_pay = input(f'Вам удалось набрать{even}{coin_declension(pockets)}! Расплатиться? да/нет\n')
                if can_pay == 'да':
                    pockets -= price_to_pay
                    print(f'В остатке {coin_declension(pockets)}. Спасибо за покупку! Приходите ещё!')
                    quit()
                else:
                    print('"Ваша воля", с едва заметным раздражением отвечает вам продавец.\n '
                          'Вы уходите из магазина под тихий ропот собравшейся за вами очереди.')
                    quit()
            else:
                print(f'Увы, Вам удалось собрать только {coin_declension(pockets)}! Вы извинились и ушли за кошельком.')
                quit()
        elif decision == 'выход':
            print('Товары остаются на прилавке. Вы молча покидаете магазин..')
            quit()
 
def shopping():
    to_pay = 0
    goods_string_correct = ' из '  # Вставляет предлог "из" при первом обращении.
    print('Для просмотра списка доступных товаров введите "прайс"')
    print('Для выхода из магазина, введите "выход"')
    while True:
        goods = input(f'Какой{goods_string_correct}товаров Вас интересует?\n')
        for i in prices.keys():  # Метод .keys() - более производительный способ итерации ключей словаря.
            if i == goods:
                choice = input(f'Есть в наличии. Стоимость: {coin_declension(prices[goods])}. '
                               'Будете брать? да/нет \n')
                if choice == 'да':
                    to_pay += prices[goods]  # Плюсует значение (стоимость) одного из элементов словаря,
                    # получаемое по ключу(goods), ранее введённому покупателем.
                    print(f'Хорошо. С вас пока {coin_declension(to_pay)}.')
                elif choice == 'выход':
                    print('Хорошо. Всего доброго!')
                    quit()
                elif choice == 'нет':
                    print('Как угодно.')
                else:
                    print('Как скажете, чтобы это не значило..')
                    continue
            goods_string_correct = ' ещё из '  # Подставляет "ещё из" в последующих обращениях.
        if goods == 'выход':
            break
        elif goods == 'прайс':
            print('В продаже имеется:')
            for key, value in prices.items():  # Метод .items() представляет словарь в виде списка из кортежей [(k,v)].
                print(f'{key:7s} цена: {coin_declension(value)}')
            goods_string_correct = ' из представленных '
        elif goods not in prices.keys():
            print('Такого товара нет. Посмотреть доступные товары: "прайс". Завершить: "выход".')
    return to_pay
 
if __name__ == '__main__':
    print('Добро пожаловать в "Уютный Магазинчик"!')
    x = shopping()
    no_purse(x)
Palrom
Не качайте прикреплённый файл! Он устарел. Копипастите прямо из основного сообщения.
py.user.next
Palrom
По какой-то причине первая же строка, “import random” смещена на один пробел вправо, из-за чего будет ошибка! Перед запуском уберите пробел, или подскажите как его убрать, я на форуме новичок..
Чтобы выкладывать код на форуме без смещений
Если есть тип кода (python, bash и так далее):

[code python]здесь ставишь один пробел и переводишь строку
здесь вставляешь код и в каждой пустой строке в её начале ставишь пробел[/code]

Если это просто общий код:

[code]здесь можно вставлять код без каких-то ухищрений[/code]

Palrom
Доработка, оптимизация, дополнение - всё приветствуется!
Файл должен называться одним словом из маленьких букв или словами из маленьких букв, которые разделены подчёркиваниями. Типа shop.py или good_shop.py или my_good_shop.py .
Это связано с тем, что в питоне каждый его исходник сам по себе является модулем, который можно импортировать в другом скрипте. Если у него неправильное имя, то его нельзя будет импортировать через import.

В конце скрипта должны стоять ворота
Palrom
  
print('Добро пожаловать в "Уютный Магазинчик"!')
x = shopping()
no_purse(x)
  
if __name__ == '__main__':
    print('Добро пожаловать в "Уютный Магазинчик"!')
    x = shopping()
    no_purse(x)
Это связано с тем, что в питоне каждый его исходник сам по себе является модулем, который можно импортировать в другом скрипте. Если у него нет ворот, то скрипт при импортировании сразу выполнится. А импортирование нужно обычно, когда ты хочешь взять какую-нибудь готовую функцию из какого-то скрипта и использовать её в другом скрипте. При этом тебе нужно лишь загрузить функции из него и не надо его выполнять. Чтобы загрузились только функции, существуют ворота, которые видят, импортируется скрипт или же выполняется сам по себе из командной строки. Если скрипт импортируется, ворота не пропускают. Если скрипт запускается сам по себе ворота пропускают и за ними всё выполняется.

Строки должны иметь длину не более восьмидесяти символов. Это связано не с размером экрана и новыми старыми экранами, а с чтением кода. Длинные строки сложнее умещать в оперативной памяти мозга, чем короткие. Соответственно, в голове должно быть свободно, чтобы туда загружать другие мысли о скрипте в любой момент. Когда же ты читаешь длинную строку, то она вся загружается в мозг и просто не остаётся места, чтобы о ней подумать с разных сторон. Когда таких строк ещё и много, то ты вообще ни о чём думать не можешь и просто запутываешься в коде. Мозг ограничен. Делай короткие строки до восьмидесяти символов, чтобы после каждой строки можно было остановиться и подумать о многом.

Palrom
Здесь активный упор на функции (до классов я ещё не дошёл, но думаю для проги такого размера они и не нужны пока).
Ты и до классов не дошёл, и до функций не дошёл. Это вот - то, что написано, - это не функции, а просто каша-малаша. Это как ребёнок сел бы за руль машины и стал бы там включать поворотники, крутить руль, смотреть в зеркала и бибикать проезжающим мимо машинам. При этом машина стояла бы незаведённой. Это не вождение и не управление транспортным средством, даже если сильно изображать рёв двигателя через дрын-дрын-дрын.

Так что до функций ты не дошёл. Надо тебе изучать этот вопрос.
Здесь писал подборку о том, как и что изучать. Там же найдёшь пример того, как разрабатывать, используя функции.

В твоей программе должно быть больше функций, и они будут получаться небольшими. Бывают функции и в одну строку, это не страшно. Функции будут появлятся типа зайти_в_магазин(), начать_покупку(), проверить_кошелёк(), прочитать_список_товаров(), выбрать_товар() и так далее. Имена пишешь на английском, естественно. Каждое имя функции должно отвечать на вопрос “что сделать?”. Твой ответ функции должен быть такой “приказываю, зайти в магазин!” - так она и будет называться, например enter_to_shop(). Всё это надо получить постепенно, используя метод разработки сверху вниз.

Пример небольшой
  
>>> def enter_to_shop():
...     print('Вы в магазине')
...     print('Выбирайте товар:')
...     list_goods()
...     product = select_product()
...     print('Вы выбрали', product)
...     print('До свидания, заходите ещё!')
... 
>>> def list_goods():
...     lst = ('масло',
...            'хлеб',
...            'кукуруза',
...            'кефир',
...            'кофе')
...     for i in lst:
...         message = wrap_product(i)
...         print(message)
... 
>>> def wrap_product(product):
...     return 'На полке лежит {}'.format(product)
... 
>>> def select_product():
...     product = ''
...     while not product:
...         print('Введите название товара:')
...         product = input()
...         if not product:
...             print('Ничего не введено, повторите ввод')
...     return product
... 
>>> def main():
...     enter_to_shop()
... 
>>> main()
Вы в магазине
Выбирайте товар:
На полке лежит масло
На полке лежит хлеб
На полке лежит кукуруза
На полке лежит кефир
На полке лежит кофе
Введите название товара:
 
Ничего не введено, повторите ввод
Введите название товара:
 
Ничего не введено, повторите ввод
Введите название товара:
 
Ничего не введено, повторите ввод
Введите название товара:
масло
Вы выбрали масло
До свидания, заходите ещё!
>>>

А так… это каша просто. Что есть здесь функции, что их не было бы, - разницы нет.
Palrom
py.user.next
Спасибо за развёрнутый комментарий! Многое подчерпнул так сказать.. Превью поправил но удалить старый исходник из своего коммента не могу теперь..
Это как ребёнок сел бы за руль машины
Ну приблизительно так я себя со стороны и представлял. Дорвавшимся мамкиным кулхацкером)
Здесь писал подборку о том, как и что изучать.
Вот за это отдельное спасибо.
Строки должны иметь длину не более восьмидесяти символов.
Ну здесь так вышло из-за того, что программа из совсем одноклеточной, а-ля что_купить>>с вас_столько-то>>конец, превратилась в текстовый квест, с какой никакой вариативностью, который как бы подразумевает много текста. Пришлось многое объяснять юзеру строками. Проблема кучи текста это проблема именно этой программы короче. + Я намерено понавставлял комментариев, дабы дурью своей блеснуть, не ошибаюсь ли я ненароком в фундаментальных вещах, отчего код смотрится ещё монструознее..

Ушёл мозговать..
py.user.next
Palrom
Превью поправил
Не, там ещё пустые строки между функциями должны быть. Как их делать, я написал.

Palrom
py.user.next
Это как ребёнок сел бы за руль машины
Ну приблизительно так я себя со стороны и представлял. Дорвавшимся мамкиным кулхацкером)
Если ты пишешь функции, это не значит, что ты умеешь их писать. Это как взятие кистей и красок, надевание берета, как у Мурзилки, и надевание очков в толстой коричневой оправе не делает тебя художником. Для рисования нужно знать теорию изобразительного искусства. Даже если ты изучишь карандаш вдоль и поперёк, какой у него там грифель и всё такое, ты всё равно не сможешь им нарисовать кошку. Вот так же и с функциями в питоне. Если ты их синтаксис узнал, это всё ещё ноль. На всех языках функции делаются одинаково, различается только синтаксис. Карандаш от кисти тоже отличается, но какой-нибудь рисунок рисуешь ты ими одинаково, по одним и тем же правилам. Так что функции не так просты, как это может показаться. Существует общая теория того, как их создавать. Она не так проста; и её нужно не только знать, но и уметь применять на практике.

Palrom
Я намерено понавставлял комментариев, дабы дурью своей блеснуть, не ошибаюсь ли я ненароком в фундаментальных вещах, отчего код смотрится ещё монструознее..
Комментарии создавать тоже не так просто, как это кажется. Лучший комментарий - это тот комментарий, которого нет. То есть код сам себя должен прояснять до такой степени, чтобы комментарии к нему не требовались. В профессиональных кодах комментируется обычно только причина. Комментируется то, почему этот код написан, а не другой; комментируется то, почему выбран и реализован в коде такой алгоритм, а не другой. А то, что написано, не комментируется никогда, потому что такой код, который этого требует, считается некачественным и должен быть переписан по-нормальному.

Строки укорачивать можешь так
Обрати внимание на то, что там нет запятых в конце строк
Это конкатенация, которая происходит благодаря круглым скобкам
  
>>> text = ('много текста много текста много текста много текста'
...         ' много текста много текста много текста много текста'
...         ' много текста много текста много текста много текста'
...         ' много текста много текста много текста много текста'
...         ' много текста много текста много текста много текста')
>>> 
>>> print(text)
много текста много текста много текста много текста много текста много текста много текста много текста много текста много текста много текста много текста много текста много текста много текста много текста много текста много текста много текста много текста
>>>
  
>>> text = ('текст'
...         ' текст'
...         ' текст'
...         ' текст'
...         ' текст'
...         ' текст')
>>> 
>>> print(text)
текст текст текст текст текст текст
>>>
  
>>> text = ('т'
...         'е'
...         'к'
...         'с'
...         'т')
>>> 
>>> print(text)
текст
>>>
Получается одна непрерывная строка.
xam1816
py.user.next
Существует общая теория того, как их создавать.
Про это бы подробнее
py.user.next
xam1816
py.user.next
Существует общая теория того, как их создавать.
Про это бы подробнее
В основном это проистекает из теории построения алгоритмов. Функция реализует алгоритм. А алгоритмы имеют строгую теорию, там Машина Тьюринга и всё такое. То есть в книгах по алгоритмам ты узнаешь, как делать функции, потому что функции - это реализации алгоритмов. Соответственно, что на входе у алгоритма должно быть и что на выходе у алгоритма должно быть, то же должно быть и на входе у функции и на выходе у функции. У алгоритма есть какое-то предусловие и какое-то постусловие. То есть он начался при одних условиях и завершился при других условиях. Вот то же самое должно быть у функции. Нужно следить за вот этими вот предусловием функции и постусловием функции. Их не видно, но ты их должен видеть. А чтобы их видеть, про них надо знать. А чтобы про них знать, надо книжки читать. Понимаешь? Надо читать книжки! Не туториалы тупые какие-то, не видюхи смотреть от всеумельцев, которые где-то там работали, но так за двадцать лет ни одной программы не сделали (всё времени не было типа, ага, - стандартная отмазка), а смотреть, кто в программировании сделал какой-то вклад, брать его книжки, которые он написал за свою жизнь, и читать эти книжки. И неважно, по каким они там языкам, многие языки уже сдохли, но теория осталась, и она осталась такой, какой и была тогда.

Ты вот какие книжки прочитал? Назови.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB