Python script to executable with cx_Freeze, exe does nothing - python

I have decided for practice purposes, I'd write a Passwordgenerator and make it an executable.
My script is running as it is intended, and the compiling works as well, but when I run the exe file, nothing happens.
I run a Windows 10 system and use Python 3.6.x and I am not a beginner of python itself.
I looked up various pages on the internet, but I found nothing that helped me on that problem, my first problem was that the compiling didn't work but I already found that solution.
Edit: I tried to run the exe with the cmd and I get no output, instead I get a new line.
This is the setup code:
import sys
from cx_Freeze import setup, Executable
build_exe_options = {"excludes": ["tkinter"]}
base = None
if sys.platform == "win32":
base = "Win32GUI"
setup(name="Password",
version="1.0",
description="Generates a password made of 20 characters",
options={"build_exe": build_exe_options},
executables=[Executable("pass.py", base=base)])
And this is my program:
import random
import string
for i in range(20):
k = random.choice(string.ascii_letters)
j = random.randint(0, 9)
z = random.randint(1, 2)
if z == 1:
x = k
if z == 2:
x = j
print(x, end=" ")
I am grateful for any kind of insight.

Remove the two lines
if sys.platform == "win32":
base = "Win32GUI"
from your setup script and it should work.
base = "Win32GUI" tells cx_Freeze not to start a console window and should be used only if the main application starts a GUI (e.g. with PySide, PyQt, Tk, ...). It presumably also redirects the standard output away from the console if you run the executable from an already started console. In your case you have a console-based application and you thus want a console to be started and to receive the standard output. This behavior is partially explained in the cx_Freeze documentation.
Now if you run your executable without using the cmd (e.g. by double-clicking it in Windows-Explorer), it starts a console window, prints the output there, and closes the console immediately when the execution is finished. In your example script, you would like to have the time to read the output before the console closes, so what you need then is something to tell your script to wait before finishing, for example until you press a key. You can add
input("Press Enter to continue...")
at the end of your script for this purpose, see How do I make python to wait for a pressed key.

Add wait after the code so it doesn't finish immediately.
import random
import string
for i in range(20):
k = random.choice(string.ascii_letters)
j = random.randint(0, 9)
z = random.randint(1, 2)
if z == 1:
x = k
if z == 2:
x = j
print(x, end=" ")
import time
time.sleep(5) #<-- Sleep for 5 seconds
You can also use my Python Executable maker.

Related

Python. Open another program in for loop

I'm creating a program in Python and I have a problem with a for loop and opening program in this loop.
The program is supposed to run e.g. 5 times and it only runs once
import subprocess
z = int(input())
def run():
subprocess.run('notepad.exe')
a = 0
while(a<z):
a = a + 1
run()
I've tried creating a function and replacing the for loop with a while loop but it doesn't work. Sorry for my English
Use subprocess.Popen('notepad.exe'), this will put the process in the background.
subprocess.run() will wait for the exit code I think, which waits until you close the notepad.
So full code is
import subprocess
z = int(input())
def run():
subprocess.Popen('notepad.exe')
a = 0
while(a<z):
a = a + 1
run()
You need to do pip install AppOpener first (or however you install modules for your device).
from AppOpener import open
z = int(input('Enter the number of times to open notepad: '))
def run():
open('notepad')
a = 0
while(a < z):
a = a + 1
run()
Additionally, for running any different apps, just change 'notepad' to the name of the app. (For Example: 'facebook')
Now it depends what you want. subprocess.run() opens the program, and pauses the code until you close notepad. Then, it will re open it, and do it z many times.
If you want to open z many instances of notepad at the same time you need to use `subprocess.Popen('notepad.exe', '-new-tab')
From the look of the code this may or may not be an issue. Python doesn't know where notepad.exe is located. You need to add the full path of the executable file. For example, try this:
import subprocess
z = int(input())
def run():
subprocess.run(r'C:\WINDOWS\system32\notepad.exe') #For most people this is the location of notepad.exe
a = 0
while(a<z):
a = a + 1
run()

Tkinter Window won't open when launched from CMD/Terminal or Python Shell?

I've seen other questions posted along this line but I have a mainloop() function in my program which for most people seems to be the usual fix.
When attempting to launch the program from a command line prompt or terminal or just by double pressing to open it as a python shell on windows it briefly shows the command window and closes instantly. This happens on Windows 11 and Ubuntu. Unsure what is causing it see attached a photo of what is happening.
The CMD Prompt just flashes up and instantly closes with a similar occurrence on Ubuntu. There are print() functions in the script of which I see none running. I'd also like to mention that the program launches absolutely fine from Python IDLE - My personal choice of Python IDE.
I do have to add I have got a infinite loop of sorts running in my program code for which I will attach below. I've played around adding "root.update_idletasks()" and "root.update()" to the loop to no avail. I'm unsure of what other actions to take?
The Infinite Loop I have mentioned above is a defined function, being called with the "after" method "root.after(0,main_program_exec)" and then continuously run with another after method " root.after(500,main_program_exec)".
NOTE: Most of the code has been left out as this is an application I'll be using for work. - Sorry about messy code normally others don't have to read it! I also have included all modules imported in the case that one of those could be causing a issue!
CODE SNIPPIT:
from pymodbus.client import ModbusTcpClient
from pymodbus.constants import Endian
from pymodbus.payload import BinaryPayloadDecoder
from tkinter import *
import time
from PIL import ImageTk, Image
from tksheet import Sheet
def main_program_exec():
global client, datatype
root.update_idletasks()
root.update()
if program_mode.get():
pass
else:
a = RegType.returnSelection()
b = StartAdd_Entry_Widget.returnValue()
if b <=0:
b = 1
if b > 9999:
b = 9999
c = Length_Entry_Widget.returnValue()
if c >100:
c = 100
elif c < 1:
c = 1
try:
main_data = client.compile_data(a,c,b,datatype) #Mode, length, starting add, mode
update_table(main_data)
except Exception as e:
print(e)
pass
root.after(500, main_program_exec)
....
root.after(0, main_program_exec)
main loop()

python-prompt-toolkit spawns a lot of threads

I'm really only using it for command history up/down functionality on windows - I couldn't get pyreadline3 to work correctly. Everything works fine, but using the up and down keys creates up to 40 threads that never go away.
from prompt_toolkit import prompt
from prompt_toolkit.history import FileHistory
while True:
print("\n")
print("=============")
print("Enter command")
command_text = prompt('>', history=FileHistory('command_history.txt'),)
cmd = command_text.lower().strip()
if cmd == "": # skip empty input
continue
if cmd == "exit": # bail
break
process_command(cmd)
That's basically it. Is this normal behavior? I guess the threadpool just creates new threads up to its maximum, but it seems a little excessive for this task, and makes my VScode call stack a mess.

How to execute a program from another program?

Is there a way to make a program which executes other programs?
I was creating a project for school then I had an idea of creating a main program which will run different program according to my choice.
I am using VS code and I created 2 programs in same folder(Here is the screenshot in case you are confused):
Here as you can see I have 2 programs(one is rockpaper.py and other is pass.py) inside of a folder named (ROCKPAPER) is there a way I can run both of these program by making another program inside of this same folder(ROCKPAPER)????
Is there a module for this?
The best practice is to import the two programs in a 3rd one like
import pass
import rockpaper
which will execute those codes.
No module is needed, this is basic functionality and you can simply import your sub-scripts into the main script.
import rockpaper
import pass
to run them, simply write
rockpaper
pass
rock.py
def stone():
return ('This is rock')
paper.py
Note here I have imported rock and assigned rock's result to a variable
import rock
def papyrus():
return ("This is paper")
scissors.py
Note here, I got rock and paper imported and their return values are being printed from this file.
import rock
import paper
def sharp():
rocke = rock.stone()
papery = paper.papyrus()
print(f"{rocke} {papery} But I am a scissors")
if __name__ == "__main__":
sharp()
Output:
This is rock This is paper But I am a scissors
Process finished with exit code 0
You should really be studying these basics though.
Here's a short "driver" program you can put in the same folder as the others. What it does is create a menu of all the other Python script files it finds in the same folder as itself and asks the user to pick one to run. If the user enters number of one of those listed, it then runs that script and quits (otherwise it repeats the question).
It uses the subprocess module to execute the chosen script.
from pathlib import Path
import subprocess
import sys
filepath = Path(__file__)
current_folder = filepath.parent
this_script = filepath.name
print(f'{this_script=}')
print(f'{current_folder=}')
scripts = sorted(script for script in current_folder.glob('*.py') if script != filepath)
menu = [script.stem for script in scripts]
print('Available programs:')
for i, script in enumerate(menu, start=1):
print(f' {i:2d}. {script}')
while True:
choice = input('Which program would you like to run (or 0 to quit)? ')
try:
choice = int(choice)
except ValueError:
print("Sorry, did not understand that.")
continue
if choice in range(len(menu)+1):
break
else:
print("Sorry, that is not a valid response.")
continue
if choice:
print(f'Running program {menu[choice-1]}')
subprocess.run([sys.executable, f'{scripts[choice-1]}'])
It's actually pretty simple!
import os
os.system("python anotherProgram.py")
Essentially, you're giving it a shell command.

Restarting a self-updating python script

I have written a script that will keep itself up to date by downloading the latest version from a website and overwriting the running script.
I am not sure what the best way to restart the script after it has been updated.
Any ideas?
I don't really want to have a separate update script.
oh and it has to work on both linux/windows too.
In Linux, or any other form of unix, os.execl and friends are a good choice for this -- you just need to re-exec sys.executable with the same parameters it was executed with last time (sys.argv, more or less) or any variant thereof if you need to inform your next incarnation that it's actually a restart. On Windows, os.spawnl (and friends) is about the best you can do (though it will transiently take more time and memory than os.execl and friends would during the transition).
The CherryPy project has code that restarts itself. Here's how they do it:
args = sys.argv[:]
self.log('Re-spawning %s' % ' '.join(args))
args.insert(0, sys.executable)
if sys.platform == 'win32':
args = ['"%s"' % arg for arg in args]
os.chdir(_startup_cwd)
os.execv(sys.executable, args)
I've used this technique in my own code, and it works great. (I didn't bother to do the argument-quoting step on windows above, but it's probably necessary if arguments could contain spaces or other special characters.)
I think the best solution whould be something like this:
Your normal program:
...
# ... part that downloaded newest files and put it into the "newest" folder
from subprocess import Popen
Popen("/home/code/reloader.py", shell=True) # start reloader
exit("exit for updating all files")
The update script: (e.g.: home/code/reloader.py)
from shutil import copy2, rmtree
from sys import exit
# maybie you could do this automatic:
copy2("/home/code/newest/file1.py", "/home/code/") # copy file
copy2("/home/code/newest/file2.py", "/home/code/")
copy2("/home/code/newest/file3.py", "/home/code/")
...
rmtree('/home/code/newest') # will delete the folder itself
Popen("/home/code/program.py", shell=True) # go back to your program
exit("exit to restart the true program")
I hope this will help you.
The cleanest solution is a separate update script!
Run your program inside it, report back (when exiting) that a new version is available. This allows your program to save all of its data, the updater to apply the update, and run the new version, which then loads the saved data and continues. To the user this can be completely transparent, as they just run the updater-shell which runs the real program.
To additionally support script calls with Python's "-m" parameter the following can be used (based on the Alex's answer; Windows version):
os.spawnl(os.P_WAIT, sys.executable, *([sys.executable] +
(sys.argv if __package__ is None else ["-m", __loader__.name] + sys.argv[1:])))
sys.exit()
Main File:
if __name__ == '__main__':
if os.path.isfile('__config.py'):
print 'Development'
push.update_server()
else:
e = update.check()
if not e: sys.exit()
Update File:
def check():
e = 1.....perform checks, if something needs updating, e=0;
if not e:
os.system("python main.pyw")
return e
Here's the logic:
Main program calls the update function
1) If the update function needs to update, than it updates and calls a new instances of "main"
Then the original instance of "main" exits.
2) If the update function does not need to update, then "main" continues to run
Wouldn't it just be easier to do something like
Very simple, no extra imports needed, and compatible with any OS depending on what you put in the os.system field
def restart_program():
print("Restarting Now...")
os.system('your program here')
You can use reload(module) to reload a module.

Categories

Resources