← Back to team overview

sikuli-driver team mailing list archive

Re: [Question #185748]: VDict() documentation request

 

Question #185748 on Sikuli changed:
https://answers.launchpad.net/sikuli/+question/185748

    Status: Open => Answered

RaiMan proposed the following answer:
The VDict  feature is something that did not change since Sikuli's
beginning, so if you decide, to have a look at it:

http://sikuli.org/trac/wiki/The%20Complete%20Guide%20To%20Sikuli%20X#ClassVDict

which is the documentation in its version for 0.10 and the transition to
version X. In the new docs, that you have consulted, the developers
decided to leave VDict out. This can be understood as being deprecated.

VDict's features work, but I never until now had a real life application
for it.

Basically, a VDict is a key-value storage with the features of a Python
dictionary (in fact not really all), whose keys are images. The unique
characteristic is, that internally the key search is done by comparing
the key images with the given images the same way, as an image is
searched on the screen.

example:

vd = VDict()
vd["image-of-nice-weather.png"] = "we should have nice wether"
vd["image-of-rainy-weather.png"] = "It might rain today"

print vd["some-captured-image.png"]

would print 
It might rain today
if Sikuli VDict engine thinks, that the given image ("some-captured-image.png") matches the key image "image-of-rainy-weather.png" as the only one with the given similarity threshold.
This is one of the possible applications of VDict: in a specific region of the screen, there might be different images at one time. So you could store all the variants in the VDict, capture the current image at that place and find out which one it is by asking the VDict. Usually, you would make some decisions based on the returned value, that will be implemented using a case structure (if/elif/else in Python). So the question is: Why not do this directly?

same example as case structure:
reg = <the region, where we have the different images>
if reg.exists("image-of-nice-weather.png", 0):
    print  "we should have nice wether"
elif reg.exists("image-of-rainy-weather.png", 0):
    print  "It might rain today"
else:
    print "sorry, today there is no weather at all ;-)"

same example with a standard dictionary:
vd = {}
vd["image-of-nice-weather.png"] = "we should have nice wether"
vd["image-of-rainy-weather.png"] = "It might rain today"
# ... as many entries as you like
reg = <the region, where we have the different images>
found = False
for img in vd:
    if reg.exists(img, 0):
        print vd[img]
        found = True
        break
if not found:
    print "sorry, today there is no weather at all ;-)"

In your example, it seems, that you want to store the image size
together with the image. Since in Sikuli the images are referenced in
the script either with the filename string or as one attribute of a
Pattern, you do not need a VDict, which would produce the overhead of
the image search operation.

the correct usage of VDict:

size = VDict()
size[<img>] = "88x31"
size[<img>] = "97x61"
size[<img>] = "120x30"
size[<img>] = "120x60"
size[<img>] = "120x90"
size[<img>] = "300x100"
size[<img>] = "300x250"
size[<img>] = "680x180"

# I suppose, you search something on the screen
# if yes, the result is a Match and not an image
# img = find(img)
match = find("some-other-image.png")

# you might now lookup your VDict:
result = size[capture(match)]
# since we need an image file to look into VDict, we have to capture the matched region as lookup key

But this makes the whole thing "nonsense": a match already "knows" its
size:

match = find("some-other-image.png")
print "Image Size: %s x %s"%(match.w, match.h)

--- result = size[img] VS result = size[img][0] // in layman's terms,
Totally being a layman is not enough for writing more advanced Sikuli scripts. You need at least some basic knowledge and understanding of scripting and the Python language.
And using a dictionary is a little bit above beginners level ;-)

The values in a dictionary referenced by a key can be any value, that is
allowed on the right side of = (assignment). So it might even be a
dictionary.

In your case the values are strings (which internally are seen as a list
of characters).

So
result = size[img]
gives you the paired value of key img (in your case the whole string)

and 
result = size[img][0]
gives you the first character of the paired string, since size[img] returns the list of characters and [0] is the index to the first element in the list of characters. In your example this would give you the first number character.

--- conclusion
Forget VDict ;-)

If you have any application and do not know how to solve this in a
Sikuli script, come back with a description of what you want to achieve.

-- 
You received this question notification because you are a member of
Sikuli Drivers, which is an answer contact for Sikuli.