Jan-30-2020, 02:54 PM
Thanks for the replies, I used the chain comparison method and that solved the issue.
I am now stuck with a separate problem. I am trying to implement a class to write the above values to a spreadsheet. The working version is this:
Thanks again for helping.
I am now stuck with a separate problem. I am trying to implement a class to write the above values to a spreadsheet. The working version is this:
from datetime import datetime, timedelta from openpyxl import load_workbook, Workbook class Spreadsheet(object): def __init__(self,certification_status,reason,age): #super(Spreadsheet,self). __init__(birth_date, exam_date, expiry_date, certification_status) self.certificate_type = certificate_type self.age = age self.reason = reason self.wb = load_workbook(filename = 'test2.xlsx') self.sheet = self.wb.active def write_reason(self,existing_value_location,target_location): #writes reason to cell c = [] existing_value = existing_value_location.value c.append(existing_value) if existing_value else " " c.append(self.reason) self.sheet[target_location] = str(",".join(c)) print(f"Reason of {self.reason} was added to cell {target_location}. The old reasons were {existing_value} and the new reasons are {(','.join(c))}") def addcount(self,target_row,target_column,target_cell_name): target_cell = self.sheet.cell(row = target_row, column = target_column) x = target_cell.value y = x+1 self.sheet[target_cell_name]= y print(f'Added one count to cell {target_cell_name}. The previous value was {x} and the new value is now {y}.') def writespreadsheet(self): while self.certificate_type == "Fit": if self.age < 20: Spreadsheet.addcount(self,10,3,'C10') break elif 20 <= self.age < 30: Spreadsheet.addcount(self,10,4,'D10') break elif 30 <= self.age < 40: Spreadsheet.addcount(self,10,5,'E10') break elif 40 <= self.age < 50: Spreadsheet.addcount(self,10,6,'F10') break elif 50 <= self.age < 60: Spreadsheet.addcount(self,10,7,'G10') break elif self.age >= 60: Spreadsheet.addcount(self,10,8, 'H10') break else: continue while self.certificate_type == "Time Limited": if self.age < 20: Spreadsheet.addcount(self,13,3,'C13') Spreadsheet.write_reason(self,(self.sheet.cell(row = 26, column = 2)), 'B26') break elif 20 <= self.age < 30: Spreadsheet.addcount(self,13,4,'D13') Spreadsheet.write_reason(self,(self.sheet.cell(row = 26, column = 3)), 'C26') break elif 30 <= self.age < 40: Spreadsheet.addcount(self,13,5,'E13') Spreadsheet.write_reason(self,(self.sheet.cell(row = 26, column = 4)), 'D26') break elif 40 <= self.age < 50: Spreadsheet.addcount(self,13,6,'F13') Spreadsheet.write_reason(self,(self.sheet.cell(row = 26, column = 5)), 'E26') break elif 50 <= self.age < 60: Spreadsheet.addcount(self,13,7,'G13') Spreadsheet.write_reason(self,(self.sheet.cell(row = 26, column = 6)), 'F26') break elif self.age >=60: Spreadsheet.addcount(self,13,8, 'H13') Spreadsheet.write_reason(self,(self.sheet.cell(row = 26, column = 7)), 'G26') break else: continue # and so on for " Limited" and "Fail" certification statusesAs you can see the code is long and difficult to maintain. I stumbled upon this link as a guide to simplify the code as such:
from datetime import datetime, timedelta from openpyxl import load_workbook, Workbook class Spreadsheet(object): def __init__(self,certification_status,reason,age): #super(Spreadsheet,self). __init__(birth_date, exam_date, expiry_date, certification_status) self.certificate_type = certificate_type self.age = age self.reason = reason self.wb = load_workbook(filename = 'test2 - Copy.xlsx') self.sheet = self.wb.active def write_reason(self,existing_value_location,target_location): #writes reason to cell c = [] existing_value = existing_value_location.value c.append(existing_value) if existing_value else " " c.append(self.reason) self.sheet[target_location] = str(",".join(c)) print(f"Reason of {self.reason} was added to cell {target_location}. The old reasons were {existing_value} and the new reasons are {(','.join(c))}") def addcount(self,target_row,target_column,target_cell_name): target_cell = self.sheet.cell(row = target_row, column = target_column) x = target_cell.value y = x+1 self.sheet[target_cell_name]= y print(f'Added one count to cell {target_cell_name}. The previous value was {x} and the new value is now {y}.') def writespreadsheet(self): #data setup certificate_type = {"Fit":{'type': self.certificate_type == "Fit", 'row_count': self.sheet[10], 'row_reason': None}, "Time Limited":{ 'type': self.certificate_type == "Time Limited", 'row_count': self.sheet[13], 'row_reason': self.sheet[26]}, "Limited": {'type': self.certificate_type ==" Limited", 'row_count': self.sheet[12], 'row_reason': self.sheet[25]}, "Fail": {'type': self.certificate_type == "Fail", 'row_count': self.sheet[11], 'row_reason': self.sheet[24]} } age_group = {"under 20": {'age':self.age < 20, 'column': self.sheet['C']}, "20-29": {'age':20 <= self.age < 30,'column': self.sheet['D']}, "30-39": {'age':30 <= self.age < 40,'column': self.sheet['E']}, "40-49": {'age':40 <= self.age < 50,'column': self.sheet['F']}, "50-59": {'age':50 <= self.age < 60,'column': self.sheet['G']}, "over 60":{'age': self.age >= 60, 'column': self.sheet['H']} } #enter data loop while True: try: for type in certificate_type: for age in age_group: Spreadsheet.addcount(self,"row_count",age_group['column'],(''.join(age_group["column"],"row_count"))) Spreadsheet.write_reason(self,"row_reason",age_group['column'],(''.join(age_group["column"],"row_reason"))) break except ValueError: raise("Unable to process. ") self.wb.save("D:\\python\\test2 - Copy.xlsx")When the code is run, I get this error:
Output:Traceback (most recent call last):
File "test.py", line 173, in <module>
b.writespreadsheet()
File "test.py", line 127, in writespreadsheet
Spreadsheet.addcount(self,"row_count",age_group['column'],(''.join(age_group["column"],"row_count")))
KeyError: 'column'
I still get a key error even though the column key is in the age_group dict. What gives..?Thanks again for helping.