Converting a string and a int into a variable Python - python

I am currently creating a loop with sikuli. My problem is that i have a fixed variables that will go up to 15 with only the numbers changing at the end. I was looking for a way to combine the string component that is fixed with the integer which will be variable in the loop but then once concatenated have it identified as the predefined variable at the top of the code.
Any help would be awesome!
Dunning1 = (Pattern("Line 1.png").similar(0.97).targetOffset(445,-2))
Balance1 = (Pattern("Line 1.png").similar(0.97).targetOffset(566,-2))
Select1 = (Pattern("Line 1.png").similar(0.97).targetOffset(38,-1))
Dunning2 = (Pattern("Line 2.png").similar(0.97).targetOffset(442,-1))
Balance2 =(Pattern("Line 2.png").similar(0.97).targetOffset(565,2))
Select2 = (Pattern("Line 2.png").similar(0.97).targetOffset(37,-1))
while n < 3:
DunningX = ("Dunning"+str(n)**
print(DunningX)**
doubleClick(DunningX)
type("c",KEY_CTRL)
doubleClick(DunningX)
type("c",KEY_CTRL)
Dunning1 = Env.getClipboard()
BalanceX = ("Balance"+str(n))
doubleClick(BalanceX)
type("c",KEY_CTRL)
doubleClick(BalanceX)
type("c",KEY_CTRL)
ContractBal = Env.getClipboard()
if Dunning1 == ContractBal:
SelectX = ("Select"+str(n))
click(SelectX)
n = n + 1

I'm not sure if I fully understand your question, but I think you're looking for this:
if some_condition:
Select1 = "Select"+str(n)
else
Select2 = "Select"+str(n)
any way, please consider using a list for this since using single variables is not scalable at all. It could look like this:
select = []
select.append(Pattern("Line 1.png").similar(0.97).targetOffset(38,-1))
select.append(Pattern("Line 2.png").similar(0.97).targetOffset(37,-1))
...
if some_condition:
m=1
else
m=2
select[m] = 'select'+str(n)

From your code shown i see a few issues.
I assume your while n < 3 is indentation issue.
error with (:
DunningX = "Dunning" + str(n)
print(DunningX)

I would recommend you to do the following:
1 - add all the variables to a class as attributes:
class Variables:
def __init__(self):
self.Dunning1 = (Pattern("Line 1.png").similar(0.97).targetOffset(445,-2))
self.Balance1 = (Pattern("Line 1.png").similar(0.97).targetOffset(566,-2))
2 - get the values dynamically by their name using getattr func:
n=1 // for example
vars = Variables()
DunningX = getattr(vars,f"Dunning{n}") //DunningX will be equal to Dunning1

Related

I want to convert the following MATLAB code into python? Is this the correct way?

How can I change this part [AIF,j]=get_AIF_j(InterpFact) and [~,j_index] = min(InterpFact-AIF_vect) correctly? And what about the remaining code? Thanks in advance.
%Matlab code
InterpFact = (fs_h/2/2)/(fd_max);
[AIF,j]=get_AIF_j(InterpFact);
function [AIF,j] = get_AIF_j (InterpFact)
j_vect = 1:10;
AIF_vect = floor(j_vect*InterpFact)./j_vect;
[~,j_index] = min(InterpFact-AIF_vect);
j = j_vect(j_index);
AIF = AIF_vect(j_index);
end
#Python code
InterpFact = (fs_h/2/2)/(fd_max)
[AIF,j]=get_AIF_j(InterpFact)
def get_AIF_j (InterpFact):
j_vect =np.arange(1,11)
AIF_vect = np.floor(j_vect*InterpFact)/j_vect
[~,j_index] = min(InterpFact-AIF_vect)
j = j_vect[j_index]
AIF = AIF_vect[j_index];
return AIF,j
This MATLAB:
[~,j_index] = min(InterpFact-AIF_vect);
would be translated to Python as:
j_index = np.argmin(InterpFact-AIF_vect)
Also, …/(fd_max) can only be translated the way you did if fd_max is a scalar. A division with a matrix in MATLAB solves a system of linear equations.
I strongly recommend that you run the two pieces of code side by side with the same input, to verify that they do the same thing. You cannot go by guesses as to what a piece of code does.
Try this to see if it delivers what it should (I am not sure here as I am not fluent in matlab):
#Python code
import numpy as np
def get_AIF_j (InterpFact):
j_vect = np.arange(1,11)
AIF_vect = np.floor(j_vect*InterpFact)/j_vect
j_index = int( min(InterpFact-AIF_vect) )
print(j_index)
j = j_vect[j_index]
AIF = AIF_vect[j_index];
return AIF, j
fs_h = 24; fd_max = 1
InterpFact = (fs_h/2/2)/(fd_max)
AIF, j = get_AIF_j(InterpFact)
print(AIF,j)
gives:
0
6.0 1

Automatically pass variables names to list

I have a long chain of code for a portion of a script. For example:
B1_2013 = images.select('0_B1')
B2_2013 = images.select('0_B2')
B3_2013 = images.select('0_B3')
B4_2013 = images.select('0_B4')
B5_2013 = images.select('0_B5')
B6_2013 = images.select('0_B6')
B7_2013 = images.select('0_B7')
B8_2013 = images.select('0_B8')
B9_2013 = images.select('0_B9')
B10_2013 = images.select('0_B10')
B11_2013 = images.select('0_B11')
B1_2014 = images.select('1_B1')
B2_2014 = images.select('1_B2')
B3_2014 = images.select('1_B3')
B4_2014 = images.select('1_B4')
B5_2014 = images.select('1_B5')
B6_2014 = images.select('1_B6')
B7_2014 = images.select('1_B7')
B8_2014 = images.select('1_B8')
B9_2014 = images.select('1_B9')
B10_2014 = images.select('1_B10')
B11_2014 = images.select('1_B11')
and so on ...
B11_2020 = images.select('7_B11')
Ultimately, from these lines of code, I need to generate a list of variables (my_variables) that I can pass off to a function. For example:
my_variables = [B1_2013, B2_2013, B3_2013, B4_2013, B5_2013, B6_2013, B7_2013, B8_2013, B9_2013, B10_2013, B11_2013, \
B1_2014, B2_2014, B3_2014, B4_2014, B5_2014, B6_2014, B7_2014, B8_2014, B9_2014, B10_2014, B11_2014]
Is there a more efficient approach to automatically generate hundreds of lines of code (e.g. B1_2013 = images.select('0_B1') and so on...) following the first code example so that I can automatically generate a list of variables in the second code example (e.g. my_variables = [B1_2013, and so on...]?
Just make a list using a loop or list comprehension.
my_images = [images.select(f'{i}_B{j}') for i in range(8) for j in range(12)]
In this use case it is more viable to use a dict to store the "variables" it is not good practice to dynamically build variables. Below is an example using itertools.product that will build a dict with desired output:
from itertools import product
images = {f'B{i}_{y+2013}': images.select(f'{y}_B{i}')
for y, i in product(range(12), range(1, 8))}
Result:
{'B1_2013': '0_B1',
'B2_2013': '0_B2',
'B3_2013': '0_B3',
'B4_2013': '0_B4',
'B5_2013': '0_B5',
'B6_2013': '0_B6',
'B7_2013': '0_B7',
'B1_2014': '1_B1',
'B2_2014': '1_B2',
'B3_2014': '1_B3',
...
}
Then to access the desired "variable" use:
>>> images['B3_2014']
'1_B1'
#Barmar's answer is correct. You can extend his answer if you wanted to index the variables by doing the following:
my_images = {f'{i}_B{j}':images.select(f'{i}_B{j}') for i in range(8) for j in range(12)}
This is called dictionary comprehension.
Or dictionary comprehension:
my_images = {'B{j}_{2013 + i}': images.select(f'{i}_B{j}') for i in range(8) for j in range(12)}
Refer them with:
my_images['B1_2013']
my_images['B2_2013']
...

How do you use an incremented variable outside of function in python?

This could be a foolish question; maybe my though process is totally wrong (if so, please point it out), but how do you extract the three incremented variables (c_char, c_word, c_sentence) inside a custom function and use it for other uses?
def length_finder(x):
#variables counting character,word,sentnece
c_char = 0
c_word = 1
c_sentence = 0
for i in x:
if (i >= 'a' and i <= 'z') or (i >= 'A' and i <= 'Z'):
c_char += 1
if i == " ":
c_word += 1
if i == '.' or i == '!' or i == '?' :
c_sentence += 1
length_finder(input("Enter the text you wish to analyze: "))
L = 100/c_word*c_char
S = 100/c_word*c_sentence
#formula to get readability
index = 0.0588 * L - 0.296 * S - 15.8
print("This text is suitable for grade " + str(index))
You can return multiple variables from within the function:
def length_finder(x):
...
return (c_char, c_word, c_sentence)
(c_char, c_word, c_sentence) = length_finder('input string')
You have two options.
Make those three variables global, and reference them in the function. You can make them global, then reference them as global within the function.
Return them from the function. You can return all 3 values as a dictionary or list.

Is there any way to replace (input) zeros with a function of (1/2)?

I am trying to replace the value of 0 with .5, or 1/2 when it has been input initially.
For example, I am trying to have it done before the functions are added. I need to redefine the value of 0 for the input only, and only for the single instance of 0 itself. Not values of 10+.
Here is the project information:
IN = input("Enter IN: ")
N = input("Enter N: ")
NP = input("Enter NP: ")
### These two lines are the part I can't get to work:
if digit == float(0):
digit = float(.5)
###
init = (float(IN)*(float(1)/float(2)))
baselimiter = - (float(N)*(float(1)/float(2))) + ((float(IN)*
(float(1)/float(2))) * (float(NP)*(float(1)/float(2))))
lset = init + baselimiter
limitconverto1 = (lset / init) * (init / lset)
infalatetoinput = (((init * float(IN))) / init )
limit = limitconverto1 * infalatetoinput
result = limit
print(result)
So here is a code that does what you want.
Now to be honest, it works but I don't understand WHY you do that. You do a bunch of weird calculations like multiplying and dividing by the same number...
IN = float(input("Enter IN: "))
N = float(input("Enter N: "))
NP = float(input("Enter NP: "))
# The part that interests you.
IN = 0.5 if IN == 0 else IN
N = 0.5 if N == 0 else N
NP = 0.5 if NP == 0 else NP
init = IN * 1/2
baselimiter = -N*1/2 + IN*1/2*NP*1/2 # Removed all the superfluous float() and parenthesis.
lset = init + baselimiter
limitconverto1 = (lset / init) * (init / lset) # That's just always 1. What is intended here?
infalatetoinput = (((init * float(IN))) / init ) # That's always IN. Same question?
limit = limitconverto1 * infalatetoinput # Equivalent to 1 x IN...
result = limit
print(result) # Your result is always IN...
You can use one-liners when you declare the variables:
IN = (float(input("...")) if float(input("...")) != 0 else .5)
One-liners are for loops or if statements (or both) that are in one line instead of multiple lines when declaring variables. They can only be used for the declaration of variables. The one-liner I suggested is would be in multiple lines:
if float(input("...")) != 0:
IN = float(input("..."))
else:
IN = .5 #You don't need to say float(.5) since .5 is a float anyway.
More about One-Liners: One-Liners - Python Wiki
I hope this edit of my previous answer fully answers your question, for more clarification I will be available on the comments

I need to vectorize the following in order for the code can run faster

This portion I was able to vectorize and get rid of a nested loop.
def EMalgofast(obsdata, beta, pjt):
n = np.shape(obsdata)[0]
g = np.shape(pjt)[0]
zijtpo = np.zeros(shape=(n,g))
for j in range(g):
zijtpo[:,j] = pjt[j]*stats.expon.pdf(obsdata,scale=beta[j])
zijdenom = np.sum(zijtpo, axis=1)
zijtpo = zijtpo/np.reshape(zijdenom, (n,1))
pjtpo = np.mean(zijtpo, axis=0)
I wasn't able to vectorize the portion below. I need to figure that out
betajtpo_1 = []
for j in range(g):
num = 0
denom = 0
for i in range(n):
num = num + zijtpo[i][j]*obsdata[i]
denom = denom + zijtpo[i][j]
betajtpo_1.append(num/denom)
betajtpo = np.asarray(betajtpo_1)
return(pjtpo,betajtpo)
I'm guessing Python is not your first programming language based on what I see. The reason I'm saying this is that in python, normally we don't have to deal with manipulating indexes. You act directly on the value or the key returned. Make sure not to take this as an offense, I do the same coming from C++ myself. It's a hard to remove habits ;).
If you're interested in performance, there is a good presentation by Raymond Hettinger on what to do in Python to be optimised and beautiful :
https://www.youtube.com/watch?v=OSGv2VnC0go
As for the code you need help with, is this helping for you? It's unfortunatly untested as I need to leave...
ref:
Iterating over a numpy array
http://docs.scipy.org/doc/numpy/reference/generated/numpy.true_divide.html
def EMalgofast(obsdata, beta, pjt):
n = np.shape(obsdata)[0]
g = np.shape(pjt)[0]
zijtpo = np.zeros(shape=(n,g))
for j in range(g):
zijtpo[:,j] = pjt[j]*stats.expon.pdf(obsdata,scale=beta[j])
zijdenom = np.sum(zijtpo, axis=1)
zijtpo = zijtpo/np.reshape(zijdenom, (n,1))
pjtpo = np.mean(zijtpo, axis=0)
betajtpo_1 = []
#manipulating an array of numerator and denominator instead of creating objects each iteration
num=np.zeros(shape=(g,1))
denom=np.zeros(shape=(g,1))
#generating the num and denom real value for the end result
for (x,y), value in numpy.ndenumerate(zijtpo):
num[x],denom[x] = num[x] + value *obsdata[y],denom[x] + value
#dividing all at once after instead of inside the loop
betajtpo_1= np.true_divide(num/denom)
betajtpo = np.asarray(betajtpo_1)
return(pjtpo,betajtpo)
Please leave me some feedback !
Regards,
Eric Lafontaine

Categories