⁨ascclemens⁩ avatar
Anna Clemens

Election tracker

unlisted ⁨1⁩ ⁨file⁩ 2020-11-05 22:58:00 UTC

elec.py

Raw
import requests
from dateutil import tz
from dateutil import parser
from dateutil import relativedelta
from datetime import datetime
from time import sleep

INTERESTING = [
  'AZ',
  'NV',
  'PA',
  'GA',
]

def update():
  return requests.get("https://politics-elex-results.data.api.cnn.io/results/view/2020-national-races-PG.json").json()

def showInteresting():
  data = update()

  max_s_len = max([len(s['stateName']) for s in data if s['stateAbbreviation'] in INTERESTING])

  for state in data:
    name = state['stateName']
    abbr = state['stateAbbreviation']

    if abbr not in INTERESTING:
      continue

    timestamp = parser.isoparse(state['voteTimestamp'])
    d_t = relativedelta.relativedelta(datetime.now(tz.tzutc()), timestamp)
    delta_time = ''
    if d_t.hours != 0:
      delta_time += '{:0>2}:'.format(d_t.hours)
    if d_t.minutes != 0:
      delta_time += '{:0>2}:'.format(d_t.minutes)
    if delta_time == '':
      delta_time += str(d_t.seconds) + 's'
    else:
      delta_time += '{:0>2}'.format(d_t.seconds)
    called = state['editorialStatus'] == 'called'
    percent = state['percentReporting']
    candidates = state['candidates']
    max_c_len = max([len(c['fullName']) for c in candidates])

    call_status = ''
    if called:
      max_votes = None
      for candidate in candidates:
        party = candidate['candidatePartyCode']
        votes = candidate['voteNum']
        if max_votes is None or votes > max_votes[1]:
          max_votes = (party, votes)
      call_status = ' ({code})'.format(code = max_votes[0])

    print('{name} {abbr} ({percent}%){call_status} ({delta_time} ago)'.format(
      name = name.ljust(max_s_len),
      abbr = abbr,
      percent = percent,
      call_status = call_status,
      delta_time = delta_time,
    ))

    all_votes = {c['fullName']: c['voteNum'] for c in candidates}
    for candidate in candidates:
      c_name = candidate['fullName']
      votes = candidate['voteNum']
      v_perc = candidate['votePercentStr']
      other_votes = sum([v for k, v in all_votes.items() if k != c_name])
      margin = votes - other_votes
      print('    {name}: {votes:,} / {margin:+,} / {v_perc}%'.format(
        name = c_name.rjust(max_c_len),
        votes = votes,
        margin = margin,
        v_perc = v_perc,
      ))
    print()
  print('------------------------------')
  print()

if __name__ == '__main__':
  while True:
    showInteresting()
    sleep(10)