python - 食谱数据库的类不起作用?
问题描述
有 3 个文件,我将一个精简的数据库移动到其中一个文件中,以便我可以证明这个概念有效。第一个文件称为 find_a_recipe.py,它是运行的文件
[find_a_recipe.py]
from random import sample
from typing import List
from main import *
#from cfonts import render
## main logic for type ingredient mode
def type_mode():
print("Let's find the ingredient you are looking for...")
keep_choosing = True
recipes = recipe_list
ingredient_list = get_ingredient_list(recipe_list)
ingredients_sorted = quicksort(ingredient_list)
while keep_choosing:
ingredients = ingredient_filtering(ingredients_sorted)
recipes = filter_recipes(ingredients, recipes)
ingredient_list = get_ingredient_list(recipes)
ingredients_sorted = quicksort(ingredient_list)
print(f"\nWe have {len(recipes)} recipes with those ingredients.")
keep_choosing = bolean_test("Want to choose other ingredients?")
if len(recipes) > 5:
recipe_choice_list = sample(recipes, 5)
else:
recipe_choice_list = recipes
print("\nHere are a few suggestions! Choose one and good luck!")
chosen_recipe = choose_recipe(recipe_choice_list, "Ok! Just choose one of those!")
print(chosen_recipe)
## main logig for yes/no mode
def yes_no_mode():
pass
recipe_dictionary = [
{'id': '192281',
'name': 'southern butter mints',
'minutes': '15',
'steps': 'melt cream cheese and butter in large saucepan over low heat, etc',
'ingredients': ['cream cheese', 'butter']},
{'id': '15017',
'name': 'baked ricotta with parmesan and thyme',
'minutes': '70',
'steps': 'preheat oven to 150c, place the parmesan',
'ingredients': ['parmesan cheese', 'thyme leaves', 'chili flakes']},
{'id': '193618',
'name': 'spaghetti with italian sausage spinach and diced tomatoes',
'minutes': '60',
'steps': 'boil spaghetti until al dente',
'ingredients': ['spaghetti', 'sweet italian turkey sausage', 'diced tomatoes']}]
##Print Welcome message
title = "Find A Recipe"
title_message = """
Welcome to Find A Recipe, the Recipe suggestion app that will blow your...kitchen?!
"""
#print(render(title))
print(title_message)
##create Recipe instances from dictionary
recipe_list = []
print(recipe_dictionary)
for i in recipe_dictionary:
id = i ["id"]
print(id)
#id = Recipe(i, id)
#recipe_list.append(id)
## Get an input on suggestion mode
choose_mode = "Please, choose a suggestion mode:"
modes_list = ["Type an ingredient", "Yes or No"]
suggestion_mode = get_choice(modes_list, choose_mode)
# Based on suggestion mode, run suggestion logic
if suggestion_mode == modes_list[0]:
type_mode()
else:
yes_no_mode()
第二个文件包含所有逻辑 [main.py]
#import recipe_dict
from recipes import Recipe
from math import inf
from random import randrange
# ingredient list function
def get_ingredient_list(recipes):
ingredient_list = []
for recipe in recipes:
for ingredient in recipe.ingredients:
if ingredient not in ingredient_list:
ingredient_list.append(ingredient)
return ingredient_list
# ingredient count function
def get_ingredient_count(recipes):
ingredient_count = {}
for recipe in recipes:
for ingredient in recipe.ingredients:
if ingredient not in ingredient_count.keys():
ingredient_count[ingredient] = 1
else:
ingredient_count[ingredient] += 1
return ingredient_count
# def recipe_by_ingredient function
def get_recipes_by_ingredient(recipes, ingredient):
recipes_by_ingredient = []
for recipe in recipes:
if ingredient in recipe.ingredients:
recipes_by_ingredient.append(recipe)
return recipes_by_ingredient
# ingredient for optimal subset function
def get_optimal_ingredient(recipes):
best_subset_possible = len(recipes) // 2
optimal_ing = ""
optimal_count = inf
ingredient_count = get_ingredient_count(recipes)
for ingredient, count in ingredient_count.items():
if abs(best_subset_possible - count) < abs(best_subset_possible - optimal_count):
optimal_ing = ingredient
optimal_count = count
return optimal_ing
# logic for getting user recipe choice
def choose_recipe(choices, input_text):
count = 0
for choice in choices:
count += 1
print(f"{count}) {choice.name}\n")
choice_range = [f"{num}" for num in range(1, count + 1)]
user_choice = input(input_text)
if user_choice not in choice_range:
print(f"invalid input: please choose from 1 to {count}")
choose_recipe(choices, input_text)
else:
return choices[int(user_choice) - 1]
# quicksort function
def quicksort(arr):
if len(arr) <= 1: return arr
m = arr[randrange(0, len(arr))]
return quicksort([i for i in arr if i < m]) + \
[i for i in arr if i == m] + \
quicksort([i for i in arr if i > m])
# quick search in sorted list
def check_match(input, text):
match_count = 0
for char in range(len(input)):
if len(input) > len(text):
return False
elif input[char] == text[char]:
match_count += 1
else:
break
if match_count == len(input):
return True
return False
def find_match(list, input):
# base case
if len(list) == 1:
if check_match(input, list[0]) is True:
return list[0]
return "no match found..."
# define slicers
pivot = len(list) // 2
start = pivot
end = pivot
# check for match
if check_match(input, list[pivot]) is True:
while start >= 0 and check_match(input, list[start]) is True:
start -= 1
while end <= (len(list) - 1) and check_match(input, list[end]) is True:
end += 1
# else call recursive steps
else:
if input < list[pivot]:
return find_match(list[:pivot + 1], input)
return find_match(list[pivot:], input)
# return sliced list
return list[start + 1:end]
##helper variables and functions
def bolean_test(prompt):
user_input = input(f"{prompt} [y/n]")
if user_input.lower() == "y":
return True
elif user_input.lower() == "n":
return False
else:
return bolean_test(prompt)
def get_choice(choices, input_text):
count = 0
for choice in choices:
count += 1
print(f"{count}) {choice}\n")
choice_range = [f"{num}" for num in range(1, count)]
user_choice = input(input_text)
if user_choice not in choice_range:
print(f"invalid input: please choose from 1 to {count}")
return get_choice(choices, input_text)
else:
return choices[int(user_choice) - 1]
# ingredient filtering logic
def ingredient_filtering(ingredient_list):
search_ingredient_input = input("Type the first letter or first few letters of the ingredient you are looking for:")
match = find_match(ingredient_list, search_ingredient_input)
if type(match) is list:
print("\nMatches found:\n")
for i in match:
print(i)
test = bolean_test("Want to filter some more?")
elif type(match) is str:
print(match)
test = False
if test is True:
return ingredient_filtering(match)
else:
if type(match) is list:
return match
return ingredient_list
# recipe filtering logic
def filter_recipes(ingredients, recipes):
recipes_filtered = []
for i in ingredients:
subset = get_recipes_by_ingredient(recipes, i)
for r in subset:
if r not in recipes_filtered:
recipes_filtered.append(r)
return recipes_filtered
第三个包含我遇到问题的课程,称为 [recipes.py]
class Recipe():
def __init__(self, dict, id):
self.id = id
self.name = dict["name"]
self.minutes = dict["minutes"]
self.steps = eval(dict["steps"])
self.ingredients = eval(dict["ingredients"])
def has_ingredient(self, ingredient):
return ingredient in self.ingredients
def __str__(self):
print(self.name.title() + "\n")
print(f"Preparation time: {self.minutes} minutes \n")
print("Ingredients:")
for i in self.ingredients:
print(f"- {i};")
print("\nPreparation Steps:")
for s in self.steps:
print(f"- {s};")
return ""
当我将数据库移动到一个文件中时,我盯着一大堆错误
解决方案
第三个是我遇到问题的课程
这些行中至少有一条会失败,因为您正在尝试使用eval()
非 Python 代码。
self.steps = eval(dict["steps"])
self.ingredients = eval(dict["ingredients"])
参考
'steps': 'melt cream cheese and butter in large saucepan over low heat, etc',
'ingredients': ['cream cheese', 'butter']},
例如
>>> eval('melt cream cheese and butter in large saucepan over low heat, etc')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 1
melt cream cheese and butter in large saucepan over low heat, etc
^
SyntaxError: invalid syntax
相反,你应该让你的类像这样(或者更好,使用 dataclass)
class Recipe():
def __init__(self, id, name, minutes, steps, ingredients):
self.id = id
self.name = name
self.minutes = minutes
self.steps = steps
self.ingredients = ingredients
然后消除对字典的需要
##create Recipe instances
recipe_list = [
Recipe(id='192281',name='southern butter mints', minutes='15', steps='melt cream cheese and butter in large saucepan over low heat, etc', ingredients=['cream cheese', 'butter']),
...
]
如果您希望in recipes
条件工作,您需要__eq__
在该类中实现功能。如果您希望能够对列表进行排序,那么__cmp__
如果您想要一个可以过滤、排序和查询的适当数据库,请从sqlite3
推荐阅读
- android - Android Studio:服务管理器的模拟器错误
- java - 如何解决库根依赖的gradle依赖冲突?
- json - 在下一个函数写入文件之前,如何让一个函数打开文件,写入文件然后关闭文件?
- c++ - 有没有办法在编译时获取函数参数名称?
- git - Strapi 定制工作流程和 CI/CD
- javascript - 如何从
- python - Sparkml 使用新数据进行预测会给出 ArrayIndexOutOfBoundsException
- c - 从C中具有特殊字符的句子中删除多余的空格
- python - 如何使用 scipy.optimize.minimize() 指定目标函数最小化的参数?
- python - Python 线性回归预测错误 - 数组问题