Уведомления

Группа в Telegram: @pythonsu

#1 Март 24, 2015 07:22:52

insiki
От: Приморский край
Зарегистрирован: 2015-01-26
Сообщения: 7
Репутация: +  0  -
Профиль   Отправить e-mail  

Как, не используя функции, сделать код элегантнее и лаконичнее?

Потихоньку учу Python по книге Доусона. В книге он после каждой главы предлагает сделать несколько практических заданий. Вот одно из них:
Напишите программу “Генератор персонажей” для ролевой игры. Пользователю должно быть предоставлено 30 пунктов, которые можно распределить между четырьмя характеристиками: Сила, Здоровье, Мудрость и Ловкость. Надо сделать так, чтобы пользователь мог не только брать эти пункты из общего “пула”, но и возвращать их туда из характеристик, которым он решит присвоить другие значения.

Условие для решение - можно использовать только списки или словари.
Что получилось у меня:

import random
MENU =  (
    """
    0 - Выход
    1 - Посмотреть текущие характеристики
    2 - Изменить Power
    3 - Изменить Health
    4 - Изменить Agility
    5 - Изменить Wisdom
    """
    )
MENU_ABILITY = (
    """
    0 - Выход в предыдущее меню
    1 - Добавить очки
    2 - Удалить очки
    """
    )
points = 30
add_points = 0
del_points = 0
abilities = {"Power": 0, "Health": 0, "Agility": 0, "Wisdom": 0}
choice = None
while choice != "0":
    choice2 = None
    print(MENU)
    choice = input("Ваш выбор: ")
    print()
    # выход
    if choice == "0":
        print ("До свидания")
    #просмотр текущих характеристик
    elif choice == "1":
        print("Количество свободных очков:", points, "\nТекущие характеристики:", abilities)
    #изменить ветку Power
    elif choice == "2":
        while choice2 != "0":
            print("\nУ вас есть", points, "свободных очков и", abilities["Power"], "очков в ветке Power.")
            print (MENU_ABILITY)
            choice2 = input("Ваш выбор: ")
            print()
            if choice2 == "0":
                print ("Возврат к предыдущему меню")
            elif choice2 == "1" and points > 0:
                add_points = int(input("Сколько очков хотите добавить в ветку Power?\n"))
                if add_points > points:
                    print ("\nВы хотите добавить больше очков, чем есть у вас на самом деле.")
                elif add_points <= points:
                    points -= add_points
                    abilities["Power"] += add_points
            elif choice2 == "2" and abilities["Power"] > 0:
                del_points = int(input("Сколько очков хотите убрать из ветки Power?\n"))
                if del_points > abilities["Power"]:
                    print ("\nВы хотите убрать больше очков, чем есть в ветке Power.")
                elif del_points <= abilities["Power"]:
                    points += del_points
                    abilities["Power"] -= del_points
            elif (choice2 == "1" and points == 0):
                print("~~Нет свободных очков~~")
            elif (choice2 == "2" and abilities["Power"] == 0):
                print("~~В ветке Power нет очков~~")
            else:
                print("~~Неправильный ввод~~")
                
    #изменить ветку Health
    elif choice == "3":
        while choice2 != "0":
            print("\nУ вас есть", points, "свободных очков и", abilities["Health"], "очков в ветке Health.")
            print (MENU_ABILITY)
            choice2 = input("Ваш выбор: ")
            print()
            if choice2 == "0":
                print ("Возврат к предыдущему меню")
            elif choice2 == "1" and points > 0:
                add_points = int(input("Сколько очков хотите добавить в ветку Health?\n"))
                if add_points > points:
                    print ("\nВы хотите добавить больше очков, чем есть у вас на самом деле.")
                elif add_points <= points:
                    points -= add_points
                    abilities["Health"] += add_points
            elif choice2 == "2" and abilities["Health"] > 0:
                del_points = int(input("Сколько очков хотите убрать из ветки Health?\n"))
                if del_points > abilities["Health"]:
                    print ("\nВы хотите убрать больше очков, чем есть в ветке Health.")
                elif del_points <= abilities["Health"]:
                    points += del_points
                    abilities["Health"] -= del_points
            elif (choice2 == "1" and points == 0):
                print("~~Нет свободных очков~~")
            elif (choice2 == "2" and abilities["Health"] == 0):
                print ("~~В ветке Health нет очков~~")
            else:
                print("~~Неправильный ввод~~")
                
    #изменить ветку Agility
    elif choice == "4":
        while choice2 != "0":
            print("\nУ вас есть", points, "свободных очков и", abilities["Agility"], "очков в ветке Agility.")
            print (MENU_ABILITY)
            choice2 = input("Ваш выбор: ")
            print()
            if choice2 == "0":
                print ("Возврат к предыдущему меню")
            elif choice2 == "1" and points > 0:
                add_points = int(input("Сколько очков хотите добавить в ветку Agility?\n"))
                if add_points > points:
                    print ("\nВы хотите добавить больше очков, чем есть у вас на самом деле.")
                elif add_points <= points:
                    points -= add_points
                    abilities["Agility"] += add_points
            elif choice2 == "2" and abilities["Agility"] > 0:
                del_points = int(input("Сколько очков хотите убрать из ветки Agility?\n"))
                if del_points > abilities["Agility"]:
                    print ("\nВы хотите убрать больше очков, чем есть в ветке Agility.")
                elif del_points <= abilities["Agility"]:
                    points += del_points
                    abilities["Agility"] -= del_points
            elif (choice2 == "1" and points == 0):
                print("~~Нет свободных очков~~")
            elif (choice2 == "2" and abilities["Agility"] == 0):
                print ("~~В ветке Agility нет очков~~")
            else:
                print("~~Неправильный ввод~~")
    #изменить ветку Wisdom
    elif choice == "5":
        while choice2 != "0":
            print("\nУ вас есть", points, "свободных очков и", abilities["Wisdom"], "очков в ветке Wisdom.")
            print (MENU_ABILITY)
            choice2 = input("Ваш выбор: ")
            print()
            if choice2 == "0":
                print ("Возврат к предыдущему меню")
            elif choice2 == "1" and points > 0:
                add_points = int(input("Сколько очков хотите добавить в ветку Wisdom?\n"))
                if add_points > points:
                    print ("\nВы хотите добавить больше очков, чем есть у вас на самом деле.")
                elif add_points <= points:
                    points -= add_points
                    abilities["Wisdom"] += add_points
            elif choice2 == "2" and abilities["Wisdom"] > 0:
                del_points = int(input("Сколько очков хотите убрать из ветки Wisdom?\n"))
                if del_points > abilities["Wisdom"]:
                    print ("\nВы хотите убрать больше очков, чем есть в ветке Wisdom.")
                elif del_points <= abilities["Wisdom"]:
                    points += del_points
                    abilities["Wisdom"] -= del_points
            elif (choice2 == "1" and points == 0):
                print("~~Нет свободных очков~~")
            elif (choice2 == "2" and abilities["Wisdom"] == 0):
                print ("~~В ветке Wisdom нет очков~~")
            else:
                print("~~Неправильный ввод~~")
Вопрос: если можете, ткните носом, как можно упростить это все и имеет ли смысл упрощать, если функции не используются?

Офлайн

#2 Март 24, 2015 07:52:22

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Как, не используя функции, сделать код элегантнее и лаконичнее?

Пресвятые небеса, что это???!!!!
Доусон от вас хотел примерно этого.

spells = ["Power", "Health", "Agility", "Wisdom"]
abilities = dict.fromkeys(spells, 0)
limit = 3
spells_label = ["%s-%s" % (i+1, x) for i, x in enumerate(spells)] + ["0 - exit"]
prompt = "Choose one of %s: " % spells_label
while limit:
    try:
        i = int(raw_input(prompt))
    except ValueError:
        print "BAD NUM!"
        continue
    if len(spells) < i < 0:
        print "BAD NUM!"
        continue
    if i == 0:
        break
    action = raw_input("+/- :")
    if action not in "+-":
        print "BAD ACTION!"
        continue
    spell_name = spells[i-1]
    if action == "+":
        abilities[spell_name] += 1
    else:
        abilities[spell_name] -= 1
    limit -= 1
print abilities



Отредактировано FishHook (Март 24, 2015 07:54:21)

Офлайн

#3 Март 24, 2015 08:54:38

insiki
От: Приморский край
Зарегистрирован: 2015-01-26
Сообщения: 7
Репутация: +  0  -
Профиль   Отправить e-mail  

Как, не используя функции, сделать код элегантнее и лаконичнее?

Неа, вот этих try, except и прочего не было еще.

Офлайн

#4 Март 24, 2015 08:57:25

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Как, не используя функции, сделать код элегантнее и лаконичнее?

Прочего, это чего?



Офлайн

#5 Март 24, 2015 10:06:36

insiki
От: Приморский край
Зарегистрирован: 2015-01-26
Сообщения: 7
Репутация: +  0  -
Профиль   Отправить e-mail  

Как, не используя функции, сделать код элегантнее и лаконичнее?

FishHook
Прочего, это чего?
Например “dict.fromkeys”.
Он же в главах в качестве примеров многое разбирает, таких вещей, как указали вы, за прочитанные главы до задания не было.
Если я правильно понимаю, это синтаксис 2ой ветки?

Офлайн

#6 Март 24, 2015 10:29:58

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Как, не используя функции, сделать код элегантнее и лаконичнее?

Ни в какой даже самой толстой книге вы не увидите объяснений и примеров всех методов всех классов стандартной библиотеки. Справочников по языку полно в сети, не говоря уже о том, что используя встроенную справку (уж об этом то Доусон вам точно рассказал) вы получите всю необходимую информацию.
Вы не понимаете, что делает dict.fromkeys? Ну так вперед изучать! Интерпретатор в руки и через 30 секунд максимум вы будете знать. Или что вы предлагаете, читать вместе с вами учебник?



Офлайн

#7 Март 24, 2015 12:31:20

insiki
От: Приморский край
Зарегистрирован: 2015-01-26
Сообщения: 7
Репутация: +  0  -
Профиль   Отправить e-mail  

Как, не используя функции, сделать код элегантнее и лаконичнее?

FishHook
Вы не понимаете, что делает dict.fromkeys? Ну так вперед изучать! Интерпретатор в руки и через 30 секунд максимум вы будете знать. Или что вы предлагаете, читать вместе с вами учебник?
Нет, конечно не предлагаю. Более того, такой справочник у меня есть, даже в бумажном виде (автор Лутц).
Просто не задумывался о том, что при обучении по одной книге, можно (и даже нужно) лезть в тот же справочник и пробовать разные варианты
Благодарю.

Офлайн

#8 Март 25, 2015 10:09:29

Shaman
Зарегистрирован: 2013-03-15
Сообщения: 1369
Репутация: +  88  -
Профиль   Отправить e-mail  

Как, не используя функции, сделать код элегантнее и лаконичнее?

insiki
Неа, вот этих try, except и прочего не было еще.
Вы считаете, код в несколько раз сократился только из-за них?

Офлайн

#9 Июль 6, 2015 23:09:14

shotokan
Зарегистрирован: 2015-07-06
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

Как, не используя функции, сделать код элегантнее и лаконичнее?

Книга Доусона написана так, что нужно использовать только те знания, которые получил до этого в книге, так что Fishhook не прав. Мы только начинаем, и не можем знать, что такое try, except и иже с ними. Да, сейчас, я конечно же полезу читать об этом. Но до этого, у меня даже мысли не было, я даже не подозревал, что такое существует.
Так что вот моя версия.

# Симулятор характеристик игрока в РПГ
POINT = 30 # Постоянная величина. Очки.
ochki = 30 # Переменная, для очков. Изменяет свое значение в процессе назначения пунктов между характеристками
person = {"Сила":"0","Здоровье":"0","Ум":"0","Ловкость":"0"} # Характеристики персонажа
points = 0 # Переменная для назначения пунктов
choice = None # Переменная выбора меню
while choice != 0: # Цикл работы, пока не будет нажат "0"
    print("""
0 - Выход
1 - Добавить пункты к характеристике
2 - Уменьшить пункты характеристики
3 - Просмотр характеристик
""")
    choice = int(input("Choose option: "))
    if choice == 1:
        print("Пожалуйста, введите характеристику для добавления пунктов. Для изменения доступны", len(person), "характеристики:")
        for item in person:
            print(item)
        char = str(input("\n:"))
        char = char.title()
        while char not in person:
             print("Нет такой характеристики, проверьте введенные данные: ")
             char = str(input("\n:"))
             char = char.title()
        else:
            print("\nВведите количество пунктов для данной характеристики. У вас", ochki, "свободных пунктов")
            points = int(input("\n:"))
            while points > ochki or points < 0: # Проверяем возможность начисления введенного количества пунктов, а также не введено ли отрицательное значение
                print("Вы не можете назначить такое количество пунктов", "Доступно", ochki, "свободных пунктов")
                points = int(input("\n:"))
        person[char] = points
        print(points, "пунктов было добавлено к", char)
        ochki -= points # Изменяем количество доступных к начислению пунктов
    elif choice == 2:
        print("Пожалуйста, введите имя характеристики для снятия пунктов.", "Доступно изменение для: ")
        for item in person:
            if int(person[item]) > 0: # Не показываем характеристику, если она равна 
                print(item)
        char = str(input("\n:"))
        char = char.title()
        while char not in person:
             print("Нет такой характеристики, проверьте введенные данные: ")
             char = str(input("\n:"))
             char = char.title()
        else:
            print("\nВведите количество пунктов для характеристики. Доступно", person[char], "пунктов:")
            points = int(input("\n:"))
            while points > int(person[char]) or points < 0: # Проверяем возможность снятия такого количества пунктов, а также не введено ли отрицательное значение
                print("Невозможно удалить такое количество пунктов. Доступно", person[char], "пунктов")
                points = int(input("\n:"))
        person[char] = points
        print(points, "пунктов было удалено")
        ochki += points # Возвращаем освободившиеся пункты в доступные
    elif choice == 3:
        print("\nХарактеристики героя")
        for item in person:
            print(item, "\t\t", person[item])
        
    elif choice == 0:
        print("Пока!")
    else:
        print("В меню нет такого пункта")

Отредактировано shotokan (Июль 6, 2015 23:10:01)

Офлайн

#10 Июль 6, 2015 23:42:00

JOHN_16
От: Россия, Петропавловск-Камчатск
Зарегистрирован: 2010-03-22
Сообщения: 3292
Репутация: +  221  -
Профиль   Отправить e-mail  

Как, не используя функции, сделать код элегантнее и лаконичнее?

shotokan
обработка исключений НИКАК не влияет на суть функционала.

shotokan
Книга Доусона написана так, что нужно использовать только те знания, которые получил до этого в книге,
и да и нет. Да - если вы хотите педантично последовательно следовать всему что написано в конкретно этой книге. Нет - если вы действительно хотите обучиться языку и программированию в целом, то про такой узкий подход надо забыть сразу. Программисту свойственно широко черпать информацию и из разных источников, и не останавливатсья на достигнутом.
И еще, не читал Доусона, но в целом могу сказать что учебные примеры в реальные жизни часто не используются. Ибо на то они и учебные. Так что на них зацикливаться может и вовсе не стоит.



_________________________________________________________________________________
полезный блог о python john16blog.blogspot.com

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version