Skip to content

Instantly share code, notes, and snippets.

@tstriker
Last active September 10, 2020 16:16
Show Gist options
  • Save tstriker/fbba343438f9320ba076ad34b827825f to your computer and use it in GitHub Desktop.
Save tstriker/fbba343438f9320ba076ad34b827825f to your computer and use it in GitHub Desktop.
Clock math, clock math + date math, and date math

Clock math!

812L5zyAmpL AC_SL1500

Counting 1-12 ad infinitum

Naive implementation

# 1 -> 2 ... 11 -> 12 -> 1 -> 2..
# naive implementation
i = 0
while True:
    i += 1
    if i > 12:
        i = 1
    print(i)

A saner implementation

# proper implementation
i = 0
while True:
  print(i + 1)
  i = (i + 1) % 12

Modulus (a.k.a. what's left when you divide the thing by the numbers) is your friend.

Eeny, meeny, miny, moe

[(i, i % 4) for i in range(13)]
>>> 
[(0, 0),
 (1, 1),
 (2, 2),
 (3, 3),
 (4, 0),
 (5, 1),
 (6, 2),
 (7, 3),
 (8, 0),
 (9, 1),
 (10, 2),
 (11, 3),
 (12, 0)]

Got some change?

Rounding up random amounts to 5 cents

for i in range(15): 
    moneys = random.randint(1, 999); 
    change = moneys % 5 
    print("%.2f" % (moneys / 100), "%.2f" % ((moneys - change) / 100)) 
>>>
2.91 2.90
0.61 0.60
2.84 2.80
9.96 9.95
0.88 0.85
5.05 5.05
5.21 5.20
9.98 9.95
3.77 3.75
8.65 8.65
3.50 3.50
3.48 3.45
8.25 8.25
1.40 1.40
0.25 0.25

Or, more realistically, rounding time to the nearest, say, quarter.

import random
for i in range(15): 
    minutes = random.randint(0, 59) 
    print(minutes, minutes - minutes % 15) 
>>>
3 0
23 15
57 45
52 45
17 15
42 30
11 0
41 30
46 45
47 45
56 45
16 15
4 0
28 15
59 45

Date math!

September-2020-calendar

What day is it today?

import datetime as dt
today = dt.datetime.now()

today.strftime("%A %b %d. %Y")
>>> 'Thursday Sep 10. 2020'

How do we get to monday?

today.weekday() 
>>> 3     # week starts on monday

monday = today - dt.timedelta(today.weekday())

monday.strftime("%A %b %d. %Y")  
>>> 'Monday Sep 07. 2020'

Ahh, but my week starts on Sunday - clock math!

week_start = today - dt.timedelta((today.weekday() + 1) % 7)
week_start.strftime("%A %b %d. %Y")  
>>> 'Sunday Sep 06. 2020'

Show me you just not messing with the numbers

for i in range(15): 
    date = today + dt.timedelta(i) 
    print(date.strftime("%a %b %d"), "-->", (date - dt.timedelta((date.weekday() + 1) % 7)).strftime("%a %b %d")) 
>>>
Thu Sep 10 --> Sun Sep 06
Fri Sep 11 --> Sun Sep 06
Sat Sep 12 --> Sun Sep 06
Sun Sep 13 --> Sun Sep 13
Mon Sep 14 --> Sun Sep 13
Tue Sep 15 --> Sun Sep 13
Wed Sep 16 --> Sun Sep 13
Thu Sep 17 --> Sun Sep 13
Fri Sep 18 --> Sun Sep 13
Sat Sep 19 --> Sun Sep 13
Sun Sep 20 --> Sun Sep 20
Mon Sep 21 --> Sun Sep 20
Tue Sep 22 --> Sun Sep 20
Wed Sep 23 --> Sun Sep 20
Thu Sep 24 --> Sun Sep 20

How do i get to next month?

today + dt.timedelta(months=1)
>>> TypeError: 'months' is an invalid keyword argument for __new__()

Naturally, because adding a month could mean next month same day, but what if you're on Jan 31st and there is no Feb 31st?

...and so

first = today.replace(day=1)
next_month = (first + dt.timedelta(days=32)).replace(day=1)

next_month.strftime("%a %b %d %Y")
>> 'Thu Oct 01 2020'

Previous month?

first = today.replace(day=1)
prev_month = (first - dt.timedelta(days=1)).replace(day=1)
prev_month.strftime("%a %b %d %Y")
>> 'Sat Aug 01 2020'

this looks random

2020-09-10_16-11

Like, why not go from biggest to smallest or something.

  • years vary in length - no single way to interpret intention
  • months vary in length
  • days do not vary - we good
  • why not hours after that?

consider default usage

today = dt.datetime.combine(today, dt.time()) # <-- cleanest way to strip time

# add 10 days
today + dt.timedelta(10)

 # ah, but i wanna get end of the ninth day - ezpz (this comes up more often than you think)
today + dt.timedelta(10, -1)

# or if you're totally bent on the very last minute of the day
today + dt.timedelta(10, 0, 0, -1)

Realistically, though (days, seconds) and after that specify explicitly - dt.timedelta(hours=77)

bonus points

figure out the clock math on this

capture

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment