Reputation: 39
Hello i am new to python and i have a question about dictionaries:
Let's say we have a dictionary :
Cars {"Audi": {"Wheels": 4, "Body": 1, "Other": 20},"Ford": {"Wheels": 2, "Body": 3, "Other":10},"BMW": {"Wheels": 5, "Body": 0.5, "Other": 30}}
And and other dictionary:
Materials {"Wheels": 30, "Body": 5, "Other": 110}
I want to return the number of cars i can produce with the materials i have so:
def production(car,Materials):
return
production("Audi",Materials)
My output in this example should return the number 5,because there are only 5 body parts to use. I was thinking to make it somehow like this: Divide the values from Materials with values from cars. Then write the numbers to an other list ,and then return the min number in whole.
More exaples:
production("BMW",Materials)
3.0 # because the value of key only is 110 and for 3 cars we need 90 other:
production("Ford",Materials)
1.0 # because the value of key body is 3 and for 1 car we need 3 body:
I thank you in advance for everything.
Upvotes: 1
Views: 563
Reputation: 180391
You can iterate over materials and decrement the values until one become 0:
def production(car, materials):
count = 0
while 0 not in materials.values():
for part in cars[car]:
materials[part] -= 1
count += 1
return count
If you don't want to change the material dict:
def production(car, materials):
count = 0
vals = materials.values()
while not 0 in vals:
for ind, part in enumerate(Cars[car]):
vals[ind] -= 1
count += 1
return count
Upvotes: 1
Reputation: 5059
If what you want is to see how many of any given car can be created without actually affecting the contents of Materials
, you could write your method like so:
def number_of_units_creatable(car_key):
required_parts = Cars[car_key]
return min(Materials["Wheels"] // required_parts["Wheels"],
Materials["Body"] // required_parts["Body"],
Materials["Other"] // required_parts["Other"])
In production, you'd want to add conditional guards to check whether your Cars
and Materials
have all the required keys. You'll get an exception if you try to get the value for a key that doesn't exist.
This will allow you to figure out the maximum number of any given car you can create with the resources available in Materials
.
I'd strongly recommend you not use nested dicts like this, though - this design would be greatly helped by creating, say, a Materials
class, and storing this as your value rather than another dictionary. abarnert has a little more on this in his post.
Another note, prompted by abarnert - it's an extremely bad idea to rely on all a shared, static set of keys between two separate dictionaries. What happens if you want to build, say, an armored car, and now you need a gun? Either you have to add Gun: 0
within the required attributes of every car, or you'll run into an exception. Every single car will require an entry for every single part required by each and every car in existence, and a good deal of those will signify nothing other than the fact that the car doesn't need it. As it stands, your design is both very constraining and brittle - chance are good it'll break as soon as you try and add something new.
Upvotes: 5
Reputation: 365657
If the set of possible materials is a static collection—that is, it can only have "Wheels", "Body", and "Other"—then you really ought to be using a class rather than a dict, as furkle's answer suggests, but you can fake it with your existing data structure, as his answer shows.
However, if the set of possible materials is open-ended, then you don't want to refer to them one by one explicitly; you want to loop over them. Something like:
for material, count in car.items():
In this case:
return min(Materials[material] // count for material, count in car.items())
Upvotes: 3