Question: Taking the average of two years, written as [1858-60]

Question

Taking the average of two years, written as [1858-60]

Answers 5
Added at 2017-11-07 22:11
Tags
Question

There are a few cases where the date is written as 'created ca. 1858-60', where a human reader would understand it as 'created ca 1858-1860.'

As such, imagine two integers representing years.

a = 1858
b = 60

I want to be able to get a+b == 1859.

I could parse them to strings, take the first two characters ('18'), concatinate the shorter string and parse them back to numbers, sure, but..that seems a bit round-a-bound.

What would be the Pythonic way to deal with this?

Answers to

Taking the average of two years, written as [1858-60]

nr: #1 dodano: 2017-11-07 22:11

Parse the string with a regex such as (dd) to get groups XXYY-ZZ those will be stored as g1 g2 and g3.

result = int(g1) * 1000 + (int(g2) + int(g3))/2

This of course assumes the preffix is always the same. So 1890-10 would break...

It also assumes the preffix is always there.

Overall doing the string concat and average seems better...

nr: #2 dodano: 2017-11-07 23:11

Mm if you don't want to convert to strings... Let's do some maths :

a = 1858
b = 60
cent = 0
s = 0
if a < 2000:
    s = a - 1000
    c, y = divmod(s, 100)
    cent = 1000
else:
     s = a - 2000
     cent = 2000
     c, y = divmod(s, 100)
avg = (b + y) / 2
result = cent + (c*100) + avg
nr: #3 dodano: 2017-11-07 23:11

This version works entirely with integers and handles cross-century boundaries:

def year_range_average(a, b):
    return a + (b - (a % 100) + 100) % 100 // 2

>>> year_range_average(1858, 60)
1859
>>> year_range_average(1858, 61)
1859
>>> year_range_average(1858, 62)
1860
>>> year_range_average(1898, 2)
1900
nr: #4 dodano: 2017-11-07 23:11

I think you're going about this wrong. The easier approach is to add the century to b, then use them as normal numbers now that they're equatable.

def add_century(n: int, from_century=1900) -> int:
    """add_century turns a two-digit year into a four-digit year.

    takes a two-digit year `n` and a four-digit year `from_century` and
    adds the leading two digits from the latter to the former.
    """

    century = from_century // 100 * 100
    return century + n

Then you can do:

a, b = 1858, 60
b = add_century(b, from_century=a)
result = (a + b) / 2

Treating the numbers this way provides two benefits.

First of all, you clarify the edge case you might have. Explicitly adding the century from one onto the ending years from the other makes it very clear what's happened if the code should return the wrong result.

Secondly, transforming objects into equatable terms isn't just a good idea, it's required in languages that are, shall we say, less accepting than Python is. A quick transformation so two items are equatable is an easy way to make sure you're not confusing things down the road.

nr: #5 dodano: 2017-11-07 23:11

try this:

a = 1858
b = 60

def average_year(a,b):
    c = int(str(a)[:2]) * 100
    a1 = int(str(a)[2:])
    return c + (b + a1)/2

print average_year(a,b)
> 1859
Source Show
◀ Wstecz