Incomprehensible error with three print following - python

I have a dictionary defined as follows:
SN = {}
SN[0] = {'verb' : 1 }
In my function I make 3 prints as follows:
print graph
print state
print graph[state]
(I do nothing else with these variables) and it returns:
SN
0
S
How is this possible? Why doesn't it return
SN
0
{'verb' : 1}
The whole code :
abstraction= {}
abstraction['de'] = ['déterminant']
abstraction['le'] = ['déterminant']
abstraction['un'] = ['déterminant']
abstraction['beau'] = ['adjectif', 'substantif']
abstraction['dodu'] = ['adjectif', 'substantif']
abstraction['grand'] = ['adjectif', 'substantif']
abstraction['méchant'] = ['adjectif', 'substantif']
abstraction['noirs'] = ['adjectif', 'substantif']
abstraction['petit'] = ['adjectif', 'substantif']
abstraction['desseins'] = ['substantif']
abstraction['loup'] = ['substantif']
abstraction['poulet'] = ['substantif']
abstraction['gosse'] = ["n'importe quoi"]
abstraction['mange'] = ['verbe']
abstraction['dort'] = ['verbe']
SN = {}
SN[0] = {'déterminant' : 1 }
SN[1] = {'adjectif' : 1, 'substantif' : 2 }
SN[2] = {'adjectif' : 3, '' : 'ok' }
SN[3] = {'' : 'ok' }
SV = {}
SV[0] = {'verbe' : 1}
SV[1] = {'transitions' : 'SN', '' : 'ok'}
SV[2] = {'' : 'ok'}
def transitions(data, graph, state = 0, transit = []) :
print 'data avt if data :'
print data
if data :
if 'transitions' in graph[state] :
return transitions(data, graph[state]['transitions'], 0, transit)
symbol = data[0]
if symbol not in abstraction.keys() :
return ['impossible, un des mots n\'est pas reconnu par l\'automate']
for a in abstraction[symbol] : # loop on abstractions
print graph
print state
print graph[state]
if a in graph[state] :
state = graph[state][a]
return transitions(data[1:], graph, state, transit + [a])
else :
return transit + [symbol] + ['impossible']
else :
if '' in graph[state] :
return transit + [graph[state]['']]
else : return transit + ['impossible']

I think your problem here is that graph == "SN", rather than (as you apparently expect) graph == SN.
To put it another way, graph is referencing a str object with value "SN", not the dict object also referenced by the name SN.
Therefore graph[0] is the first character in the string "SN", which is the letter "S".
In the case graph == SN, the output from
print graph
print state
print graph[state]
would be:
{0: {'verb': 1}} # note: not 'SN'
0
{'verb': 1}
Edit:
Now that you've posted your code, this section:
SN = {}
SN[0] = {'déterminant' : 1 }
SN[1] = {'adjectif' : 1, 'substantif' : 2 }
SN[2] = {'adjectif' : 3, '' : 'ok' }
SN[3] = {'' : 'ok' }
creates a dictionary
SN = {0: {'déterminant': 1}, 1: {'adjectif': 1, 'substantif': 2},
2: {'adjectif': 3, '': 'ok'}, 3: {'': 'ok'}}
However, in the next part:
SV[1] = {'transitions' : 'SN', '' : 'ok'}
you assign the string 'SN' to the key 'transitions', not the actual dictionary SN. That should have been:
SV[1] = {'transitions': SN, '': 'ok'}
# ^ no quote marks
Also, as all of your keys are integers starting from zero, you could consider using a list instead of a dictionary, e.g.:
SN = []
SN.append({'déterminant': 1})
SN.append({'adjectif': 1, 'substantif': 2})
...

Related

How to display the first bar in the bar plot

As can be seen in the following plot, the first bar is not displayed.
Why isn't it displayed and how the code be fixed so the bar does display?
import json
import requests
import matplotlib.pyplot as plt
i = 0
while i<=2:
key = '4ee91801f78b4271a5d90623210211'
main_url = 'http://api.weatherapi.com/v1/current.json'
city = input('Hangi Şehri Almak istiyorsunuz : ')
response = requests.get(main_url, params = {
'key': key,
'q': city,
'lang' : 'tr'
})
data = response.json()
c_values = data['current']['temp_c']
if i == 0:
city1 = city
c_values1 = c_values
elif i == 1:
city2 = city
c_values2 = c_values
else:
city3 = city
c_values3 = c_values
i = i + 1
names = [f'{city1}',f'{city2}',f'{city3}']
values = [f'{c_values1}', f'{c_values2}', f'{c_values3}']
plt.bar(names,values)
plt.show()
The issue is [f'{c_values1}', f'{c_values2}', f'{c_values3}'] is a list of str types, not numbers.
It should be [c_values1, c_values2, c_values3] so the y-axis can be plotted correctly with numbers, not text.
Notice the bottom value of the bar plot is '12', which is the top of 'Paris'
['12.0', '11.0', '17.0'] note the values are strings.
I recommend using while i<3: instead of while i<=2
Alternatively, simplify the code
i = 0
cd = dict() # create an empty dict
while i<3:
key = '4ee91801f78b4271a5d90623210211'
main_url = 'http://api.weatherapi.com/v1/current.json'
city = input('Hangi Şehri Almak istiyorsunuz : ')
response = requests.get(main_url, params = {
'key': key,
'q': city,
'lang' : 'tr'
})
data = response.json()
cd[city] = data['current']['temp_c'] # add the city and temp to the dict
i+=1
plt.bar(cd.keys(), cd.values())
plt.show()

Appending multiple values for a key

if filename not in dict1.keys():
dict1[filename] = {}
if transId not in dict1[filename].keys():
dict1[filename][transId] = {}
if error_type in dict1[filename][transId].keys():
count1 = dict1[filename][transId][error_type]
count1 = count1 + 1
dict1[filename][transId][error_type] = count1
dict data is :
{'abc': {'ACE12345678': {'ERR-2': 2}, {'ERR-3': 4}}}
where 'abc' is a filename, 'ACE12345678' a TransId, and 'ERR-2' an Error Type.
I would also like to add loglines for each transid(Eg: 'ACE12345678') so that the dict looks like as below :
{'abc': {'ACE12345678': {'ERR-2': 2, data1\n data2\n data3\n}, {'ERR-3': 4, data1\n data2\n data3\n}}}.
Can someone help me getting this output.
you can add a new key loglines that holds all the lines in a list:
dict1 = {'abc': {'ACE12345678': {'ERR-2': 2}}}
filename = 'abc'
transID = 'ACE12345678'
error_type = 'ERR-2'
logline = 'data1\n'
my_error = dict1.setdefault(filename, {}).setdefault(transID, {})
my_error[error_type] = my_error.get(error_type, 0) + 1
my_error.setdefault('loglines', []).append(logline)
print(dict1)
output:
{'abc': {'ACE12345678': {'ERR-2': 3, 'loglines': ['data1\n']}}}

Django/Python Multiple records

I have a program that compares values from the database and from a CSV file. My program works like this.
Database has values.
User uploads a file (multiple users multiple
files).
The program compares the values from the database and the
CSV files and gives an output.
Which tells me that this particular value was found in this user's file.
But I want the program to show me that if the value was found in the other user's file or not.
Here is a working example.
DB Values = [1,23,33,445,6656,88]
Example values of the CSV files:
File 1 values = [1,23,445,77,66,556,54]
File 2 values = [1,23,45,77,366]
File 3 values = [1,23,5,77,5356,524]
Output needed:
{'1':[(user1, some value),(user2, some value)...]}
Here my code:
def LCR(request):
template = "LCR\LCRGen.html"
dest = Destination.objects.values_list('dest_num', flat=True)
ratelist = { }
csv_file = { }
data_set = { }
io_string = { }
vendor = RateFile.objects.values_list()
v_count = vendor.count()
for v_id, v_name, v_file in vendor:
vendor_name = str(v_name)
vendornames = str(v_name)
vendornames = { }
for desNum in dest:
desNum = str(desNum)
for countvar in range(v_count):
csv_file[vendor_name] = RateFile.objects.get(id=v_id).ven_file
data_set[vendor_name] = csv_file[vendor_name].read().decode("UTF-8")
io_string[vendor_name] = io.StringIO(data_set[vendor_name])
next(io_string[vendor_name])
for column in csv.reader(io_string[vendor_name], delimiter=str(u",")):
vendornames[column[0]] = column[1]
for venNum, venValue in vendornames.items():
venlen = len(venNum)
deslen = len(desNum)
if venlen >= deslen or venlen <= deslen:
if desNum[:-1] == venNum[:-1] and desNum[:-2] == venNum[:-2] and desNum[:-3] == venNum[:-3]:
ratelist[desNum] = [(vendor_name, venValue),]
if (vendor_name, venValue) in ratelist[desNum]:
ratelist[desNum] = [
(vendor_name, venValue),]
elif desNum[:-1] == venNum[:-2] and desNum[:-2] == venNum[:-3] and desNum[:-3] == venNum[:-4]:
ratelist[desNum] = [(vendor_name, venValue),]
if (vendor_name, venValue) in ratelist[desNum]:
ratelist[desNum] = [
(vendor_name, venValue),]
elif desNum[:-1] == desNum[:-3] and desNum[:-2] == venNum[:-4] and desNum[:-3] == venNum[:-5]:
ratelist[desNum] = [(vendor_name, venValue),]
elif desNum[:-1] == venNum[:-5] and desNum[:-2] == venNum[:-6]:
ratelist[desNum] = [(vendor_name, venValue),]
if (vendor_name, venValue) in ratelist[desNum]:
ratelist[desNum] = [
(vendor_name, venValue),]
else:
pass
print ( ratelist )
return render ( request, template, { "ratelist" : ratelist } )
Output
Zong, Tata are usernames and the float values is their respective value for the key value of the dictionary.
{'12': [('Zong', ' 0.026')], '213': [('Tata', ' 4.150')], '49': [('Tata', ' 0.531')], '30': [('Zong', ' 0.87')], '454': [('Tata', ' 0.531')], '374': [('Zong', ' 0.87')],
This is what you asked for:
### your data example
db = [1,23,33,445,66,556,88]
us1 = [1,23,445,77,66,556,54]
us2 = [1,23,45,77,366]
### create a list of usernames (to use the string name in dictionary)
userlist = [ "us1", "us2" ]
### intialize the dict for results
values_dict = {}
### open the loop on DB values
for value in db :
# open loop on userlist
for user in userlist :
# if value is found in user list of values
if value in eval(user) :
# if values still NOT a key of results dictionary create the key with the tuple list as values
if value not in values_dict :
values_dict.update({ value : [ ( user, value ) ] })
# else just append the tuple (username, value) to the results dictionary for the DB value corresponding key
else :
values_dict[value].append([ ( user, value ) ])
values_dict
### OUTPUT:
{1: [('us1', 1), [('us2', 1)]], 23: [('us1', 23), [('us2', 23)]], 445: [('us1', 445)], 66: [('us1', 66)], 556: [('us1', 556)]}
but it makes no sense cause it simply check if a value is in the user list of values and add a tuple just to confirm it, it doesn't require all this code, could be simplified a lot. But I'm thinking that I misunderstood your question (please review the english), probably you need to use the DB value as the key to retrieve another value from the user...please review and update

What is the most efficient way to a multiple variable in dictionary in python?

this my code, i'm looking, is other way to code this in most efficient way?
i have multiple variables and inserted to the dictionary.
please feel to suggest and other options like array and etc will do.
def momentEndSpan(span_type,max_combo,length):
if "simply supported" == span_type:
q = max_combo
force = {}
RA = {"PA" : q*length/2}
RB = {"PB" : q*length/2}
RA_moment = {"MA" : 0}
R_mid_moment = {"Mmid": (q*math.pow(length,2))/8 }
RB_moment = { "MB" : 0}
force.update(RA)
force.update(RB)
force.update(RA_moment)
force.update(R_mid_moment)
force.update(RB_moment)
return force
elif "one end continuous" == span_type:
q = max_combo
x = (3/8)*length
force = {}
RA = {"Phinge" : 3*q*length/8}
RB = {"Pfixed" : 5*q*length/8}
RA_moment = {"Mhinge" : 0}
R_mid_moment = {"Mmid": (q*math.pow(length,2))*(9/128) }
RB_moment = { "MB" : -1*(q*math.pow(length,2))/8 }
force.update(RA)
force.update(RB)
force.update(RA_moment)
force.update(R_mid_moment)
force.update(RB_moment)
return force
Thank you very much
The "More Pythonic" way is to create one dictionary and update once.
q = max_combo
force = {}
if "simply supported" == span_type:
new = {"PA" : q*length/2,
"PB" : q*length/2,
"MA" : 0, "Mmid": (q*math.pow(length,2))/8,
"MB" : 0}
elif "one end continuous" == span_type:
x = (3/8)*length
new = {"Phinge" : 3*q*length/8,
"Pfixed" : 5*q*length/8,
"Mhinge" : 0,
"Mmid": (q*math.pow(length,2))*(9/128),
"MB" : -1*(q*math.pow(length,2))/8 }
force.update(new)
Also, note that if the force dictionary doesn't contain any previously defined items you can simply return the new and/or just continue to update the new in your next operations if there are any. Or just use name force instead of new.
q = max_combo
if "simply supported" == span_type:
force = {...}
elif "one end continuous" == span_type:
x = (3/8)*length
force = {...}

How to parse a string in Python

How to parse string composed of n parameter and randomly sorted such as:
{ UserID : 36875; tabName : QuickAndEasy}
{ RecipeID : 1150; UserID : 36716}
{ isFromLabel : 0; UserID : 36716; type : recipe; searchWord : soup}
{ UserID : 36716; tabName : QuickAndEasy}
Ultimately I'm looking to ouput parameters in separate columns for a table.
The regex ([^{}\s:]+)\s*:\s*([^{}\s;]+) works on your examples. You need to be aware, though, that all the matches will be strings, so if you want to store 36875 as a number, you'll need to do some additional processing.
import re
regex = re.compile(
r"""( # Match and capture in group 1:
[^{}\s:]+ # One or more characters except braces, whitespace or :
) # End of group 1
\s*:\s* # Match a colon, optionally surrounded by whitespace
( # Match and capture in group 2:
[^{}\s;]+ # One or more characters except braces, whitespace or ;
) # End of group 2""",
re.VERBOSE)
You can then do
>>> dict(regex.findall("{ isFromLabel : 0; UserID : 36716; type : recipe; searchWord : soup}"))
{'UserID': '36716', 'isFromLabel': '0', 'searchWord': 'soup', 'type': 'recipe'}
Test it live on regex101.com.
lines = "{ UserID : 36875; tabName : QuickAndEasy } ", \
"{ RecipeID : 1150; UserID : 36716}", \
"{ isFromLabel : 0; UserID : 36716; type : recipe; searchWord : soup}" , \
"{ UserID : 36716; tabName : QuickAndEasy}"
counter = 0
mappedLines = {}
for line in lines:
counter = counter + 1
lineDict = {}
line = line.replace("{","")
line = line.replace("}","")
line = line.strip()
fieldPairs = line.split(";")
for pair in fieldPairs:
fields = pair.split(":")
key = fields[0].strip()
value = fields[1].strip()
lineDict[key] = value
mappedLines[counter] = lineDict
def printField(key, lineSets, comma_desired = True):
if key in lineSets:
print(lineSets[key],end="")
if comma_desired:
print(",",end="")
else:
print()
for key in range(1,len(mappedLines) + 1):
lineSets = mappedLines[key]
printField("UserID",lineSets)
printField("tabName",lineSets)
printField("RecipeID",lineSets)
printField("type",lineSets)
printField("searchWord",lineSets)
printField("isFromLabel",lineSets,False)
CSV output:
36875,QuickAndEasy,,,,
36716,,1150,,,
36716,,,recipe,soup,0
36716,QuickAndEasy,,,,
The code above was Python 3.4. You can get similar output with 2.7 by replacing the function and the last for loop with this:
def printFields(keys, lineSets):
output_line = ""
for key in keys:
if key in lineSets:
output_line = output_line + lineSets[key] + ","
else:
output_line += ","
print output_line[0:len(output_line) - 1]
fields = ["UserID", "tabName", "RecipeID", "type", "searchWord", "isFromLabel"]
for key in range(1,len(mappedLines) + 1):
lineSets = mappedLines[key]
printFields(fields,lineSets)

Categories