Making user input a command in IPython - string

I'm fairly new to python, and this question might be fairly specific to the situation. I'm using IPython to create graphs of physics simulations.
The problem I'm running into is when I try and create a program that avoids having to retype the same code over and over. I'm trying to get a user input to execute a command in IPython without having to type everything out yourself.
For example, there is a program I am using called pynbody.what I am trying to do is get it so when I open my test program with ipython, it prompts the user for an input of what the user would like to import. However, I have only been able to get it in as a string, which won't execute.
What is the syntax involved in getting a user input, ie
input= raw_input("What would you like to import? ")
to execute as if it were a command you were typing into IPython, ie
import pynbody
It works fine if you create a program, ie test.py, and in it you have import pynbody. Any ideas on getting this to work from a user input?

Not sure I fully understand what you are trying to do, but you could try
imported_module = __import__(<string>)
or
eval('python expression') see http://docs.python.org/2/library/functions.html#eval
for more complicated, look at the 'ast' module (http://docs.python.org/2/library/ast.html)
But for a beginner I would avoid going this road of prompting user for package to import, or enter expression by hand with raw_input.

Related

Is there a better/more pythonic way to load an arbitrary set of functions from modules in another folder?

I'm just basically asking:
if it's considered OK to use exec() in this context
if there's a better/more pythonic solution
for any input or comments on how my code could be improved
First, some context. I have main.py which basically takes input and checks to see if I've written a command. Let's say I type '/help'. The slash just tells it my input was supposed to be a command, so then it checks if a function called 'help' exists, and if so, that function will be run.
To keep things tidy in main.py, and to allow myself to add more commands easily, I have a 'commands' directory, with individual command files in it, such as help.py. help.py would look like this for example:
def help():
print("You've been helped")
So then of course, I need to import help() from help.py, which was trivial.
As I added more commands, I decided to add an init.py file where I'd keep all the command import lines of code, and then just do 'from init import *' in main.py. At first, each time I added a command, I'd add another line in init.py to import it. But that wasn't as flexible as I wanted, so I thought, there's got to be a way to just loop through all the .py files in my commands directory and import them. I struggled with this for a while but came up with a solution that works.
In the init.py snippet below, I loop through the commands directory (and a couple others, but they're irrelevant to the question), and you'll see I use the dreaded exec() function to actually import the commands.
loaded, failed = '', ''
for directory in command_directories:
command_list = os.listdir(directory)
command_list.sort()
for command_file in command_list:
if command_file.endswith(".py"):
command_name = command_file.split(".")[0]
try:
# Evil exec() hack to use variable-name directories/modules
# Haven't found a more... pythonic... way to do this
exec(f"from {directory}.{command_name} import {command_name}")
loaded = loaded + f" - Loaded: {command_name}\n"
except:
failed = failed + f" - Failed to load: {command_name}\n"
if debug == True:
for init_debug in [loaded, failed]: print(init_debug)
I use exec() because I don't know a better way to make a variable with the name of the function being loaded, so I use {command_name} in my exec string to arbitrarily evaluate the variable name that will store the function I'm importing. And... well, it works. The functions work perfectly when called from main.py, so I believe they are being imported in the correct namespace.
Obviously, exec() can be dangerous, but I'm not taking any user input into it, just file names. Filenames that I only I am creating. This program isn't being distributed, but if it was, then I believe using exec() would be bad since there's potential someone could exploit it.
If I'm wrong about something, I'd love to hear about it and get suggestions for a better implementation. Python has been very easy to pick up for me, but I'm probably missing some of the fundamentals.
I should note, I'm running python 3.10 on replit (until I move this project to another host).

Is it possible, to re-convert an .exe to python3-Script again?

I'm writing a program with a Login-Window at the beginning.
Since this program is only for my personal use, there is only
one password set, which is implemented in the code. I built an .exe
via pyinstaller and its not possible to read out information out of the
.exe-file. Now i would like to know, if it's possible to re-convert
the .exe into the python3-script to read out the password, or if there is any other way to get information about the script using the .exe-file.
I have not tried yet, but I found in some blog that the following command works.
python pyinstxtractor.py file_to_decompile

Determine if Javascript (NodeJS) code is running in a REPL

I wish to create one NodeJS source file in a Jupyter notebook which is using the IJavascript kernel so that I can quickly debug my code. Once I have it working, I can then use the "Download As..." feature of Jupyter to save the notebook as a NodeJS script file.
I'd like to have the ability to selectively ignore / include code in the notebook source that will not execute when I run the generated NodeJS script file.
I have solved this problem for doing a similar thing for Python Jupyter notebooks because I can determine if the code is running in an interactive session (IPython [REPL]). I accomplished this by using this function in Python:
def is_interactive():
import __main__ as main
return not hasattr(main, '__file__')
(Thanks to Tell if Python is in interactive mode)
Is there a way to do a similar thing for NodeJS?
I don't know if this is the correct way but couldn't find anything else
basically if you
try {
const repl = __dirname
} catch (err) {
//code run if repl
}
it feels a little hacky but works ¯\_(ツ)_/¯
This may not help the OP in all cases, but could help others googling for this question. Sometimes it's enough to know if the script is running interactively or not (REPL and any program that is run from a shell).
In that case, you can check for whether standard output is a TTY:
process.stdout.isTTY
The fastest and most reliable route would just be to query the process arguments. From the NodeJS executable alone, there are two ways to launch the REPL. Either you do something like this without any script following the call to node.
node --experimental-modules ...
Or you force node into the REPL using interactive mode.
node -i ...
The option ending parameter added in v6.11.0 -- will never append arguments into the process.argv array unless it's executing in script mode; via FILE, -p, or -e. Any arguments meant for NodeJS will be filtered into the accompanying process.execArgv variable, so the only thing left in the process.argv array should be process.execPath. Under these circumstances, we can reduce the query to the solution below.
const isREPL = process.execArgv.includes("-i") || process.argv.length === 1;
console.log(isREPL ? "You're in the REPL" : "You're running a script m8");
This isn't the most robust method since any user can otherwise instantiate a REPL from an intiator script which your code could be ran by. For that I'm pretty sure you could use an artificial error to crawl the traceback and look for a REPL entry. Although I haven't the time to implement and ensure that solution at this time.

How can I write unit tests against code that uses QDesktopServices openUrl?

I'm working on a python (3.5) program that use a PyQt5 GUI. In the GUI, I need to add some help links to the documentation on a website. I manage to make it work with:
QDesktopServices.openUrl(QUrl("my_url"))
It works fine but I want to be sure that it will always be the case.
A quick and dirty unittest is to call the function and simply notice that there is no error. I would like to make a test that will check that the correct website page did show up. What should I use?
Checking for an error is not going to work at all, because Qt itself never raises errors (of course, Python or PyQt might do, but for completely unrelated reasons). The best you can do is check the return value of openUrl, which will simply return True or False depending on whether it was "successful". But note the following from the Qt docs for openUrl:
Warning: A return value of true indicates that the application has
successfully requested the operating system to open the URL in an
external application. The external application may still fail to
launch or fail to open the requested URL. This result will not be
reported back to the application.
If you want more control, I suggest you use Python's webbrowser module instead. This would, for example, allow you to register your own mock-browser class for the purposes of testing. The webbrowser module is written in pure Python and the code is quite straightforward.

Can I alter Python source code while executing?

What I mean by this is:
I have a program. The end user is currently using it. I submit a new piece of source code and expect it to run as if it were always there?
I can't find an answer that specifically answers the point.
I'd like to be able to say, "extend" or add new features (rather than fix something that's already there on the fly) to the program without requiring a termination of the program (eg. Restart or exit).
Yes, you can definitely do that in python.
Although, it opens a security hole, so be very careful.
You can easily do this by setting up a "loader" class that can collect the source code you want it to use and then call the exec builtin function, just pass some python source code in and it will be evaluated.
Check the package
http://opensourcehacker.com/2011/11/08/sauna-reload-the-most-awesomely-named-python-package-ever/ . It allows to overcome certain raw edges of plain exec. Also it may be worth to check Dynamically reload a class definition in Python

Resources