Organizing a large python script - python

I've been working on a general utility script for a while now that basically just accepts user input to preform some task like opening a program. In this program, I define a name "command" as a raw_input and then use if statements to check the list for a command (small example below).
Constantly using if statements is making the program run slowly and so I'm wondering if there is a better way such as maybe a table of commands? I'm pretty new to programming so not sure how to accomplish this.
import os
command = raw_input('What would you like to open:')
if 'skype' in command:
os.chdir('C:\Program Files (x86)\Skype\Phone')
os.startfile('Skype.exe')

You can keep the commands in a dictionary with a tuple, and do something like this to store the commands.
command = {}
command['skype'] = 'C:\Program Files (x86)\Skype\Phone', 'Skype.exe'
command['explorer'] = 'C:\Windows\', 'Explorer.exe'
You could then do the following to execute the correct command based on the user input.
if raw_input.lower().strip() in command: # Check to see if input is defined in the dictionary.
os.chdir(command[raw_input][0]) # Gets Tuple item 0 (e.g. C:\Program Files.....)
os.startfile(command[myIraw_inputput][1]) # Gets Tuple item 1 (e.g. Skype.exe)
You can find more information on Dictionaries and Tuples here.
In case you need to allow multiple commands, you can separate them by a space and split the commands into an array.
for input in raw_input.split():
if input.lower().strip() in command: # Check to see if input is defined in the dictionary.
os.chdir(command[input][0]) # Gets Tuple item 0 (e.g. C:\Program Files.....)
os.startfile(command[input][4]) # Gets Tuple item 1 (e.g. Skype.exe)
This would allow you to issue commands like skype explorer, but keep in mind that there are no room for typos, so they need to be an exact match, separated with nothing but white-spaces. As an example you could write explorer, but not explorer!.

Related

How to pass an input text value to build stage (Windows command prompt) in jenkins when there are multiple input texts (Jenkins-groovy script)

I want to pass my input text boxes value to the build stage. I'm using the windows execute command prompt as the build setup. I have an Active choice parameter containing options as values and a Active Choices Reactive Reference Parameter which includes a groovy script to be executed when the option is selected from the Active choice Parameter.
In Active Choices Reactive Reference Parameter the groovy script contains an switch statement which will render multiple input text boxes as the output when an option is selected. I want to know how to get the values of each input text box separately maybe as an parameter to echo them out.
Such as in the build stage cmd,
echo %{Input1 text box value}% %{Input 2 text box value}%
Help me out! I have attached an image of the above case for your reference. Thank you :)
Here is the image of the script, click on this to view the image
Following the guidelines of the documentation for generating the HTML, you can run something like this in the groovy script:
return """
<input name=\"value\" value=\"${ReactiveRefParam}\" class=\"setting-input\" type=\"text\">
<input name=\"value\" value=\"${ReactiveRefParam1}\" class=\"setting-input\" type=\"text\">
"""
Once the name attribute of the inputs is the same - value,
the Reactive Reference Parameter will hold the values of all inputs in the following format: first_input_value, second_input_value ....
You can then just use the parameter value to extract each input value by splitting it by , or any other way.
here is an example for the Active Choice Parameter config.
The second one is exactly the same with different values
here is an example for the Reactive Reference Parameter config
and here is the example for the Build With Parameters outcome page

Maya Python, Renaming joints: more than one object matches name

Ok, so I get two errors whenever I try to run this script: but before I get ahead of myself: lets get to my objective.
create two joint chains, names are unimportant: but essentially I know that you can use brackets to list and isolate joint chains with matching children names. Instead my script seems to be ignoring the brackets and giving me the error anyways. I've tried every different flag for list relatives: but all that seems to do is change the error to something else.
I know that if this script was properly working it would only work on one joint chain because of the hardcoded names: but the script I'm pulling it from has name prefexes tied to the GUI to avoid hardcoding and allow adaptive naming: I'm only using the hardcoded as an example for this script. My complaint is this script doesn't work on ANY joint chain because I keep getting the error "more than one object matches name."
To run the script,save the following code as a .py in your maya documents script folder, restart your copy of maya, then open a new python tab and run the first three lines of code above import maya.cmds
'''
import exampleScriptTemplate
reload (exampleScriptTemplate)
exampleScriptTemplate.gui()
'''
import maya.cmds as cmds
if cmds.window("buildWin", exists =True):
cmds.deleteUI("buildWin", window = True)
myWindow = cmds.window("buildWin",t='DS_pvFinder',rtf=1,w=100, h=100, toolbox=True)
column = cmds.columnLayout(adj=True)
def gui(*args):
cmds.columnLayout()
cmds.button(w=300,label='build placement curve',c=printMultiple)
cmds.showWindow(myWindow)
def printMultiple(*args):
root = cmds.ls(sl=True)[0]
child = cmds.listRelatives(root,ad=1,f=True,children=True,type='joint')
child.append(root)
child.reverse()
limbJnt = child
print (child)
armroot = []
for j in limbJnt:
wstJnt = cmds.rename(child[3], 'wrist_BIND')
elbJnt = cmds.rename(child[2], 'elbow_BIND')
sdrJnt = cmds.rename(child[1], 'shoulder_BIND')
clvJnt = cmds.rename(child[0], 'clavicle_BIND')
armroot.append(j)
return armroot
I know I'm in the right ballpark. I just need to know how to properly use the brackets to store the list of what i'm selecting instead of searching all of worldspace and breaking.
Thank you for your help
The code you provided is incomplete, no window is opening, so I tried only the printMultiple function which causes a Error: No object matches name in my case.
Your code cannot work like this since you mix hardcoded names with a loop which does nothing. I suppose your main problem is the order of your renamings. The child array contains absolute names like:
[u'joint1', u'|joint1|joint2', u'|joint1|joint2|joint3']
If you now rename child[0] to 'clavicle_BIND', all the remaining elements in the list become invalid because their real names in the scene now look like this:
[u'clavicle_BIND', u'|clavicle_BIND|joint2', u'|clavicle_BIND|joint2|joint3']
What results in an error at the second rename line. Inverting the order sovles this problem, first rename the leaf node, then the ones above.

Python-How to execute code and store into variable?

So I have been struggling with this issue for what seems like forever now (I'm pretty new to Python). I am using Python 3.7 (need it to be 3.7 due to variations in the versions of packages I am using for the project) to develop an AI chatbot system that can converse with you based on your text input. The program reads the contents of a series of .yml files when it starts. In one of the .yml files I am developing a syntax for when the first 5 characters match a ^###^ pattern, it will instead execute the code and return the result of that execution rather than just output text back to the user. For example:
Normal Conversation:
- - What is AI?
- Artificial Intelligence is the branch of engineering and science devoted to constructing machines that think.
Service/Code-based conversation:
- - Say hello to me
- ^###^print("HELLO")
The idea is that when you ask it to say hello to you, the ^##^print("HELLO") string will be retrieved from the .yml file, the first 5 characters of the response will be removed, the response will be sent to a separate function in the python code where it will run the code and store the result into a variable which will be returned from the function into a variable that will give the nice, clean result of HELLO to the user. I realize that this may be a bit hard to follow, but I will straighten up my code and condense everything once I have this whole error resolved. As a side note: Oracle is just what I am calling the project. I'm not trying to weave Java into this whole mess.
THE PROBLEM is that it does not store the result of the code being run/executed/evaluated into the variable like it should.
My code:
def executecode(input):
print("The code to be executed is: ",input)
#note: the input may occasionally have single quotes and/or double quotes in the input string
result = eval("{}".format(input))
print ("The result of the code eval: ", result)
test = eval("2+2")
test
print(test)
return result
#app.route("/get")
def get_bot_response():
userText = request.args.get('msg')
print("Oracle INTERPRETED input: ", userText)
ChatbotResponse = str(english_bot.get_response(userText))
print("CHATBOT RESPONSE VARIABLE: ", ChatbotResponse)
#The interpreted string was a request due to the ^###^ pattern in front of the response in the custom .yml file
if ChatbotResponse[:5] == '^###^':
print("---SERVICE REQUEST---")
print(executecode(ChatbotResponse[5:]))
interpreter_response = executecode(ChatbotResponse[5:])
print("Oracle RESPONDED with: ", interpreter_response)
else:
print("Oracle RESPONDED with: ", ChatbotResponse)
return ChatbotResponse
When I run this code, this is the output:
Oracle INTERPRETED input: How much RAM do you have?
CHATBOT RESPONSE VARIABLE: ^###^print("HELLO")
---SERVICE REQUEST---
The code to be executed is: print("HELLO")
HELLO
The result of the code eval: None
4
None
The code to be executed is: print("HELLO")
HELLO
The result of the code eval: None
4
Oracle RESPONDED with: None
Output on the website interface
Essentially, need it to say HELLO for the "The result of the code eval:" output. This should get it to where the chatbot responds with HELLO in the web interface, which is the end goal here. It seems as if it IS executing the code due to the HELLO's after the "The code to be executed is:" output text. It's just not storing it into a variable like I need it to.
I have tried eval, exec, ast.literal_eval(), converting the input to string with str(), changing up the single and double quotes, putting \ before pairs of quotes, and a few other things. Whenever I get it to where the program interprets "print("HELLO")" when it executes the code, it complains about the syntax. Also, from several days of looking online I have figured out that exec and eval aren't generally favored due to a bunch of issues, however I genuinely do not care about that at the moment because I am trying to make something that works before I make something that is good and works. I have a feeling the problem is something small and stupid like it always is, but I have no idea what it could be. :(
I used these 2 resources as the foundation for the whole chatbot project:
Text Guide
Youtube Guide
Also, I am sorry for the rather lengthy and descriptive question. It's rare that I have to ask a question of my own on stackoverflow because if I have a question, it usually already has a good answer. It feels like I've tried everything at this point. If you have a better suggestion of how to do this whole system or you think I should try approaching this another way, I'm open to ideas.
Thank you for any/all help. It is very much appreciated! :)
The issue is that python's print() doesn't have a return value, meaning it will always return None. eval simply evaluates some expression, and returns back the return value from that expression. Since print() returns None, an eval of some print statement will also return None.
>>> from_print = print('Hello')
Hello
>>> from_eval = eval("print('Hello')")
Hello
>>> from_print is from_eval is None
True
What you need is a io stream manager! Here is a possible solution that captures any io output and returns that if the expression evaluates to None.
from contextlib import redirect_stout, redirect_stderr
from io import StringIO
# NOTE: I use the arg name `code` since `input` is a python builtin
def executecodehelper(code):
# Capture all potential output from the code
stdout_io = StringIO()
stderr_io = StringIO()
with redirect_stdout(stdout_io), redirect_stderr(stderr_io):
# If `code` is already a string, this should work just fine without the need for formatting.
result = eval(code)
return result, stdout_io.getvalue(), stderr_io.getvalue()
def executecode(code):
result, std_out, std_err = executecodehelper(code)
if result is None:
# This code didn't return anything. Maybe it printed something?
if std_out:
return std_out.rstrip() # Deal with trailing whitespace
elif std_err:
return std_err.rstrip()
else:
# Nothing was printed AND the return value is None!
return None
else:
return result
As a final note, this approach is heavily linked to eval since eval can only evaluate a single statement. If you want to extend your bot to multiple line statements, you will need to use exec, which changes the logic. Here's a great resource detailing the differences between eval and exec: What's the difference between eval, exec, and compile?
It is easy just convert try to create a new list and add the the updated values of that variable to it, for example:
if you've a variable name myVar store the values or even the questions no matter.
1- First declare a new list in your code as below:
myList = []
2- If you've need to answer or display the value through myVar then you can do like below:
myList.append(myVar)
and this if you have like a generator for the values instead if you need the opposite which means the values are already stored then you will just update the second step to be like the following:
myList[0]='The first answer of the first question'
myList[1]='The second answer of the second question'
ans here all the values will be stored in your list and you can also do this in other way, for example using loops is will be much better if you have multiple values or answers.

Python loop error in SPSS syntax only if i run the same code twice

I'm quite new in python programming.
I'm trying to automate some tabulations in SPSS using python (and i kind of managed it...) using a loop and some python code, but it works fine only the first time i run the syntax, the second time it tabulates only once:
I have an SPSS file with different projects merged together (i.e. different countries) , so first i try to extract a list of projects using a built in function.
Once i have my list of project i run a loop and i change the spss syntax for the case selection and tabulation.
this is the code:
begin program.
import spss
#Function that extracts the data from spss
def DatiDaSPSS(vars, num):
if num == 0:
num = spss.GetCaseCount()
if vars == None:
varNums = range(spss.GetVariableCount())
else:
allvars = [spss.GetVariableName(i) for i in range(spss.GetVariableCount())]
varNums = [allvars.index(i) for i in vars]
data = spss.Cursor(varNums)
pydata = data.fetchmany(num)
data.close()
return pydata
#store the result of the function into a list:
all_prj=DatiDaSPSS(vars=["Project"],num=0)
#remove duplicates and keep only the country that i need:
prj_list=list(set([i[0] for i in all_prj]))
#loop for the tabulation:
for i in range(len(prj_list)):
prj_now=str(prj_list[i])
spss.Submit("""
compute filter_$=Project='%s'.
filter by filter_$.
exe.
TEXT "Country"
/OUTLINE HEADING="%s" TITLE="Country".
CTABLES
/VLABELS VARIABLES=HisInterviewer HisResult DISPLAY=DEFAULT
/TABLE HisInterviewer [C][COUNT F40.0, ROWPCT.COUNT PCT40.1] BY HisResult [C]
/CATEGORIES VARIABLES=HisInterviewer HisResult ORDER=A KEY=VALUE EMPTY=EXCLUDE TOTAL=YES
POSITION=AFTER
/CRITERIA CILEVEL=95.
""" %(prj_now,prj_now))
end program.
When i run it the second time it shows only the last value of the list (and only one tabulation). If i restart SPSS it works fine the first time.
Is it because of the function?
i'm using spss25
can I reply myself, should i edit the discussion or maybe delete it? i think i found out the reason, i guess the function picks up only the values that are already selected, i tried now adding this SPSS code before the begin and it seems to be working:
use all.
exe.
begin program.
...
at the last loop there is a filter on the data and i removed it before of running the script. please let me know if you want me to edit or remove the message

Strip prefix from all variable names in SPSS

I have a similar question as asked here (Strip suffix from all variable names in SPSS) and the answers there already helped a lot but there is still one question remaining.
I have a dataset in which every variable name has the prefix "v23_1_". I want to remove this prefix from all variables, but there are hundreds of them, so I am looking for a way to do it without using the RENAME statement hundreds of times.
I used this code:
begin program.
vdict=spssaux.VariableDict()
mylist=vdict.range(start="v23_1_dg_mnpdocid", end="v23_1_phq9t0_asku3t0")
nvars = len(mylist)
for i in range(nvars):
myvar = mylist[i]
mynewvar = myvar.strip("v23_1_")
spss.Submit(r"""
rename variables ( %s = %s) .
""" %(myvar, mynewvar))
end program.
Here is a list of the first few variables:
v23_1_dg_mnppusid
v23_1_dg_sigstatus
v23_1_dg_mnpvsno
v23_1_dg_mnpvslbl
v23_1_dg_mnpcvpid
v23_1_dg_mnpvisid
v23_1_dg_mnpvisno
v23_1_dg_mnpvispdt
v23_1_dg_mnpvisfdt
v23_1_dg_mnpfs0
v23_1_dg_mnpfs1
v23_1_dg_mnpfs2
v23_1_dg_mnpfs3
v23_1_dg_mnpfcs0
v23_1_dg_mnpfcs1
v23_1_dg_mnpfcs2
It worked ok for the first variables but then stopped with the message "renaming has created two variables named dg_mnpfs". But the next variable would after stripping has the name "dg_mnpfs2". What has happened is that the 1 at the end in "v23_1_dg_mnpfs1" gets deleted too. And then it propbably intends to also delete the 2 at the end in "v23_1_dg_mnpfs2", which will then lead to the same variable. I don't understand why this is happening and how I can avoid it.
Thanks a lot for your support!
Kind regards,
Beate
As you syntax looks right now, it will run on a variable-by-variable basis. You are submitting/running the RENAME VARIABLES command as many times as the number of variables in your list.
On one hand, this is in-efficient, as it takes longer to run than what I am suggesting below.
On the other (and more important) hand, doing it variable by variable, does not guard against duplicate variables. I am guessing that you already have in your datafile a variable named dg_mnpfs, and you are attempting to create a new one by renaming v23_1_dg_mnpfs. Just check your datafile, after your python code breaks.
A more efficient way of writing you code would be to create lists with the old names, and new names, and submit the syntax with only one command.
begin program.
import spss,spssaux
vdict=spssaux.VariableDict()
mylist=vdict.range(start="v23_1_dg_mnpdocid", end="v23_1_phq9t0_asku3t0")
nvars = len(mylist)
my_new_list=[]
for i in range(nvars):
myvar = mylist[i]
mynewvar = myvar.strip("v23_1_")
my_new_list.append(mynewvar)
my_syntax="ren var (" + " ".join(mylist) + "=" + " ".join(my_new_list) +")."
spss.Submit(my_syntax)
end program.
And one more thing: the strip function removes the text from both ends of the variables. If you only want to remove the prefix, consider using lstrip. Details can be found here, in the official documentation.
Here's a version of the process using SPSS macro. Using SPSSINC SELECT VARIABLES lets you get the whole list of all relevant variables, whatever order they are in, without naming them in the command:
*this is just to create a sample data to play with.
data list list/v23_1_var1 to v23_1_var6.
begin data
end data.
The following creates a list of the relevant variables:
SPSSINC SELECT VARIABLES MACRONAME="!list" /PROPERTIES PATTERN = "v23_1_*".
* the following macro creates one rename command for all the list.
define !doRename ()
rename variables (!eval(!list)=!do !i !in(!eval(!list)) !substr(!i, 7) !doend).
!enddefine.
!doRename .

Categories

Resources