I am attempting to find objects on the screen, see if they exist, and if so, select them. Using the Sikuli library to run this little automation.
while True:
if exist("image/one.png", "image/two.png", "image/three.png"):
click ("image/one.png", or "image/two.png", or "image/three.png")
break
I get SyntaxError: mismatched input 'or' expecting RPARENa I've done a quick search but there is nothing I saw relevant to my particular issue.
I've even tried
while True:
if exist("image/one.png", or "image/two.png", or "image/three.png"):
click ("image/one.png", or "image/two.png", or "image/three.png")
break
And that results in the same error.
#Stephan: New code snippet with error.
class gameImages():
imageFiles = ["one.png", "two.png", "three,png"]
for imageFile in imageFiles:
if exists(imageFile):
click(imageFile)
The Error now, :
NameError: name 'imageFiles' is not defined
for imageFile in imageFiles:
if exists(imageFile):
click(imageFile)
Your while loop isn't doing anything, and neither is your break statement. This might do what you want, assuming I understand what you want to do.
After reading a little of the Sikuli docs, I think this might also do what you want.
for impath in ("image/one.png", "image/two.png", "image/three.png"):
match = exists(impath)
if match:
click(match.getTarget())
Even easier, this is a perfect use of filter(ifexist,imageFiles). You then know that all >=0 elements in the return of filter can be used :). And it's more concise and clearly conveys your intent - much nicer to read then a chain of for's and if's
a = range(10)
# [1,2,3,4,5,6,7,8,9]
print filter(lambda x: x > 5, a)
# [6,7,8,9]
Also the or is a logical operator:
e.g.
a = 5
b = 6
c = 5
if( (a==c) or (b==c) ):
print 'c is repeated'
# c is repeated
your use of the or here makes no sense as it doesn't have operands to operate on - these can even be two objects, e.g.
1 or 2 since anything can be cast to a boolean
a concise way to do what you want is:
//imagepaths = your list of imagepaths
map(lambda x: click(x.getTarget()), filter(exists, imagepaths))
Related
as a part of my code, I'm trying to get a full factorial matrix, this is not a problem since I already have a working code for it. However, I would like to generalize it in a way that it wouldn't matter the number of inputs. This would require modifying the line:
for combination in itertools.product(X[0,:],X[1,:],X[2,:],X[3,:],X[4,:],X[5,:],X[6,:]):
input_list = dfraw.columns[0:n_inputs]
output_list = dfraw.columns[n_inputs:len(dfraw.columns)]
fflvls = 4
lhspoints = 60000
X = np.zeros((n_inputs, fflvls),float)
ii=0
for entrada in input_list:
X[ii] = np.linspace(min(dfraw[entrada]), max(dfraw[entrada]), fflvls)
ii+=1
number=1
i=0
X_fact=np.zeros((int(fflvls**n_inputs),n_inputs),float)
for combination in itertools.product(X[0,:],X[1,:],X[2,:],X[3,:],X[4,:],X[5,:],X[6,:]):
X_fact[i,:] = (combination)
i +=1
number+=1
I thought of writing the input of itertools.product as a string with a loop and then evaluating but it doesn't work and I've also seen it is regarded as bad practice
prodstring = ['X[0,:]']
for ii in range(n_inputs):
prodstring.append(',X[%d,:]'%(ii))
in_products = ''.join(prodstring)
for combination in itertools.product(eval(in_products)):
X_fact[i,:] = (combination)
i +=1
number+=1
what other way is there to inputing the full range of columns in this function? (or similar ones)
who said working harder is working better? im back from lunch and I delved into *args and **kwargs as a form of procrastination cause ive sometimes seen them mentioned and i was curious. It seems like it was just the tool I needed. In case this can help other code rookies like me in the future:
args = ()
for ii in range(n_inputs):
b = (X[ii,:])
args += (b,)
for combination in itertools.product(*args):
X_fact[i,:] = (combination)
i +=1
number+=1
Seems to work properly. Solved in an hour of "not working" what i haven't solved in approx 4 hours of "working"
I found this question on HackerRank and I am unable to understand the code(solution) that is displayed in the discussions page.
The question is:
Consider a list (list = []). You can perform the following commands:
insert i e: Insert integer at position .
print: Print the list.
remove e: Delete the first occurrence of integer .
append e: Insert integer at the end of the list.
sort: Sort the list.
pop: Pop the last element from the list.
reverse: Reverse the list.
Even though I have solved the problem using if-else, I do not understand how this code works:
n = input()
slist = []
for _ in range(n):
s = input().split()
cmd = s[0]
args = s[1:]
if cmd !="print":
cmd += "("+ ",".join(args) +")"
eval("slist."+cmd)
else:
print slist
Well, the code takes advantage of Python's eval function. Many languages have this feature: eval, short for "evaluate", takes a piece of text and executes it as if it were part of the program instead of just a piece of data fed to the program. This line:
s = input().split()
reads a line of input from the user and splits it into words based on whitespace, so if you type "insert 1 2", s is set to the list ["insert","1","2"]. That is then transformed by the following lines into "insert(1,2)", which is then appended to "slist." and passed to eval, resulting in the method call slist.insert(1,2) being executed. So basically, this code is taking advantage of the fact that Python already has methods to perform the required functions, that even happen to have the same names used in the problem. All it has to do is take the name and arguments from an input line and transform them into Python syntax. (The print option is special-cased since there is no method slist.print(); for that case it uses the global command: print slist.)
In real-world code, you should almost never use eval; it is a very dangerous feature, since it allows users of your application to potentially cause it to run any code they want. It's certainly one of the easier features for hackers to use to break into things.
It's dirty code that's abusing eval.
Basically, when you enter, for example, "remove 1", it creates some code that looks like sList.remove(1), then gives the created code to eval. This has Python interpret it.
This is probably the worst way you could solve this outside of coding competitions though. The use of eval is entirely unnecessary here.
Actually I Find some error in the code, but I came to an understanding of how this code runs. here is it:
input :
3
1 2 3
cmd = 1 + ( 2 + 3)
then eval(cmd) i.e., eval("1 + (2 + 3)") which gives an output 6
another input:
4
4 5 6 2
cmd = 4 + ( 5 + 6 + 2)
eval(cmd)
if __name__ == '__main__':
N = int(raw_input())
lst=[]
for _ in range(N):
cmd, *line = input().split()
ele= list(map(str,line))
if cmd in dir(lst):
exec('lst.'+cmd+'('+','.join(ele)+')')
elif cmd == 'print':
print(lst)
else:
print('wrong command', cmd)
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
Current assignment is building a basic text adventure. I'm having trouble with the following code. The current assignment uses only functions, and that is the way the rules of the assignment state it must be done.
def make_selections(response):
repeat = True
while repeat == True:
selection = raw_input('-> ')
for i, v in enumerate(response):
i +=1 # adds 1 to the index to make list indices correlate to a regular 1,2,3 style list
if selection == i:
print v[1]
else:
print "There's an error man, what are you doing?!?!?"
firstResponse = 'You chose option one.'
secondResponse = 'You chose option two.'
thirdResponse = 'You chose option three.'
responses = [(0, firstResponse), (1, secondResponse),( 0, thirdResponse)]
make_selections(responses)
My intention in that code is to make it so if the user selects a 1, it will return firstResponse, if the user selects 2 it will return secondResponse, etc.
I am basically just bug testing the code to make sure it produces the appropriate response, hence the "Error man..." string, but for some reason it just loops through the error message without printing the appropriate response string. Why is this?
I know that this code is enumerating the list of tuples and I can call them properly, as I can change the code to the following and get the expected output:
for i, v in enumerate(response):
i += 1 # adds 1 to the index to make list indices correlate to a regular 1,2,3 style list
print i, v
Also, two quick asides before anyone asks:
I know there is currently no way to get out of this while loop. I'm just making sure each part of my code works before I move on to the next part. Which brings me to the point of the tuples.
When I get the code working, a 0 will produce the response message and loop again, asking the user to make a different selection, whereas a 1 will produce the appropriate response, break out of the loop, and move on to the next 'room' in the story... this way I can have as many 'rooms' for as long of a story as I want, the player does not have to 'die' each time they make an incorrect selection, and each 'room' can have any arbitrary amount of options and possible responses to choose from and I don't need to keep writing separate loops for each room.
There are a few problems here.
First, there's no good reason to iterate through all the numbers just to see if one of them matches selection; you already know that will be true if 1 <= selection <= len(response), and you can then just do response[selection-1] to get the v. (If you know anything about dicts, you might be able to see an even more convenient way to write this whole thing… but if not, don't worry about it.)
But if you really want to do this exhaustive search, you shouldn't print out There is an error man after any mismatch, because then you're always going to print it at least twice. Instead, you want to only print it if all of them failed to match. You can do this by keeping track of a "matched" flag, or by using a break and an else: clause on your for loop, whichever seems simpler, but you have to do something. See break and continue Statements, and else Clauses on Loops in the tutorial for more details.
But the biggest problem is that raw_input returns a string, and there's no way a string is ever going to be equal to a number. For example, try '1' == 1 in your interactive interpreter, and it'll say False. So, what you need to do is convert the user's input into a number so you can compare it. You can do that like this:
try:
selection = int(selection)
except ValueError:
print "That's not a number!"
continue
Seems like this is a job for dictionaries in python. Not sure if your assignment allows this, but here's my code:
def make_selections(response):
selection = raw_input('-> ')
print response.get(selection, err_msg)
resp_dict = {
'1':'You chose option one.',
'2':'You chose option two.',
'3':'You chose option three.'
}
err_msg = 'Sorry, you must pick one of these choices: %s'%sorted(resp_dict.keys())
make_selections(resp_dict)
The problem is that you are comparing a string to an integer. Selection is raw input, so it comes in as a str. Convert it to an int and it will evaluate as you expect.
You can check the type of a variable by using type(var). For example, print type(selection) after you take the input will return type 'str'.
def make_selections(response):
repeat = True
while repeat == True:
selection = raw_input('-> ')
for i, v in enumerate(response):
i +=1 # adds 1 to the index to make list indices correlate to a regular 1,2,3 style list
if int(selection) == i:
print v[1]
else:
print "There's an error man, what are you doing?!?!?"
So, I'm working on a Pybrain-type project and I'm stuck on part of it.
So far the program takes in a tuple and assigns a variable to it using 'one of them fancy vars()['string'] statements. Specifically, it takes in a tuple of numbers and assigns it to a 'layerx' value, where x is the number of the layer (in order, layer 1, 2, 3, etc), such that the numbers are the dimensions of that layer.
The part of the program I desperately and humbly come to you for help in is what should be the next step in the program; it takes in a tuple of tuples (the number of tuples must = the number of layers), and the tuples contain 1/0's.
It is supposed to determine what type of Pybrain Layer to use in what layer, and then plugs in that layer's dimension value and, essentially, creates that layer-variable. I've...played with it for a while, and I've gotten a really...twisted...confusing block of code.
Please pardon the convoluted variable names, I thought I was being smart by making them somewhat specific:
moduleconbuff = 0
modulebuffer = 'module'
correspondinglayerbuff = 0
moduleconfigcopy = tuple(moduleconfig)
try: #Always triggers except, but it's pretty screwed up
while correspondinglayerbuff <= len(self.layers): #keeps track of how many layer/module pairs have been assigned
for elm in moduleconfigcopy:
for x in elm:
if x == 1:
moduledimmension = [layerbuff+'%s'%(correspondinglayerbuff)]
modulesdict = {1: pybrain.GaussianLayer(moduledimmension), 2: pybrain.LinearLayer(moduledimmension),\
3: pybrain.LSTMLayer(moduledimmension),4: pybrain.SigmoidLayer(moduledimmension),5: pybrain.TanhLayer(moduledimmension)} #this dict pairs integers with pybrain modules
vars()[modulebuffer +'%s'%(correspondinglayerbuff)]=modulesdict(moduleconbuff) #should return something like 'Module1 = pybrain.GaussianLayer(5) when complete
print vars()[modulebuffer+'%s'%(correspondinglayerbuff)]
moduleconbuff=0
correspondinglayerbuff+=1
print 'Valid: ', moduleconfigcopy, elm
continue
else:
elm = elm[1:]
print 'Invalid: ', moduleconfigcopy, elm
moduleconbuff+=1
except:
print 'Invalid!!!'
I honestly lost track of what was going on in it. The tuple "moduleconfig" in the beginning
was supposed to be a tuple of tuples (nested tuples) with binary operators, it was supposed to stop when one of the tuples has a 1, match that operator with the right module in Pybrain, and then plug this in so the corresponding layer = that module with the dimmensions already listed.
Obviously something went terribly wrong, and it's so fargone that my brain can't make any sense of it...it's lost all it's reason and every time I look at it I get scared...please help me or tell me I created an abomination or something, I guess...
One huge hindrance that's affecting code readability for you is variable naming and style. I've tried to clean it up a little bit for you. It still might not work, but now it's a LOT easier to see what's going on. Please refer to PEP 8, the Python style guide
For starters, I renamed some variables, below. Note that in python, variables should be all lowercase, with separate words connected by an underscore. Constants should be ALL_UPPERCASE:
assigned_layers = correspondinglayerbuff = 0
tuple_of_tuples = moduleconfigcopy = ((0, 1), (0, 0, 1), (0, 1))
dimension = moduledimension
MOD_BUFFER = modulebuffer = 'buffer'
c_buff = moduleconbuff = 0
And here is the while loop (with variable names replaced, and properly indented, with the try... except block removed:
while assigned_layers <= len(self.layers):
for element_tuple in tuple_of_tuples:
for item in element_tuple:
if item: # in python, 0 is treated as boolean False, 1 or any other value is treated as boolean True.
dimension = [layerbuff + str(assigned_layers)] #what is layerbuff?
modules_dict = {
1: pybrain.GaussianLayer(dimension),
2: pybrain.LinearLayer(dimension),
3: pybrain.LSTMLayer(dimension),
4: pybrain.SigmoidLayer(dimension),
5: pybrain.TanhLayer(dimension)
} # Notice how this dict is much easier to read.
vars()[MOD_BUFFER + str(assigned_layers)] = modules_dict[c_buff] #modules_dict is a dict and not a callable object
c_buff = 0
assigned_layers +=1
#No need for continue here, since that's what the if...else does here.
else:
element_tuple = element_tuple[1:] #what is this for?
print 'Invalid: ', tuple_of_tuples, element_tuple
I'm not sure exactly what you are trying to do in this line:
vars()[MOD_BUFFER + str(assigned_layers)] = modules_dict[c_buff] #modules_dict is a dict and not a callable object
Also, you originally had modules_dict(moduleconbuff) which will raise a TypeError as a dict is not a callable object. I'm assuming you meant to retrieve a value by key.
As I said, I'm not quite sure what your trying to do here (probably because I haven't seen the rest of your code), but renaming your variables and using good style should go a long way towards you being able to debug your code. I will continue to edit if you answer my questions/comment.