question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Add __hash__ method to Time class

See original GitHub issue

The Time class should contain the __hash__ method. This will allow it to be used with other functions that require it such as functools.lru_cache.

Here is an example implementation:

     def __hash__(self):
         return hash((self.whole, self.tt_fraction))

Here is a link to what was done for AstroPy: https://github.com/astropy/astropy/pull/8912/files

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:14 (12 by maintainers)

github_iconTop GitHub Comments

1reaction
brandon-rhodescommented, Jul 2, 2020

So I agree about the sum, that makes sense - would the key need to be rounded to some number of digits? All of the articles I have seen make me nervous about using a floating point key, and I don’t know all the ramifications.

Yes, I often take several tries to get floating point reasoning right.

Rounding seems to only make floating point problems less frequent, rather than solving them. If you round a 16-digit number to 14 digits, for example, you now hide 9,999 out of 10,000 cases where a difference could be noticeable. But in that last case, where one 14-digit number ends and the next one begins, it’s the full noise in the 16 digits of precision that will determine which way a number rounds. So I tend to avoid rounding since that rare case will still come back to cause problems for a test or a user someday.

But implicit rounding will occur here in any case because extra digits in the fractional part will disappear when combined with the whole part of the date. I guess I’ll implement it and see if it ever causes problems.

1reaction
brandon-rhodescommented, Jul 2, 2020

True, but it works if you provide floats that in fact add to the same number 😃

from skyfield.api import load, T0, Time
ts = load.timescale()
t0 = Time(ts, 2451545.5, 1.1)
t1 = Time(ts, 2451545.6, 0.9999999999068678)
print(t0.whole, t0.tt_fraction)
print(t1.whole, t1.tt_fraction)
print(t0 - t1)
print(t0 == t1)

But equality is indeed a problematic concept when dealing with floats. One way it could cause problems here is that two different Time objects, like the two we have created here, might be equal yet could give a slightly different coordinate when asked for a satellite or planetary position, because the two floats of which the time is composed could cause different rounding down inside the computation, even though the two floats might represent the same sum. So two times that are “equal” could produce coordinates that are different.

In any case: one possibility would be to hash the sum currently returned by the .tt attribute (which used to be the real value of the time, before I decided to add more digits with this split representation). In the vast majority of cases the hash will come out different for different times. Only for very closely spaced times would they hash the same and have to fall through to comparison. Does that sound like a reasonable first approach?

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to implement a good __hash__ function in python
Just make sure to use hash() on a tuple with exactly the elements that are compared in __eq__() and friends (exactly as you...
Read more >
Python hash() method - GeeksforGeeks
hash () returns hashed value only for immutable objects, hence can be used as an indicator to check for mutable/immutable objects. Python hash() ......
Read more >
Guide to hashCode() in Java - Baeldung
Simply put, hashCode() returns an integer value, generated by a hashing algorithm. Objects that are equal (according to their equals()) must ...
Read more >
5.5. Hashing — Problem Solving with Algorithms and Data ...
The folding method for constructing hash functions begins by dividing the item into equal-size pieces (the last piece may not be of equal...
Read more >
Python Hashes and Equality - Hynek Schlawack
An object hash is an integer number representing the value of the object and can be obtained using the hash() function if the...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found