How to use result in IF to spit out True/False? - python

The following code snippet
if pyautogui.locateOnScreen('test4x4.png', region = (200,200,4,4)) == "Box(left=200, top=200, width=4, height=4)":
print("Found")
else:
print("NotFound")
spits out NotFound,
but
print(pyautogui.locateOnScreen('test4x4.png', region = (200,200,4,4)))
prints out "Box(left=200, top=200, width=4, height=4)".
How to properly match the result so I can get the Found value back?

The locateOnScreen function returns a pyscreeze.Box object, not a string.
So you'll want to convert it to a tuple before doing any comparisons:
box = pyautogui.locateOnScreen('test4x4.png', region = (200,200,4,4))
if box is not None and tuple(box) == (200, 200, 4, 4):
print("Found")
else:
print("NotFound")
<Edit>
The reason you are getting TypeError: 'NoneType' object is not iterable, is because if the image is not found, locateOnScreen returns None. Trying to convert None to a tuple: tuple(None) throws an error.
You can protect against this by checking that box isn't None, as I've edited above.
I can't explain why you're still getting the error when the image is successfully found however, so you'll need to give some more info for us to solve that.
</Edit>
The reason your version doesn't work is because when you call print(box), behind the scenes the print function is actually calling str(box) and printing that instead.
Thats why even though
>>> print(box)
Box(left=200, top=200, width=4, height=4)
it doesn't mean that
box == "Box(left=200, top=200, width=4, height=4)"

Related

This is a function to be able to reverse a coordinate in the california housing dataset so as to get the specific address. But I have a problem,

please help, this is the code function. I'll post the error i'm getting when I run the function and use pickle.dump
def location(cord):
latitude=str(cord[0])
longitude=str(cord[1])
location=geolocater.reverse("{}, {}".format(latitude, longitude) ).raw['address']
#if the values are missing replace by empty string
if location.get('Road') is None:
location['Road'] = None
if location.get('County') is None:
location['County'] = None
loc_update['County'].append(location['County'])
[enter image description here][1]loc_update['Road'].append(location['Road'])
In continuation with the question above,When I run the code I get a value error. Saying "ValueError: Must be a coordinate pair or Point". The code below.
loc_update = {'County':[],
"Road":[],
"Neighbourhood":[]}
for i,cord in enumerate(df.iloc[:,6:-1].values):
location(cord)
#countiounsly reading our data and saving it on the go
pickle.dump(loc_update, open('loc_update.pickle', 'wb'))
if i%100 == 0:
print(i)

Function to calculate multiple running totals

I have a list of tuples
(something1, 500)
(something1, 200)
(something1, 300)
(something2, 200)
(something2, 600)
(something2, 400)
I have written a function in pySpark to do the calculation to get a result something like this. The function basically needs to sum up the total of the counts that occur
(something1, 1000),
(something2, 1200)
My function so far
def add_function(key, value):
last_key = None
recur_total = 0
key, value = join_data[0][0], join_data[0][1]
if last_key == key:
recur_total+ = value
else:
if last_key:
recur_total = value
if last_key == key:
recur_total = value
last_key = key
if last_key == key:
return(last_key, value)
Problems I am facing
I am unable to paste the function as one function at the pySpark console. It gets split to multiple prompts.
It says syntax error at line 6 (recur_total+ = value).
What am I doing wrong and how to rectify this?
I am unable to paste the function as one function at the pySpark console. It gets split to multiple prompts.
I do not understand what you mean by this. As long as your indentation is correct, the "multiple prompts" do create a single function correctly.
It says syntax error at line 6 (recur_total+ = value).
This error means that you seem to be pasting your code correctly. To fix the error, double check the spacing on the line that gives the syntax error.
Others have already pointed out answers to your questions regarding proper indentation , but my 2 cents regarding whole function itself..
Task you want to achieve can be simply done using groupby of itertools
from itertools import groupby
data = [ ('something1', 500),
('something1', 200),
('something1', 300),
('something2', 200),
('something2', 600),
('something2', 400)]
for key, group in groupby(data, lambda x: x[0]):
result = 0
for things in group:
result = result + things[1]
print(key,result)

Sikuli 1.1 making a new Region from an existing Region

Im trying to reuse predefined regions but I get Nonetype error when assigning it to a new variable using sikuli.setW(). Here's my code:
import math
import sikuli
self.screen_reg = sikuli.Screen(0)
self.monitor_reg = self.screen_reg
self.leftreg = sikuli.Region(
self.monitor_reg.x,
self.monitor_reg.y,
int(math.floor(self.monitor_reg.w/2)),
self.monitor_reg.h)
self.rightreg = sikuli.Region(
self.monitor_reg.x + int(math.floor(self.monitor_reg.w/2)),
self.monitor_reg.y,
int(math.floor(self.monitor_reg.w/2)),
self.monitor_reg.h)
self.leftreg.highlight(3) <=== working
self.quarter = self.leftreg.setW(int(math.floor(self.leftreg.w/2)))
self.quarter.highlight(3) <====== didnt work;
error: NoneType object has no attribute highlight
If I print type(quarter), it returns NoneType.
If I change it into these:
self.leftreg.highlight(3)
self.leftreg.setW(int(math.floor(self.leftreg.w/2)))
self.leftreg.highlight(3)
It works fine. What am I missing? Thanks for the help.
> What am I missing?
An object method may not have return type.
Here is excerpt from Sikuli source code
public void setW(int W) {
w = W > 1 ? W : 1;
initScreen(null);
}
Return type of setW is void. That is it returns nothing, while you expected that it returns a Region.
A correct way to do what you want would be:
self.quarter = Region(self.leftreg) # this constructs a new region
self.quarter.setW(int(math.floor(self.leftreg.w/2))) # and this resizes it

Python append tkinter widget to list shows as int value

I'm trying to make an array/list of tkinter Labels for a wage calculator, but whenever I append the widget to my array, it appends as an int datatype. I was thinking appending it would allow me to call list[widgetIndex].grid() but since it wasn't a Label datatype getting appended to my list for some reason, it gives me an error saying that this 'int' object has no attribute called 'grid'. Why is it an int datatype as oppose to the Label datatype that the variable definitely was before I appended it?
def addJob(jc, cc, he, wl, hl, we):
jc = jc + 1
cc = cc + 2
wageLabel = Label(root, text="Wage")
hoursLabel = Label(root, text="Hours")
wageEntry = Entry(root)
hoursEntry = Entry(root)
wl.append(wageLabel)
hl.append(hoursLabel)
we.append(wageEntry)
he.append(hoursEntry)
wl[jc-1].grid(row =0, column =cc-1, sticky=E)
hl[jc-1].grid(row =1, column =cc-1, sticky=E)
we[jc-1].grid(row = 0, column=cc)
he[jc-1].grid(row = 1, column=cc)
You initialize w1 using w1 = [ 0 ].
Later on you just append to w1, so your list will be sth. like
[ 0, <class 'tkinter.Label'>, <class 'tkinter.Label'>, <class 'tkinter.Label'>, ... ] depending on how many labels you add.
Using w1 = [] will solve your problem.
The error occurs as the first element in your list ("0") cannot be gridded.
Using print w1 in your function would have shown you this in a fairly easy way.
Bryan is right, the code you posted is without a doubt okay for the purpose you intend using it, but the initialization for your passed parameters (not posted as code sample) defines a different behaviour.
Please read on How to create a Minimal, Complete and Verifiable Example. Breaking down code into the smallest piece still reproducing the error mostly guides you direct to the solution.

Python Image Library: How to combine 4 images into a 2 x 2 grid?

I have 4 directories with images for an animation. I would like to take the set of images and generate a single image with the 4 images arranged into a 2x2 grid for each frame of the animation.
My code so far is:
import Image
fluid64 = "Fluid64_half_size/00"
fluid128 = "Fluid128_half_size/00"
fluid512 = "Fluid512_half_size/00"
fluid1024 = "Fluid1024_half_size/00"
out_image = "Fluid_all/00"
for pic in range(1, 26):
blank_image = Image.open("blank.jpg")
if pic < 10:
image_num = "0"+str(pic)
else:
image_num = str(pic)
image64 = Image.open(fluid64+image_num+".jpg")
image128 = Image.open(fluid128+image_num+".jpg")
image512 = Image.open(fluid512+image_num+".jpg")
image1024 = Image.open(fluid1024+image_num+".jpg")
out = out_image + image_num + ".jpg"
blank_image.paste(image64, (0,0)).paste(fluid128, (400,0)).paste(fluid512, (0,300)).paste(fluid1024, (400,300)).save(out)
Not sure why it's not working. I'm getting the error:
Traceback (most recent call last):
File "C:\Users\Casey\Desktop\Image_composite.py", line 24, in <module>
blank_image.paste(image64, (0,0)).paste(fluid128, (400,0)).paste(fluid512, (
ste(fluid1024, (400,300)).save(out)
AttributeError: 'NoneType' object has no attribute 'paste'
shell returned 1
Any help would be awesome. Thanks!
The only problem there is that "paste" does not return an image object - it rather modifies the "blank" image inplace.
So, when the second paste is called (the one that uses the fuild128 image), it tries to be applied on "None" - which is the return value of the first image.
If that is the only problem you are having, just make one paste call per line, like this:
blank_image.paste(image64, (0,0))
blank_image.paste(fluid128, (400,0))
blank_image.paste(fluid512, (0,300))
blank_image.paste(fluid1024, (400,300))
blank_image.save(out)
Although it looks likely you'd need to scale each image so that their format match as well.
And your code for the "image_num" variable is unecessary. Python is really good with strings - just do something like this:
image64 = Image.open(fluid64 + "%02d.jpg" % pic)
You may want to be using something along the lines of :
blank_image = Image.new("RGB", (800, 600))
This will create a new area in memory in which you can generate your image. You should then be able to paste you images into that.
Then you'll need to save it out again later on with:
blank_image.save("blank.jpg")
Read the error message:
AttributeError: 'NoneType' object has no attribute 'paste'
This means you tried to call .paste on something that was of type NoneType, i.e. on the None object.
Image.paste returns None. You can't "chain" together calls like that except when the functions are specifically designed to support it, and Image.paste is not. (Support for this sort of thing is accomplished by having the function return self. You get an error that talks about NoneType because the function is written not to return anything, and everything in Python returns None by default if nothing else is returned explicitly.) This is considered Pythonic: methods either return a new value, or modify self and return None. Thus, so-called "fluent interfaces" are not used when the functions have side effects - Pythonistas consider that harmful. Returning None is a warning that the function has side effects. :)
Just do four separate .paste calls.
Tiling figures in a 2-by-2 grid would be easy to achieve with the append_images function defined in this reply
https://stackoverflow.com/a/46623632/8738113
For example:
img1 = append_images([image64, image128], direction='horizontal')
img2 = append_images([image512, image1024], direction='horizontal')
final = append_images([img1, img2], direction='vertical')
final.save("Fluid_all/00.jpg")
Unlike PIL APIs copy, crop, resize or rotate which return an Image object, paste returns None which prevents chained method calls. Not so convenient API design.

Categories