-1

I have just started to learn Python and I have a question regarding the FOR LOOP and how to make it loop until he finds a specific element in a list and then make it stop without iterating through the other list's elements :

I created two python file: 1) Database.py 2) App.py

In "Database.py" I have the following code:

books = []

In "App.py" I have this code:

def prompt_read_book():
    book_to_search = input("Write the NAME of the book you want to mark as 'READ':\n")
    for book in database.books:
        if book_to_search.lower() == book["name"]:
            print(f"The book '{book_to_search}' is now marked as READ")
            book["read"] = True
            print("-" * 40)
        else:
            print(f"Sorry but the book {book_to_search} is not in the database")
            print("-" * 40)

When I have more than 1 book (2 or more) in my books list, the function I wrote does not work as I expected.

Example:

books = [{"name": "Fight Club", "author": "Chuck Palahniuk", "read": False}, {"name": "Homo Deus", "author": "Yuval Noah Harari", "read": False}]

I want to "mark as READ" only the book with name "Fight Club". So I input the name "Fight Club". The book_to_search variable becomes: Fight Club The function runs correctly and changes the {"read": False} to {"read": True}

HOWEVER

Since I am in the for loop, it keeps iterating and it also prints: "Sorry but the book Homo Deus is not in the database" (My understanding of the problem is the following: since we are in a for loop, the program checks one by one all the elements of the list to find if they match with the input the user wrote. Thus I need a way to stop the for loop once the matching element has been found).

What I would like is the following:

-Once the book_to_search matches with the element of the dictionary, the for loop has to stop without iterating the others list' elements

-If the book_to_search does to match with any element in the dictionary, I want to print "Sorry but the book {book_to_search} is not in the database"

Magofoco
  • 5,098
  • 6
  • 35
  • 77
  • 2
    Are you looking for the [`break`](https://docs.python.org/3/tutorial/controlflow.html#break-and-continue-statements-and-else-clauses-on-loops) statement? – Aaron Jun 12 '18 at 20:51
  • 1
    See https://stackoverflow.com/questions/42913798/searching-array-reports-not-found-even-though-its-found/42913882#42913882 – Barmar Jun 12 '18 at 20:53

1 Answers1

1

add a break once the book has been found, and declare a True or False to a variable that detects if it's been found:

def prompt_read_book():
    book_to_search = input("Write the NAME of the book you want to mark as 'READ':\n")
    found = False
    for book in database.books:
        if book_to_search.lower() == book["name"]:
            print(f"The book '{book_to_search}' is now marked as READ")
            book["read"] = True
            print("-" * 40)
            found = True
            break

    if not found:
        print(f"Sorry but the book {book_to_search} is not in the database")
        print("-" * 40)

EDIT: i just edited my answer since i misread the last part. now it will only print the "Sorry but..." if it wasn't found.

crookedleaf
  • 2,118
  • 4
  • 16
  • 38
  • This will still print the "Sorry" message for every other book before that. – Barmar Jun 12 '18 at 20:54
  • @Barmar whoops, i misread the last part of the question – crookedleaf Jun 12 '18 at 20:56
  • I understand the "break" advice and I tried it, many thanks. However, I get another problem if I set the "break". Basically, if I want to change from {"read": False} to {"read": True} in the second (or third etc.) element of the list, I get printed the string ("Sorry but the book {book_to_search} is not in the database") because the first element has been iterated even if it does not match what the user has written. – Magofoco Jun 12 '18 at 20:58
  • @FBSO please check the edit i just made. hopefully that fixes the issue. as far as what you're saying about changing "read" to True... do you mean on all occurrences of the book? – crookedleaf Jun 12 '18 at 21:00
  • @crookedleaf Yes, for all the occurrences. The edit you made solved the issue. Thanks. – Magofoco Jun 12 '18 at 21:18
  • @FBSO the edit i made probably only seems like it works because it stops after the first occurrence of the book. it doesn't mark every occurrence as read. if you'd like, i can add another edit that would show how to either mark all instances as read, or remove duplicate instances. – crookedleaf Jun 12 '18 at 22:49