#python
#python
Вопрос:
У меня есть программа, в которой есть опция поиска, которая, если курица или цыпленок есть в инвентаре, она вытащит элемент, просто набрав chi (не чувствительный к регистру). Проблема в том, как мне заставить функцию возвращать все элементы, содержащие chi?
Например, если у меня есть цыплята, цыплята, цыплята и цыплята в инвентаре, я должен иметь возможность ввести chi, и он должен распечатать всю информацию о каждом элементе.
Затронутый код (не полная программа):
def search(self, query):
#SEARCHING DATA BASED ON CLOSEST CHARACTER MATCH - NOT CASE SENSITIVE
for id in self.items:
if str(query) == id or self.items[id]['name'].lower().startswith(str(query).lower()):
return id, self.items[id]['name'], self.items[id]['qty']
return None
Полный код для целей тестирования:
import os
import json
class Inventory:
def __init__(self):
#AT LAUNCH GROUPS AND LOADING FUNCTION
self.items = {}
self.load()
def remove(self, ID):
#REMOVING ITEMS FOR LISTS AND OUTPUT DOCUMENT
del self.items[str(ID)]
self.save()
def add(self, ID, name, qty):
#ADDING ITEMS FOR LISTS AND OUTPUT DOCUMENT
self.items[str(ID)] = {"name": name, "qty": qty}
self.save()
def update(self, ID, update):
#UPDATING ITEMS FOR LISTS AND OUTPUT DOCUMENT
self.items[str(ID)]["qty"] = update
self.save()
def search(self, query):
#SEARCHING DATA BASED ON CLOSEST CHARACTER MATCH - NOT CASE SENSITIVE
found = []
for id in self.items:
if str(query) == id or self.items[id]['name'].lower().startswith(str(query).lower()):
found.append(
(id, self.items[id]['name'], self.items[id]['qty'])
)
return found
def __str__(self):
#FORMATTING
out = ""
for id, d in self.items.items():
out = f"ID Number : {id} nItem Name : {d['name']}nQuantity : {d['qty']}n"
out = "----------n"
return out
def save(self):
#WHERE TO SAVE TO
with open('data.txt','w') as outfile:
json.dump(self.items, outfile)
def load(self):
#WHERE TO PUT DATA FROM WHEN RELAUNCHING PROGRAM
try:
with open('data.txt','r') as json_file:
self.items = json.load(json_file)
except:
print("Can't load old inventory, starting fresh")
self.items = {}
def menuDisplay():
#MENU FOR PROGRAM
"""Display the menu"""
print('=============================')
print('= Inventory Management Menu =')
print('=============================')
print('(1) Add New Item to Inventory')
print('(2) Remove Item from Inventory')
print('(3) Update Inventory')
print('(4) Search Item in Inventory')
print('(5) Print Inventory Report')
print('(99) Quit')
def add_one_item(inventory):
#ADDING PROMPT AND ERROR CHECKING
print('Adding Inventory')
print('================')
while True:
try:
new_ID = int(input("Enter an ID number for the item: "))
if inventory.search(new_ID):
print("ID number is taken, please enter a different ID number")
continue
new_name = input('Enter the name of the item: ')
new_qty = int(input("Enter the quantity of the item: "))
inventory.add(new_ID, new_name, new_qty)
break
except Exception as e:
print("Invalid choice! try again! " str(e))
print()
def remove_one_item(inventory):
#REMOVING PROMPT AND ERROR CHECKING
print('Removing Inventory')
print('==================')
while True:
try:
removing = int(input("Enter the item's ID number to remove from inventory: "))
if inventory.search(removing):
inventory.remove(removing)
else:
print("Item not in inventory")
continue
break
except Exception as e:
print("Invalid choice! try again! " str(e))
print()
def ask_exit_or_continue():
#OPTION TO CONTINUE OR QUITE PROGRAM
return int(input('Enter 98 to continue or 99 to exit: '))
def update_inventory(inventory):
#UPDATING PROMPT AND ERROR CHECKING
print('Updating Inventory')
print('==================')
while True:
try:
ID = int(input("Enter the item's ID number to update: "))
if inventory.search(ID):
update = int(input("Enter the updated quantity. Enter 5 for additional or -5 for less: "))
inventory.update(ID, update)
else:
print("ID number is not in the system, please enter a different ID number")
continue
break
except Exception as e:
print("Invalid choice! try again! " str(e))
print()
def search_inventory(inventory):
#SEARCHING PROMPT AND ERROR CHECKING
print('Searching Inventory')
print('===================')
while True:
try:
search = input("Enter the name of the item: ")
result = inventory.search(search)
if result is None:
print("Item not in inventory")
continue
else:
ID, name, qty = result
print('ID Number: ', ID)
print('Item: ', name)
print('Quantity: ', qty)
print('----------')
break
except Exception as e:
print("Invalid choice! try again! " str(e))
print()
def print_inventory(inventory):
#PRINT CURRENT LIST OF ITEMS IN INVENTORY
print('Current Inventory')
print('=================')
print(inventory)
def main():
#PROGRAM RUNNING COMMAND AND ERROR CHECKING
inventory = Inventory()
while True:
try:
menuDisplay()
CHOICE = int(input("Enter choice: "))
if CHOICE in [1, 2, 3, 4, 5]:
if CHOICE == 1:
add_one_item(inventory)
elif CHOICE == 2:
remove_one_item(inventory)
elif CHOICE == 3:
update_inventory(inventory)
elif CHOICE == 4:
search_inventory(inventory)
elif CHOICE == 5:
print_inventory(inventory)
exit_choice = ask_exit_or_continue()
if exit_choice == 99:
exit()
elif CHOICE == 99:
exit()
except Exception as e:
print("Invalid choice! try again!" str(e))
print()
# If the user pick an invalid choice,
# the program will come to here and
# then loop back.
main()
Ответ №1:
Для более общего ответа, если вы просто хотите найти подмножество элементов, содержащих подстроку, это хорошее решение:
def subset_contains(input_word, valid_words):
match_list = [word for word in valid_words if input_word in word]
return match_list
запуск этого кода:
valid_words = ['chicken', 'cheese', 'chess', 'dog', 'coach']
print(subset_contains('ch', valid_words))
результат в этом выводе:
['chicken', 'cheese', 'chess', 'coach']
Вот еще несколько подробных кодов, которые могут быть больше похожи на то, что вы ищете
#defining object, which has a name and description
class object:
def __init__(self, name, info):
self.name = name
self.info = info
#returns a subset of a list where the name contains a string
def return_contains(match_name, objects):
match_list = [obj for obj in objects if match_name in obj.name]
return match_list
#defining objects
objects = [object('chicken', 'chicken 1'),
object('chicken', 'chicken 2'),
object('chicken', 'chicken 3'),
object('coach', 'teaches chickens'),
object('boat', 'im boat')]
#doing the filtering
result = return_contains('ch', objects)
#printing out the results
for r in result:
print('name: {}, description: {}'.format(r.name, r.info))
вывод:
name: chicken, description: chicken 1
name: chicken, description: chicken 2
name: chicken, description: chicken 3
name: coach, description: teaches chickens
Комментарии:
1. Возможно, @GeorgeDavidson… Как правило, идея состоит в том, чтобы предоставить как можно меньше кода, сколько необходимо, при этом предоставляя все, что необходимо. Так что, если вы хотите добавить немного больше кода, это может быть полезно
2. @GeorgeDavidson круто. пока вы это делали, я изменил свой ответ на что-то, включая фильтрацию объектов. Взгляните на это. Если моего ответа недостаточно или у вас есть какие-либо вопросы, lmk
3. кроме того, @GeorgeDavidson, несколько полезно публиковать весь ваш код, часто лучшим решением является создание нового кода, который содержит только то, что необходимо. Это называется минимально воспроизводимым кодом, и это помогает сделать stack overflow высококачественной средой, в которой каждый может учиться
4. возможно ли, чтобы вы посмотрели на другой ответ Green Cloak Guy и исправили его проблему?
Ответ №2:
Прямо сейчас вы просто возвращаете первый найденный. Вместо этого вам нужно составить список всех найденных и вернуть это:
def search(self, query):
#SEARCHING DATA BASED ON CLOSEST CHARACTER MATCH - NOT CASE SENSITIVE
found = []
for id in self.items:
if str(query) == id or self.items[id]['name'].lower().startswith(str(query).lower()):
found.append(
(id, self.items[id]['name'], self.items[id]['qty'])
)
return found
Комментарии:
1. Теперь я получаю эту ошибку с вашим кодом: неверный выбор! попробуйте еще раз! недостаточно значений для распаковки (ожидалось 3, получено 2)
2. Не могли бы вы уточнить? Где возникает эта ошибка? Обратите внимание, что с помощью этого решения вам нужно будет изменить код, вызывающий функцию, для обработки списка кортежей, а не одного отдельного кортежа.
3. как только я нажму enter после ввода символов, которые я ищу. Вам нужен полный программный код?