bvdet 2,851
Expert Mod 2GB
I provide shop drawings to structural steel fabricators with SDS/2 software ( http://sds2.com) by Design Data (DD). I am not a programmer by education or trade and started writing scripts about 5 years ago. DD has a script interface with Python in the 3D model which is very useful in production. Part of the Python interface includes a dialog box class: - dlg1 = Dialog('Dialog Box Title')
Method dlg1.done() returns a dictionary. I am exporting the dictionary or list of dictionaries to disc with Pickler and importing with Unpickler to update the variables initialized in the scripts. I have been dumping everything into the global dictionary with globals().update(dd). All variables in the scripts are accessed directly - not through a dictionary. In an effort to evolve towards local variables, I reworked one script this way: -
def run_script():
-
from math import sqrt, cos, ..........
-
from param import ............
-
import macrolib.pickle
-
...............
-
# Define default values for variables
-
...............
-
# Define functions and classes not imported
-
...............
-
# Import defaults file and update local dictionary
-
if enable_default_import_export == "Enable":
-
dd0 = import_data(default_file_path + def_file)
-
if dd0:
-
if isinstance(dd0, types.ListType):
-
for dd in dd0:
-
for key, value in dd.items():
-
exec "%s = %s" % (key, repr(value)) in None
-
elif isinstance(dd0, types.DictType):
-
for key, value in dd0.items():
-
exec "%s = %s" % (key, repr(value)) in None
-
else:
-
Warning("Invalid data - Reverting to original defaults")
-
## Main program loop
-
while 1:
-
ClearSelection()
-
# Select members
-
-
# do other stuff as necessary
-
######################################################################################################################################
-
## DIALOG BOX 1 ---------------------------------------------------------------------------------------------------------------------#
-
######################################################################################################################################
-
dlg1 = Dialog("Add stiffener plates to beam members")
-
dlg1.menu("print_doc", ("Yes", "No"), "No", "Print parametric script documentation only")
-
dlg1.tabset_begin()
-
dlg1.tab("General Information")
-
dlg1.column_group_begin()
-
dlg1.column(0)
-
if mem2 == "pick point":
-
dlg1.group_title("Stiffener Location Selection Method")
-
dlg1.menu("location_method", ("Pick Points", "Fixed Spacing"), location_method, "Method of locating stiffeners ")
-
dlg1.entry("points_x_offset", dim_print(points_x_offset), "'Pick Points' member 'X' offset distance")
-
dlg1.group_title_end
-
dlg1.group_title("Single/Double, Side, Color, Grade")
-
dlg1.menu("no_pairs", ("Single", "Double"), no_pairs, "Single or Double Stiffeners ")
-
-
# more dialog box stuff
-
try:
-
dd1 = dlg1.done()
-
except ResponseNotOK:
-
break
-
for key, value in dd1.items():
-
exec "%s = %s" % (key, repr(value)) in None
-
........................................
-
# Do what needs to be done
-
........................................
-
Add_pls = yes_or_no("Add more full or partial depth stiffener plates to beams?")
-
if Add_pls == 0:
-
break
-
#### END run_script() xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-
if __name__ == '__main__':
-
try:
-
run_script()
-
finally:
-
del run_script
-
This new way seems to work well. It would be a nightmare to rework all my scripts to access values from dictionaries or from dialog box attributes. Is there a potential problem with updating the local dictionary this way or a better way to do it? I will appreciate any suggestions.
7 2252
Isn't python a sweet language?! It is THE tool for self-taught people to learn to write well-structured code. Looking out your code, I see a well thought-out implementation that suits your needs (and you say works well). That said, here are a couple of thoughts for you to consider:
1. Python gives access to all kinds of its inner working for us to use.
I have used the exec("a = 0") trick in a large application (gui and all) without any problems. In a simpler module, this is a very cool way to avoid dict[key] referencing.
I ran some tests and found that looping
exec "%s = %s" % (key, repr(value)) in None
is equivalent to
locals().update(dict).
The latter is probably faster, but I didn't do any profiling.
2. By creating a function (and associated name-space) that lasts for the lifetime of the module, you gain two things: eliminating all the built-in stuff that's in globals() when you actually LOOK (print) at the dictionary; it's psycological only. And python may be able to lookup your variable a little quicker due to scope rules (by which, the local name-space is searched first).
3. I may go and rework my stuff after thinking about this!
Thanks for the challenge. It looks to me like you are doing great work.
Have fun!
Barton
bvdet 2,851
Expert Mod 2GB
Thanks for the positive comments! My first choice was locals().update(dict) - of course it does not work because it is read only.
I would rather program than detail steel, but I make my living detailing. It is satisfying to write a script (fun) and use it in producing shop drawings (not so fun). The productivity increase can hit me in the wallet (fun).
Detailing steel in a 3D solids model has a lot of problems that can be solved with the script interface. Example - We can add 'construction circles' in the model by selecting a center point and a radius. A 'construction circle' is a temporary object (it does not become a permanent part of the model) which displays as a circle in the user's current plane. It is useful for determining exact 3D points on the circle. Adding a construction circle by selecting 3 points in 3D space was an interesting problem. We can also add 'construction lines' by selecting 2 points in 3D. Once you get the cons circle, we usually need cons lines laid out radially from the center point and along the arc to determine the exact points for laying out model objects. I developed a class to solve the geometry as follows: -
See my next post for the source code
-
I am not a geometry expert either, so this took a lot of time. Note the credit to Paul Bourke Geometry - Paul Bourke. Now THAT was fun!
bvdet 2,851
Expert Mod 2GB
Code for previous post: - """
-
/// Plane_Intersect3D.py - Given 3 non-collinear points, define three planes and calculate the radius and center point of
-
/// the circle connecting the points.
-
/// Determine if a point lies on Plane 1 (defined by initial 3 non-collinear points).
-
/// Rotate a point about an axis defined by p1 and p1 + N_uv.
-
/// Developed by Bruce Vaughan, BV Detailing & Design, Inc. (September 2006)
-
/// URL: www.bvdetailing.com
-
####
-
from math import pi, sqrt, acos, cos, sin
-
from point import Point
-
class Plane3D:
-
def plane_def(self, p1, p2, p3):
-
A = p1.y*(p2.z-p3.z) + p2.y*(p3.z-p1.z) + p3.y*(p1.z-p2.z)
-
B = p1.z*(p2.x-p3.x) + p2.z*(p3.x-p1.x) + p3.z*(p1.x-p2.x)
-
C = p1.x*(p2.y-p3.y) + p2.x*(p3.y-p1.y) + p3.x*(p1.y-p2.y)
-
D = -(p1.x*(p2.y*p3.z-p3.y*p2.z) + p2.x*(p3.y*p1.z-p1.y*p3.z) + p3.x*(p1.y*p2.z-p2.y*p1.z))
-
return A, B, C, D
-
-
def cross_product(self, p1, p2):
-
return Point(p1.y*p2.z - p1.z*p2.y, p1.z*p2.x - p1.x*p2.z, p1.x*p2.y - p1.y*p2.x)
-
-
def dot_product(self, p1, p2):
-
return (p1.x*p2.x + p1.y*p2.y + p1.z*p2.z)
-
-
def __init__(self, p1, p2, p3, theta1 = 0):
-
if type(p1) == type(Point(0,0,0)) and type(p2) == type(Point(0,0,0)) and type(p3) == type(Point(0,0,0)):
-
"""
-
/// Paul Bourke - 'Equation of a plane' (March 1989)
-
/// Define a plane from 3 non-collinear points
-
/// Ax + By + Cz + D = 0
-
/// The normal 'N' to the plane is the vector (A, B, C)
-
"""
-
A, B, C, self.D = self.plane_def(p1, p2, p3)
-
self.N = Point(A, B, C)
-
self.N_len = round(sqrt(A*A + B*B + C*C), 6)
-
if self.N_len > 0.0:
-
self.N_uv = Point(self.N.x/self.N_len, self.N.y/self.N_len, self.N.z/self.N_len)
-
else:
-
self.N_uv = Point(0.0, 0.0, 0.0)
-
# make p1 global to class namespace
-
self.p1 = p1
-
"""
-
/// Paul Bourke - 'Equation of a plane' (March 1989)
-
/// If vector N is the normal to the plane then all points 'p' on the plane satisfy the following:
-
/// N dot p = k where 'dot' is the dot product
-
/// N dot p = N.x*p.x + N.y*p.y + N.z*p.z
-
"""
-
self.k = round(self.dot_product(self.N, p1), 6) # calculation of plane constant 'k'
-
self.k0 = round(self.dot_product(self.N_uv, p1), 6) # displacement of the plane from the origin
-
"""
-
/// Determine vector e and unit vector e0 (p1 to p3)
-
/// Determine vector d and unit vector d0 (p1 to p2)
-
/// Determine location of point F, midpoint on vector d
-
/// Determine location of point G, midpoint on vector e
-
"""
-
e = p3 - p1
-
e_len = (sqrt(e.x**2 + e.y**2 + e.z**2))
-
if e_len > 0.0:
-
self.e0 = Point(e.x/e_len, e.y/e_len, e.z/e_len)
-
else:
-
self.e0 = Point(0.0, 0.0, 0.0)
-
d = p2 - p1
-
d_len = (sqrt(d.x**2 + d.y**2 + d.z**2))
-
if d_len > 0.0:
-
self.d0 = Point(d.x/d_len, d.y/d_len, d.z/d_len)
-
else:
-
self.d0 = Point(0.0, 0.0, 0.0)
-
self.F = Point(p1.x + (d.x/2), p1.y + (d.y/2), p1.z + (d.z/2))
-
self.G = Point(p1.x + (e.x/2), p1.y + (e.y/2), p1.z + (e.z/2))
-
# Make variables 'e' and 'd' available as attributes
-
self.e = e
-
self.d = d
-
-
# Calculate distance between points p1 and p2
-
self.Ra = p2.dist(p1)
-
-
"""
-
/// Calculate net angle between vectors d0 and e0 (Q)
-
/// Radius = self.Ra
-
/// Calculate point to point distance (pp)
-
"""
-
if abs(theta1) == pi:
-
self.Q = theta1
-
else:
-
self.Q = acos(self.dot_product(self.d0, self.e0)) # radians
-
self.pp = abs(self.Q * self.Ra)
-
-
else:
-
raise TypeError, 'The arguments passed to Plane3D must be a POINT'
-
-
# Calculate points to define plane #2 and calculate N2 and c2
-
def plane_2(self):
-
p1 = self.G
-
p2 = self.G + self.N_uv
-
p3 = self.G + self.cross_product(self.e0, self.N_uv)
-
A, B, C, D = self.plane_def(p1, p2, p3)
-
d = round(sqrt(A*A + B*B + C*C), 6)
-
self.N2 = Point(A/d, B/d, C/d)
-
self.c2 = round(self.N2.x*p1.x + self.N2.y*p1.y + self.N2.z*p1.z, 6)
-
-
# Calculate points to define plane #3 and calculate N3 and c3
-
def plane_3(self):
-
p1 = self.F
-
p2 = self.F + self.N_uv
-
p3 = self.F + self.cross_product(self.d0, self.N_uv)
-
A, B, C, D = self.plane_def(p1, p2, p3)
-
d = round(sqrt(A*A + B*B + C*C), 6)
-
self.N3 = Point(A/d, B/d, C/d)
-
self.c3 = round(self.N3.x*p1.x + self.N3.y*p1.y + self.N3.z*p1.z, 6)
-
-
def three_pt_circle (self):
-
"""
-
/// Paul Bourke - 'Intersection of three planes' (October 2001)
-
/// The intersection of three planes is either a point, a line, or there is no intersection.
-
/// Three planes can be written as:
-
/// N1 dot p = c1
-
/// N2 dot p = c2
-
/// N3 dot p = c3
-
/// 'Nx' is the normal vector
-
/// 'p' is a point on the plane
-
/// 'dot' signifies the dot product of 'Nx' and 'p'
-
/// 'cx' = plane constant (displacement of the plane from the origin if Nx is a unit vector)
-
/// The intersection point of the three planes "M" is given by:
-
/// M = (c1*(N2 cross N3) + c2(N3 cross N1) + c3*(N1 cross N2)) / (N1 dot (N2 cross N3))
-
/// 'cross' indicates the cross product and 'dot' indicates the dot product
-
/// Calculate the center point of the circle (intersection point of three planes) and the radius.
-
/// Plane 1 is defined by the three points initially passed to class object.
-
"""
-
# Define Plane 2
-
self.plane_2()
-
# Define Plane 3
-
self.plane_3()
-
-
N23 = self.cross_product(self.N2, self.N3)
-
N31 = self.cross_product(self.N3, self.N)
-
N12 = self.cross_product(self.N, self.N2)
-
NdN23 = round(self.dot_product(self.N, N23), 6)
-
-
numer = Point(self.k*N23.x, self.k*N23.y, self.k*N23.z) + (self.c2*N31.x, self.c2*N31.y, self.c2*N31.z) + \
-
(self.c3*N12.x, self.c3*N12.y, self.c3*N12.z)
-
if NdN23 != 0.0:
-
self.M = Point(numer.x/NdN23, numer.y/NdN23, numer.z/NdN23)
-
self.R = self.M.dist(self.p1)
-
else:
-
self.M = Point(0.0, 0.0, 0.0)
-
self.R = 0.0
-
-
"""
-
/// Credit Paul Bourke for 'Rotate A Point About An Arbitrary Axis (3D)' (August 2002)
-
/// Rotate point p about a line passing through self.p1 and normal to the current plane by the angle 'theta' in radians
-
/// Return the new point
-
"""
-
def PointRotate3D(self, p, theta):
-
q2 = Point(0.0,0.0,0.0)
-
-
# step 1 - translate space so that the rotation axis passes through the origin
-
q1 = p - self.p1
-
u = self.N_uv
-
d = sqrt(u.y*u.y + u.z*u.z)
-
-
# step 2 - rotate space about the x axis so that the rotation axis lies in the xz plane
-
if d != 0.0:
-
q2.x = q1.x
-
q2.y = q1.y*u.z/d - q1.z*u.y/d
-
q2.z = q1.y*u.y/d + q1.z*u.z/d
-
else:
-
q2 = q1
-
-
# step 3 - rotate space about the y axis so that the rotation axis lies along the positive z axis
-
q1.x = q2.x*d - q2.z*u.x
-
q1.y = q2.y
-
q1.z = q2.x*u.x + q2.z*d
-
-
# step 4 - rotate about the z axis
-
q2.x = q1.x*cos(theta) - q1.y*sin(theta)
-
q2.y = q1.x*sin(theta) + q1.y*cos(theta)
-
q2.z = q1.z
-
-
# inverse of step 3
-
q1.x = q2.x*d + q2.z*u.x
-
q1.y = q2.y
-
q1.z = -q2.x*u.x + q2.z*d
-
-
# inverse of step 2
-
if d != 0.0:
-
q2.x = q1.x
-
q2.y = q1.y*u.z/d + q1.z*u.y/d
-
q2.z = -q1.y*u.y/d + q1.z*u.z/d
-
else:
-
q2 = q1
-
-
# inverse of step 1
-
q1 = q2 + self.p1
-
-
# return rotated point
-
return q1
-
-
def lie_check(self, p4):
-
"""
-
/// Paul Bourke - 'Equation of a plane' (March 1989)
-
/// Given any point 'a' on a plane: N dot (a-p) = 0
-
"""
-
return round((self.N.x*(p4.x-self.p1.x) + self.N.y*(p4.y-self.p1.y) + self.N.z*(p4.z-self.p1.z)), 4)
-
-
def lie_check2(self, p5):
-
"""
-
/// Paul Bourke - 'Equation of a plane' (March 1989)
-
/// s = A*p5.x + B*p5.y + C*p5.z + D
-
/// If s > 0, point p5 lies on the same side as self.N
-
/// If s < 0, point p5 lies on the oppsite side from self.N
-
/// If s = 0, point p5 lies on the plane
-
"""
-
return round((self.N.x*p5.x + self.N.y*p5.y + self.N.z*p5.z + self.D), 4)
Thanks for the positive comments! My first choice was locals().update(dict) - of course it does not work because it is read only.
I don't understand the "read only" thing. In version 2.4 a module with the following code works. What version of python are you running? -
def test():
-
print "in test()"
-
locals().update({"a":0})
-
print locals()
-
print globals()
-
test()
-
print "module name-space"
-
print locals()
-
print globals()
-
bvdet 2,851
Expert Mod 2GB
I don't understand the "read only" thing. In version 2.4 a module with the following code works. What version of python are you running? -
def test():
-
print "in test()"
-
locals().update({"a":0})
-
print locals()
-
print globals()
-
test()
-
print "module name-space"
-
print locals()
-
print globals()
-
Version 2.3 is installed with each installation of SDS/2. Believe me, I tried and tried but locals().update(dd) would not work for my application. Try this: -
def test():
-
a = 10
-
print "in test()"
-
locals().update({"a":0})
-
print locals()
-
print globals()
-
test()
-
Does 'a' update to 10?
bvdet 2,851
Expert Mod 2GB
Sorry, I meant update from 10 to 0.
Sorry, I meant update from 10 to 0.
Nope, it doesn't update. I did find this, which I didn't expect. locals()Update and return a dictionary representing the current local symbol table. Warning: The contents of this dictionary should not be modified; changes may not affect the values of local variables used by the interpreter.
So exec() IS the legal way of changing this dict.
This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: David Hitillambeau |
last post by:
Hi guys,
As I am new to Python, i was wondering how to declare and use global
variables. Suppose i have the following structure in the same module (same
file):
def foo:
<instructions>...
|
by: John M |
last post by:
Hello,
On Microsoft Visual Studio .NET 2003,
I want to use some global elements,
that can be used in each one of my pages.
i.e I put a oleDBConnection on global.asax.vb
How can I use it...
|
by: Ankit Aneja |
last post by:
I put the code for url rewrite in my Application_BeginRequest on global.ascx
some .aspx pages are in root ,some in folder named admin and some in folder
named user
aspx pages which are in user...
|
by: m.epper |
last post by:
Hi to everybody.
First of all sorry for my english, I'm italian.
How can I execute a portion of code, in a function, into the global
scope?
Example:
<?php
|
by: Ed Jensen |
last post by:
I'm having a vexing problem with global variables in Python. Please
consider the following Python code:
#! /usr/bin/env python
def tiny():
bar =
for tmp in foo:
bar.append(tmp)
foo = bar
|
by: Florian Lindner |
last post by:
Hello,
I have a little problem with the global statement.
def executeSQL(sql, *args):
try:
import pdb; pdb.set_trace()
cursor = db.cursor() # db is <type 'NoneType'>.
except:
print...
|
by: weaknessforcats |
last post by:
C++: The Case Against Global Variables
Summary
This article explores the negative ramifications of using global variables. The use of global variables is such a problem that C++ architects have...
|
by: istillshine |
last post by:
When I control if I print messages, I usually use a global variable
"int silent". When I set "-silent" flag in my command line
parameters, I set silent = 1 in my main.c.
I have many functions...
|
by: raylopez99 |
last post by:
Why is the same variable local inside a 'foreach' loop yet 'global' in
scope (or to the class) outside it?
RL
class MyClass
{
int MyMemberArray1; //member variables, arrays, that are...
|
by: Naresh1 |
last post by:
What is WebLogic Admin Training?
WebLogic Admin Training is a specialized program designed to equip individuals with the skills and knowledge required to effectively administer and manage Oracle...
|
by: Arjunsri |
last post by:
I have a Redshift database that I need to use as an import data source. I have configured the DSN connection using the server, port, database, and credentials and received a successful connection...
|
by: Matthew3360 |
last post by:
Hi,
I have been trying to connect to a local host using php curl. But I am finding it hard to do this. I am doing the curl get request from my web server and have made sure to enable curl. I get a...
|
by: Oralloy |
last post by:
Hello Folks,
I am trying to hook up a CPU which I designed using SystemC to I/O pins on an FPGA.
My problem (spelled failure) is with the synthesis of my design into a bitstream, not the C++...
|
by: Carina712 |
last post by:
Setting background colors for Excel documents can help to improve the visual appeal of the document and make it easier to read and understand. Background colors can be used to highlight important...
|
by: Rahul1995seven |
last post by:
Introduction:
In the realm of programming languages, Python has emerged as a powerhouse. With its simplicity, versatility, and robustness, Python has gained popularity among beginners and experts...
|
by: Ricardo de Mila |
last post by:
Dear people, good afternoon...
I have a form in msAccess with lots of controls and a specific routine must be triggered if the mouse_down event happens in any control.
Than I need to discover what...
|
by: Johno34 |
last post by:
I have this click event on my form. It speaks to a Datasheet Subform
Private Sub Command260_Click()
Dim r As DAO.Recordset
Set r = Form_frmABCD.Form.RecordsetClone
r.MoveFirst
Do
If...
|
by: jack2019x |
last post by:
hello, Is there code or static lib for hook swapchain present?
I wanna hook dxgi swapchain present for dx11 and dx9.
| |