Looking to gather multiple inputs for different people and store in a dictionary

Hello all,

I am seeking to gather both the user’s favorite color and favorite car. Then I am looking to gather input from multiple users (asking the same two questions multiple times) and store the results in a dictionary.

I have two problems at the moment. The first is that (with my current code) asking for the favorite color and favorite car works properly but then simply asks for the favorite color again rather than ending the running loop and printing the results. The second problem is that I am unsure how to separately store input.

> running = True
> while running:
>     favcolor = input("Please enter favorite color: ")
>     favcolorok = False
>     while not favcolorok:  
>         if favcolor:
>             try:
>                 favcolor
>                 if favcolor:
>                         favcolorok = True
>                 else: 
>                     favcolorok = False
>             except:
>                 favcolorok = False
>         else:
>             favcolorok = False    
>     favcar = input("Please enter favorite car ")
>     favcarok = False
>     while not favcarok:  
>         if favcar:
>             try:
>                 favcar
>                 if favcar:
>                     favcarok = True
>                 else: 
>                     favcarok = False
>             except:
>                 favcarok = False
>         else:
>             favcarok = False
> 
> running = False
> print(f"Your favorite color is {favcolor} and your favorite car is {favcar}")`Preformatted text`

What you have so far could be made much less complicated:

favcolor, favcar = False, False

while not favcolor:  
    favcolor = input("Please enter favorite color: ")    
while not favcar:
    favcar = input("Please enter favorite car: ")

print(f"Your favorite color is {favcolor} and your favorite car is {favcar}")

Did we not cover dictionaries already?

edit to add:

Yes; it’s right here:

So, how do you think that you could apply what you learned there, to what you need to do here?

What would be the structure of dictionary? Like

answers = {'answer1': {'favcolor': 'red', 'favcar': 'Monty Python Killer Cars'}}

or

answers = {'favcolor': ['red', 'yellow'], 'favcar': ['Monty Python Killer Cars' , 'MG1100']}

or something else?

Alternative to @rob42 approach:

>>> while not (favcar := input('Enter Your Favourite Car: ')):
...     print('Expected your favourite car but nothing was entered')
...
Enter Your Favourite Car:
Expected your favourite car but nothing was entered
Enter Your Favourite Car:
Expected your favourite car but nothing was entered
Enter Your Favourite Car: Monty Python Killer Cars
>>> favcar
'Monty Python Killer Cars'

To me, the obvious structure for storing the data is a list of dictionaries.

Yes, if the OP knows how to use the assignment expression operator. If not, this may seem a little confusing.

I don’t know that I’ve ever seen a “list of dictionaries”. Maybe you could show me?

A trivial example looks like this:

[{'foo': 1, 'bar': 2}, {'baz': -7, 'quux': 23}]

Two things :smile: : as they say: “In the face of ambiguity, refuse the temptation to guess.” and list of dictionaries is still list, not dictionary.

About list of dictionaries: these can be seen as “poor man database” :slight_smile: . If every dictionary in list have same structure/keys one can make queries. Simple function below enables to choose what keys you want from dictionaries which meet criteria set:

data = [{"id": 1, "status": 1, "location": 2, "result": 9.82},
       {"id": 2, "status": 1, "location": 2, "result": -5},
       {"id": 3, "status": 1, "location": 5, "result": 7.98}]

def filter_dicts(data, *args, **kwargs):
    for row in data:
        for k, v in kwargs.items():
            if row[k] != v:
                break
        else:
            yield {key: row[key] for key in args}

# give me id and result for dictionaries which status is 1 and location is 2

print(*filter_dicts(data, 'id', 'result', status=1, location=2))

# {'id': 1, 'result': 9.82} {'id': 2, 'result': -5}

Interesting; thank you.

Getting at the keys/data in that list has to be a bit of a mare, no? Or even changing one of the items, can’t be so easy?

With a dictionary, I would (for example) have the code:

example = {'foo': 1,
           'bar': 2,
           'baz': -7,
           'quux': 23
           }

keys = example.keys()

… to get a iterator. It’s also easy (as I’m sure you know) to access and change any item.

I’ll have to look at how one would do that, when dictionaries are nested within a list object: on the face of it, it does not seem to be so straight forward.

Yes, it’s true.

But if you want to have data for 5 cars - mark, color, price? How you solve it with flat dictionary? Dictionary keys among other things must be unique, so one can’t have 5 ‘mark’/‘color’/‘price’ keys. Create separate dictionary/variable for every car? How then to filter out red cars (it’s possible but should it be done this way?)?

What I was going to suggest, was not a flat dictionary, rather a list nested dictionary:

user_db = {'alice': [],
         'bob': []
         }

… to which the items (color and make) can be appended, if not already there (we’re assuming a program loop here). If the items are already there (because we’re in a second loop, or more), an option can be offered to change an item. This would all be controlled by: login = input("Please login:> ") so that the correct data would be accessed (the login being mapped to the dictionary keys), together with the option for change.

This will build on what the OP has already learned, from the post that I linked.

edit to add @aivarpaalberg

Looking back at that other thread, I can now see that you suggested a “list of dictionaries”, with the code that you posted, but I did not see any follow-up, by way of a working solution, based on that code.

The kind of data structure you’re trying to model is best represented by a simple class:

from dataclasses import dataclass, field


@dataclass(slots=True)
class User:
    favorite_color: str = field(init=False)
    favorite_car: str = field(init=False)
    
    def __post_init__(self):
        self.favorite_color = input("What is your favorite color?")
        self.favorite_car = input("What is your favorite car?")

I’m sure that you’re correct, but the OP does not know about basic data structures yet, let alone classes.

2 Likes

Thank you for the reply!

I will go back over the dictionaries topic we previously discussed, but how do I cut my loops at 5 inputs per person even using the code you suggested above?

Thank you for the reply! I believe the former example you listed is preferable, where it shows favorite color and favorite car of each user.

Five inputs per person?? I must of missed that detail; I’ll look back at your first post.

edit to add:

There’s no mention of that, in your first post; it simply implies that every person will have a favorite color and a favorite car: one of each, for each person.

Thank you for the reply! Rob42 is correct that I have not learned and am therefore not allowed to use classes yet.

1 Like

I apologize I must have forgot to mention that part. Not necessarily 5 inputs per person, but 5 total sets of 2 choices. So 5 people each choosing 1 favorite car and 1 favorite color…then the information stored in a dictionary.

No matter; my approach can be extended, but (as always) start with one and build on it – small steps.

What would be good for you, is to see solutions from others that have kindly offered support here, rather than just my solution.

I am still unclear as to how I am supposed to approach this, I need another while loop to count up to 5 for 5 different users inputting favorite car and favorite color correct?

Something like this

favcolor, favcar = False, False
gathering = True
while gathering
    while not favcolor:  
        favcolor = input("Please enter favorite color: ") \
        "append favcolor list"   
    while not favcar:
        favcar = input("Please enter favorite car: ")
        "append favorite car list"
    """"index count here, stops at 5"""""""