(python) Let a string be recognised as a already defined variable - python

x= 1
a_1_add = "message 1"
a_2_add = "message 2"
while x<3:
y = "a_" + x + "_add"
print(y)
x += 1
How do I get python to get make it print "message 1', "message 2" instead of "a_1_add"?
I want to specifically make the string in y to be recognised as a variable. How to I do that?
I want to have a code that automatically change from the variable "a_1_add" to "a_2_add" and so on but don't want to manually write it out since the difference is only the number in the middle.
Edit: I know of "for loop" (a thank you to those that suggested it) but for my code (not so simple as the example I wrote out) I really need to use the while loop.
Thanks in advance. I am a beginner in python. Really appreciate your help.

Since you're beginner, I would assume, you should look toward something like this instead:
a_1_add = "message 1"
a_2_add = "message 2"
container = [a_1_add, a_2_add]
for element in container:
print(element)
Note, you can still access the contents of both variables a_1_add and a_2_add, change them, add more variables to the container and so on.

Maybe you can use the for loop to loop through all the variables.
var1 = “message 1”
var2 = “message 2”
var3 = “message 3”
for i in [var1, var2, var3]:
print(i)
Edit:
Yes, as #juanpa.arrivillage suggested , string list dictionary etc. are all data types (built in) in Python. Variables are user-defined, just a name representing the value assigned to it.
I think I get what you mean: like create variables using whilè loop? If so, I m afraid that it is not possible. Maybe you can use an array to contain those all values instead ? and access them using index or slicing.
x = 1
all_val = [] # this is a list here
while x < 3:
all_val.append(f"a_{x}_add")
x += 1
print(all_val[0])
print(all_val[1])
print(all_val[1:])
Hope it can answer you question.

Related

Can I make python read a string as a parameter?

I would like to make this code somehow work, in this example i used the int() function which obviously gave me the "invalid literal for int() with base 10" error. But is there any way to make python not read the "" around the string and just read "i" in this case as a parameter.
I hope you understand what I mean.
s=0
w=""
for k in range(3):
w+="i"
for i in range(5):
s+=int(w)
I don´t know whats your expected result. Your main problems seems the quotes for w = "" and w+="i" if you want to add numbers instead of textstrings.
Maybe you also mixed up your k and i variable.
Is this your expected result(?):
s = 0
w = 0
for k in range(3):
w += k
for i in range(5):
s += w
print(s)
print(w)
In your current version of code, when you say int(w) you are trying to convert 'iii' into a base 10 number which runs the error. Also, using i as a variable will only work within the for loop 'for i in range(5):'. That is where the variable i has its lifespan.

Print variable by input

How to print variable name by input, Example:
a = 1
b = 2
what_variable = input('Which Variable?: ') #User for example introduces 'b'
Console: 2
You can write
print(globals()[what_variable])
but it's not a good approach. Use a dict instead
You can use exec:
var = input('Which Variable?: ')
exec("print(" + var + ")")
Output:
Which Variable?: b
2
>>
Just do the following:
print(eval(input('Which Variable?: ')))
You can also do
print(globals()[input('Which Variable?: ')])
While the other answers seem to address the obvious solution, it's not very 'Pythonic'. The main issues with these is, by far, safety. Let's say that your user inputs apiKey, and you happen to have a variable by that name... let's just say your bank statement is probably looking at a slight increase in magnitude. What most people in these answers don't realise is that using .globals()[input()] is no safer than eval(input()), because, shockingly, people store private info in variables. Alternatively, if it points to a method, e.g
a = print
b = os.system
eval(input())()
I could enter any function name there, and the damage would be done before the second () executes.
Why? Well, let's take a look at how exec and eval work (I won't go into the difference here, see this question for that). All they do is evaluate the string as Python code, and (simplifying here) return the value of the evaluation:
var1 = 3
print(eval("var1"))
# ====is equal to====
var1 = 3
print(var1)
(where var1 as a string obviously comes from the input typed in)
But if someone enters something malicious, this is essentially the basis of an SQL injection:
(where userInput is substituted by a user's input into an input())
userInput = "a + os.system('reboot now')"
print(eval(userInput))
# ====is equal to====
print(a + os.system('shutdown now')
and you suddenly find your computer's off.
Therefore, we'd either use a:
Dictionary (or object): x={a:1, b:2}, then do x[input()]
Array x=[1, 2], then do x[["a", "b"].index(input())]
Simply don't. Find a way to work around it. What's wrong with an if/else set? It's not good practise, because of the safety concerns outlined above. What most people seem to miss about dictionaries (or my array option) is that if you enter a malformed input (i.e not a or b), it would result in either uncaught errors being thrown, or undefineds being thrown around. And if you're going to do input validation, you're using an if statement anyway, so why not do it from the onset?

The find methon in python not giving a correct index

Hi guys check out this code.
code_tip = "code a conditional decision like you would say it"
location = work_tip.find("i")
print(location)
print (code_tip[location])
well I expect the find object to return the index of "i" which in this case is 11,and store in a variable location and the index is used to print the word "i" from the code-tip string, well it turns out that the find object rather returns a value of 10 instead of 11, and print outs "d" instead of "i".
Is there any error in this code cause i don't know why.
below is the output of the code
code_tip = "code a conditional decision like you would say it"
location = work_tip.find("i")
print(location)
print (code_tip[location])
#Output of the code.
10
d
can anyone explain what's going on.
You're running find on work_tip, not on code_tip. If you run it on the right variable you'll get the expected result:
>>> code_tip = "code a conditional decision like you would say it"
>>> location = code_tip.find("i")
>>> print(location)
11
>>> print (code_tip[location])
i
It seems to me that you mixed code_tip and work_tip at the second line. Try this:
code_tip = "code a conditional decision like you would say it"
location = code_tip.find("i")
print(location)
print (code_tip[location])
first of always use '' and not "" for Strings and second you should look in your code_tip not work_tip, here is how you can find it
Showing the answer

Assign variable if list index out of range python error

How to pass a string to a variable if an index error is found? Consider the code:
for l1, l2 in zip(open('file1.list'), open ('file2.list')):
a=fasta1[int(l1)]
b=fasta2[int(l2)]
alignments = pairwise2.align.globalxx(a,b)
top_aln = alignments[0]
aln_a, aln_b, score, begin, end = top_aln
print aln_a+'\n'+aln_b
outfast1 = aln_a
outfast2 = aln_b
A number of these functions must be imported (pairwise2 align),
but the file.lists are single column text files with one sequence id (text and numbers) per line, that are used to extract from the fasta1 and fasta2 text files.
Basically, I want to try: each list command ( a=fasta1[int(l1)]) and if there is no error (the id is in range), do as normal (assign variables a and b for that iteration), but if NOT, assign the 'a' variable some placeholder text like 'GGG':
for l1, l2 in zip(open('file1.list'), open ('file2.list')):
try:
a=fasta1[int(l1)]
except IndexError,e:
a="GGG"
continue
try:
b=fasta2[int(l2)]
except (IndexError):
b="CCC"
continue
This code doesn't quite work (when integrated with above code), which isn't surprising given my lack of python prowess, but I don't quite know why. I actually get no text output, despite the print calls... Am I thinking about this right? If there is NO error in the index, I just want it to go on and do the pairwise alignment (with the first a and b variables) and then print some text to stdout.
Any ideas?
Python's conditional (aka ternary) expressions can one-line this for you. They're often criticized for lack of readability, but I think this example reads well enough.
a = fasta1[int(l1)] if int(l1) < len(fasta1) else "GGG"
You don't need continue, because it will skip that iteration of the loop. Consider the following:
for l1, l2 in zip(open('file1.list'), open ('file2.list')):
a = 'GGG'
b = 'CCC'
try:
a = fasta1[int(l1)]
b = fasta2[int(l2)]
except IndexError:
pass

In SPSS Python essentials, can I get the value of an SPSS variable returned to Python for further use?

I have a database where each case holds info about handwritten digits, eg:
Digit1Seq : when in the sequence of 12 digits the "1" was drawn
Digit1Ht: the height of the digit "1"
Digit1Width: its width
Digit2Seq: same info for digit "2"
on up to digit "12"
I find I now need the information organized a little differently as well. In particular I want a new variables with the height and width of the first digit written, then the height and width of the second, etc., as SPSS vars
FirstDigitHt
FirstDigitWidth ...
TwelvthDigitWidth
Here's a Python program I wrote to do within SPSS what ought to be a very simple computation, but it runs into a sort of namespace problem:
BEGIN PROGRAM PYTHON.
import spss
indices = ["1", "2", "3","4","5", "6", "7", "8", "9", "10", "11", "12"]
seq=0
for i in indices:
spss.Submit("COMPUTE seq = COMDigit" + i + "Seq.")
spss.Submit("EXECUTE.")
spss.Submit("COMPUTE COM" + indices[seq] + "thWidth = COMDigit" + i + "Width.")
spss.Submit("COMPUTE COM" + indices[seq] + "thHgt = COMDigit" + i + "Hgt.")
spss.Submit("EXECUTE.")
END PROGRAM.
It's clear what's wrong here: the value of seq in the first COMPUTE command doesn't get back to Python, so that the right thing can happen in the next two COMPUTEcommands. Python's value of seq doesn't change, so I end up with SPSS code that gives me only two variables (COM1thWidth and COM1Hgt), into which COMDigit1Width, COMDigit2Width, etc. get written.
Is there any way to get Python to access SPSS's value of seq each time so that the string concatenation will create the correct COMPUTE? Or am I just thinking about this incorrectly?
Have googled extensively, but find no way to do this.
As I'm new to using Python in SPSS (and not all that much of wiz with SPSS) there may well be a far easier way to do this.
All suggestions most welcome.
Probably the easiest way to get your SPSS variable data into Python variables for manipulation is with the spss.Dataset class.
To do this, You will need:
1.) the dataset name of your SPSS Dataset
2.) either the name of the variable you want to pull data from or its index in your dataset.
If the name of the variable you want to extract data from is named 'seq' (as I believe it was in your question), then you can use something like:
BEGIN PROGRAM PYTHON.
from __future__ import with_statement
import spss
with spss.DataStep()
#the lines below create references to your dataset,
#to its variable list, and to its case data
lv_dataset = spss.Dataset(name = <name of your SPSS dataset>)
lv_caseData = lv_dataset.cases
lv_variables = lv_dataset.varlist
#the line below extracts all the data from the SPSS variable named 'seq' in the dataset referenced above into a list
#to make use of an SPSS cases object, you specify in square brackets which rows and which variables to extract from, such as:
#Each row you request to be extracted will be returned as a list of values, one value for each variable you request data for
#lv_theData = lv_caseData[rowStartIndex:rowEndIndex, columnStartIndex:columnEndIndex]
#This means that if you want to get data for one variable across many rows of data, you will get a list for each row of data, but each row's list will have only one value in it, hence in the code below, we grab the first element of each list returned
lv_variableData = [itm[0] for itm in lv_caseData[0:len(lv_caseData), lv_variables['seq'].index]]
END PROGRAM.
There are lots of ways to process the case data held by Statistics via Python, but the case data has to be read explicitly using the spss.Cursor, spssdata.Spssdata, or spss.Dataset class. It does not live in the Python namespace.
In this case the simplest thing to do would be to just substitute the formula for seq into the later references. There are many other ways to tackle this.
Also, get rid of those EXECUTE calls. They just force unnecessary data passes. Statistics will automatically pass the data when it needs to based on the command stream.
Hi I just stumbled across this, and you've probably moved on, but it might help other folks. I don't thing you actually need to access have Python access the SPSS values. I think something like this might work:
BEGIN PROGRAM PYTHON.
import spss
for i in range(1,13):
k = "COMPUTE seq = COMDigit" + str(i) + "Seq."
l = "Do if seq = " + str(i)+ "."
m = "COMPUTE COM" + str(i) + "thWidth = COMDigit" + str(i) + "Width."
n = "COMPUTE COM" + str(i) + "thHgt = COMDigit" + str(i) + "Hgt."
o = "End if."
print k
print l
print m
print n
print o
spss.Submit(k)
spss.Submit(l)
spss.Submit(m)
spss.Submit(n)
spss.Submit(o)
spss.Submit("EXECUTE.")
END PROGRAM.
But I'd have to see the data to make sure I'm understanding your problem correctly. Also, the print stuff makes the code look ugly, but its the only way I can keep a handle on whats going on under the hood. Cheerio!

Categories