I am new to programming and am trying to do the following (so far unsuccessfully):
I have an excel spreadsheet with product codes, sellers and prices and am trying to update the prices in my spreadsheet from two different spreadsheets sent by wholesalers.
I want a program to correctly
search an excel spreadsheet and
copy the corresponding price from there to the correct location above.
So I want to, for example:
download the price for product code '92526' sold by wholesaler A.
I want to leave the manufacturer prices untouched.
I had a program which was doing that correctly,
except that I was telling it to iterate for every line in my spreadsheet and it was erasing the existing prices for manufacturers.
I want a dictionary in the format:
{92526: {'price': 5.5, 'seller': 'Wholesaler A'},
97056: {'price': 19, 'seller': 'Wholesaler A'},
...
}
I tried adding a screenshot of a spreadsheet with sample data but couldn't, so here it goes:
Product Code Seller Price
92526 Wholesaler A 5.5
97056 Wholesaler A 19
97055 Wholesaler B 15
97054 Wholesaler B 4.5
925AAT Manufacturer 3.99
925AAF Manufacturer 6.75
Columns are not representative of the actual columns in my spreadsheet.
The code I have is this (again, beginner):
import openpyxl
import pprint
data = {}
files = {'My_main_file':'my_file.xlsx',
'File_WholesalerA':'FileA.xlsx',
'File_WholesalerB':'FileB.xlsx'
}
wb1 = openpyxl.load_workbook(files['My_main_file'])
wb2 = openpyxl.load_workbook(files['File_WholesalerA'])
wb3 = openpyxl.load_workbook(files['File_WholesalerB'])
sheet1 = wb1.get_sheet_by_name('Master Database')
sheet2 = wb2.get_sheet_by_name('sheetA')
sheet3 = wb3.get_sheet_by_name('sheetB')
# Collect all product codes in my database spreadsheet and add them as keys to the empty dictionary
for row in range(2, sheet1.max_row + 1):
code = sheet1['E' + str(row)].value
data[code] = code
# Get Wholesaler A prices and add them to data dictionary
for row in range(2, sheet2.max_row + 1):
code = sheet2['A' + str(row)].value
if code in data:
data[code]['price'] = sheet2['J' + str(row)].value
data[code]['seller'] = 'Wholesaler A'
# Get Wholesaler B prices and add them to prices dictionary
for row in range(2, sheet3.max_row + 1):
code = sheet3['A' + str(row)].value
if code in data:
data[code]['price'] = sheet3['K' + str(row)].value
data[code]['seller'] = 'Wholesaler B'
# Paste the prices collected into the dictionary into my excel sheet for each #corresponding product code
for row in range(2, sheet1.max_row + 1):
code = sheet1['E' + str(row)].value
if code in data:
# Here I try to ensure that the code only updates the prices for the
# corresponding sellers and doesn't overwrite the prices for
# manufacturers.
if sheet1['C' + str(row)].value == data[code]['seller']:
sheet1['K' + str(row)].value = data[code]['price']
# Save another version of the spreadsheet with the data
wb1.save('My_main_file v2.xlsx')
pprint.pprint(data)
The expected result is for the program to scan the (10k +) lines of the Wholesaler spreadsheets, find the price corresponding to my product code and paste it into my sheet overwriting the old price but not erasing any other price.
My initial program managed to collect the prices and paste them to the corresponding product codes, but it erased the manufacturer prices which I had. This new program wont even populate the dictionary for some reason.
Any help is appreciated.
This assignment can't be done
data[code]['price'] = sheet2['J' + str(row)].value
data[code]['seller'] = 'Wholesaler A'
You can try this structure if it helps you out
data[code] = {'price': sheet2['J' + str(row)].value,
'seller': 'Wholesaler A'}
Edit:
The assignment I mentioned above can be done, but your dictionary needs to know it has nested dictionary inside it as Tomerikoo commented above me,
you could initial the line data[code] = {} and then it will work too.
Right now you'll jsut get an error saying:
TypeError: 'str'/'int'/etc object does not support item assignment
Related
Hi I have written some code in which a user adds in items and the prices they bought and sold for, then it automatically adds this to an Excel sheet. However, I am having trouble thinking of a way to insert multiple rows of the same item if the quantity sold is >1 without the user entering in the same fields x amount of times. Thanks
I am using Tkinter where a Button executes the Add_Data function.
def Add_Data(Event=None):
workbook = load_workbook('Accounting Sheet.xlsx')
sheet = workbook.active
sheet.insert_rows(idx=2)
sheet['A2'] = str(Date_Entry.get())
sheet['B2'] = str(Shoe_Name_Entry.get())
sheet['C2'] = str(Purchase_Price_Entry.get())
sheet['D2'] = str(Sale_Price_Entry.get())
RRP_Float = float(Purchase_Price_Entry.get())
Sale_Float = float(Sale_Price_Entry.get())
sheet['E1'] = str(Sale_Float-RRP_Float)
Shoe_Name_Entry.delete(0, 30)
Purchase_Price_Entry.delete(0, 6)
Sale_Price_Entry.delete(0, 6)
workbook.save('Accounting Sheet.xlsx')
Include a textbox for 'Quantity' on the input form (which defaults to 1) and obtain that value prior to writing the values to excel. When writing the values to excel include a loop that will iterate 'quantity' times like below.
If the user has Quantity 1 then one entry is made as before. If the Quantity is 2 or more then then after the first row is added to excel it will loop and add another entry with exact same values a 2nd time and so on till the Quantity value is reached.
def Add_Data(Event=None):
workbook = load_workbook('Accounting Sheet.xlsx')
sheet = workbook.active
quantity = int('0'+Quantity_Entry.get())
for sale in range(quantity):
sheet.insert_rows(idx=2)
sheet['A2'] = str(Date_Entry.get())
sheet['B2'] = str(Shoe_Name_Entry.get())
sheet['C2'] = str(Purchase_Price_Entry.get())
sheet['D2'] = str(Sale_Price_Entry.get())
RRP_Float = float(Purchase_Price_Entry.get())
Sale_Float = float(Sale_Price_Entry.get())
sheet['E1'] = str(Sale_Float-RRP_Float)
Shoe_Name_Entry.delete(0, 30)
Purchase_Price_Entry.delete(0, 6)
Sale_Price_Entry.delete(0, 6)
workbook.save('Accounting Sheet.xlsx')
Project is to identify, rank and classify dividend paying stocks on multiple exchanges.
In a nutshell, program flow (using python 3.8) is as follows:
Stage 1 - read Master List of stocks on exchange from a spreadhseet.
Stage 2 - download info and dividends from Yahoo Finance and run series of tests to identify those which meet the criteria and classified as targets now, or could be in the near/far future if one of the criteria changes.
Stage 3 - Master List and Targets are saved in a spreadsheet, and targets are graphed to give visual clues to dividends trend and annual growth.
Previous versions of this program were done in 3 different scripts, and yahoo finance was called to download stock info for each stage. These worked just fine, but I am trying to consolidate all of this in 1 script.
As seen in the full program code provided below, I am going through my list of stocks and saving the information in a dictionary:
graph_dict = {'Name':[],'Symbol':[],'Avg Div Growth':[],'Dividends':[],'Annual Dividends':[]}
Name and symbol are strings, Avg Div Growth is a float, and Dividends / Annual Dividends are pandas dataframes
As the list of names is looped through, and yahoo finance obtains dividends, the dictionary is appended. Effectively, each 'row' in the dictionary contains all the information I require to graph the stock.
I have no problems populating the dictionary, but I have 3 problems when I try to access the dictionary.
How do I extract a 'row' from the dictionary? I can access individual values from a specific 'row' using:
graph_dict['Name'][row_num]
so, graph_dict['Name'][0] is 'Keppel REIT in the code below.
I can not figure out how to extact all items in the row. I am looking for the equivalent to:
graph_dict.items()[row_num]
which would give me the name, symbol, avg div growth, all dividends and annual dividends for the stock in gthat row number.
How can I sort the 'rows' by values in the key [Avg Div Growth]?
I want to graph the securities in order from highest average dividend growth to the lowest. This is how I am ranking the securities on the list.
Using sorted() : sorted_dict = sorted(graph_dict, key = lambda item: item['Avg Div Growth']))
and itemgetter() : sorted_dict = sorted(graph_dict, key = itemgetter('Avg Div Growth')))
does not work with my dictionary format.
Based on how I declared the dictionary, how can I sort the 'rows' within the dictionary?
Or do I need to declare my dictionary differently?
How to slice the dictionary so I can send a group of 'rows' to my graph function?
I am graphing the list of securities with a number of securities per page. So, I need to group or slice my dictionary so that I can send the group of securities and their dividend data to the graphing function and graph one page at a time (collection of pages is saved as a .pdf doc for future reference)
One answer I saw suggested the following:
group_to_graph = dict(list(sorted_graph_dict.items())[group_start:group_end])
where group start and end are the limits for the slice and reference the 'row' number in the dictionary.
doing that just gave me the values of the keys at group_start as follows:
Stock Group on page # 0 - start row (group_start) = 0 , (end row (group_end) = 1
{'Name': ['Keppel REIT', 'UMS', 'SPH REIT', 'Frasers Hospitality Trust']}
Stock Group on page # 1 - start row (group_start) = 2 , (end row (group_end) = 3
{'Avg Div Growth': [6.77852254732552, 25.0433491073197, 32.833907784854, -20.4956238784202]}
I suspect that once I understand how to access a complete 'row' in the dictionary vs. individual keys as in Q1 above that this may answer itself, but please feel free to peruse the code below and suggest options for how to declare my dictionary and access all items in a 'row'.
import pandas as pd
import yfinance as yf
## basic information on each stock
name = ['Keppel REIT','UMS','SPH REIT','Frasers Hospitality Trust']
symbol = ['K71U.SI','558.SI','SK6U.SI','ACV.SI']
avg_div_growth = [6.77852254732552,25.0433491073197,32.833907784854,-20.4956238784202]
## create dataframe to hold stock info (downloaded from yahoo finance)
df = pd.DataFrame (columns = ['Name','Symbol','Avg Div Growth (%)'])
df = df.astype( dtype = {'Name': str, 'Symbol': str, 'Avg Div Growth (%)': float})
df['Name'] = name
df['Symbol'] = symbol
df['Avg Div Growth (%)'] = avg_div_growth
## create dictionary to hold all relevant info for graphing. Each stock has its own 'row' in the lists within the dictionary
graph_dict = {'Name':[],
'Symbol':[],
'Avg Div Growth':[],
'Dividends':[],
'Annual Dividends':[]}
## download dividend info from Yahoo Finance using yfinance
start = 0
end = len(df)
for count in range (start, end): # loops through list of securities contained in the dataframe
stock = yf.Ticker(df.loc[count,'Symbol'])
div = stock.dividends # is type Series by default
div_df = pd.DataFrame(div) # change to Dataframe
## make annual dividends dataframe
annual_divs_df = div_df.resample('Y').sum()
annual_divs_df.rename(columns = {'Dividends':'Annual Dividends'}, inplace = True)
## populate each 'row' of the dictionary with the relevant data
graph_dict['Name'].append(df.loc[count,'Name'])
graph_dict['Symbol'].append(df.loc[count,'Symbol'])
graph_dict['Avg Div Growth'].append(df.loc[count,'Avg Div Growth (%)'])
graph_dict['Dividends'].append(div_df)
graph_dict['Annual Dividends'].append(annual_divs_df)
print ('\nNumber of Names in dictionary is:',len(graph_dict['Name'])) # testing
## loop through dictionary to print each 'row' for testing purposes
for num in range(len(graph_dict['Name'])):
print('\nStock Number:',num+1)
print('Name is:', graph_dict['Name'][num])
print('Symbol is:',graph_dict['Symbol'][num])
print('Avg Annual Div Growth is:',graph_dict['Avg Div Growth'][num],'%')
print('\nAll Dividends declared:\n',graph_dict['Dividends'][num])
print('\nAnnual Dividends:\n',graph_dict['Annual Dividends'][num])
## sort the dictionary by Avg Div Growth from highest to lowest
''' How to sort the dictionary lists such that they are in order from highest Avg Div Growth to lowest ??? '''
sorted_graph_dict = graph_dict # change once how to sort is figuired out
## get first row in Dictionary
''' How to extract all items in a single row of the list within the complete dictionary ??? '''
## group the entries in the dictionary into groups (pages in graph) of set size
graph_rows = 2
number_of_securities = len(sorted_graph_dict['Name'])
page_pad = number_of_securities % graph_rows
if page_pad == 0: # all pages have full number of securities
number_of_pages = number_of_securities // graph_rows
else: # last page needs to be padded out to send proper number of securities to graph function
number_of_pages = number_of_securities // graph_rows + 1
print ('\n\npage_pad = ',page_pad, 'number of pages is: ',number_of_pages) # testing
start_page = 0
end_page = number_of_pages
group_to_graph = {} # empty dictionary to hold group of stocks to send to graph function
for page_number in range(start_page, end_page):
group_start = (page_number + 1) * graph_rows - graph_rows
group_end = group_start + graph_rows -1
''' how to slice dictionary so 'rows' within group start and end are isolated and sent to graphing_function??? '''
group_to_graph = dict(list(sorted_graph_dict.items())[group_start:group_end]) # DOES NOT WORK AS INTENDED
print ('\nStock Group on page #',page_number + 1,' - start row (group_start) = ',group_start, ', (end row (group_end) =',group_end, '\n',group_to_graph)
'''
Should print out items in each row,instead it it prints:
Names (key = 0 which is same as group_start) on 1st time through loop, and
Avg Div Growth on ( key = 2 which is same as group_start) on 2nd time through loop
'''
I am trying to iterate over a dictionary that contains multiple row indexes in its values and then apply pd.nsmallest function to generate the top 3 smallest values for the multiple sets of row indexes that are in the dictionary. However, there seems to be something wrong with my for loop statement as I am overwriting the top 3 values over and over till the last set of values in the dictionary and so my final excel file output shows only 3 rows for the last run of the for loop.
When I use print statements this works as expected and I get an output for all 16 values in the dictionary but when writing to excel file it only gives me the output of the last run on the loop
import pandas as pd
from tabulate import tabulate
VA = pd.read_excel('Columnar BU P&L.xlsx', sheet_name = 'Variance by Co')
legcon = VA[['Expense', 'Consolidation', 'Exp Category']]
legcon['Variance Type'] = ['Unfavorable' if x < 0 else 'favorable' for x in legcon['Consolidation']]
d = {'Travel & Entertainment': [1,2,3,4,5,6,7,8,9,10,11], 'Office supplies & Expenses': [13,14,15,16,17],
'Professional Fees':[19,20,21,22,23], 'Fees & Assessments':[25,26,27], 'IT Expenses':[29],
'Bad Debt Expense':[31],'Miscellaneous expenses': [33,34,35,36,37],'Marketing Expenses':[40,41,42],
'Payroll & Related Expenses': [45,46,47,48,49,50,51,52,53,54,55,56], 'Total Utilities':[59,60],
'Total Equipment Maint, & Rental Expense': [63,64,65,66,67,68],'Total Mill Expense':[70,71,72,73,74,75,76,77],
'Total Taxes':[80,81],'Total Insurance Expense':[83,84,85],'Incentive Compensation':[88],
'Strategic Initiative':[89]}
Printing output directly works fine when I do this:
for key,value in d.items():
a = legcon.iloc[value][legcon.iloc[:,1]<0].nsmallest(3,'Consolidation')
print(a)
Expense Consolidation Exp Category Variance Type
5 Transportation - AIR -19054 Travel & Entertainment Unfavorable
9 Meals -9617 Travel & Entertainment Unfavorable
7 Lodging -9439 Travel & Entertainment Unfavorable
Expense Consolidation Exp Category Variance Type
26 Bank Charges -4320 Fees & Assessments Unfavorable
27 Finance Charges -1389 Fees & Assessments Unfavorable
25 Payroll Fees -1145 Fees & Assessments Unfavorable
However when I use the below code to write to excel:
writer = pd.ExcelWriter('testt.xlsx', engine = 'xlsxwriter')
row = 0
for key,value in d.items():
a = legcon.iloc[value][legcon.iloc[:,1]<0].nsmallest(3,'Consolidation')
for i in range(0,16):
a.to_excel(writer, sheet_name = 'test', startrow = row+4, index = False)
writer.save()
my output looks like this and does not show all the exp categories:
I would really appreciate any feedback on how to correct this. Thanks in advance!
With some help from a friend I just realized my silly mistake, there was no row iterator in my for loop for the output to print on the next lines and using the below code fixed the issue (initially i placed the row iterator within my df.to_excel statement):
writer = pd.ExcelWriter('testt.xlsx', engine = 'xlsxwriter')
row = 0
for key,value in d.items():
a = legcon.iloc[value][legcon.iloc[:,1]<0].nsmallest(3,'Consolidation')
a.to_excel(writer, sheet_name = 'Testt', startrow = row, index = False)
row = row+4
writer.save()
I am working on a script to load information from excel to SQL. I cannot figure out how to fix my loops to remove the extra comma and extra space I get at the end of my sql code..
This is python code meant to read an excel file, and create INSERT INTO querys...
This is a python script meant to pull data from an excel file
import xlrd
with open('Phase3initial.sql', 'w') as file:
data = xlrd.open_workbook('Phase3 Initial Data.xlsx', on_demand = True)
sheets = data.sheet_names()
tables = ['User', 'UserEmail', 'Employee', 'Site', 'Event', 'Transit', 'Connect', 'TakeTransit', 'AssignTo', 'VisitEvent', 'VisitSite']
for i in range(data.nsheets):
sheets[i] = data.sheet_by_index(i)
for j in range (1, sheets[i].nrows):
file.write('INSERT INTO ' + str(tables[i]) + '(')
row = sheets[i].row_values(j)
for k in range(len(row)):
cell = sheets[i].cell(j,k)
if tables[i] == 'User':
if k ==1:
file.write(str(cell.value) +', ')
continue
file.write(str(cell.value) + ', ')
file.write(');\n')
image of excel file
https://imagizer.imageshack.com/v2/1024x768q90/924/EOTu41.png
I get an extra space and comma at the end.. after my code runs..Not sure how to fix that..
INSERT INTO User(james.smith, jsmith123, Approved, James, Smith, Employee, );
INSERT INTO User(michael.smith, msmith456, Approved, Michael, Smith, Employee, Visitor, );
INSERT INTO UserEmail(james.smith, jsmith#gatech.edu, );
INSERT INTO UserEmail(james.smith, jsmith#outlook.com, );
Edit
After some trial an error I am still stuck with the Date format..
Also, any ideas on how to hide the password? It's not supposed to be visible..
import xlrd
with open('Phase3initial.sql', 'w') as file:
data = xlrd.open_workbook('Phase3 Initial Data.xlsx', on_demand = True)
sheets = data.sheet_names()
tables = ['User', 'UserEmail', 'Employee', 'Site', 'Event', 'Transit', 'Connect', 'TakeTransit', 'AssignTo', 'VisitEvent', 'VisitSite']
for i in range(data.nsheets):
sheets[i] = data.sheet_by_index(i)
for j in range (1, sheets[i].nrows):
file.write('INSERT INTO ' + str(tables[i]) + '(')
row = sheets[i].row_values(j)
# first len(row)-1 columns
for k in range(len(row)-1):
cell = sheets[i].cell(j,k)
if tables[i] == 'User':
if k ==1:
file.write(str(cell.value) +',')
continue
file.write(str(cell.value) + ',')
# last column
k = len(row) - 1
cell = sheets[i].cell(j, k)
if tables[i] == 'User':
if k == 1:
file.write(str(cell.value))
continue
file.write(str(cell.value))
file.write(');\n')
For some reason my date is changed to 435000.0... is not formated.. check StartDate and EndDate on link
https://imagizer.imageshack.com/v2/1024x768q90/921/uODMTH.png
after james.smith and michael.smith the password are showing.. any ideas on how to hide the passwords?
My output
INSERT INTO User(james.smith,jsmith123,Approved,James,Smith,Employee);
INSERT INTO User(michael.smith,msmith456,Approved,Michael,Smith,Employee, Visitor);
INSERT INTO Event(Eastside Trail,43500.0,Piedmont Park,43501.0,0.0,99999.0,1.0,A combination of multi-use trail and linear greenspace, the Eastside Trail was the first finished section of the Atlanta BeltLine trail in the old rail corridor. The Eastside Trail, which was funded by a combination of public and private philanthropic sources, runs from the tip of Piedmont Park to Reynoldstown. More details at https://beltline.org/explore-atlanta-beltline-trails/eastside-trail/,);
INSERT INTO Event(Eastside Trail,43500.0,Inman Park,43501.0,0.0,99999.0,1.0,A combination of multi-use trail and linear greenspace, the Eastside Trail was the first finished section of the Atlanta BeltLine trail in the old rail corridor. The Eastside Trail, which was funded by a combination of public and private philanthropic sources, runs from the tip of Piedmont Park to Reynoldstown. More details at https://beltline.org/explore-atlanta-beltline-trails/eastside-trail/,);
You can solve this two ways:
- Check which line is last in loop, and not add a ', ' to it,
- Change write(str(cell.value) + ', ') to write(', ' +str(cell.value)) and check for first line and skip adding ', ' to it.
Get a list of cell values i.e.: cellvalues = ['user2','user1','user3','user4','user5']
And then use join on them like so:
result = cellvalues.join(',')
The result will be:
"user2,user1,user3,user4,user5"
You can further do:
values = f"({cellvalues.join(',')})"
And just add it to the beginning of the query.
Just one thing don't you need single quotes on those values?
Or hey, her's another idea just take the cellvalues and do:
values = str(tuple(cellvalues))
It will be easy if use pandas to read excel file as data frame and you can export it to mysql table.Use default mysql connector. You can write data back to table using to_sql or execute or executemany command. By using environment variable you can hide your password. For an example if u set pass='xyz' in your computer you can assign that password to variable by passwd=os.getenv('pass').Ref https://dev.mysql.com/doc/connector-python/en/connector-python-example-connecting.html
I am writing a code which should compare values from 2 xls files. One of the files has more than 1 sheet and I always have to read the data only from the last sheet. I really don't know how manage with this. Below is my code:
#! /usr/bin/python
import xlrd #Import the package to read from excel
#start with station report
station_rep = xlrd.open_workbook("/home/fun/data/Station.xls",encoding_override='utf8') #Open the station report.xls
station_sheet = station_rep.sheet_by_index(0) #should get the last sheet
station_vn = station_sheet.col_values(5, start_rowx=1, end_rowx=None) #List of vouchers in station report
#start with billing export
billing_rep = xlrd.open_workbook("/home/fun/data/Export.xls",encoding_override='utf8') #Open billing report xls
billing_sheet = billing_rep.sheet_by_index(0) #get the current sheet
billing_vn = billing_sheet.col_values(1, start_rowx=0, end_rowx=None)#list of vouchers in billing reports
for vn in station_vn: #For every voucher in station report
if vn: #if there is data
vnb=vn[1:] #change data
vnb=float(vnb) #change data type to float
if vnb in billing_vn: # check if voucher exist in billing report
row=station_vn.index(vn)+1 #take the row of current voucher
station_vn_data = station_sheet.row_values(row, start_colx=0, end_colx=15) #take the data for current row from station report
billing_vn_data = billing_sheet.row_values(billing_vn.index(vnb),start_colx=0, end_colx=15) #take the data for current voucher from billing report
if float(station_vn_data[5])==billing_vn_data[1]: #check if vouchers are equal
print "nomer na vouchera", station_vn_data[5], billing_vn_data[1]
if round(station_vn_data[10],3)<>round(billing_vn_data[5],3): #check for differences in ammount
print "Razlika v edinichna cena", round(station_vn_data[10],3),"-" , round(billing_vn_data[5],3),"=", round(station_vn_data[10]-billing_vn_data[5],3)
if station_vn_data[11]<>billing_vn_data[4]: #check for difference in price
print "kolichestvo", round(station_vn_data[11],4),"-", round(billing_vn_data[4],4),"=",round(station_vn_data[11]-billing_vn_data[4],4) #Ako ima razliki kolichestvata se printirat
if station_vn_data[12]<>billing_vn_data[6]:# check for 1 more difference
print "obshta suma", round(station_vn_data[12],3),"-", round(billing_vn_data[6],3),"=",round(station_vn_data[12]-billing_vn_data[6],3)
else:
print "voucher is OK"
print " " #print empty row for more clear view
else: #if voucher do not exist in billing
if vnb:
print vnb, "does not exist in billing report" #print the voucher number wich don`t exist
station_sheet = station_rep.sheet_by_index(0) #should get the last sheet
There is no reason this should get the last sheet; Python indices are zero-based, so 0 is the first element in a sequence:
>>> [1, 2, 3][0]
1
If you want the last worksheet, note that Python allows negative indexing from the end of a sequence:
>>> [1, 2, 3][-1]
3
On that basis, I think you want:
station_sheet = station_rep.sheet_by_index(-1) # get the last sheet
# ^ note index
I managed to fix it with that code:
for id in station_rep.sheet_names():
sheet_id=station_rep.sheet_names().index(id)
station_sheet = station_rep.sheet_by_index(sheet_id) #get the last sheet