I have already created AgGrid by loading data from a csv file. I am adding rows one by one via an external button. But when I try to edit the line I added, it disappears. I would be very grateful if you could help me where the error is. The codes are as follows.
import pandas as pd
import streamlit as st
from st_aggrid import AgGrid, GridUpdateMode, JsCode
from st_aggrid.grid_options_builder import GridOptionsBuilder
import sys
import os
import altair as alt
from streamlit.runtime.legacy_caching import caching
def data_upload():
df = pd.read_csv("data.csv")
return df
if 'grid' in st.session_state:
grid_table = st.session_state['grid']
df = pd.DataFrame(grid_table['data'])
df.to_csv(“data.csv”, index=False)
else:
df = data_upload()
gd = GridOptionsBuilder.from_dataframe(df)
gd.configure_column("Location", editable=True)
gd.configure_column("HourlyRate", editable=True)
gd.configure_column("CollaboratorName", editable=True)
gridOptions = gd.build()
button = st.sidebar.button("Add Line")
if "button_state" not in st.session_state:
st.session_state.button_state = False
if button or st.session_state.button_state:
st.session_state.button_state = True
data = [['', '', 0]]
df_empty = pd.DataFrame(data, columns=['CollaboratorName', 'Location', "HourlyRate"])
df = pd.concat([df, df_empty], axis=0, ignore_index=True)
df.to_csv(“data.csv”, index=False)
gd= GridOptionsBuilder.from_dataframe(df)
grid_table = AgGrid(df,
gridOptions=gridOptions,
fit_columns_on_grid_load=True,
height=500,
width='100%',
theme="streamlit",
key= 'unique',
update_mode=GridUpdateMode.GRID_CHANGED,
reload_data=True,
allow_unsafe_jscode=True,
editable=True
)
if 'grid' not in st.session_state:
st.session_state['grid'] = grid_table
else:
grid_table_df = pd.DataFrame(grid_table['data'])
grid_table_df.to_csv(“data.csv”, index=False)
You can see the running app from here enter image description here
This one has a different approach but the goal could be the same.
Two radio buttons are created, if value is yes new line will be created, if value is no there is no new line.
If you want to add a new line, select yes and then add your entry. Then press the update button in the sidebar.
If you want to edit but not add a new line, select no, edit existing entry and then press the update button.
Code
import streamlit as st
from st_aggrid import AgGrid, GridOptionsBuilder
import pandas as pd
def data_upload():
df = pd.read_csv("data.csv")
return df
def show_grid(newline):
st.header("This is AG Grid Table")
df = data_upload()
if newline == 'yes':
data = [['', '', 0]]
df_empty = pd.DataFrame(data, columns=['CollaboratorName', 'Location', "HourlyRate"])
df = pd.concat([df, df_empty], axis=0, ignore_index=True)
gb = GridOptionsBuilder.from_dataframe(df)
gb.configure_default_column(editable=True)
grid_table = AgGrid(
df,
height=400,
gridOptions=gb.build(),
fit_columns_on_grid_load=True,
allow_unsafe_jscode=True,
)
return grid_table
def update(grid_table):
grid_table_df = pd.DataFrame(grid_table['data'])
grid_table_df.to_csv('data.csv', index=False)
# start
addline = st.sidebar.radio('Add New Line', options=['yes', 'no'], index=1, horizontal=True)
grid_table = show_grid(addline)
st.sidebar.button("Update", on_click=update, args=[grid_table])
That happened because of your if button: statement. Streamlit button has no callbacks so any user entry under a st.button() will always reload the page so you end up losing the data, to prevent this, you can either initialize a session state fo your button or you can use st.checkbox() in place of st.button().
In this case I am going to fix your code by initializing a session state of the button.
def data_upload():
df = pd.read_csv("data.csv")
return df
st.header("This is AG Grid Table")
if 'grid' in st.session_state:
grid_table = st.session_state['grid']
df = pd.DataFrame(grid_table['data'])
df.to_csv('data.csv', index=False)
else:
df = data_upload()
gd = GridOptionsBuilder.from_dataframe(df)
gd.configure_column("Location", editable=True)
gd.configure_column("HourlyRate", editable=True)
gd.configure_column("CollaboratorName", editable=True)
gridOptions = gd.build()
def update():
caching.clear_cache()
button = st.sidebar.button("Add Line")
# Initialized session states # New code
if "button_state" not in st.session_state:
st.session_state.button_state = False
if button or st.session_state.button_state:
st.session_state.button_state = True # End of new code
data = [['', '', 0]]
df_empty = pd.DataFrame(data, columns=['CollaboratorName', 'Location', "HourlyRate"])
df = pd.concat([df, df_empty], axis=0, ignore_index=True)
gd= GridOptionsBuilder.from_dataframe(df)
df.to_csv('data.csv', index=False)
gridOptions = gd.build()
grid_table = AgGrid(df,
gridOptions=gridOptions,
fit_columns_on_grid_load=True,
height=500,
width='100%',
theme="streamlit",
key= 'unique',
update_mode=GridUpdateMode.GRID_CHANGED,
reload_data=True,
allow_unsafe_jscode=True,
editable=True
)
if 'grid' not in st.session_state:
st.session_state['grid'] = grid_table
grid_table_df = pd.DataFrame(grid_table['data'])
grid_table_df.to_csv('data.csv', index=False)
I think your code should work fine now with regards to the button issue.
Related
I am trying to add a new row to an AgGrid Table using streamlit and python
At this point, I just want to add 1 or more new rows to the table generated by the AgGrid by pressing the "add row" button.
After pressing the "add row" button I generate a second table with the new row mistakenly, so I get 2 data-tables instead of updating the main table.
The initial data df = get_data() is been gathered from a SQL query. I want to add a new row and (for now) save it into a CSV file or at least get the updated DF with the new row added as an output and graph it
My current code
import streamlit as st
from metrics.get_metrics import get_data
from metrics.config import PATH_SAMPLES
filename: str = 'updated_sample.csv'
save_path = PATH_SAMPLES.joinpath(filename)
def generate_agrid(data: pd.DataFrame):
gb = GridOptionsBuilder.from_dataframe(data)
gb.configure_default_column(editable=True) # Make columns editable
gb.configure_pagination(paginationAutoPageSize=True) # Add pagination
gb.configure_side_bar() # Add a sidebar
gb.configure_selection('multiple', use_checkbox=True,
groupSelectsChildren="Group checkbox select children") # Enable multi-row selection
gridOptions = gb.build()
grid_response = AgGrid(
data,
gridOptions=gridOptions,
data_return_mode=DataReturnMode.AS_INPUT,
update_on='MANUAL', # <- Should it let me update before returning?
fit_columns_on_grid_load=False,
theme=AgGridTheme.STREAMLIT, # Add theme color to the table
enable_enterprise_modules=True,
height=350,
width='100%',
reload_data=True
)
data = grid_response['data']
selected = grid_response['selected_rows']
df = pd.DataFrame(selected) # Pass the selected rows to a new dataframe df
return grid_response
def onAddRow(grid_table):
df = pd.DataFrame(grid_table['data'])
column_fillers = {
column: (False if df.dtypes[column] == "BooleanDtype"
else 0 if df.dtypes[column] == "dtype('float64')"
else '' if df.dtypes[column] == "string[python]"
else datetime.datetime.utcnow() if df.dtypes[column] == "dtype('<M8[ns]')"
else '')
for column in df.columns
}
data = [column_fillers]
df_empty = pd.DataFrame(data, columns=df.columns)
df = pd.concat([df, df_empty], axis=0, ignore_index=True)
grid_table = generate_agrid(df)
return grid_table
# First data gather
df = get_data()
if __name__ == '__main__':
# Start graphing
grid_table = generate_agrid(df)
# add row
st.sidebar.button("Add row", on_click=onAddRow, args=[grid_table])
Here is a sample minimal code.
import streamlit as st
import pandas as pd
from st_aggrid import AgGrid, GridOptionsBuilder, GridUpdateMode
def generate_agrid(df):
gb = GridOptionsBuilder.from_dataframe(df)
gb.configure_selection(selection_mode="multiple", use_checkbox=True)
gridoptions = gb.build()
grid_response = AgGrid(
df,
height=200,
gridOptions=gridoptions,
update_mode=GridUpdateMode.MANUAL
)
selected = grid_response['selected_rows']
# Show the selected row.
if selected:
st.write('selected')
st.dataframe(selected)
return grid_response
def add_row(grid_table):
df = pd.DataFrame(grid_table['data'])
new_row = [['', 100]]
df_empty = pd.DataFrame(new_row, columns=df.columns)
df = pd.concat([df, df_empty], axis=0, ignore_index=True)
# Save new df to sample.csv.
df.to_csv('sample.csv', index=False)
def get_data():
"""Reads sample.csv and return a dataframe."""
return pd.read_csv('sample.csv')
if __name__ == '__main__':
df = get_data()
grid_response = generate_agrid(df)
st.sidebar.button("Add row", on_click=add_row, args=[grid_response])
Initial output
Output after pressing add row
sample.csv
team,points
Lakers,120
Celtics,130
I’m trying to compare two charts side by side that can be sourced from different datasets with the same structure.
This is what it looks like:
This is what the code looks like:
col1, col2 = st.columns(2)
#Left Column
with col1:
dataset1 = st.selectbox(
'Pick Type',
datasets)
df1 = pd.read_csv(os.path.join(".\\data\\",dataset1+".csv"), index_col=False)
option1 = st.selectbox(
'Pick Flight',
df1['log_id_full'].unique(),
key='option1')
col1_choice = list(df1.columns)
col1_choice.remove('timestamp')
columns1 = st.multiselect(
'Pick Values',
col1_choice,
key='col1'
)
if 'df1_filtered' not in st.session_state:
st.session_state.df1_filtered = df1.loc[df1['log_id_full'] == option1]
form1= st.form(key='form1')
submit1 = form1.form_submit_button('Submit')
if submit1:
st.line_chart(
st.session_state.df1_filtered,
x = 'timestamp',
y = columns1)
#Right column
with col2:
dataset2 = st.selectbox(
'Pick Type',
datasets,
key = 'dataset2')
df2 = pd.read_csv(os.path.join(".\\data\\",dataset2+".csv"), index_col=False)
option2 = st.selectbox(
'Pick Data',
df2['log_id_full'].unique(),
key = 'option2')
col2_choice = list(df2.columns)
col2_choice.remove('timestamp')
columns2 = st.multiselect(
'Pick Values',
col2_choice,
key='col2'
)
if 'df2_filtered' not in st.session_state:
st.session_state.df2_filtered = df2.loc[df2['log_id_full'] == option2]
form2 = st.form(key='form2')
submit2 = form2.form_submit_button('Submit')
if submit2:
st.line_chart(
st.session_state.df2_filtered,
x = 'timestamp',
y = columns2)
If I remove the submit button one chart always shows an error until it gets values selected so I basically just need each column to operate independently and preserve state.
The above is how I tried to add stateful-ness based on the documentation examples. But it still behaves such that when I submit one it reruns the app and removes the line chart.
I know there are other optimizations, best-practice improvements I can make but this app is just for a POC and I was hoping to demo this functionality
Remove the form and just replace it with checkbox.
submit1 = st.checkbox(...)
submit2 = st.checkbox(...)
I created a form with two drop down menu's:
My goal is to make one dropdown dependent on the other dropdown.
This picture illustrates my goal and the current situation.
The sample code below can be run in Google Colab or Jupyter notebook to replicate the current situation.
##title
import ipywidgets as widgets
from ipywidgets import HBox, Label
from ipywidgets import Layout, Button, Box, FloatText, Textarea, Dropdown, Label, IntSlider
import time
import pandas as pd
#Create DF
df = df = pd.DataFrame(columns = ['Dropdown_column', 'Float_column'])
df
# Layout
form_item_layout = Layout(
display='flex',
flex_flow='row',
justify_content='space-between',
)
button_item_layout = Layout(
display='flex',
flex_flow='row',
justify_content='center',
padding = '5%'
)
# Independent dropdown item
drop_down_input = 'Dropdown_input_1'
drop_down = widgets.Dropdown(options=('Dropdown_input_1', 'Dropdown_input_2'))
def dropdown_handler(change):
global drop_down_input
print('\r','Dropdown: ' + str(change.new),end='')
drop_down_input = change.new
drop_down.observe(dropdown_handler, names='value')
# Dependent drop down
# Dependent drop down elements
dependent_drop_down_elements = {}
dependent_drop_down_elements['Dropdown_input_1'] = ['A', 'B']
dependent_drop_down_elements['Dropdown_input_2'] = ['C', 'D', 'E']
# Define dependent drop down
dependent_drop_down = widgets.Dropdown(options=(dependent_drop_down_elements['Dropdown_input_1']))
def dropdown_handler(change):
global drop_down_input
print('\r','Dropdown: ' + str(change.new),end='')
drop_down_input = change.new
drop_down.observe(dropdown_handler, names='value')
# Button
button = widgets.Button(description='Add row to dataframe')
out = widgets.Output()
def on_button_clicked(b):
global df
button.description = 'Row added'
time.sleep(1)
with out:
new_row = {'Dropdown_column': drop_down_input, 'Float_column': float_input}
df = df.append(new_row, ignore_index=True)
button.description = 'Add row to dataframe'
out.clear_output()
display(df)
button.on_click(on_button_clicked)
# Form items
form_items = [
Box([Label(value='Independent dropdown'),
drop_down], layout=form_item_layout),
Box([Label(value='Dependent dropdown'),
dependent_drop_down], layout=form_item_layout)
]
form = Box(form_items, layout=Layout(
display='flex',
flex_flow='column',
border='solid 1px',
align_items='stretch',
width='30%',
padding = '1%'
))
display(form)
display(out)
Is this possible? If so, can you explain how?
You can do this by setting a if statement in your dropdown_handler function that checks if the value chosen in your independent dropdown is Dropdown_input_1 or Dropdown_input2. Still in the dropdown_handler, you can then modify accordingly the options arguments to either dependent_drop_down_elements['Dropdown_input_1'] or dependent_drop_down_elements['Dropdown_input_2'].
See code below:
import ipywidgets as widgets
from ipywidgets import HBox, Label
from ipywidgets import Layout, Button, Box, FloatText, Textarea, Dropdown, Label, IntSlider
import time
import pandas as pd
#Create DF
df = df = pd.DataFrame(columns = ['Dropdown_column', 'Float_column'])
df
# Layout
form_item_layout = Layout(
display='flex',
flex_flow='row',
justify_content='space-between',
)
button_item_layout = Layout(
display='flex',
flex_flow='row',
justify_content='center',
padding = '5%'
)
# Independent dropdown item
drop_down_input = 'Dropdown_input_1'
drop_down = widgets.Dropdown(options=('Dropdown_input_1', 'Dropdown_input_2'))
# Dependent drop down
# Dependent drop down elements
dependent_drop_down_elements = {}
dependent_drop_down_elements['Dropdown_input_1'] = ['A', 'B']
dependent_drop_down_elements['Dropdown_input_2'] = ['C', 'D', 'E']
# Define dependent drop down
dependent_drop_down = widgets.Dropdown(options=(dependent_drop_down_elements['Dropdown_input_1']))
def dropdown_handler(change):
global drop_down_input
print('\r','Dropdown: ' + str(change.new),end='')
drop_down_input = change.new
#If statement checking on dropdown value and changing options of the dependent dropdown accordingly
if change.new=='Dropdown_input_2':
dependent_drop_down.options=dependent_drop_down_elements['Dropdown_input_2']
elif change.new=='Dropdown_input_1':
dependent_drop_down.options=dependent_drop_down_elements['Dropdown_input_1']
drop_down.observe(dropdown_handler, names='value')
# Button
button = widgets.Button(description='Add row to dataframe')
out = widgets.Output()
def on_button_clicked(b):
global df
button.description = 'Row added'
time.sleep(1)
with out:
new_row = {'Dropdown_column': drop_down_input, 'Float_column': float_input}
df = df.append(new_row, ignore_index=True)
button.description = 'Add row to dataframe'
out.clear_output()
display(df)
button.on_click(on_button_clicked)
# Form items
form_items = [
Box([Label(value='Independent dropdown'),
drop_down], layout=form_item_layout),
Box([Label(value='Dependent dropdown'),
dependent_drop_down], layout=form_item_layout)
]
form = Box(form_items, layout=Layout(
display='flex',
flex_flow='column',
border='solid 1px',
align_items='stretch',
width='30%',
padding = '1%'
))
display(form)
display(out)
As an example, this is what the output looks like when you pick Dropdown_input_2 on the first widget:
hi there i m still trying to get trade bot and try to plot them with their time and low price data.
i wanna get buy signals that i ve specified at if condition (when macdh turns from negative to positive). then i want to plot them at a data. but can not add them at buy_signal=[] place.
my error is
self.plotData(buy_signals = buy_signals)
IndexError: list index out of range
import requests
import json
from stockstats import StockDataFrame as Sdf
import plotly.graph_objects as go
from plotly.offline import plot
class TradingModel:
def __init__(self, symbol):
self.symbol = symbol
self.df = self.getData
def getData(self):
# define URL
base = 'https://api.binance.com'
endpoint = '/api/v3/klines'
params = '?&symbol='+self.symbol+'&interval=4h'
url = base + endpoint + params
# download data
data = requests.get(url)
dictionary = data.json()
# put in dataframe and clean-up
df = pd.DataFrame.from_dict(dictionary)
df = df.drop(range(6, 12), axis=1)
# rename columns and stockstasts
col_names = ['time', 'open', 'high', 'low', 'close', 'volume']
df.columns = col_names
stock = Sdf.retype(df)
for col in col_names:
df[col]=df[col].astype(float)
#defined macdh
df['macdh']=stock['macdh']
return (df)
def strategy(self):
df = self.df
buy_signals=[]
for i in range(1, len(df['close'])):
if df['macdh'].iloc[-1]>0 and df['macdh'].iloc[-2]<0:
buy_signals.append([df['time'][i], df['low'][i]])
self.plotData(buy_signals = buy_signals)
def plotData(self,buy_signal=False):
df=self.df
candle=go.Candlestick(
x=df['time'],
open=df['open'],
close=df['close'],
high=df['high'],
low=df['low'],
name="Candlesticks"
)
macdh=go.Scatter(
x=df['time'],
y=df['macdh'],
name="Macdh",
line = dict(color=('rgba(102, 207, 255, 50)')))
Data=[candle,macdh]
if buy_signals:
buys = go.Scatter(
x = [item[0] for item in buy_signals],
y = [item[1] for item in buy_signals],
name = "Buy Signals",
mode = "markers",
)
sells = go.Scatter(
x = [item[0] for item in buy_signals],
y = [item[1]*1.04 for item in buy_signals],
name = "Sell Signals",
mode = "markers",
)
data = [candle, macdh, buys, sells]
# style and display
layout = go.Layout(title = self.symbol)
fig = go.Figure(data = data, layout = layout)
plot(fig, filename=self.symbol)
def Main():
symbol = "BTCUSDT"
model = TradingModel(symbol)
model.strategy()
if __name__ == '__main__':
Main() ```
You need to replace :
self.plotData(buy_signals[i]) by self.plotData(buy_signals)
def plotData(self,buy_signal=False): by def plotData(self,buy_signals=None):
And it should be good to go !
I'm creating a simple calculation program using tkinter module and want to convert to exe as I want it to be executable at any pc. But somehow the error message show (failed to execute script pyi_rth_win32comgenpy).
I've try used pyinstaller ( cmd and the one on GitHub at : https://github.com/brentvollebregt/auto-py-to-exe) but to no avail. I also try using both types of python file (.py and .pyw)
from tkinter import *
from tkinter.filedialog import askopenfilename
import pandas as pd
from tkinter import messagebox
from pandastable import Table, TableModel
class Window(Frame):
def __init__(self, master =None):
Frame.__init__(self, master)
self.master = master
self.init_window()
def init_window(self):
self.master.title('GUI')
self.pack(fill=BOTH, expand=1)
quitButton = Button(self, text='quit', command=self.client_exit)
quitButton.place(x=0, y=230)
# fileButton = Button(self, text='Browse Data Set', command=self.import_data)
# fileButton.place(x=150, y=0)
fileButton = Button(self, text='SBO', command=self.sbo)
fileButton.place(x=200, y=50)
fileButton = Button(self, text='CBO', command=self.cbo)
fileButton.place(x=150, y=50)
# menu = Menu(self.master)
# self.master.config(menu=menu)
#
# file = Menu(menu)
# file.add_command(label='Save',command=self.client_exit)
# file.add_command(label='Exit', command= self.client_exit)
# menu.add_cascade(label='File', menu=file)
#
# edit = Menu(menu)
# edit.add_command(label='Undo')
# menu.add_cascade(label='Edit', menu=edit)
def client_exit(self):
exit()
# def import_data(self):
#
# csv_file_path = askopenfilename()
# # print(csv_file_path)
# df = pd.read_excel(csv_file_path)
# return df
def sbo(self):
csv_file_path = askopenfilename()
df = pd.read_excel(csv_file_path)
data = df.drop(df.index[0]) # remove first row
data['BOVal%'] = data['BOVal%'].astype(str) # convert to string
data['BOQty%'] = data['BOQty%'].astype(str)
data['CustomerPONo'] = data['CustomerPONo'].astype(str)
data['OrdNo'] = data['OrdNo'].astype(str)
data['VendorNo'] = data['VendorNo'].astype(str)
pivot = data.pivot_table(index='Style', aggfunc='sum') # first pivot
pivoted = pd.DataFrame(pivot.to_records()) # flattened
pivoted = pivoted.sort_values(by=['BOVal'], ascending=False) # sort largest to smallest
pivoted['Ranking'] = range(1, len(pivoted) + 1) # Ranking
cols = pivoted.columns.tolist()
cols = cols[-1:] + cols[:-1]
pivoted = pivoted[cols]
pivoted = pivoted.set_index('Ranking')
col = df.columns.tolist()
col = (col[22:23] + col[15:17] + col[:14] + col[17:22] + col[23:37]) # rearrange column
data = df[col]
data = data.sort_values(by=['BOVal'], ascending=False) # sort value
data['Ranking'] = range(1, len(data) + 1) # Set rank
colm = data.columns.tolist()
colm = colm[-1:] + colm[:-1] # rearrange rank column
data = data[colm]
data = data.set_index('Ranking')
# sumboval = data['BOVal'].sum()
# sumboqty = data['BOQty'].sum()
# rounded = sumboval.round()
dates = data['SnapShotDate']
# print(dates)
dates = dates.iloc[1].strftime('%d%m%Y')
sos = data['SOS']
sos = sos[2]
result = pivoted.iloc[:10, :3]
# Create a Pandas Excel writer using XlsxWriter as the engine.
writer = pd.ExcelWriter('%s SBO %s .xlsx' % (sos, dates), engine='xlsxwriter')
# Write each dataframe to a different worksheet.
result.to_excel(writer, sheet_name='pivot')
df.to_excel(writer, sheet_name=dates)
data.to_excel(writer, sheet_name='SBO')
# Close the Pandas Excel writer and output the Excel file.
writer.save()
messagebox.showinfo("Note", "Calculation Completed")
def cbo(self):
csv_file_path = askopenfilename()
Stylemat = askopenfilename()
df = pd.read_excel(csv_file_path)
sm = pd.read_excel(Stylemat)
df = df.drop(df.index[0])
df.insert(loc=8, column='PH', value=['' for i in range(df.shape[0])])
df.insert(loc=9, column='Site', value=['' for i in range(df.shape[0])])
df['Region'] = df['Region'].fillna('"NA"')
df['S&OP Style Aggrt'] = df['S&OP Style Aggrt'].astype(str)
sm['Style'] = sm['Style'].astype(str)
dates = df['Date_Rp']
# print(dates)
dates = dates.iloc[1]
w = list(dates)
w[1] = '-'
w[3] = '-'
temp = w[0]
w[0] = w[2]
w[2] = temp
dates = "".join(w)
rowcount = len(df)
rowstyle = len(sm)
i = 0
j = 0
Style = []
for i in range(rowcount):
for j in range(rowstyle):
if df.iloc[i, 7] == sm.iloc[j, 0]:
df.iloc[i, 8] = 'Horizon'
df.iloc[i, 9] = sm.iloc[j, 2]
table = pd.pivot_table(df[df.PH == 'Horizon'], index='S&OP Style Aggrt', columns='Region',
values='Net CBO Value', aggfunc='sum')
table['Grand Total'] = table.sum(axis=1)
table = table.sort_values(by=['Grand Total'], ascending=False)
table['Ranking'] = range(1, len(table) + 1)
# Create a Pandas Excel writer using XlsxWriter as the engine.
writer = pd.ExcelWriter('CBO %s .xlsx' % dates, engine='xlsxwriter')
# Write each dataframe to a different worksheet.
table.to_excel(writer, sheet_name='pivot')
df.to_excel(writer, sheet_name=dates)
sm.to_excel(writer, sheet_name='StyleMat')
# Close the Pandas Excel writer and output the Excel file.
writer.save()
messagebox.showinfo("Note", "Calculation Completed")
root = Tk()
root.geometry('400x300')
app = Window(root)
root.mainloop()
I'd like to know how to find the main reason for this error and where to look for it, is it either my scripting method is incorrect or is there any additional file or module that I need. Appreciate in advance for your help. Thank you
I uninstalled everything related to win32 (pypiwin32, pywin32, pywin32-ctypes, pywinpty) and then installed again and magically it worked.
Took the idea from here and here.
this is quite late, but the answer to that issue is just the py to exe cannot execute on numpy 1.17. after downgrade to numpy 1.16, the program can run normally.
You are getting this error failed to execute script pyi_rth_win32comgenpy as result of not including the images you used for you icons and labels
I included images of icon, Question mark and the title
copy this images and include it the directory you have your pyi_rth_win32comgenpy executable.