Spaces:
Sleeping
Sleeping
| import hashlib | |
| from input.input_validator import generate_random_md5 | |
| # autogenerated class to hold the input data | |
| class InputObservation: | |
| """ | |
| A class to hold an input observation and associated metadata | |
| Attributes: | |
| image (ndarray): | |
| The image associated with the observation. | |
| latitude (float): | |
| The latitude where the observation was made. | |
| longitude (float): | |
| The longitude where the observation was made. | |
| author_email (str): | |
| The email of the author of the observation. | |
| date (Any): # FIXME: specify the type | |
| The date when the observation was made. | |
| time (Any): # FIXME: specify the type | |
| The time when the observation was made. | |
| date_option (datetime.date): | |
| Additional date option for the observation. | |
| time_option (datetime.time): | |
| Additional time option for the observation. | |
| uploaded_file (UploadedFile): | |
| The uploaded file associated with the observation. | |
| image_md5 (str): | |
| The MD5 hash of the image associated with the observation. | |
| Methods: | |
| __str__(): | |
| Returns a string representation of the observation. | |
| __repr__(): | |
| Returns a string representation of the observation. | |
| __eq__(other): | |
| Checks if two observations are equal. | |
| __ne__(other): | |
| Checks if two observations are not equal. | |
| show_diff(other): | |
| Shows the differences between two observations. | |
| to_dict(): | |
| Converts the observation to a dictionary. | |
| from_dict(data): | |
| Creates an observation from a dictionary. | |
| from_input(input): | |
| Creates an observation from another input observation. | |
| """ | |
| _inst_count = 0 | |
| def __init__( | |
| self, image:ndarray=None, latitude:float=None, longitude:float=None, | |
| author_email:str=None, date=None, time=None, date_option:datetime.date=None, | |
| time_option:datetime.time=None, | |
| uploaded_file:UploadedFile=None, image_md5:str=None): | |
| self.image = image | |
| self.latitude = latitude | |
| self.longitude = longitude | |
| self.author_email = author_email | |
| self.date = date | |
| self.time = time | |
| self.date_option = date_option | |
| self.time_option = time_option | |
| self.uploaded_file = uploaded_file | |
| self.image_md5 = image_md5 | |
| self._top_predictions = [] | |
| InputObservation._inst_count += 1 | |
| self._inst_id = InputObservation._inst_count | |
| #self.assign_image_md5() | |
| def set_top_predictions(self, top_predictions:list): | |
| self._top_predictions = top_predictions | |
| # add a method to get the top predictions (property?) | |
| def top_predictions(self): | |
| return self._top_predictions | |
| # add a method to assign the image_md5 only once | |
| def assign_image_md5(self): | |
| raise DeprecationWarning("This method is deprecated. hash is a required constructor argument.") | |
| if not self.image_md5: | |
| self.image_md5 = hashlib.md5(self.uploaded_file.read()).hexdigest() if self.uploaded_file else generate_random_md5() | |
| # new comment / hybj hunk | |
| self._cprint(f"[D] Assigned image md5: {self.image_md5} for {self.uploaded_file}") | |
| def _cprint(self, msg:str, color:str=OKGREEN): | |
| """Print colored message""" | |
| print(f"{color}{msg}{ENDC}") | |
| def __str__(self): | |
| _im_str = "None" if self.image is None else f"image dims: {self.image.shape}" | |
| return ( | |
| f"Observation: {_im_str}, {self.latitude}, {self.longitude}, " | |
| f"{self.author_email}, {self.date}, {self.time}, {self.date_option}, " | |
| f"{self.time_option}, {self.uploaded_file}, {self.image_md5}" | |
| ) | |
| def __repr__(self): | |
| _im_str = "None" if self.image is None else f"image dims: {self.image.shape}" | |
| return ( | |
| f"Observation: " | |
| f"Image: {_im_str}, " | |
| f"Latitude: {self.latitude}, " | |
| f"Longitude: {self.longitude}, " | |
| f"Author Email: {self.author_email}, " | |
| f"Date: {self.date}, " | |
| f"Time: {self.time}, " | |
| f"Date Option: {self.date_option}, " | |
| f"Time Option: {self.time_option}, " | |
| f"Uploaded Filename: {self.uploaded_file}" | |
| f"Image MD5 hash: {self.image_md5}" | |
| ) | |
| def __eq__(self, other): | |
| # TODO: ensure this covers all the attributes (some have been added?) | |
| # - except inst_id which is unique | |
| _image_equality = False | |
| if self.image is None or other.image is None: | |
| _image_equality = other.image == self.image | |
| else: # maybe strong assumption: both are correctly ndarray.. should I test types intead? | |
| _image_equality = (self.image == other.image).all() | |
| equality = ( | |
| #self.image == other.image and | |
| _image_equality and | |
| self.latitude == other.latitude and | |
| self.longitude == other.longitude and | |
| self.author_email == other.author_email and | |
| self.date == other.date and self.time == other.time and | |
| self.date_option == other.date_option and | |
| # temporarily skip time_option, it is followed by the clock and that is always differnt | |
| #self.time_option == other.time_option and | |
| self.uploaded_file == other.uploaded_file and | |
| self.image_md5 == other.image_md5 | |
| ) | |
| return equality | |
| # define a function show_diff(other) that shows the differences between two observations | |
| # only highlight the differences, if element is the same don't show it | |
| # have a summary at the top that shows if the observations are the same or not | |
| def show_diff(self, other): | |
| """Show the differences between two observations""" | |
| differences = [] | |
| if self.image is None or other.image is None: | |
| if other.image != self.image: | |
| differences.append(f" Image is different. (types mismatch: {type(self.image)} vs {type(other.image)})") | |
| else: | |
| if (self.image != other.image).any(): | |
| cnt = (self.image != other.image).sum() | |
| differences.append(f" Image is different: {cnt} different pixels.") | |
| if self.latitude != other.latitude: | |
| differences.append(f" Latitude is different. (self: {self.latitude}, other: {other.latitude})") | |
| if self.longitude != other.longitude: | |
| differences.append(f" Longitude is different. (self: {self.longitude}, other: {other.longitude})") | |
| if self.author_email != other.author_email: | |
| differences.append(f" Author email is different. (self: {self.author_email}, other: {other.author_email})") | |
| if self.date != other.date: | |
| differences.append(f" Date is different. (self: {self.date}, other: {other.date})") | |
| if self.time != other.time: | |
| differences.append(f" Time is different. (self: {self.time}, other: {other.time})") | |
| if self.date_option != other.date_option: | |
| differences.append(f" Date option is different. (self: {self.date_option}, other: {other.date_option})") | |
| if self.time_option != other.time_option: | |
| differences.append(f" Time option is different. (self: {self.time_option}, other: {other.time_option})") | |
| if self.uploaded_file != other.uploaded_file: | |
| differences.append(" Uploaded filename is different.") | |
| if self.image_md5 != other.image_md5: | |
| differences.append(" Image MD5 hash is different.") | |
| if differences: | |
| print(f"Observations have {len(differences)} differences:") | |
| for diff in differences: | |
| print(diff) | |
| else: | |
| print("Observations are the same.") | |
| def __ne__(self, other): | |
| return not self.__eq__(other) | |
| def to_dict(self): | |
| return { | |
| #"image": self.image, | |
| "image_filename": self.uploaded_file.name if self.uploaded_file else None, | |
| "image_md5": self.image_md5, | |
| #"image_md5": hashlib.md5(self.uploaded_file.read()).hexdigest() if self.uploaded_file else generate_random_md5(), | |
| "latitude": self.latitude, | |
| "longitude": self.longitude, | |
| "author_email": self.author_email, | |
| "date": self.date, | |
| "time": self.time, | |
| "date_option": str(self.date_option), | |
| "time_option": str(self.time_option), | |
| "uploaded_file": self.uploaded_file | |
| } | |
| def from_dict(cls, data): | |
| return cls( | |
| image=data.get("image"), | |
| latitude=data.get("latitude"), | |
| longitude=data.get("longitude"), | |
| author_email=data.get("author_email"), | |
| date=data.get("date"), | |
| time=data.get("time"), | |
| date_option=data.get("date_option"), | |
| time_option=data.get("time_option"), | |
| uploaded_file=data.get("uploaded_file"), | |
| image_hash=data.get("image_md5") | |
| ) | |
| def from_input(cls, input): | |
| return cls( | |
| image=input.image, | |
| latitude=input.latitude, | |
| longitude=input.longitude, | |
| author_email=input.author_email, | |
| date=input.date, | |
| time=input.time, | |
| date_option=input.date_option, | |
| time_option=input.time_option, | |
| uploaded_file=input.uploaded_file, | |
| image_hash=input.image_hash | |
| ) | |