Why does this code print two error messages instead of one?

Question:

So I was making a test code that reads in json and you have to input the value to access:

import json

f = "keys.json"
data = json.loads(open(f).read())

username = input("User: ")
key = input("Key: ")

for item in data:
    if item['user'] != username:
        print("Incorrect username.")
    elif item['key'] != key:
        print("Incorrect key.")
    else:
        print(f"Welcome, {username}.")

And this is what the json file looks:

[
 {
    "id": 1,
    "user": "susan",
    "key": "yes"
  },
  {
    "id": 2,
    "user": "susana",
    "key": "yess"
  }
]

And this is the output:

User: susan
Key: yes
Welcome, susan.
Incorrect username.

It prints the correct verification and the incorrect verification, but only username, because if key is incorrect it prints like this:

User: susan
Key: e
Incorrect key.
Incorrect username.

What I can do to delete the second message?

Asked By: rVan

||

Answers:

Reason: the problem is that you have two elements in the json file, as it loop through the list,it runs the print function for all elements.

Solution: put an addtional if check at the beginning of the loop to prevent any output from other failed cases.

flag = False
for item in data:
    # skip if username doesn't match
    if item['user'] == username:
        # check if password matches
        if item['key'] != key:
            print("Incorrect key.")
        else:
            print(f"Welcome, {username}.")
        flag = True
if not flag:
    print("Incorrect username.")
Answered By: ZackTack
  1. After a successful verification, you don’t want to continue the for loop – use the break command.

  2. If the for loop is exhausted (i.e., no break command was performed) it means that the correspondent record was not found. Use the else: branch of the for loop to inform about a fail:

for item in data:
    if item['user'] == username and item['key'] == key:
        print(f"Welcome, {username}.")
        break
else:
    print("Incorrect username or key.")

Notes:

  1. This code don’t reveal, what part is incorrect, so a potential intruder will have less information.

  2. Yes, the for loop may have the else: branch, too. It is performed if (and only if) the for loop is fully exhausted.

Answered By: MarianD

The reason is because you do not break out of the loop when you do find a successful match. I would recommend however learning the built in array methods like: filter, find, etc.

In this case you could make your code much easier by saying:

   // [...] the input code is fine
   // Find in data an item that has the username and key == to our inputs
   var user = data.find( item => item.user == username && item.key == key )
   if(user) {
      print(f"Welcome, {username}")
   }
   else {
      print("Incorrect username or key.")
   }

If you were to do it the older more manual way:

    var found = false;
    for item in data:
      if item['user'] == username && item['key'] == key {
         print (f"Welcome, {username}")
         found = true;
         break;
      } 
    }
    if !found 
       print("Incorrect username or key")
Answered By: MiltoxBeyond
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.