I'm not sure I am approaching this in the right way.
Scenario:
I have two SQL tables that contain rent information. One table contains rent due, and the other contains rent received.
I'm trying to build a rent book which takes the data from both tables for a specific lease and generates a date ordered statement which will be displayed on a webpage.
I'm using Python, Flask and SQL Alchemy.
I am currently learning Python, so I'm not sure if my approach is the best.
I've created a dictionary which contains the keys 'Date', 'Payment type' and 'Payment Amount', and in each of these keys I store a list which contains the data from my SQL queries. The bit im struggling on is how to sort the dictionary so it sorts by the date key, keeping the values in the other keys aligned to their date.
lease_id = 5
dates_list = []
type_list = []
amounts_list = []
rentbook_dict = {}
payments_due = Expected_Rent_Model.query.filter(Expected_Rent_Model.lease_id == lease_id).all()
payments_received = Rent_And_Fee_Income_Model.query.filter(Rent_And_Fee_Income_Model.lease_id == lease_id).all()
for item in payments_due:
dates_list.append(item.expected_rent_date)
type_list.append('Rent Due')
amounts_list.append(item.expected_rent_amount)
for item in payments_received:
dates_list.append(item.payment_date)
type_list.append(item.payment_type)
amounts_list.append(item.payment_amount)
rentbook_dict.setdefault('Date',[]).append(dates_list)
rentbook_dict.setdefault('Type',[]).append(type_list)
rentbook_dict.setdefault('Amount',[]).append(amounts_list)
I was then going to use a for loop within the flask template to iterate through each value and display it in a table on the page.
Or am I approaching this in the wrong way?
so I managed to get this working just using zipped list. Im sure there is a better way for me to accomplish this but im pleased I've got it working.
lease_id = 5
payments_due = Expected_Rent_Model.query.filter(Expected_Rent_Model.lease_id == lease_id).all()
payments_received = Rent_And_Fee_Income_Model.query.filter(Rent_And_Fee_Income_Model.lease_id == lease_id).all()
total_due = 0
for debit in payments_due:
total_due = total_due + int(debit.expected_rent_amount)
total_received = 0
for income in payments_received:
total_received = total_received + int(income.payment_amount)
balance = total_received - total_due
if balance < 0 :
arrears = "This account is in arrears"
else:
arrears = ""
dates_list = []
type_list = []
amounts_list = []
for item in payments_due:
dates_list.append(item.expected_rent_date)
type_list.append('Rent Due')
amounts_list.append(item.expected_rent_amount)
for item in payments_received:
dates_list.append(item.payment_date)
type_list.append(item.payment_type)
amounts_list.append(item.payment_amount)
payment_data = zip(dates_list, type_list, amounts_list)
sorted_payment_data = sorted(payment_data)
tuples = zip(*sorted_payment_data)
list1, list2, list3 = [ list(tuple) for tuple in tuples]
return(render_template('rentbook.html',
payment_data = zip(list1,list2,list3),
total_due = total_due,
total_received = total_received,
balance = balance))
I have over 100 lists to make.
How can I make just one and then loop over them?
It is more complex than the usual dictionary looping.
list(i)=[]
for a in dict(i)['a']:
d={}
d['A']=string
list(i).append(d)
list(i) = pd.DataFrame(list(i))
list(i)['Link'] = df['link'][i-1]
list(i)['Caption'] = df['caption'][i-1]
list(i)['Family_Type']=df['family_type'][i-1]
list(i)['Product_Type']=df['product_type'][i-1]
list(i).to_excel('list'+str(i).xlsx')
Variable Types:
print(type(dict1)) --> dict
print(type(dict1['a'])) --> list
print(type(string)) --> str
print(type(list1)) --> list
Edit tried code:
d2 = {}
for i in range(1,100):
d["list{0}".format(i)]=[]
for i in range(1, 100):
d["list{0}".format(i)] = comment.text
d["list{0}".format(i).append(d2)
d["list{0}".format(i)] = pd.DataFrame(d["list{0}".format(i)])
d["list{0}".format(i)]['Link'] = df['link'][i-1]
d["list{0}".format(i)]['Caption'] = df['caption'][i-1]
d["list{0}".format(i)]['Family_Type'] = df['family_type'][i-1]
d["list{0}".format(i)]['Product_Type'] = df['product_type'][i-1]
d["list{0}".format(i)].to_excel('list'+str(i).xlsx')
returns an error
for i,_ in enumerate(df['link'], 1):
listi = pd.DataFrame( [{'A':string} for a in locals()[f"dict{i}"]['a'] ] )
listi['Link']=df['link'][i-1]
listi['Caption']=df['caption'][i-1]
listi['Family_Type']=df['family_type'][i-1]
listi['Product_Type']=df['product_type'][i-1]
listi.to_excel(f'list{i}.xlsx')
I have a list of lists containing company objects:
companies_list = [companies1, companies2]
I have the following function:
def get_fund_amount_by_year(companies_list):
companies_length = len(companies_list)
for idx, companies in enumerate(companies_list):
companies1 = companies.values_list('id', flat=True)
funding_rounds = FundingRound.objects.filter(company_id__in=companies1).order_by('announced_on')
amount_per_year_list = []
for fr in funding_rounds:
fr_year = fr.announced_on.year
fr_amount = fr.raised_amount_usd
if not any(d['year'] == fr_year for d in amount_per_year_list):
year_amount = {}
year_amount['year'] = fr_year
for companies_idx in range(companies_length):
year_amount['amount'+str(companies_idx)] = 0
if companies_idx == idx:
year_amount['amount'+str(companies_idx)] = fr_amount
amount_per_year_list.append(year_amount)
else:
for year_amount in amount_per_year_list:
if year_amount['year'] == fr_year:
year_amount['amount'+str(idx)] += fr_amount
return amount_per_year_list
The problem is the resulting list of dictionaries has only one amount attribute updated.
As you can see "amount0" contains all "0" amounts:
[{'amount1': 12100000L, 'amount0': 0, 'year': 1999}, {'amount1':
8900000L, 'amount0': 0, 'year': 2000}]
What am I doing wrong?
I put list of dictionaries being built in the loop and so when it iterated it overwrote the last input. I changed it to look like:
def get_fund_amount_by_year(companies_list):
companies_length = len(companies_list)
**amount_per_year_list = []**
for idx, companies in enumerate(companies_list):
companies1 = companies.values_list('id', flat=True)
funding_rounds = FundingRound.objects.filter(company_id__in=companies1).order_by('announced_on')
I have a list of drawingnumbers, I am attempting to split these strings and then append to a number of lists.
I am hoping to end up with a number of lists, which contains each relevant piece of the original string.
At the minute my definition is iterating through the list, but overwriting the variables, not appending them. So I have a single entry for each variable and these correspond to the final entry of the list.
Could anybody please help?
# drawingnumber split
drawingnumber = ["AAA601-XXX-A-L00-1028-DR-GA-200-001",
"AAA601-XXX-A-L10-1028-DR-GA-200-001",
"AAA601-XXX-A-L00-1029-DR-GA-200-001",
"AAA601-XXX-A-L00-1029-DR-GA-200-XXX"]
building = []
buildinglist = []
originator = []
discipline = []
level = []
scope = []
drawingtype = []
drawingsubtype = []
numbera = []
numberb = []
for i in drawingnumber:
building, originator, discipline, level, scope, \
drawingtype,drawingsubtype, numbera, numberb = i.split("-")
print("building:", building)
print("originator: ", originator)
print("discipline: ", discipline)
print("level: ", level)
print("scope: ", scope)
print("drawingtype: ", drawingtype)
print("drawingsubtype", drawingsubtype)
print("drawingident", numbera, "-", numberb)
You can use zip after splitting each element in the list to transpose your lists as:
zip(*[i.split("-") for i in drawingnumber])
And assign them to lists names:
building, originator, discipline, level, scope, \
drawingtype, drawingsubtype, numbera, numberb = zip(*[i.split("-") for i in drawingnumber])
Example output:
building
# ('AAA601', 'AAA601', 'AAA601', 'AAA601')
originator
# ('XXX', 'XXX', 'XXX', 'XXX')
numberb
# ('001', '001', '001', 'XXX')
Just change
for i in drawingnumber:
building, originator, discipline, level, scope, drawingtype,drawingsubtype, numbera, numberb = i.split("-")
to:
for i in drawingnumber:
building_, originator_, discipline_, level_, scope_, drawingtype_,drawingsubtype_, numbera_, numberb_ = i.split("-")
building.append(building_)
originator.append(originator_)
...etc...
splitted valeus redefine your variables each time what you want to do here is basically append those to lists you created, also pick plural names for list like: buildings and append singular variables to them
drawingnumber = ["AAA601-XX1-A-L00-1028-DR-GA-200-001",
"AAA602-XX2-A-L10-1028-DR-GA-200-001",
"AAA603-XX3-A-L00-1029-DR-GA-200-001",
"AAA604-XX4-A-L00-1029-DR-GA-200-XXX"]
building = []
buildinglist = []
originator = []
discipline = []
level = []
scope = []
drawingtype = []
drawingsubtype = []
numbera = []
numberb = []
for i in drawingnumber:
j = i.split('-')
building.append(j[0])
buildinglist.append(j[1])
for i in range(len(drawingnumber)):
print("building:", building[i])
print("buildinglist:", buildinglist[i])
How can I sort my list of dicts by their name values according to an arbitrary ordering? I want dicts with a name of 720p to come first, then dicts with a name of 1080p, and finally dicts with a name of 360p.
hosters = []
for entry in json.loads(aResult[1][0]):
if 'file' not in entry or 'label' not in entry: continue
sLabel = sName + ' - ' + entry['label'].encode('utf-8')
hoster = dict()
hoster['link'] = entry['file']
hoster['name'] = sLabel
hoster['resolveable'] = True
hosters.append(hoster)
You're going to need to use a custom sorting function. Something like this should work:
def sort_by_resolution(hoster):
desired_order = ['720p', '1080p', '360p']
if hoster['name'] in desired_order:
return desired_order.index(hoster['name'])
else:
return len(desired_order)
sorted(foo, key=sort_by_resolution)
# [{'name': '720p'}, {'name': '1080p'}, {'name': '360p'}]