openpyxl removes drop-down lists - python

I wrote a Python script, which inserts data into an Excel file. My problem is that my drop-down list disappears after every save. I do have multiple sheets in my Excel file and not only my current page, which I edit is affected, also all others too.
Here is my code:
def openExcelFile(path: str = None) -> openpyxl:
if path is None:
raise ValueError("path is None!")
return openpyxl.load_workbook(path)
def saveToExcelFile(wb_object: openpyxl = None, path: str = None) -> None:
if wb_object is None or path is None:
raise ValueError("wb_object or path is None!")
wb_object.save(path)
wb_object.close()
def findDuplicate(sheet_object, dataset: LandRegister = None, column: int = 0, row: int = 0, index: int = 0):
if index == 0 and row == 1:
return (-1, -1, -1)
duplicate_found = False
family_found = False
for i in range(0, index + 1):
cell_firstname = sheet_object.cell(row=row - i, column=column).value
cell_lastname = sheet_object.cell(row=row - i, column=column + 1).value
cell_address = sheet_object.cell(row=row - i, column=column + 2).value
cell_zipcode = sheet_object.cell(row=row - i, column=column + 3).value
if cell_lastname == dataset.lastname[index] and \
cell_address == dataset.address[index] and \
cell_zipcode == dataset.zipcode[index]:
if cell_firstname == dataset.firstname[index]:
return (-2, -2, -2)
return (row - 1, column, index)
if duplicate_found:
return (-2, -2, -2)
elif family_found:
return (row - 1, column, index)
else:
return (-1, -1, -1)
def insertNewRow(sheet, row, nr):
sheet.insert_rows(row, amount=1)
cell_object = sheet.cell(
row=row, column=2)
cell_object.value = nr
def insertData(sheet_object, dataset: LandRegister = None, column: int = 0, row: int = 0, index: int = 0):
# Insert the first name.
cell_object = sheet_object.cell(
row=row, column=column)
cell_object.value = dataset.firstname[index]
# Insert the last name.
cell_object = sheet_object.cell(
row=row, column=column + 1)
cell_object.value = dataset.lastname[index]
# Insert the location
cell_object = sheet_object.cell(
row=row, column=column + 2)
cell_object.value = dataset.address[index]
# Insert the zipcode
cell_object = sheet_object.cell(
row=row, column=column + 3)
tmp_zipcode = dataset.zipcode[index]
cell_object.value = tmp_zipcode
def insertMetaData(sheet_object, row: int = 0, column: int = 0):
kg_nr_p = sheet_object.cell(
row=row, column=column)
kg_name_p = sheet_object.cell(
row=row, column=column + 1)
grst_nr_p = sheet_object.cell(
row=row, column=column + 2)
cell_object = sheet_object.cell(
row=row+1, column=column)
cell_object.value = kg_nr_p.value
cell_object = sheet_object.cell(
row=row+1, column=column + 1)
cell_object.value = kg_name_p.value
cell_object = sheet_object.cell(
row=row+1, column=column + 2)
cell_object.value = grst_nr_p.value
def writeToExcelFile(wb_object, dataset: LandRegister = None, sheet_name: str = None, cell: str = 'A0'):
if dataset is None or sheet_name is None or wb_object is None:
raise ValueError("dataset, sheet_name or wb_object is None!")
start_row = SETTINGS[sheet_name]['row']
start_col = SETTINGS[sheet_name]['col']
sheet_names = wb_object.sheetnames
if sheet_name not in sheet_names:
raise ValueError("No matching sheet name found!")
sheet_object = wb_object[sheet_name]
row = 0
for index in range(len(dataset.firstname)):
found_row, found_colum, found_index = findDuplicate(
sheet_object, dataset, column=start_col, row=(row + start_row), index=index)
if found_colum == -1 and found_row == -1 and found_index == -1:
if index > 0:
cell_object = sheet_object.cell(
row=row + start_row-1, column=start_col-10)
insertNewRow(sheet_object, row + start_row, cell_object.value)
insertMetaData(sheet_object, row + start_row-1, start_col-9)
insertData(sheet_object, dataset,
column=start_col, row=(row + start_row), index=index)
row += 1
elif found_colum == -2 and found_row == -2 and found_index == -2:
continue
else:
cell_object = sheet_object.cell(
row=found_row, column=found_colum)
cell_object.value += " und " + dataset.firstname[index]
SETTINGS[sheet_name]['row'] = start_row + row
def loadSettings():
global SETTINGS
with open(os.path.join(DIRPATH, 'settings.json'), 'r') as file:
SETTINGS = json.load(file)
def saveSettings():
with open(os.path.join(DIRPATH, 'settings.json'), 'w') as file:
json.dump(SETTINGS, file)
def run(files: List[str], landregiser: LandRegister = None, extractor: ExtractorLandRegister = None) -> None:
path = os.path.join(DIRPATH, EXCEL_FILE_NAME)
excel_file = openExcelFile(path)
sheet_name = SETTINGS["Sheets"][SETTINGS["Source"]['4']]
main_logger.info(f'Insert in {sheet_name}')
counter = 1
for key in files:
print_message = f'==={files[key]:<2}===\n'
try:
txt = extractor.extractTextFromPdf(files[key])
landregiser.dataset = txt
landregiser.execute()
writeToExcelFile(excel_file, landregiser, sheet_name)
main_logger.info(
f'Counter {counter:<2}: | {files[key]:<75} | {len(landregiser.firstname):<2}')
counter += 1
except Exception as exce:
print(exce)
print_message += str(exce)
main_logger.error("Error")
counter += 1
SETTINGS[sheet_name]['row'] = SETTINGS[sheet_name]['row'] + 1
saveToExcelFile(excel_file, path)
# saveSettings()
def main():
loadSettings()
ex = ExtractorLandRegister(SETTINGS["Source"]['4'])
lr = LandRegister()
files = ex.getPdfFiles()
run(files, landregiser=lr, extractor=ex)
if __name__ == '__main__':
main()
Do I use openpyxl in a wrong way or does it not support to load an existing drop-down list?

Ok it is not working to load the Data-Validation into, but it is possible to insert the data and afterwards format everything accordingly.
To make a validation with openpyxl use this link to do so.

Related

Openpyxl - Empty rows when copy and pasting data

I've written a script which copies data from one workbook to another. My only issue is that empty cells are being added between data. Can anyone understand why? It looks like the script is skipping values which don't meet the condition of the if statement, but still copying a blank cell.
from openpyxl import load_workbook
from openpyxl import Workbook
wb = load_workbook('testData.xlsx')
wb2 = load_workbook('testTemplate.xlsx')
ws = wb.worksheets[0]
mr = ws.max_row
ws2 = wb2.worksheets[0]
mr2 = ws2.max_row
for row in ws.iter_rows(min_row = 1, min_col = 1, max_row = mr, max_col = 3):
for cell in row:
if cell.value == "A":
ws2.cell(row = mr2 + 1, column = 1).value = (cell.offset(column = + 1).value)
mr2 += 1
elif cell.value == "B":
ws2.cell(row = mr2 + 1, column = 2).value = (cell.offset(column = + 1).value)
mr2 += 1
elif cell.value == "C":
ws2.cell(row = mr2 + 1, column = 3).value = (cell.offset(column = + 1).value)
mr2 += 1
wb2.save('testTemplate.xlsx')
Your issue:
Giving Enter(mr2 += 1) every time after entering value as it return in if condition
Solution:
Create separate counter for different columns and Enter(Counter += 1) when value in entered in that column
As per example:
A = ws2.max_row
if cell.value == "A":
ws2.cell(row = A + 1, column = 1).value = (cell.offset(column = + 1).value)
A += 1
Full Code:
from openpyxl import load_workbook
from openpyxl import Workbook
wb = load_workbook('testData.xlsx')
wb2 = load_workbook('testTemplate.xlsx')
ws = wb.worksheets[0]
mr = ws.max_row
ws2 = wb2.worksheets[0]
A = ws2.max_row
B = ws2.max_row
C = ws2.max_row
for row in ws.iter_rows(min_row = 2, min_col = 1, max_row = mr, max_col = 2):
for cell in row:
if cell.value == "A":
ws2.cell(row = A + 1, column = 1).value = (cell.offset(column = + 1).value)
A += 1
elif cell.value == "B":
ws2.cell(row = B + 1, column = 2).value = (cell.offset(column = + 1).value)
B +=1
elif cell.value == "C":
ws2.cell(row = C + 1, column = 3).value = (cell.offset(column = + 1).value)
C +=1
wb2.save('testTemplate.xlsx')

Why is my flask route saving xlsx file to the root directory of the project instead of instance files?

I am trying to create a flask route that sends data to a function, that function creates an openpyxl excel file and returns the excel file to the route, and the route then returns the downloadable file to a React frontend. I'm not sure if this is the exact problem, but I am getting errors that the file is not found in my instance/files folder. Instead, the file is saving to my project's root directory. The same path is working for other routes, so I'm not sure what I'm doing wrong here/why it is saving elsewhere. I'm assuming this is why I can't return the excel file to the frontend, but it could be other issues with my function/route. Please help!
This is my openpyxl function:
def generate_prev_sim_csv(data):
get_dict = data
claims = data['claims']
setup_dict = data['setups']
summary_metric_headers = data['setupSummaryMetricHeaders']
filename = "Simulation_Summary.xlsx"
wb = Workbook()
sheet = wb.active
# styles
heading_font = Font(size=11, bold=True)
heading = NamedStyle(name='Heading')
wb.add_named_style(heading)
heading.font = heading_font
percent_value = NamedStyle(name='Percentage')
wb.add_named_style(percent_value)
percent_value.number_format = '0.00%'
# Claim Header
headers = ['Claim']
start_claim_header_row = 1
start_claim_header_col = 2
for i, header in enumerate(headers):
current_row = start_claim_header_row
column_letter = get_column_letter(start_claim_header_col)
cell_ref = f"{column_letter}{current_row}"
sheet[cell_ref] = header
sheet[cell_ref].style = heading
# Setup Header
setup_title = "Setup "
start_setup_header_row = 1
start_setup_header_col = 3
for header_index, header in enumerate(setup_dict):
current_row = start_setup_header_row
column_letter = get_column_letter(start_setup_header_col)
cell_ref = f"{column_letter}{current_row}"
sheet[cell_ref] = setup_title + str(header_index)
sheet[cell_ref].style = heading
for col_index, col_data in enumerate(setup_dict):
current_col = start_setup_header_col + 1
column_letter = get_column_letter(current_col)
cell_ref = f"{column_letter}{current_row}"
sheet[cell_ref] = setup_title + str(col_index + 1)
sheet[cell_ref].style = heading
# Side by Side Claim and Claim States Table
starting_col_index = 2
starting_row_index = 2
for index, claim in enumerate(claims):
current_row = starting_row_index + index
column_letter = get_column_letter(starting_col_index)
cell_ref = f"{column_letter}{current_row}"
sheet[cell_ref] = claim
sheet[cell_ref].style = heading
for i, setup in enumerate(setup_dict):
setup_claims_on = setup[3]
current_col = starting_col_index + i + 1
column_letter = get_column_letter(current_col)
cell_ref = f"{column_letter}{current_row}"
if claim in setup_claims_on:
sheet[cell_ref] = setup[2][claim]['Summary_Metrics']['Reach']
sheet[cell_ref].style = percent_value
elif setup[0][claim] == "Offered":
sheet[cell_ref] = "Already Offered"
elif setup[0][claim] == "Considered":
sheet[cell_ref] = "Considered"
elif setup[0][claim] == "Excluded":
sheet[cell_ref] = "Excluded"
else:
sheet[cell_ref] = ""
# Summary Metrics Header
start_metric_header_row = 16
start_metric_header_col = 2
for i, header in enumerate(summary_metric_headers):
current_row = start_metric_header_row
column_letter = get_column_letter(start_metric_header_col)
cell_ref = f"{column_letter}{current_row}"
sheet[cell_ref] = "Summary Metrics"
sheet[cell_ref].style = heading
# Summary Metrics Table
start_col_index = 2
start_row_index = 17
for i, header in enumerate(summary_metric_headers):
current_row = start_row_index + i
column_letter = get_column_letter(start_col_index)
cell_ref = f"{column_letter}{current_row}"
sheet[cell_ref] = header
sheet[cell_ref].style = heading
for id, setup in enumerate(setup_dict):
current_col = starting_col_index + id + 1
column_letter = get_column_letter(current_col)
cell_ref = f"{column_letter}{current_row}"
if header == "Subgroup":
sheet[cell_ref] = setup[5]
elif header == "Number of Respondents":
sheet[cell_ref] = setup[4]
elif header == "Average Liked":
sheet[cell_ref] = round(setup[1]["Average_Number_of_Items_Liked"], 2)
elif header == "Average Reach":
sheet[cell_ref] = setup[1]["Reach"]
sheet[cell_ref].style = percent_value
elif header == "Average Favorite":
sheet[cell_ref] = setup[1]["Favorite_Percentage"]
sheet[cell_ref].style = percent_value
else:
sheet[cell_ref] = ""
wb.save(filename=filename)
return filename
This is my route. I'm not sure what to do with the return from the function?:
#bp.route("/api/export_prev_sim_to_csv", methods=["GET", "POST"])
def export_simulations_to_csv():
data = request.get_json() or {}
print(data)
if not os.path.exists(current_app.instance_path):
os.mkdir(current_app.instance_path)
if not os.path.exists(os.path.join(current_app.instance_path, "files")):
os.mkdir(os.path.join(current_app.instance_path, "files"))
cs_fn = os.path.join(
current_app.instance_path, "files", "Simulation_Summary.xlsx"
)
openpyxl_file = generate_prev_sim_csv(data)
return send_file(
cs_fn,
mimetype=(
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
),
as_attachment=True,
cache_timeout=0,
)
You are saving the file in root directory in generate_prev_sim_csv function
filename = "Simulation_Summary.xlsx"
[...]
wb.save(filename=filename)
Wb.save creates a file if it doesn't exist so you don't need to create file in your route
Just change the filename to this in your openpyxl function
filename = 'instance/files/Simulation_Summary.xlsx'

How to make the value not null in skewness in the extraction of the color moment feature?

I want to use the color moment feature extraction, which must get the value (mean, standard deviation and skewness) but the skewness value cannot be entered into the excel because there is a negative division value and the skewness result becomes (Nan), how can you still use it?
<<RuntimeWarning: invalid value encountered in double_scalars
hasil_akhir_skewS (skewnessS/totS)**(1/3)>>
import cv2
import numpy as np
import math
import xlsxwriter as xlsx
book = xlsx.Workbook('data_ayam.xlsx')
sheet = book.add_worksheet()
sheet.write(0, 0, 'file')
column = 1
fitur = ['meanH','meanS','meanV', 'stdevH','stdevS','stdevV', 'skewnessH','skewnessS','skewnessV']
for i in fitur :
sheet.write(0, column, i)
column += 1
ayam_type = ['non_segar', 'segar']
sum_each_type = 100
row = 1
for i in ayam_type:
for j in range(1, sum_each_type+1):
column = 0
file_name = 'ayam/' + i + str(j) + '.jpg'
print(file_name)
sheet.write(row, column, file_name)
column += 1
#preprocessing
img = cv2.imread(file_name, 1)
resized_image = cv2.resize(img, (256, 256))
fitur = cv2.cvtColor(resized_image, cv2.COLOR_BGR2HSV)
H = fitur[:, :, 0]
S = fitur[:, :, 1]
V = fitur[:, :, 2]
totH = H.size
totS = S.size
totV = V.size
totalH = H.sum()
totalS = S.sum()
totalV = V.sum()
#Mean
meanH = totalH/totH #equivalent to file_name.mean()
meanS= totalS/totS #equivalent to file_name.mean()
meanV = totalV/totV #equivalent to file_name.mean()
#Stdev
vrH = ((H - meanH)**2).sum()
vrS = ((S - meanS)**2).sum()
vrV = ((V - meanV)**2).sum()
hasil_akhir_stdH = math.sqrt((vrH/totH))
hasil_akhir_stdS = math.sqrt((vrS/totS))
hasil_akhir_stdV = math.sqrt((vrV/totV))
#Skewness
meanijH = (H - meanH)
meanijS = (S - meanS)
meanijV = (V - meanV)
skewnessH = (meanijH**3).sum()
skewnessS = (meanijS**3).sum()
skewnessV = (meanijV**3).sum()
hasil_akhir_skewH = (skewnessH/totH)**(1/3)
hasil_akhir_skewS = (skewnessS/totS)**(1/3)
hasil_akhir_skewV = (skewnessV/totV)**(1/3)
hasil = [meanH,
meanS,
meanV,
hasil_akhir_stdH,
hasil_akhir_stdS,
hasil_akhir_stdV,
hasil_akhir_skewH,
hasil_akhir_skewS,
hasil_akhir_skewV]
feature_props = {
hasil[0],
hasil[1],
hasil[2],
hasil[3],
hasil[4],
hasil[5],
hasil[6],
hasil[7],
hasil[8]
}
for item in feature_props:
sheet.write(row, column, item)
column += 1
row += 1
book.close()
This is the error:

Error with copying values from one sheet to other

I am trying to copy the values from some cells but it give me this error, i tried even without using the def cell(x,y) but still the same error.
This is the error:
learn_tar.cell(row=learn_tar, column=1).value = sheet.cell(row=learn_tar, column=1).value
AttributeError: 'int' object has no attribute 'cell'
Source:
import openpyxl
def cell(x,y):
cell = sheet.cell(row=x,column=y).value
return cell;
def percentage(percent, whole):
return int((percent * whole) / 100.0);
ex = openpyxl.load_workbook("Final_excel2.xlsx")
sheet = ex.get_sheet_by_name('Sheet1')
num = [0,0,0]
per = [0,0,0]
for row in range(2,4798):
if cell(row,1) == '1: Progression':
num[0] = num[0] + 1
elif cell(row,1) == '2: Incidence':
num[1] = num[1] + 1
elif cell(row,1) == '3: Non-exposed control group':
num[2] = num[2] + 1
for column in range(2,49):
#doing stuff
per[0] = percentage(70,num[0])
per[1] = percentage(70,num[1])
per[2] = percentage(70,num[2])
learn_att = ex.create_sheet('Learn-Att',2)
learn_tar = ex.create_sheet('Learn-Tar',3)
test_att = ex.create_sheet('Test-Att',4)
test_tar = ex.create_sheet('Test-Tar',5)
learn_att = 1
learn_tar = 1
test_att = 1
test_tar = 1
for row in range(2,4798):
if row<=1391:
if row<=974:
learn_tar.cell(row=learn_tar, column=1).value = cell(row,1)
learn_att+= 1
learn_tar+= 1
else:
test_tar.cell(row = test_tar,column = 1).value = cell(row,1)
test_att+= 1
test_tar+= 1
for column in range(2,49):
if row<=1391:
if row<=974:
learn_att.cell(row = learn_att,column = column - 1).value = cell(row,column)
else:
test_att.cell(row = test_att,column = column - 1).value = cell(row,column)
You override learn_tar with 1:
learn_tar = ex.create_sheet('Learn-Tar',3)
...
learn_tar = 1
Remove:
learn_tar = 1
and:
learn_tar+= 1
from your code.

Undefinded Syntax Error?

Very new to this, but so far have had a little help in making this. It keeps giving syntax error on line 131.. and many other errors too. Im not really sure on what it is and the person who helped me create this is gone leaving me by my noob self to try and fix this.There is more to the script in the middle after -------- which decompiles the direct files but i cant post them. But i only need to figure out whats wrong with this "syntax error" so, Whats worng with this script?
#o-----------------------------------------------------------------------------o
#(-----------------------------------------------------------------------------)
#|Compatible w/ Python 3.2 |
#########################
# Configuration section #
#########################
toptablefolder = 'C:/Games/TOP/kop/scripts/table/'
toptableversion = 6
toptableencoding = 'gbk'
####end of config####
import struct
from types import *
#---------------------------------------------
class top_tsv:
name = ''
file_name = ''
list = []
version = ''
frombin_map = [('',{'v':0})]
def __init__(self, file_name=0, version=0):
if file_name == 0:
self.file_name = toptablefolder+self.__class__.__name__
else:
self.file_name = file_name
if (version == 0):
self.version = toptableversion
else:
self.version = version
self.list = []
self.frombin_map = [('',{'v':0})]
def unencrypt(self):
item = []
#Load data
file = open(self.file_name+'.bin', 'rb')
data = bytearray(file.read())
file.close()
i = 0
array_size = int(list(struct.unpack_from('<i',data[i:i+4]))[0])
rdata = data[i:i+4]
data = data[i+4:len(data)]
m = 0
k = 0
l = len(data)//array_size
#2.2 encryption
if ((self.version >= 5) and ((self.__class__.__name__ != 'magicsingleinfo') and (self.__class__.__name__ != 'magicgroupinfo') and (self.__class__.__name__ != 'resourceinfo') and (self.__class__.__name__ != 'terraininfo'))):
newbytes = bytes.fromhex('98 9D 9F 68 E0 66 AB 70 E9 D1 E0 E0 CB DD D1 CB D5 CF')
while(k<l):
item = data[i:i+array_size]
i = i+array_size
if ((self.version >= 5) and ((self.__class__.__name__ != 'magicsingleinfo') and (self.__class__.__name__ != 'magicgroupinfo') and (self.__class__.__name__ != 'resourceinfo') and (self.__class__.__name__ != 'terraininfo'))):
for m,c in enumerate(item):
j = m % len(newbytes)
item[m] = ((item[m] - newbytes[j]) + 256) % 256
rdata = rdata + item
k = k + 1
m = 0
file = open(self.file_name+'-un.bin', 'wb')
file.write(rdata)
file.close()
def load_bin_data(self):
array = []
item = []
addresses = []
#Load structure (calculate size)
struct_type_map={
"char":"c",
"byte":"b",
"ubyte":"B",
"_bool":"?",
"short":"h",
"ushort":"H",
"int":"i",
"uint":"I",
"long":"l",
"ulong":"L",
"quad":"q",
"uquad":"Q",
"float":"f",
"double":"d",
"str":"s",
"color":"B",
"rcolor":"B",
}
struct_vars = {'t':'','s':1,'l':1,'stp':1,'f':-1,'v':-1,'lpad':0,'rpad':0,'sa':-1,'sap':-1,'ea':-1,'eap':-1,'st':'','lm':0,'sm':0,'smb':0,'smea':0,'sv':0,'func':0}
#initialize addresses
struct_init_address = 0
struct_limit_address = 0
struct_marked_addresses = [0,0,0,0,0,0]
struct_func_indexes = []
for i, v in enumerate(list(zip(*self.frombin_map))[1]):
struct_item = struct_vars.copy()
struct_item.update(v)
if struct_item['smb']>=1:
struct_marked_addresses[struct_item['smb']] = struct_init_address
if struct_item['lm']>=1:
struct_init_address = struct_marked_addresses[struct_item['lm']]
if struct_item['sm']>=1:
struct_marked_addresses[struct_item['sm']] = struct_init_address
if (type(struct_item['func']) == FunctionType):
struct_func_indexes.append(i)
elif (struct_item['v'] == -1):
if type(struct_item['t']) == tuple:
struct_item['s'] = len(struct_item['t'])
struct_item['st'] = []
for j,t in enumerate(struct_item['t']):
struct_item['st'].append(struct_type_map[struct_item['t'][j]])
struct_item['st'] = tuple(struct_item['st'])
struct_item['s'] = len(struct_item['st'])
else:
struct_item['st'] = struct_type_map[struct_item['t']]
if ((struct_item['t'] == 'color') or (struct_item['t'] == 'rcolor')):
struct_item['s'] = 3
struct_item['sa'] = struct_init_address
struct_item['sap'] = struct_item['sa'] + struct_item['lpad']
struct_item['ea'] = struct_item['sap']
if type(struct_item['t']) == tuple:
for j,t in enumerate(struct_item['t']):
struct_item['ea'] = struct_item['ea'] + struct.calcsize(struct_item['st'][j]) * ((struct_item['stp'] * struct_item['l'])-(struct_item['stp']-1))
else:
struct_item['ea'] = struct_item['ea'] + struct.calcsize(struct_item['st']) * ((struct_item['s'] * struct_item['stp'] * struct_item['l'])-(struct_item['stp']-1))
if struct_item['smea']>=1:
struct_marked_addresses[struct_item['smea']] = struct_item['ea']
struct_item['eap'] = struct_item['ea'] + struct_item['rpad']
struct_init_address = struct_item['eap']
if (struct_init_address > struct_limit_address):
struct_limit_address = struct_init_address
#print(struct_item)
self.frombin_map[i] = (self.frombin_map[i][0],struct_item)
struct_size = struct_limit_address
#Load data
file = open(self.file_name+'.bin', 'rb')
data = bytearray(file.read())
file.close()
i = 0
k = 0
array_size = int(list(struct.unpack_from('<i',data[i:i+4]))[0])
if array_size != struct_size:
print(self.file_name+'.bin: Actual array size ('+str(array_size)+') doesn''t match structure size ('+str(struct_size)+')')
raise 'Size error.'
data = data[i+4:len(data)]
m = 0
k = 0
l = len(data)//struct_size
#2.2 encryption
if ((self.version >= 5) and ((self.__class__.__name__ != 'magicsingleinfo') and (self.__class__.__name__ != 'magicgroupinfo') and (self.__class__.__name__ != 'resourceinfo') and (self.__class__.__name__ != 'terraininfo'))):
newbytes = bytes.fromhex('98 9D 9F 68 E0 66 AB 70 E9 D1 E0 E0 CB DD D1 CB D5 CF')
while(k<l):
item = data[i:i+struct_size]
i = i+struct_size
if ((self.version >= 5) and ((self.__class__.__name__ != 'magicsingleinfo') and (self.__class__.__name__ != 'magicgroupinfo') and (self.__class__.__name__ != 'resourceinfo') and (self.__class__.__name__ != 'terraininfo'))):
for m,c in enumerate(item):
j = m % len(newbytes)
item[m] = ((item[m] - newbytes[j]) + 256) % 256
array.append(item)
k = k + 1
m = 0
#Associate the data with the structure
self.list = []
self.list.append(list(zip(*self.frombin_map))[0])
for y,rawrow in enumerate(array):
row = []
for x,cell_struct in enumerate(list(zip(*self.frombin_map))[1]):
if type(cell_struct['func']) == FunctionType:
cell = []
cell.append('0')
row.append(self.transformtostr(cell,**cell_struct))
else:
cell = []
if (cell_struct['v'] == -1):
i = cell_struct['sap']
for j in range(cell_struct['l']):
processed_data=list(struct.unpack_from('<'+str((cell_struct['s']//len(cell_struct['st']))*cell_struct['stp'])+"".join(cell_struct['st']),rawrow,i))[::cell_struct['stp']]
#if (x == 4) and (y == 70):
# #print(cell_struct['s'])
cell.append(processed_data)
i=i+cell_struct['s']*struct.calcsize("".join(cell_struct['st']))*cell_struct['stp'] #sizeof here
if (cell_struct['t'] == 'rcolor'):
cell[0].reverse()
else:
cell.append(cell_struct['v'])
#if y == 70:
# print(cell) #'s':0x02,'l':0x08
row.append(self.transformtostr(cell,**cell_struct))
self.list.append(row)
for x,row in enumerate(self.list):
if x>0:
for func_index in struct_func_indexes:
self.list[x][func_index] = list(zip(*self.frombin_map))[1][func_index]['func'](func_index, row)
deletions = 0
for z,struct_item_name in enumerate(list(zip(*self.frombin_map))[0]):
if (struct_item_name == ''):
del self.list[x][z-deletions]
deletions = deletions + 1
return
def i(self,x):
for i,v in enumerate(self.list):
if(x==v):
return i
break
return -1
def j(self,x):
for i,v in enumerate(list(zip(*self.frombin_map))[0]):
if(x==v):
return i
break
return -1
def remap(self,v):
for i,n in enumerate(list(zip(*v))[0]):
if self.j(n) == -1:
self.frombin_map.append((list(zip(*v))[0][i],list(zip(*v))[1][i]))
else:
if (list(zip(*v))[1][i] == {}):
del self.frombin_map[self.j(n)]
else:
self.frombin_map[self.j(n)] = (list(zip(*v))[0][i],list(zip(*v))[1][i])
def bintotsv(self):
file = open(self.file_name+'.txt', 'wt', encoding=toptableencoding)
for i,a in enumerate(self.list):
a=list(a)
if (i==0):
deletions = 0
for z,item in enumerate(a[:]):
if (item == ''):
del a[z-deletions]
deletions = deletions + 1
file.write('//'+'\t'.join(a))
else:
#print(a)
file.write('\n'+'\t'.join(a))
file.close()
return self
def trim_nullbytestr(string, flag=0): #flag=1, return "0" when string is empty
result = string
for i,byte in enumerate(string[:]):
if byte == '\00':
result = string[:i]
break
if (flag & 1) and ((string == '\00') or (string == '')):
result = '0'
return result
def transformtostr(self,result,t,s,l,stp,f,v,ea,eap,lpad,rpad,sa,sap,st,sm,lm,smb,smea,sv,func):
if v != -1:
return str(v)
_type = t
j = 0
for n,v in enumerate(result[:]):
m = 0
if type(t) == tuple:
_type = t[j]
is_integer = not((_type=="float") or (_type=="double") or (_type=="str") or (_type=="char") or (_type=="_bool"))
if is_integer:
if f==-1:
f=0
for k,w in enumerate(v[:]):
if is_integer:
#Result: flag=0x0001 = remove FF's, #flag=0x0002 = cut file defect bytes, #flag=0x0004 = remove 0's
if ((((f & 0x4) and (w == 0))) or
((f & 0x1) and ((w == (2**8)-1) or (w == (2**16)-1) or (w == (2**32)-1) or (w == (2**64)-1) or (w == -1))) or
((f & 0x2) and ((((_type=="byte") or (_type=="ubyte")) and (w == (2**8)-51)) or (((_type=="short") or (_type=="ushort")) and (w == (2**16)-12851)) or (((_type=="long") or (_type=="ulong")) and (w == (2**32)-842150451)) or (((_type=="quad") or (_type=="uquad")) and (w == (2**64)-3617008641903833651))))):
del result[j][m]
m=m-1
else:
if (f & 0x2 and w == 0):
result[j] = result[j][:m]
break
result[j][m]=str(result[j][m])
m=m+1
if (_type=="float"):
if f==-1:
f=3
result[j][k]=str(round(float(w),f))
if (_type=="str"):
if f==-1:
f=0
if (w[0] == 205) and (w[1] == 205):
result[j][m] = ''
else:
result[j][m] = w.decode('gbk','ignore')
for o,x in enumerate(result[j][m]):
if x == '\00':
result[j][m] = result[j][m][:o]
break
#result[j][m] = result[j][m].strip()
if ((f & 1) and (result[j][m] == '')):
result = '0'
if (result[j] != '0'):
result[j] = ','.join(result[j])
if is_integer:
if (result[j] == ''):
result[j] = '0'
j=j+1
if (_type=="str"):
result = ','.join(result)
if ((f & 1) and (result == '')):
result = '0'
else:
result = ';'.join(result)
if is_integer:
if (result == ''):
result = '0'
return result
]
for c in toptablebins:
myc = c()
try:
myc.load_bin_data()
except IOError:
print('"'+myc.file_name+'.bin'+'" doesn''t exist, skipping...')
myc.bintotsv()
these are a few lines below and above line 131 which is the error
for j,t in enumerate(struct_item['t']):
struct_item['st'].append(struct_type_map[struct_item['t'][j]])
struct_item['st'] = tuple(struct_item['st'])
struct_item['s'] = len(struct_item['st'])
else: <--- this is 131
struct_item['st'] = struct_type_map[struct_item['t']]
if ((struct_item['t'] == 'color') or (struct_item['t'] == 'rcolor')):
struct_item['s'] = 3
struct_item['sa'] = struct_init_address
struct_item['sap'] = struct_item['sa'] + struct_item['lpad']
struct_item['ea'] = struct_item['sap']
if type(struct_item['t']) == tuple:
for j,t in enumerate(struct_item['t']):
struct_item['ea'] = struct_item['ea'] + struct.calcsize(struct_item['st'][j]) * ((struct_item['stp'] * struct_item['l'])-(struct_item['stp']-1))
It doesn't look like the you have the proper indention. Remember, in Python, whitespace is very very important.
The problem section of code should probably start looking something like:
elif (struct_item['v'] == -1):
if type(struct_item['t']) == tuple:
struct_item['s'] = len(struct_item['t'])
struct_item['st'] = []
for j,t in enumerate(struct_item['t']):
struct_item['st'].append(struct_type_map[struct_item['t'][j]])
struct_item['st'] = tuple(struct_item['st'])
struct_item['s'] = len(struct_item['st'])
This seems a bit weird:
l = len(data)//struct_size
You really need to post the traceback the the interpreter is giving you - it makes finding the error much easier.

Categories

Resources