Windows10 Python Program Disappear - python

I wrote a py file called simplifier. Usually when you double click the py file, Windows should give you both a console and the program. Just like the picture below.
However, I clicked my py file and the console showed up and disappeared in a flash and the program did not show up at all. Usually this means there should be some bugs in my code. So I opened the py file in IDLE and ran it, expecting the shell to give me an error. However, it did not report anything. I don't know how to locate the error. The file used to work well and it just started to behave like that. I tested putting "input('')" only in a py file and it worked as expected. And some of my programs also work well, but the rest doesn't.
Could the bug come from my imported modules? I import some module written by myself (ez and eztk). I checked those functions. They are ok.
Here is the code of simplifier.
from tkinter import *
from tkinter import messagebox
from eztk import *
import ez
root=Tk()
root['bg']='MintCream'
t1=Text(root)
def newline():
t=gettxt(t1)
new=''
for i,ch in enumerate(t):
if ch=='\n' and t[i+1:i+3]!='- ':
new+=' '
else:
new+=ch
inst2(new)
w0=Label(root,text='Input:↑')
w1=Button(root,text="\\n",command=newline)
def brackets():
t=gettxt(t1)
new=''
stop=0
d={'[':']','(':')','{':'}',0:None}
for ch in t:
if ch in d:
stop=ch
elif ch==d[stop]:
stop=0
elif not stop:
new+=ch
inst2(new)
w2=Button(root,text='([{}])',command=brackets)
def linecount(event):
count=lambda t:t.count('\n')+(t[-1]!='\n') if t else 0
up=count(gettxt(t1))
down=count(gettxt(t2))
w3['text']=f'LineCount:↑{up}↓{down}'
root.bind('<KeyPress>', linecount)
w3=Label(root,text='LineCount')
def clear():
deltxt(t1)
deltxt(t2)
w4=Button(root,text='Clear',command=clear)
t2=Text(root)
ws=[w0,w1,w2,w3,w4]
t1.grid(row=0,column=0,columnspan=len(ws))
for i,w in enumerate(ws):
w.configure(relief=FLAT,bg='SeaGreen1')
w.grid(row=1,column=i,sticky=NS)
t2.grid(row=2,column=0,columnspan=len(ws))
def inst2(text):
deltxt(t2)
instxt(t2,text)
linecount('<KeyPress>')
try: ez.cpc(text)
except UnicodeError: messagebox.showerror('Error','You need to copy it to your clipboard manually.')
root.mainloop()
These are the functions used in the imported modules:
def copyToClipboard(text):
win32clipboard.OpenClipboard()
win32clipboard.EmptyClipboard()
win32clipboard.SetClipboardText(text)
win32clipboard.CloseClipboard()
## abbreviation
cpc=copyToClipboard
def gettxt(text):
return text.get(1.0,'end').strip()
def deltxt(text):
text.delete(1.0,'end')
def instxt(textwidget,text):
textwidget.insert(1.0,text)
--- Update ---
I just tried copy the 4 functions to the simplifier.py instead of importing them, it worked. However, I also tried importing either of them and both cases failed. And there is still no error after I ran them in the python shell. Actually the bottom 3 functions are the only code in my eztk module. And it still doesn't work as expected when I import eztk alone, which means there shouldn't be any problems with importing.

Related

Python not importing functions from module

So, I have this project of a form similar to this:
./
./__init__.py
./main.py
./errorHandle.py
./functions.py
Now, In my main.py I have this:
import errorHandling
from functions import *
And in errorHandle.py:
from functions import sendMessage
def exceptionHandle(ex,errorCode):
def exceptionHandle(ex,errorCode):
print(ex)
extra = ""
status = 1
if errorCode == constants.ErrorCodes.aws:
constants.awsWorking = 0
if checkConnection() == True:
extra = "A network connection was detected but no connection to AWS was possible. Possibilities include an issue of authentication, renamed/incorrectly named shadow, or a duplicate client name. "
constants.errorsListDelayed[int(time.time())] = [ex,errorCode,extra,constants.TargetConnection.aws]
else:
extra = "No internet connection detected/Google DNS down. "
constants.errorsListDelayed[int(time.time())] = [ex,errorCode,extra,constants.TargetConnection.awsAndMail]
return
elif errorCode == constants.ErrorCodes.loadConfig:
extra = checkIniExists()
elif errorCode == constants.ErrorCodes.camera:
status, extra = checkCameraInitial()
elif errorCode == constants.ErrorCodes.loadImages:
extra= "Couldn't load images. "
else:
extra= "Unknown Error location"
if status == 1:
cv2.destroyAllWindows()
sendErrorMessage(ex,errorCode,extra)
uploadError(ex,errorCode)
(indentation got a bit messy after copying)
And in my functions I have a number of functions, including the aforementioned sendMessage
Now, for some reason while I am able to import errorHandle, none of its functions, including the exceptionHandle function show, but it IS importing, as I can do something like this fine:
errorHandle.sendMessage(...)
And it would work without any real issues
I have also attempted different imports, with different errors that more or less resulted in the same idea. So I tried:
from errorHandle import exceptionHandle
But that didn't work either.
I have also tried
from errorHandle import *
which just loaded sendMessage only, and I tried to change the code in errorHandle to change the sendMessage to *, which loaded all the functions.py files, and I tried removing the whole import functions from errorHandle.py, which changed nothing.
Kind-of lost here, since it IS importing the module and recognizing it, just not the functions in the module.
EDIT:
ImportError: cannot import name 'exceptionHandle' from 'errorHandling'
I have ensured all the names are correct, also no functions exist with either of those names, I have also tried different names to make sure its not a weird bug due to a certain name.
Do you by any chance have a function named errorHandle inside your functions.py file?
Please see the code I have, and that it is running. Can you please provide a minimal reproducible example so the bug/problem can be replicated.
user#Inspiron:~/code/general/remthisdir$ cat errorHandle.py ;echo;cat functions.py ;echo ;cat main.py
from functions import sendMessage
def exceptionHandle():
print('Inside exceptionHandle')
def sendMessage():
print('Inside sendMessage')
import errorHandle
from functions import *
if __name__ == '__main__':
errorHandle.exceptionHandle()
sendMessage()
user#Inspiron:~/code/general/remthisdir$ python main.py
Inside exceptionHandle
Inside sendMessage
user#Inspiron:~/code/general/remthisdir$

Cannot click on tkinter button more than twice

I am a newbie to tkinter and have know idea what I am doing sometimes:D . I created a python script to get Corona Virus Stats from a GitHub post link The script has over 20 files in it so I thought I should just create one file to run all the other files. So what other better way to do it than creating a UI. And that's what I did I used tkinter to run all the files. If they clicked on x button then I would run abc. And I ended up running these files by importing them in a certain order(Don't know If that was the best way). So here is where I ran into an error. I don't exactly know if this error is because of how I imported my files or my tkinter code is just wrong. I just couldn't seem to click on a button twice. I would run my program and click on a button, it would run properly and then the next time I clicked on that same button It would just not work. There was no error and no output. Nothing would happen. Here is my code:
#Import tkinter
import tkinter as tk
from tkinter import *
from tkinter import simpledialog
tk = tk.Tk()
Max = 190
def RunDeaths():
#If they click on RunDeaths I will run this function
#Check if they have already entered a path
try:
open('/Users/test/Documents/python/Py_Programs/Hackathon/DeathStats/Info.txt','r')
from DeathStats import RunAll
except:
YourPath = simpledialog.askstring('Countries','''Please Enter Your Path To HACKATHON Folder:
Example:
\"/Users/Name/Documents/python/\"
Note: Leave out the HACKATHON folder and you must put a slash at the end''',parent=tk)
#Write this path to a file call Info.txt
file = open('/Users/test/Documents/python/Py_Programs/Hackathon/DeathStats/Info.txt','w')
file.write(str(YourPath)+'\n')
file.write(str(Max))
file.close()
#Run all the files that gather the data for Corona Virus Deaths
from DeathStats import RunAll
def RunRecoveredCases():
#If they click on RecoveredCases Run this
#Check If they had already entered a path
try:
open('/Users/test/Documents/python/Py_Programs/Hackathon/RecoveredCases/Info.txt','r')
from RecoveredCases import RunAll
except:
YourPath = simpledialog.askstring('Countries','''Please Enter Your Path To HACKATHON Folder:
Example:
\"/Users/Name/Documents/python/\"
Note: Leave out the HACKATHON folder and you must put a slash at the end''',parent=tk)
file = open('/Users/test/Documents/python/Py_Programs/Hackathon/RecoveredCases/Info.txt','w')
#Write there path to a file
file.write(str(YourPath)+'\n')
file.write(str(Max))
file.close()
#Run all the files that gather all the Recovered Cases
from RecoveredCases import RunAll
#* * Here is where I think I went wrong But Im not sure
Deaths = Button(tk,height = 20, width = 30, text='Run Deaths',command = RunDeaths,highlightbackground='#000000')
Recovered = Button(tk,height = 20, width = 30, text='Run Recovered Cases',command = RunRecoveredCases,highlightbackground='#000000')
Deaths.pack()
Recovered.pack()
tk.mainloop()
So my question and problem is: Why can I not click on a button more than twice?
This has happened to me before and I could not fix it. Any help would be appreciated.(If you would like to run my program because my explanation was just not good enough here is a git hub repo GitHub)
Thank You
It appears that you are assuming that from RecoveredCases import RunAll will run the code in RecoveredCases.py each time it is imported. That is a false assumption. Python caches code that is imported.
The proper way to use code in a separate file is to put the code in a function or class, import the function or class exactly once, and then call the function or instantiate the class whenever you want to run the code.

How to dynamically reload function in Python?

I'm trying to create a process that dynamically watches jupyter notebooks, compiles them on modification and imports them into my current file, however I can't seem to execute the updated code. It only executes the first version that was loaded.
There's a file called producer.py that calls this function repeatedly:
import fs.fs_util as fs_util
while(True):
fs_util.update_feature_list()
In fs_util.py I do the following:
from fs.feature import Feature
import inspect
from importlib import reload
import os
def is_subclass_of_feature(o):
return inspect.isclass(o) and issubclass(o, Feature) and o is not Feature
def get_instances_of_features(name):
module = __import__(COMPILED_MODULE, fromlist=[name])
module = reload(module)
feature_members = getattr(module, name)
all_features = inspect.getmembers(feature_members, predicate=is_subclass_of_feature)
return [f[1]() for f in all_features]
This function is called by:
def update_feature_list(name):
os.system("jupyter nbconvert --to script {}{} --output {}{}"
.format(PATH + "/" + s3.OUTPUT_PATH, name + JUPYTER_EXTENSION, PATH + "/" + COMPILED_PATH, name))
features = get_instances_of_features(name)
for f in features:
try:
feature = f.create_feature()
except Exception as e:
print(e)
There is other irrelevant code that checks for whether a file has been modified etc.
I can tell the file is being reloaded correctly because when I use inspect.getsource(f.create_feature) on the class it displays the updated source code, however during execution it returns older values. I've verified this by changing print statements as well as comparing the return values.
Also for some more context the file I'm trying to import:
from fs.feature import Feature
class SubFeature(Feature):
def __init__(self):
Feature.__init__(self)
def create_feature(self):
return "hello"
I was wondering what I was doing incorrectly?
So I found out what I was doing wrong.
When called reload I was reloading the module I had newly imported, which was fairly idiotic I suppose. The correct solution (in my case) was to reload the module from sys.modules, so it would be something like reload(sys.modules[COMPILED_MODULE + "." + name])

How to compile multiple subprocess python files into single .exe file using pyinstaller

I have a similar question to this one:Similar Question.
I have a GUI and where the user can input information and the other scripts use some of that information to run.I have 4 different scripts for each button. I run them as a subprocess so that the main gui doesn’t act up or say that it’s not responding. This is an example of what I have since the code is really long since I used PAGE to generate the gui.
###Main.py#####
import subprocess
def resource_path(relative_path):
#I got this from another post to include images but I'm also using it to include the scripts"
try:
# PyInstaller creates a temp folder and stores path in _MEIPASS
base_path = sys._MEIPASS
except Exception:
base_path = os.path.abspath(".")
return os.path.join(base_path, relative_path)
Class aclass:
def get_info(self):
global ModelNumber, Serial,SpecFile,dateprint,Oper,outputfolder
ModelNumber=self.Model.get()
Serial=self.SerialNumber.get()
outputfolder=self.TEntry2.get()
SpecFile= self.Spec_File.get()
return ModelNumber,Serial,SpecFile,outputfolder
def First(self):
aclass.get_info(self) #Where I use the resource path function
First_proc = subprocess.Popen([sys.executable, resource_path('first.py'),str(ModelNumber),str(Serial),str(path),str(outputfolder)])
First_proc.wait()
#####First.py#####
import numpy as np
import scipy
from main import aclass
ModelNumber = sys.argv[1]
Serial = sys.argv[2]
path = sys.argv[3]
path_save = sys.argv[4]
and this goes on for my second,third, and fourth scripts.
In my spec file, I added:
a.datas +=[('first.py','C\\path\\to\\script\\first.py','DATA')]
a.datas +=[('main.py','C\\path\\to\\script\\main.py','DATA')]
this compiles and it works, but when I try to convert it to an .exe, it crashes because it can't import first.py properly and its own libraries (numpy,scipy....etc). I've tried adding it to the a.datas, and runtime_hooks=['first.py'] in the spec file...and I can't get it to work. Any ideas? I'm not sure if it's giving me this error because it is a subprocess.
Assuming you can't restructure your app so this isn't necessary (e.g., by using multiprocessing instead of subprocess), there are three solutions:
Ensure that the .exe contains the scripts as an (executable) zipfile—or just use pkg_resources—and copy the script out to a temporary directory so you can run it from there.
Write a multi-entrypoint wrapper script that can be run as your main program, and also run as each script—because, while you can't run a script out of the packed exe, you can import a module out of it.
Using pkg_resources again, write a wrapper that runs the script by loading it as a string and running it with exec instead.
The second one is probably the cleanest, but it is a bit of work. And, while we could rely on setuptools entrypoints to some of the work, trying to explain how to do this is much harder than explaining how to do it manually,1 so I'm going to do the latter.
Let's say your code looked like this:
# main.py
import subprocess
import sys
spam, eggs = sys.argv[1], sys.argv[2]
subprocess.run([sys.executable, 'vikings.py', spam])
subprocess.run([sys.executable, 'waitress.py', spam, eggs])
# vikings.py
import sys
print(' '.join(['spam'] * int(sys.argv[1])))
# waitress.py
import sys
import time
spam, eggs = int(sys.argv[1]), int(sys.argv[2]))
if eggs > spam:
print("You can't have more eggs than spam!")
sys.exit(2)
print("Frying...")
time.sleep(2)
raise Exception("This sketch is getting too silly!")
So, you run it like this:
$ python3 main.py 3 4
spam spam spam
You can't have more eggs than spam!
We want to reorganize it so there's a script that looks at the command-line arguments to decide what to import. Here's the smallest change to do that:
# main.py
import subprocess
import sys
if sys.argv[1][:2] == '--':
script = sys.argv[1][2:]
if script == 'vikings':
import vikings
vikings.run(*sys.argv[2:])
elif script == 'waitress':
import waitress
waitress.run(*sys.argv[2:])
else:
raise Exception(f'Unknown script {script}')
else:
spam, eggs = sys.argv[1], sys.argv[2]
subprocess.run([sys.executable, __file__, '--vikings', spam])
subprocess.run([sys.executable, __file__, '--waitress', spam, eggs])
# vikings.py
def run(spam):
print(' '.join(['spam'] * int(spam)))
# waitress.py
import sys
import time
def run(spam, eggs):
spam, eggs = int(spam), int(eggs)
if eggs > spam:
print("You can't have more eggs than spam!")
sys.exit(2)
print("Frying...")
time.sleep(2)
raise Exception("This sketch is getting too silly!")
And now:
$ python3 main.py 3 4
spam spam spam
You can't have more eggs than spam!
A few changes you might want to consider in real life:
DRY: We have the same three lines of code copied and pasted for each script, and we have to type each script name three times. You can just use something like __import__(sys.argv[1][2:]).run(sys.argv[2:]) with appropriate error handling.
Use argparse instead of this hacky special casing for the first argument. If you're already sending non-trivial arguments to the scripts, you're probably already using argparse or an alternative anyway.
Add an if __name__ == '__main__': block to each script that just calls run(sys.argv[1:]), so that during development you can still run the scripts directly to test them.
I didn't do any of these because they'd obscure the idea for this trivial example.
1 The documentation is great as a refresher if you've already done it, but as a tutorial and explanatory rationale, not so much. And trying to write the tutorial that the brilliant PyPA guys haven't been able to come up with for years… that's probably beyond the scope of an SO answer.

Application doesn't work after sourcecode

I have a working Python+Tkinter program working which is a dictionary creator. However, when I convert soucecode into app, program itself doesn't create the file it is supposed to create. I am quite new to programming, and I would appreciate if you could help me. So far I have tried py2app and platypus both give the same result.
Here is the code:
#!/usr/bin/env python
from Tkinter import *
import tkMessageBox
import itertools
import string
def done():
l=list()
if check_a.get() == True:
l.append(string.lowercase)
if check_A.get() == True:
l.append(string.uppercase)
if check_0.get() == True:
l.append(string.digits)
l=''.join(l)
n=entryvar.get()
with open("b.txt","a+") as f:
for i in itertools.product(l,repeat=n):
f.write(''.join(list(i)))
f.write('\n')
f.close()
generater=Tk()
generater.title("Generater")
generater.geometry("450x300+200+200")
mainlabel=Label(generater).pack()
entryvar=IntVar()
entry=Entry(generater, textvariable=entryvar).pack()
check_a=BooleanVar()
check_A=BooleanVar()
check_0=BooleanVar()
checkBox_a=Checkbutton(generater, variable=check_a, text="a-z").pack()
checkBox_A=Checkbutton(generater, variable=check_A, text="A-Z").pack()
checkBox_0=Checkbutton(generater, variable=check_0, text="0-9").pack()
DoneButton=Button(generater, text="Done", command=done).pack()
generater.mainloop()
When you start an application created by py2app the current working directory is changed to the 'Contents/Resources' folder inside the application bundle. Because your script creates a file relative to the current working directory it ends up inside the application.
(For examples a myapp.app/Contents/Resources/b.txt)

Categories

Resources