I am working on a text based game that I run by double clicking on my top level script namely TopLevel.py.
I am looking for a way to open two terminals in this script. In the one terminal the main game will be run where damage is done and spells are used etc. In the other terminal I would like to display a list of commands that the user can type in , and I want the latter one to stay there and not close until the game is finished. I am not going to show you the whole top level script (it is too long) but this is basically what I want to achieve:
def displayCommands(hero):
list_of_commands = []
#this contains all my commands that the user can type in
def main():
hero = Hero() #make hero instance
enemy = Enemy() #make and enemy instance
a_game = TopLevel(hero,enemy) #create game engine
a_game.play() #start game
#implement code here to open another terminal
#and display user commands in there
Is there a way that I can open another terminal in this script and pass the displayCommands() function as a parameter to display its contents in the second terminal? Any help will be appreciated :)
It's possible for one Python script to spawn another that will run in parallel with it via subprocess. The spawned process can then display any text piped to it (via normal print statements or calls) in a simple tkinter-based window -- see the errorwindow module in this answer of mine for more information.
It likely doesn't matter how the original script gets started. I personally have used it both in ones that were started from a command shell as well as from other tkinter based applications -- so starting yours from powershell should be fine. The module's original author was using Linux or something similar, I believe.
You should convert your second program to .exe first,the one will display user commands. Say you saved it as usercommands.exe, after then in your main script use this to open that;
import subprocess
subprocess.Popen([r"usercommands.exe"],
creationflags=subprocess.CREATE_NEW_CONSOLE)
It'll open another console window that runs usercommands.exe when you run your main file.
Notes;
They must be in the same directory, your main file and .exe file
usercommands.exe must show the commands in an infinite loop(while True), so it's
going to display commands untill the user close it.
Edit;
Now, we have some spells and usercommands will have to use that spell variables after then show us some combinations. For doing this, we have to import your first file to usercommands script.It's going to like this;
usercommands.py
import mainfile #mainfile.py
if choose == mainfile.wizard:
print (something)
if choose == mainfile.subzero:
print (something)
The algorithm should be like this,you will convert usercommands.py to .exe then it will work as you want I guess, we can't now before you try it ;)
Related
I'm using Windows' Power Shell. I'd like to run a Python script that will take a long time to be finished (it's a code for data acquisition, so it'll take about a few hours to conclude). So, I'd like to be able to see all the prints and results on the terminal, but I would like to save all the output (in the end) as a string, a file or whatever.
I've been trying using the redirection commands like python example_file.py > output.txt , python example_file.py | tee output.txt and similars, but the problem is that those commands run all the script in the background and just show the results when it's finished (and, again, I'd like to be able to see the progress of the acquisition).
I've looked online and found that there's a command called "script" in Linux that serves for the same purpose that I want, but I've not found any equivalent for Windows Power Shell. I'm also accepting any solution in Python, it doesn't need to be necessarily on PS.
Please, someone help me?
EDIT: I'd like to see in real time the output. I mean, the intention is to see all the results of the code normally, as it's normally executed on the PS terminal, AND THEN save all the output to a file, to a string or whatever.
Example: if I run
from time import sleep
print('banana')
sleep(3)
print('banana again')
it'll show, on the terminal, the first 'banana' and then, after three seconds, it'll show 'banana again'. The problem is that with the above codes it'll execute the script on the background and then show the results at once. And that's not what I want.
I would use the following code:
from time import sleep
outputs = []
def myprint(print):
global outputs
print(print)
outputs.append(print)
myprint('banana')
sleep(3)
myprint('banana again')
open("output.txt", "w").write("\n".join(outputs))
The code now writes into(and creates if not already there) a file named output.txt all the things printed with the myprint() function. If you want, you can also access them if as single strings in the outputs array. Also, don't wonder, but in python you can use both " and ' as the same thing.
I have two python scripts, one that needs to continuously get input from the user and write into a file while the other simultaneously continuously check for updates from the file. My problem is that when running the check script, the os system terminal "position" seems to be already filled and I can not run the input script. It either shows the check scripts terminal or stays on a blinking cursor on the cmd terminal and not loading up. Also, I am unable to find a way to make both of the scripts run indefinitely until the user kills the process. Also, it might be my pc, but when running
while True:
check()
in my check script, it freezes my pc and also does not allow the input script to run
BTW, my pc had been having some problems, so I am going to reset it today and I hope that is the problem, but I have been going crazy over this problem and don't trust my judgement on this anymore:(
#my check script
def check():
with open('Tasks.txt','r') as file:
data = file.readlines()
if not "Neuron" in data and len(data)!=0:
i=0
Chars = data[0].split(" ")
while(i<len(Chars)):
c=0
print(len(data[0]))
print('Count:' + str(i))
print('Chars are ' + Chars[i])
while(c<len(Chars[i])):
Neuron.createNeuron(Chars[i][c-1:c])
c+=1
i+=1
data.pop(0)
Neuron.writeData('Tasks.txt',data,'w')
#os.system('py Create.py')
check()
#my user input script
def CM():
String = input(">")
#res = ' '.join(format(ord(x), 'b') for x in String)
#print(res)
Neuron.writeData('Logs.txt',Neuron.writeData('Tasks.txt',(' '.join(format(ord(x), 'b') for x in String)+'\n'),'a'),'a')
CM()
CM()
So, I found the answer. Originally both files actually could run, but one of them, the input file, had to be opened from the IDLE and then run there. To run them both simultaneously repetitively was to put
os.system('py Create.py')
at the end of the file. So it would run a new session of the py script.
Also, I imported a file that was not just functions but commands also and it ran them, which is why I was unable to use the Input script.
I am starting with Python and want to use it to dispatch an application with win32com (the application is PTV Vissim, for traffic modelling), however, after the script is done with whatever I ask it to do, it closes and kills Vissim with it too.
Is there a way to avoid this?
i.e. I want the Python script to finish but leaving the dispatched application open for the user to keep working with it.
This is the code I'm using:
import win32com.client as com
import os
# Opening a new Vissim window
Vissim = com.Dispatch("Vissim.Vissim")
# Define filename and save as new model
Path = "C:\ModelWIP\Vissim\Script_test"
Filename = os.path.join(Path, "My_Model.inpx")
Vissim.SaveNetAs(Filename)
# Keeps python command line open until the user confirms
raw_input('Press any key to exit')
The final bit with raw_input is there to keep the script from finishing and therefore keeping the Vissim instance alive, this is the only solution I've found so far.
Can you open Vissim with the os.system command? If you can, it will let you terminate the Python process and keep the Vissim instance opened.
E.g.:
os.system("start vissim.exe")
I have a script that does random calculation and prints it, but now I need these results written in a text file. I edited it and now each time I execute this script, new results are appended in a text file. However, I need as many new results as I can get into the same text file, so is there a way to make it run again and again (and stop it when I want to by keyboard interrupt)?
I could do something like:
inf_loop=0
while inf_loop==0:
#code to append to text file
But the script is rather long, thus I need to have each line within the loop indented properly.
I cannot comment so I'm gonna say my opinion here.
tab is your friend here. If you're using Python IDLE, just select all the lines and hit Tab. If you wanna outdent, try shift + tab.
If indenting is a problem for you and you really want to hack this down, you could simply restart your script like this:
#!/usr/bin/env python
import os
# your script content
args=['some_name']
os.execlp('./your_script.py',*args)
Run the script from the directory it is located in. If you need to pass arguments, simply append them to args.
If your script finishes it will restart itself again and again...
If you're adamant that you don't want to change your existing script, create a new one, then keep calling the other...
while True:
execfile('/path/to/other/script.py')
Although you should really be putting the work of the other script into a function, then repeatedly calling that instead of the script...
while True:
call_your_function()
I have a small script that launches and, every half hour, feeds a command to a java program (game server manager) as if the user was typing it. However, after reading documentation and experimenting, I can't figure out how I can get two things:
1) A version which allows the user to type commands into the terminal windoe and they will be sent to the server manager input just as the "save-all" command is.
2) A version which remains running, but sends any new input to the system itself, removing the need for a second terminal window. This one is actually half-happening right now as when something is typed, there is no visual feedback, but once the program is ended, it's clear the terminal has received the input. For example, a list of directory contents will be there if "dir" was typed while the program was running. This one is more for understanding than practicality.
Thanks for the help. Here's the script:
from time import sleep
import sys,os
import subprocess
# Launches the server with specified parameters, waits however
# long is specified in saveInterval, then saves the map.
# Edit the value after "saveInterval =" to desired number of minutes.
# Default is 30
saveInterval = 30
# Start the server. Substitute the launch command with whatever you please.
p = subprocess.Popen('java -Xmx1024M -Xms1024M -jar minecraft_server.jar',
shell=False,
stdin=subprocess.PIPE);
while(True):
sleep(saveInterval*60)
# Comment out these two lines if you want the save to happen silently.
p.stdin.write("say Backing up map...\n")
p.stdin.flush()
# Stop all other saves to prevent corruption.
p.stdin.write("save-off\n")
p.stdin.flush()
sleep(1)
# Perform save
p.stdin.write("save-all\n")
p.stdin.flush()
sleep(10)
# Allow other saves again.
p.stdin.write("save-on\n")
p.stdin.flush()
Replace your sleep() with a call to select((sys.stdin, ), (), (), saveInterval*60) -- that will have the same timeout but listens on stdin for user commands. When select says you have input, read a line from sys.stdin and feed it to your process. When select indicates a timeout, perform the "save" command that you're doing now.
It won't completely solve your problem, but you might find python's cmd module useful. It's a way of easily implementing an extensible command line loop (often called a REPL).
You can run the program using screen, then you can send the input to the specific screen session instead of to the program directly (if you are in Windows just install cygwin).