How to perform function multiple times with Button in Tkinter - python

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')

Related

How do I update a specific parameter of a function, every time a bot runs?

I am writing a bot using gspread and IMDbPy. The script right now takes input(a movie title), it then grabs the movie ID, finds the movie's rating on IMDB.com, then posts the rating onto a spreadsheet into a specific cell.
There is a function named "update_cell" that updates the the specific cell based off the given row and column parameters. Once the bot is complete, I don't want to have to keep going into the code to update the row cell parameter. I want it to update by 1 each time the bot executes.
Is there a way to do this? I'll post the code below:
ia = imdb.IMDb()
def take_input():
fd = open('movielist.txt',"w")
print("Input your movie please: \n")
inp = input()
fd.write(inp)
fd.close()
take_input()
# Wed 8/28/19 - movie_list is a list object. Must set it equal to our ia.search_movies
# Need to find out where to put movie_list = ia.search_movies in the code, and what to
# remove or keep.
a = int(52)
b = int(18)
def Main():
c = """Python Movie Rating Scraper by Nickydimebags"""
print(c)
time.sleep(2)
f1 = open('movielist.txt')
movie_list = []
for i in f1.readlines():
movie_list.append(i)
movie_list = ia.search_movie(i)
movie_id = movie_list[0].movieID
print(movie_id)
m = ia.get_movie(movie_id)
print(m)
rating = m['rating']
print(rating)
scope = ["https://spreadsheets.google.com/feeds",'https://www.googleapis.com/auth/spreadsheets', "https://www.googleapis.com/auth/drive.file","https://www.googleapis.com/auth/drive"]
creds = ServiceAccountCredentials.from_json_keyfile_name("creds.json", scope)
client = gspread.authorize(creds)
sheet = client.open("Movie Fridays").sheet1
sheet.update_cell(a, b, rating) #updates specific cell
Main()
^ The a variable is what I need to update by 1 everytime the bot runs
I am guessing the a variable tracks the row index. You could get the index of the next empty row cell in the column you are adding the values to.
def next_available_row(worksheet, col):
return len(worksheet.col_values(col)) + 1
sheet = client.open("Movie Fridays").sheet1
sheet.update_cell(next_available_row(sheet, b), b, rating)
You are going to need to save the current or next value of your a variable somewhere and update it every time the script runs.
You could abuse a cell in the spreadsheet for this, or write it out to a file.

How to create nested dictionaries from excel sheet using Openpyxl

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

xlrd. Printing one row at a time. trouble incrementing rows

I'm trying to write a script that will pull one row of excel at a time and print it. I would like to use a method to change the row. I am able to get the value of the row to change (variable rrowx) but when I print the currentRow string, I get the original row and not the newly adjusted row.
import xlrd
class Loader(object): ## engine to load and unload spread sheets
## then sets them to a variable
# set the variables
workbook = " " # name of the file
sheetCount = 0 # amount of sheets in the spreadsheet
sheetNumber = 0 # current sheet (index)
rowCount = 0 # amount of rows in the spreadsheet
currentSheet = " " # name of current sheet
topRow = " " # row 0 string
currentRow = " " # row x string
global rrowx
rrowx = 0
# begin the load
workbook = xlrd.open_workbook('test.xlsx')
sheetCount = workbook.nsheets
sheetNames = workbook.sheet_names()
currentSheet = workbook.sheet_by_index(sheetNumber)
#topRow = currentSheet.row_values(rowx=rrowx, start_colx=scolx, end_colx=ecolx)
currentRow = currentSheet.row_values(rowx=rrowx)
# methods to navigate the sheet
def nextrow(self):
global rrowx
print(rrowx)
rrowx += 1
print(rrowx)
return rrowx
spreadsheet = Loader()
## Debuggin prints
print(spreadsheet.sheetNames)
print(spreadsheet.sheetCount)
print("What Sheet would you like to use? (Use numbers)")
spreadsheetadjust = int(input()) # takes input as a interger
spreadsheet.currentSheet = spreadsheetadjust - 1 # takes input and -1 for index value
print ('Current sheet name: %s' % spreadsheet.currentSheet)# prints current sheet name
print('top row:')
#print(spreadsheet.topRow)
print('row 1 ')
print(spreadsheet.currentRow)
print("NextRow")
spreadsheet.nextrow()
print(spreadsheet.currentRow)
I thought after changing the rrowx variable and calling print again on the currentRow would change the row that is printed. But instead I am getting the same row printed twice, even though I can see the value of rrowx is changing with the prints I added in the method.
disclosure: I've only been programming for a month so sorry if this is a easy answer i'm just missing.
I highly recommend you read python object oriented basics. You have multiple issues with your code, I will mention some:
Your class variables are class variables, meaning all instances of
the class will share the same variable. so if you create multiple
instances of your class, you will get unexpected/undesired behavior.
The use of a global variable is not recommended, especially when you
can do without it.
You don't need to initialize variables in python
In your implementation you have
spreadsheet.currentSheet = spreadsheetadjust - 1 which will cause you to fail even if you fix
your problem. You want
spreadsheet.sheetNumber = spreadsheetadjust - 1
Here is code that works with proper usage of python classes:
import xlrd
class Loader:
def __init__(self, path_to_xlsx='test.xlsx'):
self.sheetNumber = 0
self.rrowx = 0
self.workbook = xlrd.open_workbook(path_to_xlsx)
self.sheetCount = self.workbook.nsheets
self.sheetNames = self.workbook.sheet_names()
self.currentSheet = self.workbook.sheet_by_index(self.sheetNumber)
self.currentRow = self.currentSheet.row_values(rowx=self.rrowx)
def nextrow(self):
self.rrowx += 1
self.currentRow = self.currentSheet.row_values(rowx=self.rrowx)
spreadsheet = Loader()
print("What Sheet would you like to use? (Use numbers)")
spreadsheetadjust = int(input()) # takes input as a interger
spreadsheet.sheetNumber = spreadsheetadjust - 1 # takes input and -1 for index value
print('Current sheet name: %s' % spreadsheet.currentSheet) # prints current sheet name
print(spreadsheet.currentRow)
spreadsheet.nextrow()
print(spreadsheet.currentRow)

How to calculate a formula in Excel and pull the calculated value with OpenPyXL

I am trying to copy/paste quantities from one excel form into another excel form (that i use as a template) that calculates COGS, and then take the sum of the COGS and assign it to a variable. After some research on OpenPyXL, it looks like you cant calculate the formula in real-time, so i am attempting to save the file with the quantities copied, then re open it, grab my COGS sum, and clear out the quantities to leave it as a blank template.
However, when i do this, i can see that it is pasting the quantity values and clearing them out, but the total COGS value remains 'None.'
This is my first attempt at a Python application after reading through most of Automate the Boring, so I am quite new to this. Any help would be appreciated!
# TODO: Calculate total sell using order form and total cost using ' Costing.xlsx
# Create variables to hold qty of each trim from the total_sheet
costing_wb = openpyxl.load_workbook('Z:\\Costing.xlsx')
costing_sheet = costing_wb['COSTING']
for i in range(3, 46, 1):
costing_sheet.cell(row=i+2, column=4).value = total_sheet.cell(row=i, column=3).value
# Save Costing Sheet
costing_wb.save('Z:\\Costing.xlsx')
# TODO: total_COGS not grabbing value, returning as 'None'
# Reopen costing sheet and set COGS value
costing_wb = openpyxl.load_workbook('Z:\\Costing.xlsx', data_only=True)
costing_sheet = costing_wb['COSTING']
total_COGS = costing_sheet['I6'].value
# Empty Column D contents and save as blank
costing_wb = openpyxl.load_workbook('Z:\\Costing.xlsx')
costing_sheet = costing_wb['COSTING']
for i in range(5, 48, 1):
costing_sheet.cell(row=i, column=4).value = None
costing_wb.save('Z:\\Costing.xlsx')

python xlrd, read from last sheet in a workbook

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

Categories