@anon9000

Как можно упростить этот код на Python?

Я учусь Питону придумывая себе несложные задачки. Вот так вот написала простенький генератор рецептов.
Но как можно это сделать покрасивее? Вот например вставила костыль - если какой то ингредиент повторяется,
то перезапускается функция, а как можно по другому, я пока не знаю.
Второй акцент на том что пришлось делать длинные конструкции if (...) or (...) or (...) и тд. Просто если будут, например,
сто ингредиентов, то какой длинны нужно будет код писать... Заранее Всем - спасибо!
# -*- coding: utf-8 -*-
import random

# Составные части зелий
INGRIDNT = ["Бобов", "Мяты", "Папоротника", "Воска", "Пикси", "Пыли", "Пера", "Ромашки", "Крапивы"]
CH1 = ["Отвар", "Элексир", "Фиал"]
CH2 = ["Любви", "Силы", "Ловкости", "Смерти", "Трасформации", "Левитации", "Выносливости", "Интелекта", "Внимания"]
NAZVANIE = str(random.choice(CH1)) + ' ' + str(random.choice(CH2))
SLOGNOST = ["Сложносоставной", "Средний", "Малый"]
ERORS = 1
CARD = str(random.choice(SLOGNOST))

def ing():
    if CARD == SLOGNOST[0]:
        NABOR = [str(random.choice(INGRIDNT)), str(random.choice(INGRIDNT)), str(random.choice(INGRIDNT)), str(random.choice(INGRIDNT))]
        if NABOR[0] == NABOR[1] == NABOR[2] == NABOR[3] or NABOR[0] == NABOR[1] or NABOR[0] == NABOR[2] or NABOR[0] == NABOR[3] or NABOR[1] == NABOR[2] or NABOR[1] == NABOR[3] or NABOR[2] == NABOR[3]:
            print "была ошибка повторений сложных ингридиентов"
            ing()
        else:
            print CARD + ": " + NAZVANIE + " состоит из " + NABOR[0] + ', ' + NABOR[1] + ', ' + NABOR[2] + ', ' + NABOR[3]
    elif CARD == SLOGNOST[1]:
        NABOR = [str(random.choice(INGRIDNT)), str(random.choice(INGRIDNT)), str(random.choice(INGRIDNT))]
        if NABOR[0] == NABOR[1] == NABOR[2] or NABOR[0] == NABOR[1] or NABOR[0] == NABOR[2] or NABOR[1] == NABOR[2]:
            print "была ошибка повторений средних ингридиентов"
            ing()
        else:
            print CARD + ": " + NAZVANIE + " состоит из " + NABOR[0] + ', ' + NABOR[1] + ', ' + NABOR[2]
    else:
        NABOR = [str(random.choice(INGRIDNT)), str(random.choice(INGRIDNT))]
        if NABOR[0] == NABOR[1]:
            print "была ошибка повторений малых ингридиентов"
            ing()
        else:
            print CARD + ": " + NAZVANIE + " состоит из " + NABOR[0] + ', ' + NABOR[1]

ing()
  • Вопрос задан
  • 316 просмотров
Решения вопроса 1
есть замечательный модуль https://docs.python.org/3.5/library/itertools.html
в котором есть функции работы с комбинаторикой:
product('ABCD', repeat=2)
permutations('ABCD', 2)
combinations('ABCD', 2)
combinations_with_replacement('ABCD', 2)

ну и соответственно варианты с получением случайного объекта:
random_product
random_permutation
random_combination
random_combination_with_replacement


посмотрите почитайте, это позволит сразу сделать выборку неповторяющихся элементов.

Именно для избегания сложных if, а в них как понимаю вы проверяете что ингредиенты уникальны, можно воспользоваться set
if len(NABOR) != len(set(NABOR))
либо вот таким решением stackoverflow.com/a/5281641 - на больших объектах будет гораздо производительнее.

вот эти проверки
if CARD == SLOGNOST[0]:
 elif CARD == SLOGNOST[1]:
...

тоже плохой код, у вас фактически одна и таже логика просто меняется количество элементов зелья, вынесите в конфиг, что такой-то сложности соответствует такоей-то количество элементов, и исходя из этого числа создавайте списки с нужным количеством ингридиентовв и тд и тп

str(random.choice(SLOGNOST))
так random.choice и так вернёт строку, зачем ещё вызывать преобразование в строку? (и так несколько раз)
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы