Conditions with nested dictionaries - python

Given the following data:
diccionario_datos_clientes = [
{"Name": "Marcos", "Age": 23, "Ranking": 14, "Contact":{ "Work": 99000001, "Personal": 7222003}},
{"Name": "Hugo", "Age": 26, "Ranking": 83, "Contact": { "Work": 99000002, "Personal": 97220042}},
{"Name": "Manuel", "Age": 13, "Ranking": 2, "Contact": { "Work": 99000003, "Personal": 47220003}},
{"Name": "Maria", "Age": 66, "Ranking": 7, "Contact": { "Work": 99000004, "Personal": 47220004}},
{"Name": "Itziar", "Age": 20, "Ranking": 23, "Contact": { "Work": 99000005, "Personal": 47220005}}
]
I have to see if the personal contact is valid. The conditions are the following:
The number has to have 8 digits min
The first number has to be 4
The numbers in the positions 4,5,6 have to be 0.
If the number is not valid I should append the name and work contact to a list.
I was able to do the first 2 conditions but i´m having trouble with the third one.
dic_llamar=[]
for dic in diccionario_datos_clientes:
if len(str(dic['Contact']['Personal']))<8:
dic_llamar.append((dic['Name'],dic['Contact']['Work']))
elif int(str(dic['Contact']['Personal'])[0])!=4:
dic_llamar.append((dic['Name'],dic['Contact']['Work']))
Ask right away if something is not clear!

I think is better to extract this into its own function
def isValid(number):
"""take a number and said if is a valid contact number"""
s = str(number)
return len(s)>=8 and s[0]=="4" and s[4:7]=="000"
(I don't understand why the other repeat the same so many times)
By putting it into its own function is more easy to check if it work (because it can be tested individually) and can be more easily use in other parts of your project if needed.
And use it like
for dic in diccionario_datos_clientes:
if isValid(dic['Contact']['Personal']):
#do something
else:
#do something else
and is cleaner and more beautiful

The last condiction is
if str(dic['Contact']['Personal'])[4:7] == '000':
On a side note, it'll be better if you used only one if:
condiction1 = len(str(dic['Contact']['Personal'])) == 8
condiction2 = str(dic['Contact']['Personal'])[0] == '4'
condiction3 = str(dic['Contact']['Personal'])[4:7] == '000'
if not (condiction1 or condiction2 or condiction3):
append(...)

I believe this would help you solve the issue, I am stating all three conditions needed to be met in the if:
for dic in diccionario_datos_clientes:
s = str(dic['Contact']['Persona'])
if (len(s) >=8) & (s[0]=='4') & (s[4:7] == '000'):
print("Valid contact!")
else:
print("Not valid contact!")
dic_llamar.append((dic['Name'],dic['Contact']['Work']))
So if all conditions are met, you will get valid contact, otherwise not valid contact. Of course you can modify this to fit your best needs.

Related

How do I compare user integer input to values in dictionary? (Python)

I'm working on a vending machine program and my code skips straight to the else statement instead of taking the user input and comparing it to the ID number in the list.
Here's the list and code:
`
itemstock = [
{
"idnum": 0,
"name": 'Water',
"price": 12,
},
{
"idnum": 1,
"name": 'Soda',
"price": 14,
},
{
"idnum": 2,
"name": 'Juice',
"price": 13,
},
]
choice = int(input("Now, choose an item ID from the Menu and enter the ID: "))
for i in itemstock:
if choice in ["idnum"]:
print("You have chosen item", choice)
else:
print("This is not a valid ID.")
break
`
I had hoped for if I had input the number 2, it would display what the user chose along with some text but it skips straight to the else statement. I've tried looking online but I may be doing something wrong here.
if choice in ["idnum"]
That is just a list containing the text "idnum". You want i["idnum"] instead:
for i in itemstock:
if i["idnum"] == choice:
print("You have chosen item", choice)
break
else:
print("This is not a valid ID.")
I also moved the else block out one level, so it is paired with the for loop, not the if statement. When a for loop iterates all the way to the end, the else block is executed (if it has one).

how to use hashmap for string and dictionary in python

I want to implement a use case through hashmap in python. I will be having a json object of type dict.
x={
"name": "Jim",
"age": 30,
"married": True,
"phonenumber": "123456"
"pets": None,
"cars": [
{"model": "toyota", "mpg": 23.5},
{"model": "kia", "mpg": 21.1}
]
}
if (x["married"] == True):
h.put(x[phonenumber]) // i want to make phonenumber as key and the entire dict x as value. by using something like Map<String, dict> h = new HashMap<>();
when i do h.get(phonenumber), i want the entire dict x as an output.
How can i implement this usecase in python.
A dict is python's version of a hash map. To do what you want, try the following:
m = {}
if x["married"]:
m[x["phonenumber"]] = x
As has already been said, the dict() is Python's implementation of hastmaps / hash tables. I've assumed that you are going to have many records, all of which will be stored in a dict(), and that you are adding records according to your example. I have not error-checked for the existence of a phone number in the record; since you're using the phone number as the key then you should already have ensured that there is an actual phone number in the information which you are adding.
#just one record
x={
"name": "Jim",
"age": 30,
"married": True,
"phonenumber": "123456", #you left out a comma here
"pets": None,
"cars": [
{"model": "toyota", "mpg": 23.5},
{"model": "kia", "mpg": 21.1}
]
}
my_dict = dict() #this would hold ALL of your records
def add_to_mydict(my_dict:dict, new_record:dict):
if new_record["married"]:
phone = new_record.pop("phonenumber")
y = {phone: new_record}
my_dict.update(y)
add_to_mydict(my_dict, x)
print(my_dict)
my_dict would be the master dictionary in which you will store your data. SQLite makes a much better database than in-memory dicts.

I am trying to print out the highest bidder in my list of dictionaries

I am trying to loop through my list of dictionaries and print out the highest bidder in my list of dictionaries. In a for loop with python is 'i' not automatically an integer?
Example : for i in dictionary:
Does i not equal 0, 1, 2 so on?
bidders = [
{
"name": "nicholas",
"bid": 12,
},
{
"name": "jack",
"bid": 69,
},
]
for i in bidders:
bid = bidders[i]["bid"]
name = bidders[i]["name"]
if bid > bid:
print(f"Congratulations {name}! Your bid of ${bid} wins!")
else:
print(f"Congratulations {name}! Your bid of ${bid} wins!")
You can use enumerate to range through a list and get the current index. Fixing your for loop, it would look like this:
for idx, _ in enumerate(bidders):
bid = bidders[idx]["bid"]
name = bidders[idx]["name"]
No, since you are not calling the range function i is not default a integer. Leonardo's answer looks more correct, however what I wrote down below would also work.
bidders = [
{
"name": "nicholas",
"bid": 12,
},
{
"name": "jack",
"bid": 69,
},
]
maxBid = -1
maxBidName = "";
for i in range(0, len(bidders)):
bid = bidders[i]["bid"]
name = bidders[i]["name"]
if bid > maxBid:
maxBid = bid
maxBidName = name
print(f"Congratulations {maxBidName}! Your bid of ${maxBid} wins!")
there are few mistakes, i think this will works
bidders = [
{
"name": "nicholas",
"bid": 12,
},
{
"name": "jack",
"bid": 69,
},
]
highestBid = 0
highestBidData = {}
for i in bidders:
if i['bid'] > highestBid:
highestBid = i['bid']
highestBidData = i
print("Congratulations {0}! Your bid of {1} `enter code
here`wins!".format(highestBidData['name'],highestBidData['bid']))
bidders = [
{
"name": "nicholas",
"bid": 12,
},
{
"name": "jack",
"bid": 69,
},
]
maxBidder = max(bidders, key=lambda x:x['bid'])
print("Congratulations {}! Your bid of {} wins!".format(maxBidder['name'],maxBidder['bid']))
In a for loop with python is 'i' not automatically an integer?
Example : for i in dictionary: Does i not equal 0, 1, 2 so on?
No
A very easy way to find out what it is is simply:
for i in bidders:
print(i)
print(type(i))
Output:
{'name': 'nicholas', 'bid': 12}
<class 'dict'>
{'name': 'jack', 'bid': 69}
<class 'dict'>
I believe what you’re looking for is bid = i[‘bid’]. i in this case is simply part of the dictionary. So for each entry, you want the value of ’bid’.

How do I read an JSON object in python?

Im currently working on a Python Pygame project were I have to work with JSON files. Im trying to read of an JSON file but I just cant get it to print what I want to know.
Here is the JSON file
"pokemons": {
"5": {
"name": "Snivy",
"type": "Grass",
"hp": 45,
"attack": 45,
"defence": 55,
"speed": 63,
"moves": [
"Tackle",
"Leer",
"null",
"null"
],
"level": 4,
"xp": 54
},
"2": {
"name": "Tepig",
"type": "Fire",
"hp": 65,
"attack": 63,
"defence": 45,
"speed": 45,
"moves": [
"Tackle",
"Tail Whip",
"Ember",
"null"
],
"level": 7,
"xp": 11
}
}
}
Im trying to read the "name", "type", ect from the different "ID's" aka "5" and "2", but I can only make it print "5" and "2" from the "pokemons" array
with open("data.json", "r") as f:
data = json.load(f)
for i in data["pokemons"]:
print(i)
You've titled this json read from array inside of array python, but you don't have JSON arrays (translated into Python lists) here - you have JSON objects (translated into Python dicts).
for i in data["pokemons"]:
data["pokemons"] is a dict, so iterating over it like this gives you the keys - "5" and "2"`. You can use those to index into the data:
data["pokemons"][i]
That gives you one of the objects (dicts) representing an individual pokemon, from which you can access the name:
data["pokemons"][i]["name"]
Better yet, you can loop over the values of data["pokemons"] directly, instead of the keys:
for pokemon in data["pokemons"].values():
name = pokemon["name"]
Or you can get both at once using .items(), for example:
for pid, pokemon in data["pokemons"].items():
# use string formatting to display the pid and matching name together.
print(f"pokemon number {pid} has name {pokemon['name']}")
My Solution
data = '{"pokemons": {"5": {"name": "Snivy","type": "Grass","hp": 45,"attack": 45,"defence": 55,"speed": 63,"moves": ["Tackle","Leer","null","null"],"level": 4,"xp": 54},"2": {"name": "Tepig","type": "Fire","hp": 65,"attack": 63,"defence": 45,"speed": 45,"moves": ["Tackle","Tail Whip","Ember","null"],"level": 7,"xp": 11}}}}'
datadict = json.loads(data)
dataOfId = datadict['pokemons']
for i in dataOfId:
print(dataOfId[i]["name"])
print(dataOfId[i]["type"])

parsing a line into a dictionary through a list comprehension

I am trying to slice different parts of a line into a list of dictionaries using a list comprehension. The code below doesn't work, but it illustrates what I am trying to do. Any help would be much appreciated!
Thanks
def getDataElements(self):
return [x for x for line in self.data: {"Number": line[0:9],
"FullName": line[9:27].rstrip(),
"LastName": line[27:63].rstrip(),
"Area": line[63:65].rstrip(),
"City": line[65:90].rstrip(),
"Status": line[91],
"Status2": line[92],
"Status3": line[93]]
You were somewhat clear, but you have to put the dictionary in the beginning...if I fully understand what you want, the following should work:
return [{"Number": line[0:9],"FullName": line[9:27].rstrip(),"LastName": line[27:63].rstrip(),"Area": line[63:65].rstrip(),"City": line[65:90].rstrip(),"Status": line[91],"Status2": line[92],"Status3": line[93]} for line in self.data]
unless there is some extra level of nesting because you say x for x for line yet you don't use x so I ignored it in that manner. Let me know if that was incorrect, and if so explain in a bit more detail please!
There are instances where list comprehensions are good, but this is not one of them. Just use a loop and a generator:
for line in self.data:
yield {
"Number": line[0:9],
"FullName": line[9:27].rstrip(),
"LastName": line[27:63].rstrip(),
"Area": line[63:65].rstrip(),
"City": line[65:90].rstrip(),
"Status": line[91],
"Status2": line[92],
"Status3": line[93]
}
If you absolutely need to return a list, pass the output through list():
output_list = list(self.getDataElements())
If you're not comfortable with that, there's always the append-to-a-list way:
people = []
for line in self.data:
people.append({
"Number": line[0:9],
"FullName": line[9:27].rstrip(),
"LastName": line[27:63].rstrip(),
"Area": line[63:65].rstrip(),
"City": line[65:90].rstrip(),
"Status": line[91],
"Status2": line[92],
"Status3": line[93]
})
return people
First write a function that parses a line and returns the corresponding dict:
def parseDataLine(self, line):
return { ... } # Same as your parsing code.
The rest of your code would be like this:
def getDataElements(self):
return [self.parseDataLine(line) for line in self.data]
This type of approach keeps everything very readable and simple.

Categories