non-interactive Python command history - python

I know the python interpreter and ipython have a easy way to browse through the history of commands. That is in interactive Python programming.
My problem/question:
I have a GUI-based Python tool that allows me to click and enter values in fields before hitting the "PLOT" button and I get a plot on screen. What I am looking for is a way to access a "minimimum script" that exactly reproduces the plot.
So I was wondering if there was a way to request a backlog of all the commands an uninteractive Python instance went through.
If it is not built-in, could someone advise a way to automatically dump function calls in a file at the same time as they are run.

The simplest way to do that would be to Pickle your plot object. Then you can just reload the pickle file and the object will be in memory just as it was when dumped.
It should only take a couple of lines to implement a dump and reload feature in your program.
This of course doesn't give you a list of commands or anything like that to regenerate the figure, but it does give you the exact state of the object.
If you are using matplotlib to do the plotting, then the image itself is not picklable. But you could create a class that contains all the information you entered that is passed to the matplotlib routines and pickle that, again saving the state.

Related

How can I initialise an object to be used in multiple calls Python from the command-line

I have a script I've written that uses a very large object. I load the object with pickle, but it takes quite a few seconds to do so. That's not a big deal if it has to happen once or twice, but I'm hoping to use the code many hundreds or thousands of times!
I think my issue is that I'd like to almost 'leave' the object alive and then be able to call it from command line whenever I need it. I'm reasonably new to Python so I'm not sure how possible that is; sorry if I haven't used the right terminology in my question. I'm writing and running my python in Spyder at the moment, but eventually I'd like to run it on a server, calling the code as and when required.
If your script is looping over the python program, move the loop inside the program.
If on the other hand, you want to be able to use the large object on demand, you probably need a client/server configuration. Thriftpy is a very simple way to achieve this. The thriftpy server will hold the object and the processing logic, and the client will be a command line script that will call the server and pass whatever parameters you need to process the object.

How to suppress "Setting display..." in Abaqus scripting

I have many abaqus plugins that perform actions in Abaqus CAE through a scripting interface. For many actions after they are executed Abaqus performs some display refresh procedures that take some time. If the models are small and the script does not do too much it is alright. However, e.g. one of my scripts takes a part and replicates it in the assembly at the coordinates specified by user's CSV file. Sometimes there might be up to 2000 such replications. In this case it takes forever to complete the procedure and most of the time you only see "Setting display..."
Furthermore this "Setting display..." overwrites your scripts' progress (milestone) so it is difficult to see how far the script had advanced.
Is there any way to suspend this display updating behavior until the script finishes? Maybe there is a hack that you could redefine abaqus update function until the script is done or something because according to the manual the only thing you can do is to prevent the updating of the color scheme, but that does not help at all.
Any tips will be appreciated, thanks!
EDIT: To clarify I used folowing methods on a viewport object with no vain:
disableRefresh()
disableColorCodeUpdates()
What does the disableColorCodeUpdates() do is quite clear and the benefit is apparent when color coding is used in the model viewport. However, I see no difference between using and not using disableRefresh().
EDIT: Sorry for such a long wait, only now I had a chance to get back at abaqus. Here is a simple example script that takes a part and places it in assembly:
import random
modelName='Model-1'
partName='Part-1'
noInst=1000
i = 0
lists = []
for i in range(noInst):
lists.append([random.random()*10,random.random()*10,random.random()*10])
totalParts = len(lists)
session.Viewport(name='Viewport: 2', origin=(6.63750028610229,
20.7638893127441), width=335.746887207031, height=149.77685546875)
session.viewports['Viewport: 2'].makeCurrent()
session.viewports['Viewport: 2'].maximize()
session.viewports['Viewport: 1'].restore()
for n,l in enumerate(lists):
milestone('Replicating parts', 'parts', n+1, totalParts)
a = mdb.models[modelName].rootAssembly
p = mdb.models[modelName].parts[partName]
a.Instance(name='Random_'+'-'+str(n), part=p, dependent=ON)
a = mdb.models[modelName].rootAssembly
a.translate(instanceList=('Random_'+'-'+str(n), ), vector=(float(l[0]), float(l[1]), float(l[2])))
If I try to create viewport object without specifying displayed object. Viewport defaults to current displayed object in initial Viewport. I noticed if I change a module from amssembly to any other e.g. Part, I gain speed improvement, but it relies that the part is sufficiently empty. If I have model with parts that are large and complex it is still rather slow on "setting display.." also my milestone is overwritten by "setting display.." by any case.
I think I've seen this before in a similar situation, where I was creating elements one-by-one in a GUI CAE session. I could not figure out how to disable the screen refresh, and it was maddeningly slow. There were two workarounds:
1. Use an alternative command, if one exists, that creates many items at once. In my example above, instead of creating each new element one at a time using the Element method, I was able to generate an entire Part and the mesh at once with makePartFromNodesAndElements which was significantly faster. In your case, it might be possible to do something similar.
2. If you do not need an active GUI, run the script from the system shell: abaqus cae noGui=script.py. You can even pass arguments to the script from the command line interface.
Another (untested) possibility I just thought of is that you may be able to create and switch to a new viewport without specifying the displayed object. Then try your code and see if that speeds things up.

how to have one file work on objects generated by another in spyder

I'm sure someone has come across this before, but it was hard thinking of how to search for it.
Suppose I have a file generate_data.py and another plot_utils.py which contains a function for plotting this data.
Of note, generate_data.py takes a long time to run and I would like to only have to run it once. However, I haven't finished working out the kinks in plot_utils.py, so I have to run this a bunch of times.
It seems in spyder that when I run generate_data (be it in the current console or in a new dedicated python interpreter) that it doesn't allow me to modify plot_utils.py and call "from plot_utils import plotter" in the command line. -- I mean it doesn't have an error, but it's clear the changes haven't been made.
I guess I kind of want cell mode between different .py files.
EDIT: After being forced to formulate exactly what I want, I think I got around this by putting "from plot_utils import plotter" \n "plotter(foo)" inside a cell in generate_data.py. I am now wondering if there is a more elegant solution.
SECOND EDIT: actually the method mentioned above in the edit does not work as I said it did. Still looking for a method.
You need to reload it:
# Python 2.7
plotter = reload(plotter)
or
# Python 3.x
from imp import reload
plotter = reload(plotter)

save figure to .pdf after displaying in python notebook

A similar question was asked here and here on Stack, but I'm not satisfied as it still did not resolve my issue.
Consider I have a function which does some calculations and displays a figure (without returning a figure object). Out of personal preference (and to keep track of what my plots looked like without saving each) I use %matplotlib inline in IPython. Now after I generated some plots I decide to save one of them (say the second out of 3 displayed in the notebook), which works fine by right clicking and choosing 'Save as...', but only as .png.
Is there a way to save it as .pdf without modifying the function to return a figure object? (I know it is not difficult at all, but for most of my cases it is just unnecessary since it is 1 out of, say, 20 figures worth saving in the end).
I figured out that the backend is being changed after %matplotlib inline which is (I guess) the reason why I can not save figures as .pdf. The workaround seems to be using %config InlineBackend.close_figures = False and using plt.savefig(...)(answer from here). But this way I could save only the last figure and have to close the figures manually each time.
If my problem arises from bad program workflow / programming style, I will happily accept suggestions on how to do it better. If a code example is needed, I can provide one.
I use:
ipython (2.1.0)
matplotlib (1.4.1) (with Qt4Agg backend if not inline)
Python 2.7.6
MacOSX 10.9.4
Reposting as an answer:
You can't save the PDF directly from your browser, because the browser and JS code doesn't know that the PNG image it displays is associated with a particular matplotlib figure - indeed, it doesn't know about matplotlib at all. All that is handled by the Python kernel process running your code.
However, you can configure IPython to display figures in SVG format, as described in the docs. It also appears to have a PDF option, though I forget what that does.

Save Python variables with Maya scene

How can I save Python variables in a Maya scene?
For example I create a variable x in Maya's Script Editor and I save the scene. When I reopen Maya and reopen the saved scene, x variable doesn't exist anymore.
Is it possible?
Yes, use a script node, use a optionVar or store the variable in a attribute.
In general
Scene persistence is supposed to be built with nodes. In fact everything in Maya is supposed to be a node or built out of a node tree. The bonus is if you make your computation a node then maya will automatically handle all the stuff for you. This is how render engines for example store the data. They register a special node and read the data from the node.
Needing to ask this question, "How can I save Python variables in a Maya scene?", is a indication that you indeed should have built a nodal solution. There are a few exceptions to this and those are related to general user GUI preferences that should be saved as optionVars.
Maya does not actually enforce that you do things sanely. You are free to do whatever you want, sane or not. So it is possible, tough a bit fishy, to use a scene save scriptjob to store the snapshot of your environment to a script node that auto runs on load. This is undesirable in the same way as using global variables is undesirable for code in general. It is also slightly unreliable, as a user can disable auto running of on load scriptNodes, for good reason.
About nodal solutions
Maya as a rule does not work the way most people intuitively expect at first glance. Just like the text you write in code is not what your computer generally executes, but rather the compiled code is what gets executed. The compiler has a bit of leeway on what i can do in this context and usually throws away some stuff. So in code its not really sane to think in terms of what the text looks like in code but rather what structures it builds.
In Maya the structures you should be building are nodes. There are two extra use cases outside this and those are:
Exporters (Importers but due to their nature they are node bound because they target Maya)
Graphical user interfaces that introspect Mayas current state or bring external info to the user
These two could only specialize in reading nodes. Mayas object auxiliary function nature can quite efficiently hide the fact from the user but this is essentially want your doing. Anything outside this scope does not benefit form using Maya. So whenever you use maya you want to capitalize on nodes. Think of it as if you are using a second language on top of your own programming language. This one is the actual language of Maya.
Let us start with a naive approach for randomizing point positions for a mesh (note i avoid the term object as Maya has no such concept):
import maya.cmds as cmds
import random
def randomize_points(scale):
sel = cmds.polyListComponentConversion(ff=1, fe=1, fuv=1, fvf=1, tv=1)
sel = cmds.ls(sel ,fl=1)
for item in sel:
cmds.move((random.random()-0.5)*scale,
(random.random()-0.5)*scale,
(random.random()-0.5)*scale,
item, r=1)
It works, but has three deficiencies:
You can not know what it looks like until you run it.
You can undo tough so test and undo. Maybe youd need a seed variable for the random too?
You need to build a GUI for this so the user can work it.
There's is no way to specify the profile of the randomness.
(This one is here so it easy for you to run the code i could use one of many pythons noise implementations. I will fix this nonetheless.)
The code is straightforward in sense id does what a user would do in the GUI. But what really happens? Where do the changes go? Simply put the answer is 2 fold they go either to the tweak array (most likely), or the objects position array. But there is a better way i can use Maya primitives to manipulate a similar behavior. Enter nodes.
First you need to go a bit node shopping, what nodes could actually provide a noise functionality? The thing is there does not seem to be many contenders here. There is despite this one node that's basically roll your own deformation and that is the particle node. So this is how you'd attack the problem with a particle node, some noise and a few attributes:
... to be continued ...
Here is the simple example to saving a python variable inside maya file.
lets Save Variable X in Maya file and the value of X is 100.
and we dont want see this error:
# Error: NameError: name 'x' is not defined #
To Save Variable in Maya file Execute this code before you save your Maya file.
import maya.cmds as cmds
var_node = cmds.scriptNode(scriptType=1, name='CustomVariable', beforeScript='python("x = 100")')
cmds.scriptNode( var_node, executeBefore=True )
open file again and execute:
print x

Categories

Resources