AttributeError: when change font colour in xlwings python - python

I want to change font colour if before row of value is same with next cell in xlwings.I try with "worksheet.range(changeFontCell).api.font.Color = rgb_to_int((176,176,176))" to change font.
But i get error "AttributeError: '<win32com.gen_py.Microsoft Excel 16.0 Object Library.Range instance at 0x2163906949584>' object has no attribute 'font'"
Below is my source code. How can i solve that error
lastRow = worksheet.range('A' + str(worksheet.cells.last_cell.row)).end('up').row + 1
startNewRow = 'A' + str(lastRow)
worksheet.range(startNewRow).value = finalResult
finalLastRow = worksheet.range('A' + str(worksheet.cells.last_cell.row)).end('up').row
for i in list(range(lastRow, finalLastRow)):
if worksheet.range('A' + str(i)).value == worksheet.range('A' + str(i+1)).value:
changeFontCellColour = 'A' + str(i+1)
worksheet.range(changeFontCellColour ).api.font.Color = rgb_to_int((176,176,176))
else:
continue
Any advice helps! Thank you

Now i solve my problem with below source.
lastRow = worksheet.range('A' + str(worksheet.cells.last_cell.row)).end('up').row + 1
startNewRow = 'A' + str(lastRow)
worksheet.range(startNewRow).value = finalResult
finalLastRow = worksheet.range('A' + str(worksheet.cells.last_cell.row)).end('up').row
for i in list(range(lastRow, finalLastRow)):
if worksheet.range('A' + str(i)).value == worksheet.range('A' + str(i+1)).value:
changeFontCellColour = 'A' + str(i+1)
**myRange = worksheet.range(changeFontCellColour)**
myRange.api.Font.Color = rgb_to_int((160,160,160))
continue
else:
continue

Related

Is there a shorter way to increment bd_address in python?

I wrote a python's function to increment BT device BD_ADDR by any value but my function can only work up to xx:xx:xx:xx:FE:FF. For example, original BD_ADDR = AA:BB:CC:DD:EE:FF --> incremented by 1 BD_ADDR = AA:BB:CC:DD:EF:00. Also is there a shorter way to do this without all if statements? any suggestions will be appreciated.
Below is the script:
def ba_incr(mac,incr):
old_bytes = mac[12:].split(":")
if (old_bytes[0] != "00"):
if (old_bytes[0] != "01" and old_bytes[0] != "0F"):
old_hex = str(old_bytes[0] + old_bytes[1])
incr_hex = hex(int(str(int(old_hex, base=16) + incr)))[2:]
new_bytes = str(incr_hex[:2]) + ":" + str(incr_hex[2:])
elif (old_bytes[0] == "0F" and old_bytes[1] == "FF") :
old_hex = str(old_bytes[0] + old_bytes[1])
incr_hex = hex(int(str(int(old_hex, base=16) + incr)))[2:]
new_bytes = str(incr_hex[:2]) + ":" + str(incr_hex[2:])
else:
old_hex = str(old_bytes[0] + old_bytes[1])
incr_hex = hex(int(str(int(old_hex, base=16) + incr)))[2:]
#print ("incremented hex",incr_hex)
new_bytes = "0" + str(incr_hex[:1]) + ":" + str(incr_hex[1:])
elif (old_bytes[0] == "00" and old_bytes[1] == "FF"):
old_hex = old_bytes[1]
#print ("old hex:",old_hex)
incr_hex = hex(int(str(int(old_hex, base=16) + incr)))[2:]
#print ("incremented hex:",incr_hex)
new_bytes = "01" + ":" + str(incr_hex[1:])
elif (old_bytes[0] == "00" and old_bytes[1][:1] == "0") and old_bytes[1][1:] != "F":
old_hex = old_bytes[1]
#print ("old hex:",old_hex)
incr_hex = hex(int(str(int(old_hex, base=16) + incr)))[2:]
#print ("incremented hex:",incr_hex)
new_bytes = old_bytes[0] + ":0" + str(incr_hex)
elif (old_bytes[0] == "00" and old_bytes[1] != "FF"):
old_hex = old_bytes[1]
#print ("old hex:",old_hex)
incr_hex = hex(int(str(int(old_hex, base=16) + incr)))[2:]
#print ("incremented hex:",incr_hex)
new_bytes = old_bytes[0] + ":" + str(incr_hex)[:2]
print ("mac after:", mac[:12] + new_bytes.upper())
You can probably try something like this:
Remove the ':' from the mac address
Convert the mac address to integer
Increment the integer value
Convert the integer to hex string
Insert back the ':' at the appropriate positions
Sample code that worked for me (for simplicity I am incrementing by 1). You may need to modify it to handle corner cases.
s = 'AA:BB:CC:DD:EE:FF'
s = s.replace(':', '')
val = int(s, 16)
val = val + 1
incr_s = hex(val)
incr_s = incr_s[2:].upper()
incr_s = ':'.join(incr_s[i:i+2] for i in range(0, len(incr_s), 2))
print(s)
print(incr_s)
Output:
AABBCCDDEEFF
AA:BB:CC:DD:EF:00

Python replace str in list with new value

I’m writing a program that makes music albums into files that you can search for, and for that i need a str in the file that have a specific value that is made after the list is complete. Can you go back in that list and change a blank str with a new value?
I have searched online and found something called words.replace, but it doesn’t work, i get a Attribute error.
def create_album():
global idnumber, current_information
file_information = []
if current_information[0] != 'N/A':
save()
file_information.append(idnumber)
idnumber += 1
print('Type c at any point to abort creation')
for i in creation_list:
value = input('\t' + i)
if value.upper == 'C':
menu()
else:
-1file_information.append('')
file_information.append(value)
file_information.append('Album created - ' + file_information[2] +'\nSongs:')
-2file_information = [w.replace(file_information[1], str(file_information[0]) + '-' + file_information[2]) for w in file_information]
current_information = file_information
save_name = open(save_path + str(file_information[0]) + '-' + str(file_information[2]) + '.txt', 'w')
for i in file_information:
save_name.write(str(i) + '\n')
current_files_ = open(information_file + 'files.txt', 'w')
filenames.append(file_information[0])
for i in filenames:
current_files_.write(str(i) + '\n')
id_file = open(information_file + 'albumid.txt', 'w')
id_file.write(str(idnumber))
-1 is where i have put aside a blank row
-2 is the where i try to replace row 1 in the list with the value of row 0 and row 2.
The error message I receive is ‘int’ object has no attribute ‘replace’
Did you try this?
-2file_information = [w.replace(str(file_information[1]), str(file_information[0]) + '-' + file_information[2]) for w in file_information]

AttributeError: 'str' object has no attribute 'size'

This is kind of related to my previous question, unanswered, from here:Inserting random values based on condition
for row in range(len(df)):
while df["Full_Input_Length"][row] >= 55:
df["Input3"][row] = np.random.choice(sentence_list, size=len(df))
df["Full_Input"][row] = np.array2string(df['TitleTag'][row]).replace("'","") + " " + np.array2string(df['Input2'][row]).replace("'","") + " " + np.array2string(df['Input3'][row]).replace("'","") + " " + np.array2string(df['Input4'][row]).replace("'","") + " " + np.array2string(df['Input5'][row]).replace("'","")
df["Full_Input_Length"][row] = len(df["Full_Input"][row])
break
I stuck to my initial plan and continued my attempts to write down this for loop properly. The error I am getting is on line 4, where it says
AttributeError: 'str' object has no attribute 'size'
Basically I am trying to concatenate multiple strings into column Full_Input. I would assume that now the problem is at df["Full_Input"][row] but I am not quite sure how to write it properly so my code would run. I tried different ways but none worked - other errors popped up.
What am I getting wrong? Is there any other way of doing this?
Full code:
df['TitleTag'] = np.nan
for col in range(len(df)):
condlist = [df['BrandId'][col] != 2, df['BrandId'][col] == 2]
choicelist = [df['Name'][col] + ' fra ' + df['BrandName'][col], df['Name'][col]]
df['TitleTag'][col] = np.select(condlist, choicelist)
df['Input1'] = np.nan
for col in range(len(df)):
condlist = [df['BrandId'][col] != 2, df['BrandId'][col] == 2]
choicelist = [df['Name'][col] + ' fra ' + df['BrandName'][col], np.nan]
df['Input1'][col] = np.select(condlist, choicelist)
symbol_list = (['-','=>','|','->'])
df["Input2"] = np.random.choice(symbol_list, size=len(df))
sentence_list = (['Køb online her','Sammenlign priser her','Tjek priser fra 4 butikker','Se produkter fra 4 butikker', 'Stort udvalg fra 4 butikker','Sammenlign og køb'])
df["Input3"] = np.random.choice(sentence_list, size=len(df))
symbol_list2 = (['-','|'])
df["Input4"] = np.random.choice(symbol_list2, size=len(df))
df["Input5"] = "Site.dk"
df["Full_Input"] = df['TitleTag'].astype(str) + " " + df['Input2'].astype(str) + " " + df['Input3'].astype(str) + " " + df['Input4'].astype(str) + " " + df['Input5'].astype(str)
df["Full_Input_Length"] = df["Full_Input"].apply(len)
for col in range(len(df)):
while df["Full_Input_Length"][col] >= 55:
df["Input3"][col] = np.random.choice(sentence_list, size=len(df))
df["Full_Input"][col] = np.array2string(df['TitleTag'][col]).replace("'","") + " " + np.array2string(df['Input2'][col]).replace("'","") + " " + np.array2string(df['Input3'][col]).replace("'","") + " " + np.array2string(df['Input4'][col]).replace("'","") + " " + np.array2string(df['Input5'][col]).replace("'","")
df["Full_Input_Length"][col] = len(df["Full_Input"][col])
break

How can I programmatically return the location (row and column) of a keyword

I am trying to use python to automate the analysis of hundreds of excel files. Currently I can open, write, and save files but I need to insert calculations in cells that contain keywords. I am using python 2.7, here is a snipet from my code where I am struggling:
def run_analysis():
excel = Dispatch('Excel.Application')
excel.DisplayAlerts = False
keyword = "Total Traffic"
x = 0
t = data_file_location_list
while x < len(t):
#for files in data_file_location_list:
wb = excel.Workbooks.Open(t[x].root_dir + "\\" + t[x].file_name)
ws = wb.Sheets('Bandwidth Over Time')
keyword_range = #here is where I am stuck
ws.Range(keyword_range).Value = 'write something'
wb.SaveAs(Filename=str(t[x].root_dir + "\\" + t[x].file_name))
wb.Close()
excel.Quit()
print x
x += 1
Just in case anyone was following this action, I figured it out and thought I would share the answer. The FindCell function was what I came up with, although there is probably a much more elegant way to do this.
def run_analysis():
excel = Dispatch('Excel.Application')
excel.DisplayAlerts = False
x = 0
t = data_file_location_list
while x < len(t):
# MATCHES ROW AND COL INPUT FOR CELL ADDRESS OUTPUT
def FindCell(descriptor, banner):
return(ws.Cells(excel.WorksheetFunction.Match(descriptor, ws.Range("B:B"), 0),
excel.WorksheetFunction.Match(banner, ws.Range("A:A"), 0)).Address)
try:
print 'opening: ' + t[x].root_dir + "\\" + t[x].file_name
wb = excel.Workbooks.Open(t[x].root_dir + "\\" + t[x].file_name)
ws = wb.Sheets('Bandwidth Over Time')
#find the cell below the cell containing "Total Traffic"
total_traffic_calc_range = FindCell("Traffic", 'Bandwidth Over Time')
total_traffic_calc_range_delimiter = int(total_traffic_calc_range.strip('$A$'))
total_traffic_equation_cell = "C" + str(total_traffic_calc_range_delimiter)
#add the equations for calculation
ws.Range(total_traffic_equation_cell).Value = '=Sum(' + 'B' + str(
total_traffic_calc_range_delimiter + 1) + ':B' + str(
total_throughput_calc_range_delimiter - 2) + ')'
wb.SaveAs(Filename = str(t[x].root_dir + "\\" + t[x].file_name))
except Exception as e:
print e
finally:
wb.Close()
excel.Quit()
print x
x += 1

python reading numbers from xlsx as different types

I have Python reading the following xlsx. What I noticed when I run the code again on the a similar xlsx but located in a different directory the types of numbers change. I tried to format the cells in xlsx so they are the same but it doesn't seem to work.
On the first xlsx I see the value in B1 as long and B15 as float, but in the second xlsx i see them as numpy.float64.
from openpyxl import load_workbook
import pandas as pd
import xlrd
import string as st
from string import ascii_uppercase # allows creation of Excel "A1" reference
import numpy as np
#address_1='C:/Users/user/Desktop/target/new version/xlsx/new colour.xlsx'#new version/xlsx/new colour.xlsx'
address_1='C:/Users/user/Desktop/target/new/xlsx/colour.xlsx'
book_formula = load_workbook(address_1,data_only=False)# location of file
book = load_workbook(address_1,data_only=True)# location of file
l = list(st.ascii_uppercase) + [letter1 + letter2 for letter1 in ascii_uppercase for letter2 in ascii_uppercase]
#reference data i.e. =
sheets_formula = book_formula.get_sheet_names()
name = []
ref_equal_dup = []
ref_cell_dup = [] # this has duplicates this goes through each worksheet to get the cells in each
index_1 = 0
def equal():
ref_equal_dup.append(str('=') + l[col] + str(row+1))
ref_equal_dup.append(str('=') + l[col] + '$' + str(row+1))
ref_equal_dup.append(str('=') + '$' + l[col] + '$' + str(row+1))
ref_equal_dup.append(str('=') + '$' + l[col] + str(row+1))
def cell():
ref_cell_dup.append( l[col] + str(row+1))
ref_cell_dup.append( l[col] + '$' + str(row+1))
ref_cell_dup.append( '$' + l[col] + '$' + str(row+1))
ref_cell_dup.append( '$' + l[col] + str(row+1))
while index_1 <len(sheets_formula):
name.append((str('=') + str(sheets_formula[index_1]) + str('!')))
df = pd.DataFrame(book_formula[(sheets_formula[index_1])].values)
rows, cols = len(df.index) - 1, len(df.columns) - 1
for col in range(cols):
for row in range(rows):
equal()
cell()
index_1 = index_1 + 1
# removes the dup from ref_cell_dup and ref_equal_dup:
ref_equal_dup_table = pd.DataFrame(np.array(ref_equal_dup).reshape(len(ref_equal_dup)/1,1),columns=['Cell'])
ref_cell_dup_table = pd.DataFrame(np.array(ref_cell_dup).reshape(len(ref_cell_dup)/1,1),columns=['Cell'])
# drops dups and keeps the first occurance
ref_cell_flat = ref_cell_dup_table.drop_duplicates(keep ='first')
ref_equal_flat = ref_equal_dup_table.drop_duplicates(keep ='first')
ref_cell = list(ref_cell_flat.values.flatten())
ref_equal = list(ref_equal_flat.values.flatten())
# gets the worksheet!cell
wrk_cell = []
for x in (name):
for y in (ref_cell):
wrk_cell.append(x + y)
sheets_formula = book_formula.get_sheet_names()
# gets the cell value and formula
index = 0
formula = []
def if_statements():
if str(thecell) <> str(thecell_0):
if (thecell) in str(wrk_cell + ref_equal):
formula.append(['Cell Reference',sheets_formula[index].encode('utf-8'),l[col] + str(row + 1), str(thecell)[1:]])
if (thecell) not in wrk_cell and thecell not in ref_equal and thecell is not None and thecell <> 'nan':
formula.append(['Formula',sheets_formula[index].encode('utf-8'),l[col] + str(row + 1), str(thecell)[1:]])
elif thecell == thecell_0:
if type(thecell) == unicode:
formula.append(['u',sheets_formula[index].encode('utf-8'),l[col] + str(row + 1), thecell])
elif type(thecell) == long:
formula.append([type(thecell),sheets_formula[index].encode('utf-8'),l[col] + str(row + 1), float(thecell)])
# elif str(type(thecell)) == "<type 'numpy.float64'>":
# formula.append(['f',sheets_formula[index].encode('utf-8'),l[col] + str(row + 1), thecell])
elif type(thecell) <> unicode:# and type(thecell) <> long: #and str(type(thecell)) <> "<type 'numpy.float64'>":
formula.append([type(thecell),sheets_formula[index].encode('utf-8'),l[col] + str(row + 1), str(thecell)])
while index < len(sheets_formula):
df = pd.DataFrame(book_formula[(sheets_formula[index])].values)
df_0 = pd.DataFrame(book[(sheets_formula[index])].values)
rows, cols = len(df.index) , len(df.columns)
for row in range(rows):
for col in range(cols):
thecell = df.iloc[row, col]
thecell_0 = df_0.iloc[row, col]
if thecell is not None:
if_statements()
index = index + 1
new_version = pd.DataFrame(np.array(formula).reshape(len(formula)-1/4,4),columns=['ACTION','SHEET_NAME','CELL_ADDRESS','CELL_VALUE'])
out put from python
xlsx format
The idea behind this is to compare a data set then store it, if a new version pops up I want to compare the old one vs the new one. This is issue caused by having numpy library?

Categories