How to Make a Loop that keeps the user in an entry loop til the input matches a key value in a list of dicitonaries?

Question:

I am in the process of trying to create a loop, that allows a user to delete an item if the input matches a key value found in a list of dictionaries.

Here is my current list of dicitionaries.


{'Item #': 1, 'Price': 3.99, 'Quantity': 1, 'Name': 'Muffin 1'}
{'Item #': 2, 'Price': 4.99, 'Quantity': 2, 'Name': 'Muffin 2'}
{'Item #': 3, 'Price': 5.99, 'Quantity': 3, 'Name': 'Cookie 1'}
{'Item #': 4, 'Price': 6.99, 'Quantity': 4, 'Name': 'Cookie 2'}
{'Item #': 5, 'Price': 7.99, 'Quantity': 50, 'Name': 'Muffin 3'}

I already have a valid method that deletes the specific dictionary, based upon the value of the item # key.

Here is my relevant code:


def enter_data(self, message, typ):
            while True:
                try:
                    v = typ(input(message))
                except ValueError:
                    print(f"Thats not an {typ}!")
                    continue
                else:
                    break
            return v

def delete_item_interaction(self):
            while True:
                delete_item_number = self.enter_data("Please enter the item # of the item you would like to deleten", int)
                for item item in self.database.result
                    if item["Item #"] != delete_item_number:
                       #keep in loop? 
                       #print item not found in any dictionary Item # value in list
                    else:
                       #break?
            self.database.delete_item(delete_item_number)
            print("Item Deleted! Check Inventory again for a refresh!")

I am trying to make a loop, but seem to be struggling with the logic and formatting behind it. I would like something similiar to what I did with enter_data, in which it keeps the user in a input loop, until a valid entry is given. For example, with delete_item_interaction, it should

  1. In the loop, ask the user for the input of the Item# they would like to delete
  2. For every dictionary in the list, search if any of them have the input equal to their "Item #" key value
  3. If found print item found! and exit the loop and send the input to the method that deletes the item
  4. If not found in any of the dictionaries "Item #" key values, print Item not found, and circle back to the beginning of the loop, to ask for another input.

I understand the logic behind what I am looking for and want, but seem to be having trouble
formatting it, and the inclusion of the for loop confuses me. How would I make this method do this?

Asked By: py_coder1019

||

Answers:

With least possible modification to the provided code, since you have two loops a for loop inside a while loop, you can create a flag variable item_found inside the while loop which is initially False, then when you are iterating the values in for loop, you can set the variable to True and break the for loop. Once you are outside the for loop, you can check if the flag is True or not and then decide whether to break the while loop or to continue

while True:
    delete_item_number = self.enter_data("Please enter the item # "
                                         "of the item you would like to deleten", 
                                         int)
    item_found = False
    for item  in self.database.result
        if item["Item #"] == delete_item_number:
            item_found = True
            break
        # keep in loop? 
        # print item not found in any dictionary Item # value in list
    if item_found:
        self.database.delete_item(delete_item_number)
        print("Item Deleted! Check Inventory again for a refresh!")
    else:
        continue

And in fact, you can even bring item_found outside the while loop and run the while loop based on the flag value, something likea:

item_found = False
while not item_found:
 .
 .
 .
 .
 for ... :
    if item["Item #"] == delete_item_number:
        item_found = True
 if item_found:
    self.database.delete_item(delete_item_number)
    print("Item Deleted! Check Inventory again for a refresh!")
Answered By: ThePyGuy

You can do it by create while that will run (enter_data) and when the user write something wrong make the function do return to the loop or the wile

Like this idea

 def enter_date():
     Data = input("ENTER THE DATA : ")
     if Data == "right answer":
         print("Good")
     else:
          return

while True:
     enter_data()
Answered By: Mohammed almalki

the most pythonic (and efficient) way to do it is with a generator expression.

def delete_item_interaction(self):
    while(True):
        delete_item_number = self.enter_data("Please enter the item # of the item you would like to deleten", int)
        if delete_item_number in (item["Item #"] for item in self.database.result):
            self.database.delete_item(delete_item_number)
            print("Item Deleted! Check Inventory again for a refresh!")
            break
        else:
            print("item not found ...")
Answered By: Ahmed AEK

Add a variable that can tell if the item was found or not:

def delete_item_interaction(self):
            while True:
                delete_item_number = self.enter_data("Please enter the item # of the item you would like to deleten", int)
                Found_Item = None
                for item in self.database.result:
                    if item["Item #"] == delete_item_number:
                        #Found the item
                        Found_Item = item
                        print(f"Found item with number {item['Item #']}")
                    if Found_Item is not None:
                        #We don't need to check anymore items because we found the matching one
                        continue
                if Found_Item is None:
                    #Print and restart the loop
                    print("Item was not found!")
                else:
                    #Break because item was found
                    break
            #Delete the item with the number
            self.database.delete_item(delete_item_number)
            print("Item Deleted! Check Inventory again for a refresh!")

Answered By: susthebus
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.