I am currently attempting to write a Python 3 script that reads and manipulates Excel files to tell me how often a purchase in a particular place was made. For that I am using the openpyxl module.
My script currently automatically creates a dictionary for me that consists of a unique key for every store and how often it was purchased from.
It looks like this: {'Sains': 2, 'Sains Petrol': 1, 'McDonalds': 2, 'Council Tax': 1, 'Car Repair': 1, 'Steam Purchase': 1}
The next thing I would like to do is to write the name of every shop and the value of how often it was purchased from in cells that are next to each other, like so:
A3: Shop | number
A4: Shop | number
A5: Shop | number
Each shop and it's number is supposed to be in a new row.
The function to write to cell is new_sheet['A3'] = 'Hello World'. new_sheet is the name of the variable I assigned to the sheet.
I now want to write a piece of code that writes every shop and it's number to my new sheet.
I successfully managed to write a for-loop that lets me write a string to the cells on my sheet, but only as many times as there are entries in my dictionary.
The loop:
a = len(dict_shops_purchased_from)
for cell_number in range(2, a + 2):
cell = 'A' + str(cell_number)
for i in cell:
new_sheet[cell] = 'Hello World'
So this is going to write 'Hello World' into cells A3 to A8.
I also managed to write a for-loop that let's me make the dictionary's key and value into variables:
for key, value in dict_shops_purchased_from.items():
print(key, value)
My question is, how can I change the code so it will write the dictionary key in cell Ax and the value to cell Bx, because the problem is that
new_sheet[cell] comes from a for-loop and so do key and value
I tried the following:
for key, value in dict_shops_purchased_from.items():
print(key, value)
for cell_number in range(2, a + 2):
cell = 'A' + str(cell_number)
for i in cell:
new_sheet[cell] = key
But that only writes the last entry in the dictionary, which is 'Steam Purchase', six times
Any ideas how I could make this work?
I hope this makes sense
cell_no = 2
for key, value in dict_shops_purchased_from.items():
new_sheet['A' + str(cell_no)] = key
new_sheet['B' + str(cell_no)] = value
cell_no += 1
can you try above code, hope this helps
Related
I have some code which is something along the lines of
storage = {}
for index, n in enumerate(dates):
if n in specific_dates:
for i in a_list:
my_dict[i] = {}
my_dict[i]["somthing"] = value
my_dict[i]["somthing2"] = value_2
else:
#print(storage[dates[index - 1]["my_dict"][i]["somthing"])
for i in a_list:
my_dict[i] = {}
my_dict[i][somthing] = different_value - storage[dates[index - 1]["my_dict"][i]["somthing"]
my_dict[i]["somthing2"] = different_value_2
storage[n]["my_dict"] = my_dict
The first pass will initiate the code in if n in specific_dates: the second pass goes to for i in a_list:
Essentially the code is getting a value set on specific dates and this value is then used for nonspecific dates that occur after the specific date until the next specific date overrides that value. However, at every date, i save a dictionary of values within a master dictionary called storage.
I found the problem which is when I print my_dict on the second pass my_dict[i] is literally an empty dictionary whereas prior to that loop it was filled. Where I have put the commented-out print line it would print value. I have fixed this by changing storage[n]["my_dict"] = my_dict to storage[n]["my_dict"] = my_dict.copy() and can now access value.
However, I do not really understand why this didnt work how I expected in the first place as I thought by assigning my_dict to storage it was creating new memory.
I was hoping someone could explain why this is happening and why storage[dates[index - 1]["my_dict"][i]["somthing"] doesn't create a new space in memory if that is indeed what is happening.
I am trying workarounds for a discord command that modifies a document.
I am have a simple question: is it possible to update a whole column with something like sheet.update('B:B', scores) with a dictionary (multiple objects)? I want to have columns B and C updated with the keys being in B and values in C.
Before I had to use code specified in this post, and make two lists (one with the names [B] and one with the values [C]) with the names and values in their own lists, so they were nested.
for count in range(len(data['guild']['members'])): # For every guild member:
res = requests.get("https://playerdb.co/api/player/minecraft/" + data['guild']['members'][count]['uuid']) # Response from server
if res.status_code != 200: # If it wasn't a success, continue the loop and print a message
ctx.author.send("Error 1: Invaild name from player database API!")
continue
name = res.json()['data']['player']['username'] # We know it was successful if we got to this point, so it's safe to try and get data from our response
names.append(name)
# Members' GXP
xp = data['guild']['members'][count]['expHistory']
xp = sum(xp.values())
xpHist.append(xp)
# Weekly Total
wTotal = sum(xpHist)
print(xpHist)
That didn't work in the command and I am trying a dictionary method with the enumerate function.
Thanks!
EDIT: Updated to reference code as got striked for that :)
You can achieve the following with a simple for loop.
Add "Keys" to Cell A1 and "Values" to Cell B1.
Make a variable idx or anything and set it 2 as we already set A1 and B1 cell to "Keys" and "Values".
Iterate through dict.items() and update cell "A{idx}" to key and "B{idx}" to key and value respectively.
Add one to idx so while iterating to nth key and value, it does not update the same cell
sheet.update_cell("A1", "Keys")
sheet.update_cell("B1", "Values")
idx = 2
for k, v in dict.items():
sheet.update_cell(f"A{idx}", k)
sheet.update_cell(f"B{idx}", v)
idx += 1
I create a dictionary from a dataset and now I want to access every single row of the dictionary. Every single row of this dictionary contains 2 names, ex: Winner: Alex Loser: Leo.
My problem is that I don't know how to access the 2 names by index.
I would like something like this:
Row 1: Winner: Alex
Loser: Leo
and I would like to access the row like this: dictionary[x] -> so I can get the row and then once I have the row I want to access it like a=raw[y] and b=raw[y+1]. And then I want to print A and B. I want to do this because I have to copy just one specific player from every single row and to save it into another dictionary.
This is the code that I wrote to create the dictionary and to access it but doesn't work as I want.
dicti= imd4.to_dict('index') // dicti is the dictionary that I created and imd4 is the dataset containing the Winner and the Loser name
for x in dicti:
print (x,':')
for y in dicti[x]:
a=dicti[x][y]
b=dicti[x][y+1] //I can't do this but I would like to do it. So I can save the data base on their index
print (y,':',dicti[x][y])
print('Test :' ,a)
Here you can see how the dataset is build
Thank you in advance for your help.
Let's set up a test dictionary:
test_dictionary=[
{'winner':'ross','loser:'chandler'},
{'winner':'rachael','loser:'phoebe'},
{'winner':'joey','loser:'monica'},
{'winner':'gunther','loser:'chandler'}
]
We can loop through this easily:
for contest in test_dictionary:
print (contest)
and we could add a line number using the enumerate function:
for line_number, contect in test_dictionary:
print (line_number,contest)
so now we have the line number we can easily access the next element - we have to bear in mind though we don't want to access the final element as we can't print the contest after this so we loop to the [-1] element:
for line_number, contect in test_dictionary[:-1]:
print (line_number,contest)
print (line_number+1,test_dictionary[line_number+1])
We could also simply use a range on the length of test_dictionary and access the elements directly:
for line_number in range(len(test_dictionary)-1]:
print (line_number,test_dictionary[line_number])
print (line_number+1,test_dictionary[line_number+1])
I want to append the key value pairs in my python dictionary without including the brackets... I'm not really sure how to do that.
I've tried looking at similar questions but it isn't working for me.
#this creates a new workbook call difference
file = xlrd.open_workbook('/Users/im/Documents/Exception_Cases/Orders.xls')
wb = xl_copy(file)
Sheet1 = wb.add_sheet('differences')
#this creates header for two columns
Sheet1.write(0,0,"S_Numbers")
Sheet1.write(0,1," Values")
#this would store all the of Key, value pair of my dictionary into their respective SO_Numbers, Booking Values column
print(len(diff_so_keyval))
rowplacement = 1
while rowplacement < len(diff_so_keyval):
for k, v in diff_so_keyval.items():
Sheet1.write(rowplacement,0,k)
Sheet1.write(rowplacement,1,str(v))
rowplacement = rowplacement + 1
#This is what I have in my diff_so_keyval dictionary
diff_so_keyval = {104370541:[31203.7]
106813775:[187500.0]
106842625:[60349.8]
106843037:[492410.5]
106918995:[7501.25]
106919025:[427090.0]
106925184:[30676.4]
106941476:[203.58]
106941482:[203.58]
106941514:[407.16]
106962317:[61396.36]}
#this is the output
S_numbers Values
104370541 [31203.7]
106813775 [187500.0]
106842625 [60349.8]
I want the values without the brackets
Looks to me like the 'values' in the dictionary are actually single-element lists.
If you simply extract the 0th element out of the list, then that should work for 'removing the brackets':
Sheet1.write(rowplacement, 1, v[0])
I am trying to figure out the most efficient way of finding similar values of a specific cell in a specified column(not all columns) in an excel .xlsx document. The code I have currently assumes all of the strings are unsorted. However the file I am using and the files I will be using all have strings sorted from A-Z. So instead of doing a linear search I wonder what other search algorithm I could use as well as being able to fix my coding eg(binary search etc).
So far I have created a function: find(). Before the function runs the program takes in a value from the user's input that then gets set as the sheet name. I print out all available sheet names in the excel doc just to help the user. I created an empty array results[] to store well....the results. I created a for loop that iterates through only column A because I only want to iterate through a custom column. I created a variable called start that is the first coordinate in column A eg(A1 or A400) this will change depending on the iteration the loop is on. I created a variable called next that will get compared with the start. Next is technically just start + 1, however since I cant add +1 to a string I concatenate and type cast everything so that the iteration becomes a range from A1-100 or however many cells are in column A. My function getVal() gets called with two parameters, the coordinate of the cell and the worksheet we are working from. The value that is returned from getVal() is also passed inside my function Similar() which is just a function that calls SequenceMatcher() from difflib. Similar just returns the percentage of how similar two strings are. Eg. similar(hello, helloo) returns int 90 or something like that. Once the similar function is called if the strings are above 40 percent similar appends the coordinates into the results[] array.
def setSheet(ws):
sheet = wb[ws]
return sheet
def getVal(coordinate, worksheet):
value = worksheet[coordinate].value
return value
def similar(first, second):
percent = SequenceMatcher(None, first, second).ratio() * 100
return percent
def find():
column = "A"
print("\n")
print("These are all available sheets: ", wb.sheetnames)
print("\n")
name = input("What sheet are we working out of> ")
results = []
ws = setSheet(name)
for i in range(1, ws.max_row):
temp = str(column + str(i))
x = ws[temp]
start = ws[x].coordinate
y = str(column + str(i + 1))
next = ws[y].coordinate
if(similar(getVal(start,ws), getVal(next,ws)) > 40):
results.append(getVal(start))
return results
This is some nasty looking code so I do apologize in advance. The expected results should just be a list of strings that are "similar".