Function properly defined and working but not printing results in terminal - python

I recently wrote a simple function that gets the present value of an asset, the function PV works properly and I have tested it. The function prints well in my pv file. However, when I run this code in the main file it does not print the output to the terminal and just closes after taking the inputs. Is there a reason for this? For reference the functions just perform some simple mathematics problems.
Below is a minimal reproduction, both files are in the same folder.
in file_x you have a function that works like this:
def func(w,x,y,z):
z1 = w/(1 + (x/100))**(y*z)
print(z1)
return 0
this function is then imported into another file which is written like so
from file_x import func
w = int(input("Future Value: "))
x = float(input("ROR: "))
y = float(input("# of periods: "))
z = float(input("# of payment per anum: "))
func(w,x,y,z)
My problem is that when I run the 2nd file it takes the inputs properly but does not print the result from the function. Hope it was explained properly

In interactive mode an unused expression (here PV(w,x,y,z) which does returns a value and that value is not used) is printed to the terminal, because it is a common way to just display expression values.
But when you run a script in a non interactive mode (python script.py) then those unused expression are just discarded. As a general rule, you should never have such an unused expression in a script, because the behaviour will depend on the interactive mode of the interpretor.
So you should be explicit:
_ = PV(w,x,y,z) # value will be discarded even in interactive mode
or
print(PV(w,x,y,z)) # value will be printed even in non interactive mode

Related

Problem running successive Python scripts using 'Reticulate' function in R

I'm having a problem running two successive python scripts in a single R script that calls the reticulate function. When I run them separately, it works perfectly. Am I missing something? Do I need some sort of function that closes the previous py_run before executing the second one? Note that I am working with the ArcGIS 'arcpy' tools.
Here is an example.
If I run this in an Rstudio session:
use_python("C:/Python27/ArcGISx6410.7/python.exe", required = T)
import("arcpy")
import("os")
import("glob")
import("re")
import("math")
pythonRun1 = paste0("modelName = ", "'", modelName, "'")
py_run_string(pythonRun1)
py_run_file("C:/GIS/Bathymetry_UdeM/Radial_Linear_Mean_R/Output/Workflow/InterpolateResults.py")
and then this in a second Rstudio session:
use_python("C:/Python27/ArcGISx6410.7/python.exe", required = T)
import("arcpy")
import("arcpy.sa")
import("os")
import("glob")
import("re")
import("math")
pythonRun2 = paste0("modelName = ", "'", modelName, "'")
py_run_string(pythonRun2)
py_run_file("C:/GIS/Bathymetry_UdeM/Radial_Linear_Mean_R/Output/Workflow/FocalMean.py")
it works perfectly. But when I'm trying to successively execute these two code blocks:
use_python("C:/Python27/ArcGISx6410.7/python.exe", required = T)
import("arcpy")
import("os")
import("glob")
import("re")
import("math")
pythonRun1 = paste0("modelName = ", "'", modelName, "'")
py_run_string(pythonRun1)
py_run_file("C:/GIS/Bathymetry_UdeM/Radial_Linear_Mean_R/Output/Workflow/InterpolateResults.py")
#########################################################################################################
use_python("C:/Python27/ArcGISx6410.7/python.exe", required = T)
import("arcpy")
import("arcpy.sa")
import("os")
import("glob")
import("re")
import("math")
pythonRun2 = paste0("modelName = ", "'", modelName, "'")
py_run_string(pythonRun2)
py_run_file("C:/GIS/Bathymetry_UdeM/Radial_Linear_Mean_R/Output/Workflow/FocalMean.py")
I get noData as my final output. The second portion of the script does not callback any error technically speaking, but the code does not execute what it is supposed to.
Does anyone have an idea as to what may cause the difference between these two methods (i.e., separate and successive py_run execution)?
Thanks everyone!
Try constructing a MRWE. It's hard to answer a question like this without being able to run the code. Here's a couple of starting points for troubleshooting, though.
I would not advise running reticulate::use_python twice. It is my understanding that once the Python interpreter is embedded into the R session it cannot be changed, so when this is called a second time at best it can have no effect, and at worst it could be causing issues.
You don't show any code where a value is bound to model_name, is it supposed to be changed in-between the two blocks of code?
Is there any state that is being modified in the first code block that is affecting the evaluation of the second code block? For example, if a variable is created in the first code block that is shadowing a variable being used in the second code block.
Try running the analogous code directly in Python and ensure that that works correctly. If not then it will be easier to debug in that environment.
Good luck!

How to run ipython script in python?

I'd like to run ipython script in python, ie:
code='''a=1
b=a+1
b
c'''
from Ipython import executor
for l in code.split("\n"):
print(executor(l))
that whould print
None
None
2
NameError: name 'c' is not defined
does it exists ? I searched the doc, but it does not seems to be (well) documented.
In short, depending on what you want to do and how much IPython features you want to include, you will need to do more.
First thing you need to know is that IPython separates its code into blocks.
Each block has its own result.
If you use blocks use this advice
If you don't any magic IPython provides you with and don't want any results given by each block, then you could just try to use exec(compile(script, "exec"), {}, {}).
If you want more than that, you will need to actually spawn an InteractiveShell-instance as features like %magic and %%magic will need a working InteractiveShell.
In one of my projects I have this function to execute code in an InteractiveShell-instance:
https://github.com/Irrational-Encoding-Wizardry/yuuno/blob/master/yuuno_ipython/ipython/utils.py#L28
If you want to just get the result of each expression,
then you should parse the code using the ast-Module and add code to return each result.
You will see this in the function linked above from line 34 onwards.
Here is the relevant except:
if isinstance(expr_ast.body[-1], ast.Expr):
last_expr = expr_ast.body[-1]
assign = ast.Assign( # _yuuno_exec_last_ = <LAST_EXPR>
targets=[ast.Name(
id=RESULT_VAR,
ctx=ast.Store()
)],
value=last_expr.value
)
expr_ast.body[-1] = assign
else:
assign = ast.Assign( # _yuuno_exec_last_ = None
targets=[ast.Name(
id=RESULT_VAR,
ctx=ast.Store(),
)],
value=ast.NameConstant(
value=None
)
)
expr_ast.body.append(assign)
ast.fix_missing_locations(expr_ast)
Instead doing this for every statement in the body instead of the last one and replacing it with some "printResult"-transformation will do the same for you.

How to make IDLE python display directly results from a function defined and ran from a .py file

I have tried many set and search quite some time. I'll try to summarize to my problem.
I a have a file I name script.py.
Inside this script.py I have something like this:
import math
import numpy as np
from numpy import matrix
#Inserting variables:
A=float(input("insert position 1: "))
K=float(input("insert position 2: "))
#Doing some math:
a1=A*K
a2=A/K
#Defining a funtion:
def solve(var1,var2)
#This function uses numpy and math and handles matrices.
#I am not putting it to save space and make my problem clear
#Calling the funtion:
solve(a1,a2)
print (solve)
#The values of a1 and a2 are the once I calculated previously
Then I press "run module" to run script.py, it shows:
>> insert position 1:
>> insert position 2:
I insert the values and then it shows:
<function solve at 0x000000000A0C1378>
What can I do to make the python shell display the result directly?
Currently in order to get the results I need to type in the python shell
>> solve(a1,a2)
to have my result.
I hope I was able to make my problem clear and simple. Thanks.
You are printing the function itself, not the output from the function call. To achieve this, either save the function output to a variable then print, or just print straight away.
1st Method:
ans = solve(a1,a2)
print(ans)
2nd Method:
print(solve(a1,a2))

How to start a program on Python?

I'm doing a project on projectile motion where I have to create a program that given some values, it will give several values. I haven't finished it yet, but I wish to test it, but I have very little knowledge on how to run my programs. I created a file on Notepad++ with some of my code, but every time I try to run it, it says:
Traceback (most recent call last):
File <"stdin">, line 1, in
ImportError: no module named py
The thing is, I don't see anywhere how to run my programs on Python using Notepad++ so I am confused as to what I have to do. I am using the command prompt to run my program.
I will post what I have so far of my project because maybe it's a problem of what I have written. This is what I have so far:
"""Mini-Project about projectile motion."""
USER = ""
USER_ID = ""
import numpy as np
#Define variables for ease of use:
g = 9.81 #gravitational constant
u = (float(raw_input("enter launch_speed: ")))#speed of launch
r = (float(raw_input("enter launch_angle_deg: "))*(np.pi)/180) #angle of launch in radians
n = (float(raw_input("enter num_samples: "))) #number of time divisions
#"t" variable of time
#"x" variable of horizontal distance
#"y" variable of vertical distance
def x(t):
"""function that gives the horizontal position "x" as a function
of time.
"""
return u*(np.cos(r))*t #formula for horizontal displacement
def y(t):
"""function that gives the vertical position "y" as a function of
time.
"""
return u*(np.sin(r))*t - (g/2)*t**2 #formula for vertical displacement
def y(x):
"""function that gives the vertical position "y" as a function of the
horizontal position "x".
"""
return x*(np.tan(r))-(g/2)*(x/(u*np.cos(r)))**2
a = np.arange(1, n+1, dtype=float)
def trajectory(launch_speed, launch_angle_deg , num_samples ):
"""This function gives the values of horizontal x-values, vertical
y-values, and time values, respectively, given the values for initial
launch speed, and the angle at which it is launched, for some given
divisions of time that the object is in the air.
"""
while t <= (u*(np.sin(r))/g): #maximum time given by this formula
t = x/(u*(np.cos(r)))
I am assuming you are on Windows, for the reference good ol' command prompt. Be sure you have Python installed, then navigate to the folder you have your Python script stored. Shift right-click on the folder and select "Open command window here". A CMD window should appear. Now just type
python name_of_your_python_file.py
And you should see the output. As for the ImportError you posted, be sure to have all dependencies installed. (Numpy)
If you are determined to use Notepad++ as your development environment, read here for more information on running those Python scripts direct from notepad++
Store the program in a file named "projectile.py"
Install Python 3 and NumPy.
Then open console, navigate to the folder containing the file
Invoke
python3 projectile.py

Viewing Local Variables in Spyder's Variable Explorer

I'm new to python and am using Spyder's IDE. One feature I appreciate about it is it's variable explorer. However, based on some research, I found that it only shows global variables. A workaround that I found for that is by using the inspect module:
import inspect
local_vars = {}
def main():
global local_vars
a = 2
b = 4
c = a+b
local_vars = inspect.currentframe().f_locals
return c
main()
This works well, however, I have other functions that are called from within main() and I'd like to see those variables in the variable explorer as well. I mimicked what was done for the variables in the main function and the dict does not appear. I noticed that when I disable the setting to "exclude unsupported data types" in Spyder's variable explorer options, the second dict appears with the right size attribute, however, I am unable to open/view it. Any ideas on a possible work around? This is my first time posting BTW.
Thanks!!
Here is a working example of my issue and I've traced it down to pylab subplots.
import inspect, pylab
mainVars = {}
def main():
global mainVars
a = 1
b = 2
fig = pylab.figure()
subPlot = fig.add_subplot(211) ## line of interest
pylab.close('all')
mainVars = inspect.currentframe().f_locals
main()
When the line of interest is commented out, the dict is created successfully and can be viewed. It appears that the object created using fig.add_subplot() is not being handled properly by the dict. It seems to be an unsupported datatype.
Hope this helps clarify the issue.
Thanks again.
To view the contents of local variables when some of them are unsupported, you have to follow these steps:
Go to the options menu of the Variable Explorer (the last icon from left to right on it).
Select the option called Exclude unsupported data types.
Then you'll see all local variables saved in the f_locals dict, even if you're unable to double click on it.
All of these workarounds are making your code significantly harder to read for outsiders. You have two options to inspect the values of the variables inside your function. First, you could just return the variables you are interested in:
def main():
a = 2
b = 4
c = a+b
return a, b, c
a, b, c = main()
Second, if you just want to check that the function works as expected or debug it, you can debug the function and step into it. So select Run|Debug from the menu instead of running the file directly. Then you can step into the function - the values of the variables will be visible in the variable explorer when the execution is inside the function.

Categories