What can VDict() be used for and where can I find the documentation?

Asked by Winners

I could not find documentation on VDict() functionality on skuli.org or google. I blame myself. The sikuli website says:

Getting Help

Looking for specific information?

Try the Table of Contents
Look through the Index
Use the Search Page

I type "VDict" in the search and get no documentation on the subject. The "index" contains no information on the subject. I still blame myself for being too slow to learn. Please don't just paste the link for the documentation. Also, show me how you found it.

On another note: if someone can nail it to my head why they put a zero when using vdict functionality, I promise I won't sue you for assault and battery.

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"

img = find(img)

result = size[img] VS result = size[img][0] // in layman's terms, please explain the difference. What content will "result" variable display in each scenario. Thanks in advance!

Question information

Language:
English Edit question
Status:
Solved
For:
SikuliX Edit question
Assignee:
No assignee Edit question
Solved by:
Winners
Solved:
Last query:
Last reply:
Revision history for this message
RaiMan (raimund-hocke) said :
#1

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.

Revision history for this message
Winners (felixpremium) said :
#2

Thank you RaiMan!