How to import variables from one file into another - python

I'm trying to take a separate text file, with a list of defined variables, and import them into the main py file. Not trying any classes or functions, just predefined variables. I tried a number of different solutions but the syntax isn't working for all the different types.I'm working on a Linux device and .py is in the file name. I dont know if that's causing an issue or not so I renamed it and still is not working. Files are here.
list of variables:
/home/example/file.module.py
actual code file to run:
/home/example/filetorun.py
I've tried on filetorun:
import file.module.py
import 'file.module.py'
from file.module.py import *
from 'file.module.py' import *
import ./file.module.py
import /home/example/file.module.py
(renamed file to file.module) import /home/example/file.module
All these are not working, not sure if have to make a function to return all these values or what.

Your issue is that you have a dot in the file name. Either change the name of the file and follow what I have posted below, or check out importlib.util from this post: Import with dot name in python
https://www.geeksforgeeks.org/how-to-import-variables-from-another-file-in-python/
Import the file (no need to specify Path if in same directory) and then use the file name pre-the variable.
# calval.py file where to import variables
# import swaps.py file from which variables
# to be imported
# swaps.py and calval.py files should be in
# same directory.
import swaps
# Import x and y variables using
# file_name.variable_name notation
new_x = swaps.x
new_y = swaps.y
print("x value: ", new_x, "y value:", new_y)
# Similarly, import swapVal method from swaps file
x , y = swaps.swapVal(new_x,new_y)
print("x value: ", x, "y value:", y)

Related

How to avoid this circular import?

Asset variable must be declared from mother file (this is a simplified version).
File cannot be merged.
This mother file works :
import pandas as pd
import datetime as dt
import yfinance as yf
data=yf.Ticker("^NDX")
dataHist= data.history(interval="1d",start= dt.date.today()-dt.timedelta(days = 50) ,end= dt.date.today()-dt.timedelta(days = 0))
df = pd.DataFrame(dataHist[["Open","High","Low","Close"]])
import child_file
if __name__=="__main__":
df["expo"] = child_file.exponential_moving_average
print(df)
With this child file :
import pandas as pd
import parent_file
exponential_moving_average = pd.Series.ewm(parent_file.df["Close"],span=12).mean()
But if replace in mother file:
data=yf.Ticker("^NDX")
by this to be able to choose the asset :
if __name__=="__main__":
asset = "^"+str(input()).upper()
data=yf.Ticker(asset)
It says
NameError: name 'asset' is not defined
(from child file point of view)
How do i reorganize the code ?
I tried a lot this has went for several days now
Since you are not defining anything new or implementing any modular functions in your child file, I would suggest moving that to the parent file and deleting the child file.
However, if you so choose to maintain the two, you should
load dataFrame in your child file, but not your parent file.
You could potentially define a function in your child file that takes parameters required for loading your ticker data, and call that function from your parent file.
Edit:
I would write a function in your child file.
def moving_average(close_price):
return pd.Series.ewm(close_price, span=12).mean()

How can I load a function, which can add global variables, without using exec(open(...))?

I have a SymPy python project which is working well but I currently need to use exec(open(...)) at the start of each file. I would like to know if I can avoid this? Partly because I've read that exec should be avoided buy I would also just like to discover any possible alternatives to my current approach.
The following is a heavily simplified version of what I have. There is a file hat.py with a function, which expects a symbol as an input and returns a new symbol with the suffix 'h' added. Importantly it also adds this new symbol to the global namespace.
from sympy import Symbol
def hat(var):
nameh = str(var)+"h"
globals()[nameh] = Symbol(nameh)
return globals()[nameh]
My project involves multiple files which want to use the hat() function as follows.
from sympy import Symbol
exec(open("hat.py").read())
x = Symbol('x')
e1 = x + hat(x)
print(xh + e1)
If hat() instead came from an import statement, xh would not be defined here and would return an error. I would need to use import after every use of hat to add the new variables to the namespace. This is not an option, as I have hundreds of symbols and hundreds of uses of hat. I also don't want to just import thousands of symbols preemptively.
Is there any other way I can load functions with the ability to dynamically add variables to the top-level namespace?
This answers the question but I don't think its a good way to code:
from sympy import Symbol
def hat(var,namespace):
nameh = str(var)+"h"
namespace[nameh] = Symbol(nameh)
return namespace[nameh]
Then in the project:
from sympy import Symbol
from hat import hat
x = Symbol('x')
e1 = x + hat(x,globals())
print(xh + e1)
Answering my own question, inspired by kubatucka's suggestion. One can point a module variable to the global namespace. This gives me all the functionality I had, by replacing an exec() line with an import line and set globals() namespace line.
function file hat.py:
from sympy import Symbol
def set_global_namespacece(namespace):
global global_namespace
global_namespace = namespace
def hat(var):
nameh = str(var)+"h"
global_namespace[nameh] = Symbol(nameh)
return global_namespace[nameh]
project file x_eqns.py:
from sympy import Symbol
from hat import *
set_global_namespacece(globals())
x = Symbol('x')
e1 = x + hat(x)
print(xh + e1)

Why is the order of importing files resolving a NameError?

I have three files, one being the main file that needs to be run, and the other two contain utility functions, as follows. All the files are in the same directory and I am running it on PyCharm.
# delta_plots.py - This is the main file
...
from delta_plots_utility_1 import *
from delta_plots_utility_2 import *
...
def print_parameter_header(params, flag):
batch_size, epochs, lr = params[0], params[1], params[2]
print("{} - Batch size: {}, Epochs: {}, Learning rate: {}".
format(flag.upper(), batch_size, epochs, lr))
...
if __name__ == '__main__':
# call the utility functions based on a condition
if (condition1):
utility_function_1()
elif (condition2):
utility_function_2()
# delta_plots_utility_1.py - Utility file 1
# this import statement is to import the print_parameter_header() function
# from the main file
from plot_delta_mp import *
def utility_function_1():
# this function makes a call to the print_parameter_header() function
...
print_parameter_header(params, flag)
...
# delta_plots_utility_2.py - Utility file 2
from plot_delta_mp import *
def utility_function_2():
# this function also makes a call to the print_parameter_header() function
...
print_parameter_header(params, flag)
...
The problem is when in the main file, if condition1 is true, then I am forced to put the import statement for utility file 1 before the import statement for utility file 2, and vice versa.
Otherwise, I get the following error:
NameError: name 'print_parameter_header' is not defined
I also tried importing the files as modules and then accessing the function as module.print_parameter_header(), but that does not help either.
I had the following questions regarding this:
From what I understand, the order of the import statements is not important. So why is this happening? Why does changing the order resolve the error?
Could this be because of the loop-like importing? Since I am importing the main file in the utility functions too.
If yes, then is it okay to define print_parameter_header() in the utility files? Although it would be redundant, is that a good practice?
It seems that all of your issues come from that initial misunderstanding: "From what I understand, the order of the import statements is not important."
In python, an import statement
can happen anywhere in the code (not necessarily at the beginning), so if you enter into circular dependency issues it might be a good idea to import the latest possible if you have no other design choice
creates symbols in the code. So from xxx import a will create variable a locally, just like writing a = 0. It is exactly the same.
So maybe a good solution for you would be to stop using from <xxx> import * or import <xxx>, which both import all symbols from the other module, but to import selected symbols in precisely controlled places. Such as from <xxx> import a, b and later in your code from <xxx> import c.
Sorry for not taking the time to adapt the above answer to your precise code example, but hopefully you'll get the idea.

Import single OBJ files into Maya, moving and rotating it with Python/MEL

Hi I have this code to import OBJ files into maya with Python
**
import maya.cmds as cmds
pathOfFiles = "/Path/to/the/files/folder/"
fileType = "obj"
files = cmds.getFileList(folder=pathOfFiles, filespec='*.%s' % fileType)
if len(files) == 0:
cmds.warning("No files found")
else:
for f in files:
cmds.file(pathOfFiles + f, i=True)
**
It imports all the obj files which are into that folder.
However, what I need is:
Import an individual OBJ file at once
Move and rotate the imported file
Apply a Material already created in Maya
Render
Delete the file
6 Repeat the process with the next file
Is it possible to do it with Python or MEL
This looks like a fun challenge, so here's my attempt at answering it:
import maya.cmds as cmds
import glob
#1. Import an individual OBJ file at once
def importFile(i):
cmds.file(i, i=True, groupReference=True, groupName="myobj")
#2. Move and rotate the imported file
def moveFile():
cmds.select("myobj")
# Add the X,Y,Z cordinates to change scale, translate and rotate below
cmds.scale(1,1,1)
cmds.move(0,0,0)
cmds.rotate(0,90,0)
#3. Apply a Material already created in Maya
def materialFile():
cmds.select("myobj")
myMaterial = "lambert2" + "SG" #replace lambert2 with your material
cmds.sets(forceElement=myMaterial)
#4. Render
def renderFile(i):
cmds.setAttr("defaultRenderGlobals.imageFilePrefix", i, type="string")
cmds.render(batch=True)
#5. Delete the imported file
def deleteFile():
cmds.select("myobj")
cmds.delete()
# Add the path to your obj files. Make sure to leave the /*.obj at the end
myglob = glob.glob("/Users/OSX/Desktop/objs/*.obj")
for i in myglob:
importFile(i)
moveFile()
materialFile()
renderFile(i)
deleteFile()
Because you have a list of individual things you need the script to do I've divided up each requirement on your list into its own function. This should make the script more modular and hopefully easy to edit and reuse.
Python works much better for this kind of task because MEL doesn't have functions, instead it has procedures which act like functions but don't work as well from what I've experienced.

Passing a list from an imported module

I have a file with a function defined, which imports and organizes data into a list of lists. It returns that list of lists, and this all functions fine within the same file (if I write a main function and call the import function, no problems).
def import_viscosity_data(size_of_header):
...
return (list_of_lists)
I'm trying to call this function from another file in the same directory, using the following:
import load_files
print(load_files.import_viscosity_data(7))
Unfortunately, this keeps returning 'None', and if I try to get the length of the returned array, it throws an error:TypeError: object of type 'NoneType' has no len()
I'm guessing that it's passing me a reference to the list, and the actual list gets deleted as soon as the function terminates, but I'm not sure how to resolve this problem. Any help would be greatly appreciated!
Here's the code:
import os
import tkinter
from tkinter import filedialog
#import decimal
from decimal import *
def import_viscosity_data(size_of_header):
### This function imports viscosity data from multiple files, skipping the
### header passed inof the form shearRate '\t' viscosity and puts it into
### an array of the form test_num[result_type[data]]] where result type
### is 0 (shearRate) or 1 (viscosity)
header_size = size_of_header
root = tkinter.Tk()
root.withdraw()
file_path = root.tk.splitlist(filedialog.askopenfilenames(
parent=root, title='Choose a file(s):'))
test_num = []
result_type = []
data_1 = []
data_2 = []
for file_name in file_path:
f = open(file_name)
## Skip the header, which consists of header_size lines
for i in range(header_size):
next(f)
lines = [line.strip() for line in f]
f.close()
## For a line, slice all characters before the tab, then after the tab
## convert to Decimal, and append to the data list
for index in range(len(lines)):
data_1.append(Decimal(lines[index][0:lines[index].find('\t')]))
data_2.append(Decimal(lines[index][lines[index].find('\t') + 1:]))
result_type.append(data_1)
result_type.append(data_2)
test_num.append(result_type)
data_1, data_2, result_type = [], [], []
return(test_num)
Here's some sample data to try it on (any data in 2 columns with a tab in between):
0 1.2381
0.004 1.23901
0.008 1.23688
0.012 1.23734
0.016 1.23779
0.02 1.23901
0.024 1.23932
0.028 1.23886
0.032 1.23688
0.036 1.2384
Again, within this program (running in an IDE, or if I write a small main() function), this returns a list of list of lists, and works just fine. However, when I import the function in a different file, it returns None, without throwing any errors. The function name pops up automatically in the IDE after the import load_files, so it seems to be importing properly.
Note
*This secondary problem was resolved. The file load_files.py was within a directory called load_files. The import statement was changed to from load_files import load_files and it now functions properly.*
Today my problem has gotten even worse. Now, I can't get any functions from the first file to be recognized in the second. Even a simple set of code like:
#load_files.py
def test_func():
print('test successful')
#test.py
import load_files
load_files.test_func()
is throwing this error:
Traceback (most recent call last):
File "C:\Users\tmulholland\Documents\Carreau - WLF\test.py", line 8, in <module>
load_files.test_func
AttributeError: 'module' object has no attribute 'test_func'
load_files.py is in it's own folder (of the same name) with a blank __init__.py file
Note I should add that I'm using the Pyzo IDE because I want to use the scipy library to do curve fitting / optimization problems. I can't get any functions to import correctly today into Pyzo, no matter how simple. Has anybody else had this problem?
The problem was the test.py file's import statement. At first, I confused the issue by having, in the same directory as the test.py, load_files.py and also a directory called load_files which contained load_files.py as well as a blank file called __init__.py.
The original script read
import load_files
print(load_files.import_viscosity_data(7))
I eliminated the load_files.py which shared a directory with test.py. Now, I have test.py in the parent directory, then a sub-directory called load_files which contains load_files.py. The new script reads:
from load_files import load_files
print(load_files.import_viscosity_data(7))
Now, the list of lists is passed in to the local space, so a statement like
list_test = load_files.import_viscosity_data(7)
works fine.
I couldn't get things to work correctly when I just had the two .py files in the same directory (e.g. test.py and load_files.py in the same directory, no sub-directory). The import statement of import load_files threw an error that the module doesn't exist. Anyway, it all works well now with the above code.
Special thanks to Martijn Pieters for the feedback.

Categories