What's new

How do I access variable file in a script?

R-man

Senior Member
My script sets values for over a hundred variables that are shared in the creation of several parts. Right now I have everything in one script. I set the values of the variables in a section at the top, then several sections to create the various parts. As I include more parts (and more variables) the script is getting unmanageable. My plan is to break it into many scripts, one for each part.

In this case I will need to have each script access the same set of variables. I have been experimenting with importing 'sub-scripts' into a main script. I can run code from another file, but it seems I can't have variables recognized. For example, MyName = "Doug" when executed in the sub-script does not give MyName a value in the main script, or vice versa.

I guess I'm trying to create my own method of having global variables, within the context of scripting. My hope was that I could import a sub-script and it would simply execute exactly as if it were part of the main script, but so far no success. Can anyone advise on how I might achieve my goal? Can I use the built-in system of global variables to do this?
 

idslk

Alibre Super User
Hello R-man,

are they all in a formt like:
MyName = "Doug"
There are many ways to store information in files in python.
Eg. CSV, Excel, Text ...
There is also a way to use user data in AlibreScript.
The solution depends a little bit on what you have to store and restore...
Regards
Stefan
 

R-man

Senior Member
Hi Stefan,

I can understand how I can store values (4.56 let's say) in an Excel file, but what will make "print DiaGD" give the result "4.56"? It seems that I'd still need 100+ assignment statements in each script. The Excel method does have the benefit of assuring that the value is only updated in one place but I also want to only have to have the assignment of the value in one place.
 

idslk

Alibre Super User
Hello R-man,

as an example here on row of an .CSV-File:
200.0,250.0,300.0,15.0,20.0,15.0
a cutout (there's a bit more of preperation needed...) of a script code:
Code:
  with open(Verzeichnis + Standardsfile, 'rb') as f:
    reader = csv.reader(f)
    for row in reader:
      print row
      Value1 = row[0]
      Value2 = row[1]
      DiaGD = row[2]
      Test = row[3]
      MyDoug = row[4]
      Z_Turn = row[5]
    f.close()
results the same like:
Code:
      Value1 = 200.0
      Value2 = 250.0
      DiaGD = 300.0
      Test = 15.0
      MyDoug = 20.0
      Z_Turn = 15.0
So if you place a copy of the csv reading and assigning, yes, in each of your scripts you have to maintain only the CSV-file or...
(The reading of an excel-file is nearly the same...)
Of course there are more sophisticated methods, like reading the Name and the Value of the variable...

Regards
Stefan
 

R-man

Senior Member
Thanks Stefan,

After thinking about how to use excel I came up with a similar idea. I combined it with what I've recently learned about python 'global' declarations.

Python does have a 'global' declaration but the declarations are separate from the assignment. With all my parameters, and new ones being added I thought it would be too much headache to keep track of the variable names in two places. But I now realize I can automate all of that by having a script read the excel and create a python file with all the declarations and assignments. That has to be imported into my scripts to access the variables.

If it turns out well, or not, I'll post the results.
 

ajayre

Alibre Super User
Define all of your variables in a dictionary:

Code:
MyGlobals = {
  'MyName': 'Doug',
  'DiaGD': 4.56
}

then pass this dictionary to each function you call, whether it is in the current script or it is in another script.

Code:
Result = CreatePart(MyGlobals)

See the link Nate gave for how to import a script into another script and make it's functions available.

More info on dictionaries here: https://docs.python.org/2.7/tutorial/datastructures.html#dictionaries

Andy
 

R-man

Senior Member
Andy:
Assuming I have a parameter AvHeight and a library 'LIB' it seems I'd have to use replace AvHeight with LIB('AvHeight'). Is there anyway of regaining the ability to use AvHeight directly? To have every variable accessed in this way would make my code more of a jumble than it is already.

Nate:
I see you've really put a lot of work into that system, but I am not inclined to try it because even a small hiccup would defeat me, since couldn't (or wouldn't want to) figure out what went wrong.
 
Last edited:

albie0803

Alibre Super User
Unless I'm missing something, simply AvHeight = LIB('AvHeight') is all you need once and then you can use AvHeight through the rest of your script.
 

R-man

Senior Member
Albie:

Yes, that would allow me to keep my code as is - thanks. However, I am developing the scripts as I develop my design, so I'm adding parameters all the time, and most of them affect several parts. (It's probably not how most folks use scripting, but once my script is perfected the parts are perfected and the script's life is over unless some part of the design needs changing.)

So a library would give me the ability to only update a value in one location, and as you point out I could keep my code as is, but I still would need to update a long list of assignment statements in many scripts every time I introduced a new parameter (several per hour). Not much benefit over just copying the parameter script into each part script (something I could automate I guess). Nate's system of "external saved variables" looks like it was motivated by the same vision of 'global' variables for scripts as I have. (Nate: Correct me if I'm wrong!)

This example, and others here, have added to my python education and helped me simplify and better organize my scripts, so thanks to all.

As it stands now I have one main script that initiates all of the parameters, and has most of the code in functions. The driving part selectively calls the functions to update parts as required. It's not so bad a system - I just thought putting each separate task into a separate script would be a sounder approach.
 

idslk

Alibre Super User
Hello R-man,

can you post a little sample script?
However, I am developing the scripts as I develop my design, so I'm adding parameters all the time, and most of them affect several parts.
What are you using the scripts for?

Regards
Stefan
 

R-man

Senior Member
Great! I will follow closely.

In the meantime I've figured out how to import my variables and reference them relatively conveniently.
( MyGlobalVariables has assignments var1 = 33 and var2 = 22.)

Code:
import sys

# make sure my globals folder is in sys.path (but only one time)
p = "C:\\Users\\dh\Documents\\RotoAlibre\\Alibre\\TestPackage"
if p not in sys.path:
  sys.path.insert(0, p)

# import the global variables using short alias "g" and reload to get latest version
import MyGlobalVariables as g
reload(g)

# code
print g.var1, g.var2, g.var1 + g.var2
 

R-man

Senior Member
Thanks to everyone who took an interest and contributed ideas and clues. Finally I have 'Hack2' ready, and this really is a hack in the sense that it uses the python system in a way that is not as intended.

This works by adding variables to the namespace used for python reserved names. However the changes are temporary and disappear when the Alibre 'console' is closed. Also, before a variable is set it is verified to not be in the namespace. It's not complicated but it took a long time to get working properly. It works well for my needs, but I'm presenting it here FYI only. If anyone is interested in trying this, the three scripts below should be a good start. Just update the folder and file names to suit.

The parameter file: TestParams.py
Code:
# This is a small section of the parameter assignments taken directly from my parameters script

    # origin
    HmX = 5.0 # 0.0  #  shift from actual origin
    HmY = 5.0 # 0.0
    HmZ = 5.0 # 0.0
    # concentric axles
    AxCtX    =  HmX
    AxCtY    =  HmY
    Ax3Od    =  4.00
    Ax3Hx    =  6.35   # with corners rounded to  7.00 (alternate method if using slide cam)
    Ax3Sq    =  3.175  # .125" corners rounded to 4.00 (standard method if no slide cam)
    Ax2Id    =  4.00
    Ax2Od    =  7.00
    Ax2Hx    =  6.35   # with corners rounded to  7.00
    Ax1Id    =  7.00
    Ax1Od    = 10.00
    Ax1Hx    =  9.00   # with corners rounded to 10.00
    # axle bearings
    Ax3BrId  =  4.00
    Ax3BrOd  =  7.00
    Ax3BrTh  =  2.50  # maybe 3.00 ????????????????
    Ax1BrId  = 10.00
    Ax1BrOd  = 15.00
    Ax1BrTh  =  3.00
    # wheel parameters
    WhTh   =   6.00
    WhSp   =   5.50
    WhDm   =  30.00
    WhRd   =  WhDm/2
    Wh1CtZ =  HmZ + Ax1BrTh + WhTh/2
    Wh2CtZ =  Wh1CtZ  + WhSp
    Wh3CtZ =  Wh2CtZ  + WhSp

The script that processes the parameter file: InitParams.py
Code:
import __builtin__ as bi

# If not yet created, create list of names that have been added
if "MyParamNames" not in vars(bi):
  bi.MyParamNames = []          

path = "C:\\Users\\dh\Documents\\RotoAlibre\\Alibre\\Hack2"
f = open(path + "\\" + "TestParams.py", "r")             # use full path to params file

for x in f:
  x = x.split('#')[0].strip()                          # keep text before first '#'
  if not len(x) == 0 and not x[0] == '#' and "=" in x: # make sure len>0, no '#', and has '='
    name  = x.split('=')[0].strip()                    # split at '=' into name & value
    value = x.split('=')[1].strip()                    #     and strip away white space
    if name not in vars(bi) or name in MyParamNames:   # name is OK
      if name not in MyParamNames:
        MyParamNames.append(name)                      # add name to list
      exec("bi." + name + " = " + value)               # inialize name with value
    else:
      print "Name is invalid"                          # name was not OK
f.close

And here is a TestScript that imports InitParams:

Code:
# All the regular imports etc go here

# Add file path to sys.path (but only once) to make sure import works
p = "C:\\Users\\dh\Documents\\RotoAlibre\\Alibre\\Hack2"
if p not in sys.path:
  sys.path.insert(0, p)

# Initalize Parameters
import InitParams

# Put code here

# test to see how things went
print "HmX =     " + str(HmX)
print "HmY =     " + str(HmY)
print "HmZ =     " + str(HmZ)
print "AxCtX =   " + str(AxCtX)
print "AxCtY =   " + str(AxCtY)
print "Ax3Od =   " + str(Ax3Od)
print "Ax3Hx =   " + str(Ax3Hx)
print "Ax3Sq =   " + str(Ax3Sq)
print "Ax2Id =   " + str(Ax2Id)
print "Ax2Od =   " + str(Ax2Od)
print "Ax2Hx =   " + str(Ax2Hx)
print "Ax1Id =   " + str(Ax1Id)
print "Ax1Od =   " + str(Ax1Od)
print "Ax1Hx =   " + str(Ax1Hx)
print "Ax3BrId = " + str(Ax3BrId)
print "Ax3BrOd = " + str(Ax3BrOd)
print "Ax3BrTh = " + str(Ax3BrTh)
print "Ax1BrId = " + str(Ax1BrId)
print "Ax1BrOd = " + str(Ax1BrOd)
print "Ax1BrTh = " + str(Ax1BrTh)
print "WhTh =    " + str(WhTh)
print "WhSp =    " + str(WhSp)
print "WhDm =    " + str(WhDm)
print "WhRd =    " + str(WhRd)
print "Wh1CtZ  = " + str(Wh1CtZ)
print "Wh2CtZ  = " + str(Wh2CtZ)
print "Wh3CtZ  = " + str(Wh3CtZ)
print

# print out the names that were used (for no particular reason)
print  MyParamNames

One last comment: any variables created within the script, and any re-assignment to variables, will NOT be recorded back to the TestParams.py file. However, it only takes seconds to add a new parameter and re-run InitParams so that it can be used.
 
My script sets values for over a hundred variables that are shared in the creation of several parts. Right now I have everything in one script. <Snip>
R-man -- Have you looked at the "CSV Import" system? It allows you t create a "CommaSeparatedValue" input file that can be "decoded" to loaded Screipt-base variables. I have not done this in a while (i.e.more than a year) so the context and format do not leap to what's left of my mind -- but it is an approach that I regularly find useful...
 

R-man

Senior Member
Lew: I have jumped to a conclusions about how CSV files would be used and admit that I have not looked carefully into what has been done regarding a "CSV Import" system. I will though. Thanks.

Stefan: The same applies to post #5 which I looked at, but not as carefully as I might have. In light of my recent discoveries I now attach a lot more significance to the remark: "Of course there are more sophisticated methods, like reading the Name and the Value of the variable...". Thanks.

So stand by as I apply my recently gained knowledge to developing a method (perhaps unsophisticated) inspired by that comment! For anyone who is following my attempts I'll call it 'Hack3'.
 
Last edited:

idslk

Alibre Super User
Hello R-man,

i'm looking for your next hack;)
If you do run the following code in Python37 it works as expexted...
Also if you run it multiple times.
Code:
import sys
for loop in range(3):
    for i in range(len(sys.path)):
        print (loop,i,sys.path[i])
    print (' ',)
    p = "C:\\Users\\Default\\Documents"
    if p not in sys.path:
      sys.path.insert(0, p)

If you do the same in AlibreScript it behaves a little bit different...
Code:
import sys
for loop in range(3):
    for i in range(len(sys.path)):
        print loop,i,sys.path[i]
    print ' ',
    p = "C:\\Users\\Default\\Documents"
    if p not in sys.path:
      sys.path.insert(0, p)

the printed sys.path gets longer and longer.
I do not have any explanation for this, do you have one?

Regards
Stefan
 
Top