Coronavirus Updates : NPR

The World Health Organization warns of very high risk posed by omicron variant : Coronavirus Updates : NPR

The World Health Organization is warning that the new omicron variant of the coronavirus poses a "very high" global risk because of the possibility that it spreads more easily and might resist vaccines and immunity in people who were infected with previous strains.

In a technical brief issued Sunday, the WHO warned its 194 member states that the new variant's numerous mutations "may confer immune escape potential and possibly transmissibility advantage," and as a result "the likelihood of potential further spread of omicron at the global level is high."

Below is the code I am using to generate the crunched numbers for Albany County, for example my 2021 Albany County Election Spreadsheet

Below is the code I am using to generate the crunched numbers for Albany County, for example my 2021 Albany County Election Spreadsheet. Text is converted using pdftotext -layout 2021GeneralRecanvass.txt which converts the PDF to a structured text file for easier parsing. The Excel Writer library is used for extensive formatting of the file for easy reading and parsing. View this as a separate page for syntax highlighting.

from io import StringIO
import re
import pandas as pd
import numpy as np

# paths
# electionResultText = '/home/andy/Desktop/2021GeneralRecanvass.txt'
# enrollmentXLS = '/home/andy/enroll/nov21-Enrollment/AlbanyED_nov21.xlsx' 
# outputPath = '/tmp/2021_albany_county_races.xlsx'

# electionResultText = '/home/andy/Documents/GIS.Data/election.districts/2020GeneralRecanvass.txt'
# enrollmentXLS = '/home/andy/enroll/nov20-Enrollment/AlbanyED_nov20.xlsx' 
# outputPath = '/tmp/2020_albany_county_races.xlsx'

electionResultText = '/home/andy/Documents/GIS.Data/election.districts/2019'
enrollmentXLS = '/home/andy/enroll/nov19-Enrollment/AlbanyED_nov19.xlsx' 
outputPath = '/tmp/2018_albany_county_races.xlsx'

# number to excel column letter
def letter(colNum):
    import math
    
    if colNum > 26:
        return chr(ord('@')+math.floor(colNum/26))+chr(ord('@')+colNum%26)
    else:
        return chr(ord('@')+colNum)

pd.set_option("display.max_rows", None)
pd.set_option("display.max_columns", None) # show everything when previewing

with open(electionResultText) as f:
    data = f.read()

enroll = pd.read_excel(enrollmentXLS, header=4)
enroll = enroll[(enroll['STATUS']=='Active')][['ELECTION DIST', 'TOTAL']].dropna()
enroll['ELECTION DIST'] = enroll['ELECTION DIST'].astype(str).str.replace('  ',' ')
enroll['ELECTION DIST']=enroll['ELECTION DIST'].str.strip()
enroll['Enrollment'] = enroll['TOTAL']
enroll.drop(labels=['TOTAL'], axis=1, inplace=True)

# array containing election result dataframes
er = {}
    
# split each race which is divided by ten or more equal signs
for raceData in re.split('={10,}',data):

    # blank out old data frame
    df = None

    # split lines
    rows = raceData.split('\n')

    race = ""
    candidates = {}
    startAt = 0
    
    for i, line in enumerate(rows):
        # find race name
        if re.search('VOTES\s*?PERCENT', line):
            race = rows[i+1]
        
        race = race.replace('  ',' ')
        race = race.rstrip()
        #print(race)
        
        # find candidate names
        for result in re.findall('(\d\d)\s*?=\s*?(\w.*?)\d', line):
            candidates[int(result[0])] = result[1].rstrip()
       
        # find start at location for CSV reader
        if re.findall('-{5,}', line):
            startAt = i+3
            break
    
    # skips enrollment stats, as the don't have candidates
    if not candidates or not 2 in candidates:
        continue
    
    if not race:
        continue
        
    #print(race)
    
    df = pd.read_csv(
        StringIO(raceData),
        header=None,
        skiprows=startAt,
        sep='(?<=\d)\s{1,}(?=\d)',
        engine='python',
        on_bad_lines='warn')
    
    df=df[df[0].str.contains('^\d{4}').fillna(False)] # ONLY ROWS STARTING WITH 4-DIGIT ED CODE
    
    df.reset_index(drop=True, inplace=True) # reset index so we can use it in formulas

    df=df.rename(candidates,axis=1) # rename columns 
    
    df.iloc[:,1:]=df.iloc[:,1:].apply(pd.to_numeric) # make sure all columns are numeric 
    df.iloc[:,1:]=df.iloc[:,1:].convert_dtypes('int32') # cast columns to int32

    # crunching
    df.insert(1, 'Ballot', df.iloc[:,1:].convert_dtypes('int32').sum(axis=1)) # add total column
    
    df.insert(2, 'Blanks', df['OVER VOTES'].convert_dtypes('int32')) # add blank
    df.drop(labels=['OVER VOTES'], axis=1, inplace=True)

    df['Blanks']+=df['UNDER VOTES'].convert_dtypes('int32') # add under votes
    df.drop(labels=['UNDER VOTES'], axis=1, inplace=True)

    df.insert(3, 'Canvas', '=F'+(df.index+2).map(str)+'-G'+(df.index+2).map(str))  
    df.insert(4, 'TO %', '=(F'+(df.index+2).map(str)+'/E'+(df.index+2).map(str)+')')
    df.insert(5, 'DO %', '=(G'+(df.index+2).map(str)+'/F'+(df.index+2).map(str)+')')
        
    # create check columns
    df['CHECK'] = '=F'+(df.index+2).map(str)+'-G'+(df.index+2).map(str)
    df['CHECK %'] = '=0'
    
    # add percent columns
    for i, col in enumerate(df.columns[6:-2]): 
        try:
            # check columns
            if (len(df.columns)-i-2) > 0:
                # add to check column
                df['CHECK'] += '-'+letter(i+i+11)+(df.index+2).map(str)

                # add check percent
                df['CHECK %'] += '+'+letter(i+i+12)+(df.index+2).map(str)

            # add percent
            df.insert(i+i+7, col+' %', '=('+letter(i+i+11)+(df.index+2).map(str)+'/H'+(df.index+2).map(str)+')') 
        except:
            pass

    # add T W E Columns, drop combined field
    df[['ED Code','Municipality','String','Ward','ED']]=df[0].str.extract('(\d\d\d\d)\s*?(.*?)(\s*?WARD\s*(\d*))?\s*?ED\s*(\d*)')

    # temporary string used for data merge with enrollments
    df['ELECTION DIST'] = df['Municipality'].str.strip().replace('  ',' ') + \
    ' '+df['Ward'].fillna(0).astype(str).str.zfill(3)+df['ED'].str.zfill(3).astype('str')

    # merge on ED Key
    df=df.merge(enroll, on='ELECTION DIST', how='left')
    df=df.drop(0, axis=1)
    df=df.drop(labels=['ELECTION DIST','String'],axis=1)
    
    # move columns to proper order
    cols = list(df.columns)
    df = df[cols[-5:]+cols[:-5]]
    
    df['Municipality']=df['Municipality'].str.title()
    df['Municipality'] = df['Municipality'].str.strip().replace('  ',' ') # remove whitespace around muni column
    
    # array with election result dataframes
    er[race]=df.fillna(0)
    
# write file
ew = pd.ExcelWriter(outputPath)

for i, race in enumerate(er):
    raceStr = str(i+1)+' '+race
    if (len(race)>28):
        raceStr = str(i+1)+' '+race[:10] + '...' + race[-10:]
    
    # disble header, manually write, as pre-defined headers can't be formatted
    er[race].fillna(0).to_excel(ew,sheet_name=raceStr, index=False)
    
    headForm = ew.book.add_format({'text_wrap': 1, 'font_family': 'Arial', 'bold': True , 
                                   'valign': 'vcenter', 'align': 'center', 'bg_color': '#CCCCCC'})
    for colnum, value in enumerate(er[race].columns.values):
        ew.sheets[raceStr].write(0, colnum, value, headForm)
    
    ew.sheets[raceStr].set_row(0,50)
    
    # set column width for all columns to 20, freeze panes
    bodyForm = ew.book.add_format({'text_wrap': 1, 'font_family': 'Arial', 'num_format': '#,##0', 'valign': 'vcenter', 'align': 'right'})
    bodyPerForm = ew.book.add_format({'text_wrap': 1, 'font_family': 'Arial', 'num_format': '0.0%', 'valign': 'vcenter', 'align': 'right'})
    muniForm = ew.book.add_format({'text_wrap': 1, 'font_family': 'Arial', 'valign': 'vcenter', 'align': 'center'})
    ew.sheets[raceStr].set_column('A1:A9999', 6, bodyForm)
    ew.sheets[raceStr].set_column('B1:B9999', 15, muniForm)
    ew.sheets[raceStr].set_column('C1:D9999', 4, bodyForm)
    ew.sheets[raceStr].set_column('E1:H9999', 10, bodyForm)
    ew.sheets[raceStr].set_column('I1:J9999', 10, bodyPerForm)
    
    for colNum in range(11,40):
        if colNum%2:
            ew.sheets[raceStr].set_column(letter(colNum)+'1:'+letter(colNum)+'9999', 12, bodyForm)
        else:
            ew.sheets[raceStr].set_column(letter(colNum)+'1:'+letter(colNum)+'9999', 12, bodyPerForm)

    ew.sheets[raceStr].freeze_panes('E2')
        
ew.save()

Weather Update – November 29, 2021

This looks like another cold week ahead ❄

Not a lot of snow ahead but generally cool and December like. I guess that’s to be expected this time of year. The weekend doesn’t look that bad but it’s too early to make plans. If I headed up to the Berskires I could use my skis 🎿. Or maybe the Adirondacks, depends on how much snow and if my truck is ready by then.

Truth be told though at this point I plan to basically hibernate, focus on work, hike out to Five Rivers 🐦 and count down the days to spring. Some smaller trips, but the days are short, the nights are long and it’s kind of cold. Maybe though definately thinking about an end of the year trip to kick off the New Year. NYE is a Friday this year.

Today.
Feels like …
December 22nd.

Cloudy then Slight Chance of Snow Showers

A slight chance of snow showers between noon and 4pm. Mostly cloudy.

North wind 3 to 8 mph. Chance of precipitation is 20%.

and

36 degrees , 4:23
sunset.
Tonight.
Feels like …
December 21st.

Partly Cloudy

Partly cloudy.

Northwest wind 5 to 7 mph becoming calm in the evening.

and

21 degrees , 7:05
sunrise.
Tuesday.
Feels like …
December 15th.

Partly Sunny

Partly sunny.

South wind 5 to 8 mph.

and

38 degrees , 13 max wind chill, 4:23
sunset.
Tuesday Night.
Feels like …
November 26th.

Mostly Cloudy

Mostly cloudy.

South wind around 8 mph.

and

28 degrees , 7:06
sunrise.
Wednesday.
Feels like …
December 3rd.

Partly Sunny

Partly sunny.

Southwest wind 7 to 9 mph.

and

42 degrees , 4:23
sunset.
Wednesday Night.
Feels like …
November 17th.

Mostly Cloudy then Chance of Snow Showers

A chance of snow showers after 1am. Mostly cloudy.

Chance of precipitation is 30%.

and

31 degrees , 7:07
sunrise.
Thursday.
Feels like …
November 25th.

Snow Showers is likely then Rain/Snow is likely

Snow showers likely before 1pm, then a chance of rain showers. Mostly cloudy.

Chance of precipitation is 60%.

and

45 degrees , 4:22
sunset.
Thursday Night.
Feels like …
November 13th.

Mostly Cloudy

Mostly cloudy.

 

and

32 degrees , 7:08
sunrise.
Friday.
Feels like …
December 15th.

Mostly Sunny

Mostly sunny.

 

and

38 degrees , 4:22
sunset.
Friday Night.
Feels like …
November 30th.

Partly Cloudy then Chance of Snow Showers

A chance of snow showers after 1am. Mostly cloudy.

Chance of precipitation is 30%.

and

27 degrees , 7:09
sunrise.
Saturday.
Feels like …
December 18th.

Chance of Snow Showers

A chance of snow showers. Partly sunny.

Chance of precipitation is 30%.

and

37 degrees , 4:22
sunset.
Saturday Night.
Feels like …
December 17th.

Partly Cloudy

Partly cloudy.

 

and

22 degrees , 7:10
sunrise.
Sunday.
Feels like …
December 31st.

Partly Sunny

Partly sunny.

 

and

34 degrees , 4:22
sunset.

Good Morning – November 29, 2021

Good morning! Happy Cyber Monday πŸ›οΈ !

Go buy all that cheap plastic shit from China the marketers say.

Cloudy and 28 degrees in Delmar, NY. ☁ Calm wind.There is a dusting of snow on the ground. β˜ƒ Things will start to thaw out at around 10 am. 🌑️

Winters back, I heard the heat click on and off a few times last night. ❄ Not a real cold night but still winter. I told myself I would turn up the heat last night but kind of went upstairs and forgot about it. Up not quite as early as some days recently but still pretty early – around six. Pancakes πŸ₯ž and strawberries πŸ“ again this morning.

I have a meeting today so I have to dress up for work πŸ‘¨β€βš–οΈ so I am taking the local bus 🚍 into the office 🏒. Actually the later bus than I should because I got working with R programming and forgot about the time. ⌚ And it’s not like I was up late, although last night I stayed up relatively late until 9 pm.

Today in the afternoon I’m going to call πŸ“± about the truck tires. I have reason to believe that they should arrive today or tomorrow. πŸ€”I’m hopeful as I’m ready to get Big Red inspected and moved behind this all.🚘

I don’t really care about Cyber Monday πŸ›οΈ but it’s pretty obvious that there are some good deals on the stock market with Omnricon COVID out there on the horizon. πŸ‘Ύ As I noted on Saturday, I’m ready to work from home if necessary. I have my laptop πŸ–₯ and my phone plan contains some hot spot data and I can upgrade to more data if it goes entirely remote again. It’s a whole lot easier the second time around and I’m quite happy to work from the wilderness when it warms up somewhat. β˜€