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
Related
I am using python3.7 and this is the current code base(apologies for putting so much code but thought it would help overall)
def TRADE_ENTRY(df_names, df_underlyings,df_strategies, columns, param, out_path,recovery_path):
nameUpdate =0
strategyUpdate=0
underlyingUpdate=0
sg.theme('Dark Brown 1')
listing = [sg.Text(u, size = param) for u in columns]
header = [[x] for x in listing]
now = datetime.datetime.now()
core = [
sg.Input(f"{now.month}/{now.day}/{now.year}",size = param),
sg.Input(f"{now.hour}:{now.minute}:{now.second}",size = param),
sg.Listbox(list(df_strategies.STRATEGIES), size=(20,2), enable_events=False, key='_PLAYERS0_'),
sg.Listbox(['ETF', 'EQT', 'FUT', 'OPT', 'BOND'],enable_events=False,key='_PLAYERS20_',size = (20,2)),
sg.Listbox(list(df_names.NAMES), size=(20,4), enable_events=False,key='_PLAYERS6_'),
sg.Listbox( ['B', 'S'],size = (20,1),enable_events=False,key='_PLAYERS12_'),
sg.Input(size = param),
sg.Input(size = param),
sg.CalendarButton('Calendar', pad=None, font=('MS Sans Serif', 10, 'bold'),
button_color=('yellow', 'brown'), format=('%d/%m/%Y'), key='_CALENDAR_', target='_INP_'),
sg.Input(size = param),
sg.Listbox(list(df_underlyings.UNDERLYINGS), size=(20,4), enable_events=False,key='_PLAYERS2_'),
sg.Listbox(['C', 'P', 'N/A'],size = param),
]
mesh = [[x,y] for (x,y) in list(zip(listing, core))]
mesh[8].append(sg.Input(size = (10,2),key = '_INP_'))
layout =[[sg.Button("SEND"),sg.Button("NEW_NAME"), sg.Button("NEW_STRAT"), sg.Button("NEW_UND")] ]+ mesh
window = sg.Window('Trade Entry System', layout, font='Courier 12').Finalize()
while True:
event, values = window.read(timeout=500)
#print('EVENT, VALUES', event, values)# all the inputs with extra information for compiler
if event == "SEND":
data = values
a = list(data.values())
a = [x if isinstance(x, list) == False else empty_handler(x) for x in a]
a = [x if x !="" else "EMPTY" for x in a ]
#print('A', a)#all the inputs now in a list
df = pd.DataFrame(a, index = columns)
print('DF1', df)#columns dataframe with column names and then the values
df = df.transpose()
#print('DF2', df)#rows dataframe with column names and then the values
status = error_handling(df)
#print('STATUS', status)
if status == "ERROR":
print("YOU MUST RECTIFY INPUT")
elif status == "CORRECT":
#if a future then will overwrite its name
if df['TYPE'][0] == "FUT":
df['NAME'][0] = "F-"+ df['UNDERLYING'][0] + "-" +df['EXPIRATION'][0]
#if an option then will overwrite its name
elif df['TYPE'][0] =="OPT":
df['NAME'][0] = 'O-' + df['UNDERLYING'][0] + "--" + df['OPTION_TYPE'][0] +df['STRIKE'][0] +"--" +df['EXPIRATION'][0]
else:
pass
processing(df, recovery_path, out_path)
else:
print("ERROR WITH USER INPUT FATAL")
break
elif event == "NEW_NAME":
security_creation(r'Y:\NAMES.xlsx', "Sheet1", "NAME", param)
nameUpdate=1
continue
elif event == "NEW_STRAT":
security_creation(r'Y:\STRATEGIES.xlsx', "Sheet1", "STRATEGY", param)
strategyUpdate=1
continue
elif event == "NEW_UND":
security_creation(r'Y:\UNDERLYINGS.xlsx', "Sheet1", "UNDERLYINGS", param)
underlyingUpdate=1
continue
elif event == sg.TIMEOUT_KEY:
if(nameUpdate==1):
df_names = pd.read_excel(r'Y:\NAMES.xlsx', "Sheet1")
df =df_names.values.tolist()
window['_PLAYERS6_'].update(values=df, set_to_index=0)
if(underlyingUpdate==1):
df_underlyings = pd.read_excel(r'Y:\UNDERLYINGS.xlsx', "Sheet1")
df =df_underlyings.values.tolist()
window['_PLAYERS2_'].update(values=df, set_to_index=0)
if(strategyUpdate==1):
df_strategies = pd.read_excel(r'Y:\STRATEGIES.xlsx', "Sheet1")
df =df_strategies.values.tolist()
window['_PLAYERS0_'].update(values=df, set_to_index=0)
print("Listboxes updated !")
else:
print("OVER")
break
window.close()
TRADE_ENTRY(df_names, df_underlyings,df_strategies, columns, param,out_path, recovery_path)
Towards the end of the function there's 3 elif, all NEW_NAME, NEW_STRAT and NEW_UND are the user submitting information to the corresponding 3 excel files. The function security_creation actually updates said excel files. Below that I am trying to update the Listboxes but no luck.
Any help would be greatly appreciated since i am so confused
Below is the code I have tried, actually I am looking for result like comparision of each key dictionary so my max_value for each dictionary will be like "2539:Mark:35" … same thing for rest other dictionary pls help me here to solve this..
student_data = {2539:{'James':30, 'Mark': 35}, 8214: { 'Michelle': 32,'Mark': 40},7411:{'Travis':28, 'Mark': 45}}
for id,v in student_data.items():
print(id, '-->', student_data[id][0] + ',', max(student_data[id][1].values()))
print('Subjects:', student_data[id][2], '\n')
Using your code as much as possible.
Use find max in dictionary to find key with max value in dictionary
Code
student_data = { 2539: { 'James': 30, 'Mark': 35 }, 8214: { 'Michelle': 32,'Mark': 40 }, 7411: { 'Travis': 28, 'Mark': 45 } }
for id,v in student_data.items(): # v is a dictionary
max_student = max(v, key=v.get) # student name with max
print(f'{id}:{max_student}:{v[max_student]}')
Output
2539:Mark:35
8214:Mark:40
7411:Mark:45
Expanded to input info for student_data
def get_parameter(prompt, type_input='str'):
" Used for getting student id, name or score "
while True:
param = input(prompt)
if not param:
return None # done entering
if type_input=='int':
if param.isdigit():
return int(param)
else:
print('Value should be integer')
elif type_input == 'str':
if param.isalpha():
# string so okay
return param
else:
print('Value should be single word string')
# Get student data as list of stuples
# [(id1, name1, score1), (id2, name2, score2), ...]
while True:
id = get_parameter('Student id (blank line to close entries):', 'int')
if not id:
break # break inputting data on blank line
name = get_parameter('Student name: ')
if not name:
break
score = get_parameter('Student score: ', 'int')
if not score:
break
data.append((id, name, score))
# Convert list of tuples to student_data dictionary
student_data = {}
for id, name, score in data:
if not id in student_data:
student_data[id] = {} # add dictionary for id
# Add score and name
student_data[id][name] = score
# Show results
for id,v in student_data.items():
max_student = max(v, key=v.get )
print(f'{id}:{max_student}:{v[max_student]}')
I am trying to insert records into a table, but only last record(result data) from the loop is inserting into the table
Here is the code i tried:
CDates = ['2020-05-10','2020-05-12','2020-05-13','2020-05-16','2020-05-20']
ResultData = {}
for date in CDates:
filterDate = Key('Date').eq(id)
appResponse = appTable.scan(FilterExpression = filterDate)
accResp = table.query(KeyConditionExpression = Key('PrimaryId').eq('Key'),FilterExpression = Key('Date').eq(date))
if len(accResp['Items']) == 0:
ResultData['PrimaryId'] = 'Key'
ResultData['CreatedDate'] = date
ResultData['Type'] = 'Appt'
ResultData['Id'] = str(uuid.uuid4())
print(ResultData)
table.put_item(Item=ResultData)
Not getting where did I go wrong
You assigned ResultData outside of the loop and changed the values for the same keys every time the loop ran. Try this:
CDates = ['2020-05-10', '2020-05-12', '2020-05-13', '2020-05-16', '2020-05-20']
for date in CDates:
filterDate = Key('Date').eq(id)
appResponse = appTable.scan(FilterExpression=filterDate)
accResp = table.query(
KeyConditionExpression=Key('PrimaryId').eq('Key'),
FilterExpression=Key('Date').eq(date))
if len(accResp['Items']) == 0:
ResultData = {
'PrimaryId': 'Key',
'CreationDate': date,
'Type': 'Appt',
'Id': str(uuid.uuid4())
}
print(ResultData)
table.put_item(Item=ResultData)
I'm trying to deduce the volume contributions of each category (like summarize by row value in excel's pivot table) from a csv file (which has two cols ['customer','category']) in to a dict in the following format,
foodict = {
'customer' : 'cust1' ,
'categories' : { 'cat1' : 50, 'cat2' : 55 } ,
'contribution' : {
'cat1' : cat1/(cat1+cat2) ,
'cat2' : cat2/(cat1+cat2)
}
}
so far, I've got like this, but unable to achieve the needful one. I'm trying to do it in pure python without using any other data libraries.
c = {}
for i in customer:
for j in category:
for k in db:
count = 0
if k['customer'] == i and k['category'] == j:
count += 1
if not i in c.keys():
c[i] = {'category' : j , 'counts' : count}
else:
pass
#len:
This satisfied my requirement, but is there any efficient way to group by get the count contributions like we do in the excel as 'Summarize by row values in the pivot table
foo_dict = {}
for name in cust:
for j in category:
foo_dict[name] = {
'total' : int(sum(1 for i in db if i['cust'] == name)),
'lob' : {pro : int(sum(1 for i in db if i['cust'] == name and i['category'] == pro)) for pro in category},
'conts' : {pro : round(
float(
sum(1 for i in db if i['cust'] == name and i['category'] == pro)/int(sum(1 for i in db if i['cust'] == name))),2) for pro in category},
'samples' : {pro : round(
float(
sum(1 for i in db if i['cust'] == name and i['category'] == pro)/int(sum(1 for i in db if i['cust'] == name))),0) for pro in category}
}
I'm trying to create a dictionary where the key is date ,
In my case each date is a list like this : [2012, 5, 25].
This is the code that I have which reads from a csv file into dictionary.
This code is given I can't change it :
def read_profiles(r_file_name):
"""Reads the file profiles-full.csv into a dictionary where the key is the users id
and the value is a dictionary with users fields "public", "compl_percent", "gender",
"region", "last_login", "age", "body". In addition to this dictionary, the function
returns the list of all users that have 0 completion percentage."""
users = {}
noinfo_users = []
with open(r_file_name, 'rb') as csvfile:
linereader = csv.reader(csvfile)
for line in linereader:
profile = {}
data_fields = ("public", "compl_percent", "gender", "region",
"last_login", "age", "body")
for field, raw_data in zip(data_fields, line[1:]):
if field == "compl_percent" and int(raw_data) == 0:
noinfo_users.append(int(line[0]))
if raw_data == "null":
profile[field] = None
elif field == "body":
profile[field] = raw_data
elif field == "last_login": #<=== reading last_login
profile[field] = map(int, raw_data.split("-"))
elif field == "region":
profile[field] = map(int, raw_data.split(";"))
else:
profile[field] = int(raw_data)
users[int(line[0])] = profile
return users, noinfo_users
And this is the content of the csv file, corresponding to this pattern:
"public", "compl_percent", "gender", "region", "last_login", "age", "body"**
231702, 1, 60, 0, 1;1;21, 2012-05-15, 0, 171 cm;58 kg
This is how an element in profiles dictionary looks like:
1492433: {'body': '160 cm;54 kg', 'compl_percent': 78, 'gender': 0, 'region': [1, 10, 6], 'age': 36, 'last_login': [2012, 5, 25], 'public': 1}
This is my function:
def getStrongConnectedForAttr(user,edges,profiles,attr):
result = dict()
if user in edges:
userFriends = edges.get(user)
for friend in userFriends:
if isBidirectional(edges,user,friend) == 2:
if friend in profiles:
friendAttr = (profiles.get(friend))[str(attr)]
if attr == "last_login":
#friendAttr = '-'.join(map(str, friendAttr))
friendAttr = tuple(friendAttr)
if friendAttr in result: #<===== error
result[friendAttr] = result.get(friendAttr) + 1
else:
result[friendAttr] = 1
return sorted(result.items(), key=operator.itemgetter(1), reverse=True)
else:
return result
It takes profiles as one of the parameters, and builds an empty dictionary.
In the line if friendAttr in result: I get the error:
TypeError: unhashable type: 'list'
I tried searching the web for solution and I found many, especially here on Stack Overflow, and as you can see I tried many solutions, one to convert the list to tuple, or join the list to string.
But none of them worked.
You are only turning the login_attr values to a tuple, but forgetting about the region attribute. It is those values that still throw the exception.
You are only testing for login_attr here:
if attr == "last_login":
friendAttr = tuple(friendAttr)
Rather than turn your values to tuples there, just store tuples when reading the file.
Replace
elif field == "last_login": #<=== reading last_login
profile[field] = map(int, raw_data.split("-"))
elif field == "region":
profile[field] = map(int, raw_data.split(";"))
with
elif field == "last_login":
profile[field] = tuple(map(int, raw_data.split("-")))
elif field == "region":
profile[field] = tuple(map(int, raw_data.split(";")))