OLD | NEW |
---|---|
(Empty) | |
1 #!/usr/bin/python | |
2 | |
3 """ | |
4 Copyright 2014 Google Inc. | |
5 | |
6 Use of this source code is governed by a BSD-style license that can be | |
7 found in the LICENSE file. | |
8 | |
9 ImagePairSet class; see its docstring below. | |
10 """ | |
11 | |
12 import column | |
13 | |
14 # Keys used within dictionary representation of ImagePairSet. | |
15 KEY__COLUMNHEADERS = 'columnHeaders' | |
16 KEY__IMAGEPAIRS = 'imagePairs' | |
17 KEY__IMAGESETS = 'imageSets' | |
18 KEY__IMAGESETS__BASE_URL = 'baseUrl' | |
19 KEY__IMAGESETS__DESCRIPTION = 'description' | |
20 | |
21 DEFAULT_DESCRIPTIONS = ('setA', 'setB') | |
22 | |
23 | |
24 class ImagePairSet(object): | |
25 """A collection of ImagePairs, representing two arbitrary sets of images. | |
26 | |
27 These could be: | |
28 - images generated before and after a code patch | |
29 - expected and actual images for some tests | |
30 - or any other pairwise set of images. | |
31 """ | |
32 | |
33 def __init__(self, descriptions=None): | |
34 """ | |
35 Args: | |
36 descriptions: a (string, string) tuple describing the two image sets. | |
37 If not specified, DEFAULT_DESCRIPTIONS will be used. | |
38 """ | |
39 self._column_header_factories = {} | |
40 self._descriptions = descriptions or DEFAULT_DESCRIPTIONS | |
41 self._extra_column_tallies = {} # maps column_id -> values | |
42 # -> instances_per_value | |
43 self._image_pair_dicts = [] | |
44 | |
45 def add_image_pair(self, image_pair): | |
46 """Adds an ImagePair; this may be repeated any number of times. | |
rmistry
2014/02/13 12:10:02
Another style comment (last one I promise). I have
epoger
2014/02/13 17:16:31
Done throughout. Makes sense.
| |
47 """ | |
48 # Special handling when we add the first ImagePair... | |
49 if not self._image_pair_dicts: | |
50 self._base_url = image_pair.base_url | |
51 | |
52 if image_pair.base_url != self._base_url: | |
53 raise Exception('added ImagePair with base_url "%s" instead of "%s"' % ( | |
54 image_pair.base_url, self._base_url)) | |
55 self._image_pair_dicts.append(image_pair.as_dict()) | |
56 extra_columns_dict = image_pair.extra_columns_dict | |
57 if extra_columns_dict: | |
58 for column_id, value in extra_columns_dict.iteritems(): | |
59 self._add_extra_column_entry(column_id, value) | |
60 | |
61 def set_column_header_factory(self, column_id, column_header_factory): | |
62 """Overrides the default settings for one of the extraColumn headers. | |
63 | |
64 Args: | |
65 column_id: string; unique ID of this column (must match a key within | |
66 an ImagePair's extra_columns dictionary) | |
67 column_header_factory: a ColumnHeaderFactory object | |
68 """ | |
69 self._column_header_factories[column_id] = column_header_factory | |
70 | |
71 def get_column_header_factory(self, column_id): | |
72 """Returns the ColumnHeaderFactory object for a particular extraColumn. | |
73 | |
74 Args: | |
75 column_id: string; unique ID of this column (must match a key within | |
76 an ImagePair's extra_columns dictionary) | |
77 """ | |
78 column_header_factory = self._column_header_factories.get(column_id, None) | |
79 if not column_header_factory: | |
80 column_header_factory = column.ColumnHeaderFactory(header_text=column_id) | |
81 self._column_header_factories[column_id] = column_header_factory | |
82 return column_header_factory | |
83 | |
84 def _add_extra_column_entry(self, column_id, value): | |
85 """Records one column_id/value extraColumns pair found within an ImagePair. | |
86 | |
87 We use this information to generate tallies within the column header | |
88 (how many instances we saw of a particular value, within a particular | |
89 extraColumn). | |
90 """ | |
91 known_values_for_column = self._extra_column_tallies.get(column_id, None) | |
92 if not known_values_for_column: | |
93 known_values_for_column = {} | |
94 self._extra_column_tallies[column_id] = known_values_for_column | |
95 instances_of_this_value = known_values_for_column.get(value, 0) | |
96 instances_of_this_value += 1 | |
97 known_values_for_column[value] = instances_of_this_value | |
98 | |
99 def _column_headers_as_dict(self): | |
100 """Returns all column headers as a dictionary. | |
101 """ | |
102 asdict = {} | |
103 for column_id, values_for_column in self._extra_column_tallies.iteritems(): | |
104 column_header_factory = self.get_column_header_factory(column_id) | |
105 asdict[column_id] = column_header_factory.create_as_dict( | |
106 values_for_column) | |
107 return asdict | |
108 | |
109 def as_dict(self): | |
110 """Returns a dictionary describing this package of ImagePairs. | |
111 | |
112 Uses the KEY__* constants as keys. | |
113 """ | |
114 return { | |
115 KEY__COLUMNHEADERS: self._column_headers_as_dict(), | |
116 KEY__IMAGEPAIRS: self._image_pair_dicts, | |
117 KEY__IMAGESETS: [{ | |
118 KEY__IMAGESETS__BASE_URL: self._base_url, | |
119 KEY__IMAGESETS__DESCRIPTION: self._descriptions[0], | |
120 }, { | |
121 KEY__IMAGESETS__BASE_URL: self._base_url, | |
122 KEY__IMAGESETS__DESCRIPTION: self._descriptions[1], | |
123 }], | |
124 } | |
OLD | NEW |