I have a relatively simple use case, where I need to load up the types of vehicles that fit a specific criteria. This criterion is shown in the "sample_input" variable.
Now I need to display cars that fit the correct criteria. I am reading my car
database JSON and then creating car objects and adding them to my carDatabase list, from this list I need to select cars that fit the user's request.
So essentially what happens is this I have loaded a simple sample_input
variable in my Main.Py
The code should do this but it doesn't (better implementations are always welcome)
Check if Name
is empty []
; if it is, move on; if not, search for cars with the same name, move to the next criterion which is country of origin, check if it is empty, if it is not look for cars with the Name(s) and country of origins(s), and etc etc for the rest of criteria.
import json
from Vehicle import Vehicle
sample_input = {
"Name": [],
"country of origin": ["france", "uk"],
"transmission": [],
"body type": ["coupe"],
"drive type": [],
"doors": [],
"fuel type": []
}
def test():
with open("data.json") as omapper:
data = json.load(omapper)
Database= []
for i in data["vehicles"]:
name = i["Name"]
origin = i["country of origin"]
transmission = i["transmission"]
bodytype = i["body type"]
drivetype = i["drive type"]
doors = i["doors"]
fueltype = i["fuel type"]
vehicle= Vehicle(name,origin,transmission,bodytype,drivetype,doors,fueltype)
Database.append(car)
UserOutput = []
for vehicles in Database:
if vehicles.origin in sample_input["country of origin"] and vehicles.body_type in sample_input["body type"] and vehicles.doors in sample_input["doors"] != "":
print(vehicle.name)
if __name__ == "__main__":
test()
Vehicle.py
: Model class
class Vehicle:
def __init__(self, name, origin, transmission, body_type, drive_type, doors, fuel_type):
self.name = name
self.origin = origin
self.transmission = transmission
self.body_type = body_type
self.drive_type = drive_type
self.doors = doors
self.fuel_type = fuel_type
Vehicle JSON: All the vehicles my application supports.
{
"attributes": {
"country of origin": ["japan", "america", "germany", "south korea", "italy", "sweden"],
"transmission": ["automatic", "manual"],
"body type": ["hatchback", "sedan", "SUV", "ute", "coupe", "convertible", "van"],
"drive type": ["RWD", "FWD", "4WD"],
"doors": ["4 door", "2 door"],
"fuel type": ["petrol", "diesel", "electric", "hybrid"]
},
"vehicles": [
{
"Name": "studebaker dictator",
"country of origin": "america",
"transmission": "manual",
"body type": "sedan",
"drive type": "RWD",
"doors": "2 door",
"fuel type": "petrol"
},
{
"Name": "mitsubishi zero",
"country of origin": "japan",
"transmission": "manual",
"body type": "hatchback",
"drive type": "FWD",
"doors": "2 door",
"fuel type": "petrol"
},
...
]
}
You just need to spell out the conditions you already laid out in your prose exposition.
for vehicle in Database:
if (not sample_input["country of origin"] or vehicle.origin in sample_input["country of origin"]) and (
not sample_input["transmission"] or vehicle.transmission in sample_input["transmission"]) and (
not sample_input["body type"] or vehicle.body_type in sample_input["body type"]
):
print(vehicle.name)
not sample_input["x"]
will be True
if sample_input["x"]
is an empty list; if it is not, we check that vehicle.x
is in the list.
Note also how I changed the loop variable to the singular form; we are examining one vehicle
at a time.
If you need to be able to access each possible attribute in a loop, try something like
class Vehicle:
# ...
def attr_map(self, label):
"""
Map a label like 'country of origin' to
the corresponding internal attribute,
and return that.
"""
return {
'country of origin': self.origin,
'transmission': self.transmission,
'body type': self.body_type,
# ... etc
}[label]
and then just loop over the attributes you want:
for vehicle in Database:
vehicle_selected= True
for attr in sample_input:
if sample_input[attr] and vehicle.attr_map(attr) not in sample_input[attr]:
vehicle_selected = False
break
if vehicle_selected:
print(vehicle.name)
You could do something similar with the i
in your JSON import loop if you wanted to; then the method to map a key to an attribute isn't necessary, and you can simply check ... and i[attr] in sample_input[attr]