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.""" |
| 47 # Special handling when we add the first ImagePair... |
| 48 if not self._image_pair_dicts: |
| 49 self._base_url = image_pair.base_url |
| 50 |
| 51 if image_pair.base_url != self._base_url: |
| 52 raise Exception('added ImagePair with base_url "%s" instead of "%s"' % ( |
| 53 image_pair.base_url, self._base_url)) |
| 54 self._image_pair_dicts.append(image_pair.as_dict()) |
| 55 extra_columns_dict = image_pair.extra_columns_dict |
| 56 if extra_columns_dict: |
| 57 for column_id, value in extra_columns_dict.iteritems(): |
| 58 self._add_extra_column_entry(column_id, value) |
| 59 |
| 60 def set_column_header_factory(self, column_id, column_header_factory): |
| 61 """Overrides the default settings for one of the extraColumn headers. |
| 62 |
| 63 Args: |
| 64 column_id: string; unique ID of this column (must match a key within |
| 65 an ImagePair's extra_columns dictionary) |
| 66 column_header_factory: a ColumnHeaderFactory object |
| 67 """ |
| 68 self._column_header_factories[column_id] = column_header_factory |
| 69 |
| 70 def get_column_header_factory(self, column_id): |
| 71 """Returns the ColumnHeaderFactory object for a particular extraColumn. |
| 72 |
| 73 Args: |
| 74 column_id: string; unique ID of this column (must match a key within |
| 75 an ImagePair's extra_columns dictionary) |
| 76 """ |
| 77 column_header_factory = self._column_header_factories.get(column_id, None) |
| 78 if not column_header_factory: |
| 79 column_header_factory = column.ColumnHeaderFactory(header_text=column_id) |
| 80 self._column_header_factories[column_id] = column_header_factory |
| 81 return column_header_factory |
| 82 |
| 83 def _add_extra_column_entry(self, column_id, value): |
| 84 """Records one column_id/value extraColumns pair found within an ImagePair. |
| 85 |
| 86 We use this information to generate tallies within the column header |
| 87 (how many instances we saw of a particular value, within a particular |
| 88 extraColumn). |
| 89 """ |
| 90 known_values_for_column = self._extra_column_tallies.get(column_id, None) |
| 91 if not known_values_for_column: |
| 92 known_values_for_column = {} |
| 93 self._extra_column_tallies[column_id] = known_values_for_column |
| 94 instances_of_this_value = known_values_for_column.get(value, 0) |
| 95 instances_of_this_value += 1 |
| 96 known_values_for_column[value] = instances_of_this_value |
| 97 |
| 98 def _column_headers_as_dict(self): |
| 99 """Returns all column headers as a dictionary.""" |
| 100 asdict = {} |
| 101 for column_id, values_for_column in self._extra_column_tallies.iteritems(): |
| 102 column_header_factory = self.get_column_header_factory(column_id) |
| 103 asdict[column_id] = column_header_factory.create_as_dict( |
| 104 values_for_column) |
| 105 return asdict |
| 106 |
| 107 def as_dict(self): |
| 108 """Returns a dictionary describing this package of ImagePairs. |
| 109 |
| 110 Uses the KEY__* constants as keys. |
| 111 """ |
| 112 return { |
| 113 KEY__COLUMNHEADERS: self._column_headers_as_dict(), |
| 114 KEY__IMAGEPAIRS: self._image_pair_dicts, |
| 115 KEY__IMAGESETS: [{ |
| 116 KEY__IMAGESETS__BASE_URL: self._base_url, |
| 117 KEY__IMAGESETS__DESCRIPTION: self._descriptions[0], |
| 118 }, { |
| 119 KEY__IMAGESETS__BASE_URL: self._base_url, |
| 120 KEY__IMAGESETS__DESCRIPTION: self._descriptions[1], |
| 121 }], |
| 122 } |
OLD | NEW |