Monthly Archives: January 2015

The Real PG Snow Priority Routes?

PG_roadsThe City of Prince George publishes an annual Snow Operations Map, however, according to it my street (lowest priority) should not get plowed nearly as often as it does (almost always within 24 hours of snowfall). The accompanying, confusing infographic (which does not seem to differentiate between Priority 1 and 2, by the way), makes a passing reference to Bylaw 8625, which does shed some light on the mystery. My street is listed in the bylaw, amongst almost all other highest priority streets in PG.

I spent some of the morning modifying the PG Street Centrelines file (downloaded from the PG Open Data Catalogue) and you can inspect the resulting map here.

Don’t get me wrong: I’m not complaining that my street gets plowed regularly (thank you, plow operators!), I just think the City could use some clarification on the snow operations policy.

Advertisements

Word tables to Excel: Python

Question: I’ve got a folder of 100+ Word documents, each containing a table or two. Can you format that into an Excel spreadsheet for me?

Answer: Yes – bask in the power and glory of Python.

Using the Python for Windows Extension (specifically the win32com.client library), you can drive both Word and Excel with Python. Knowing that this functionality exists is half the battle.

# import libraries
import win32com.client as win32
import os

myDir = r'C:\Projects\ProjectX'

# open invisible Excel app
XL = win32.Dispatch('Excel.Application')
XL.Visible = 0
# load pre-made workbook
XLbook = XL.Workbooks.Open(os.path.join(myDir,'ProjectX_Spreadsheet.xlsx'))
# navigate to first worksheet
XLsheet = XLbook.Worksheets(1)
# counter to keep track of Excel row
XLrow = 2

# loop through files in directory
for myFile in os.listdir(myDir):
 filepath = os.path.join(myDir,myFile)
 filename = os.path.splitext(myFile)[0]
 ext = os.path.splitext(myFile)[1]

 # check if *.docx {optional}
 if ext == '.docx':
 # open invisible Word app
 word = win32.Dispatch('Word.Application')
 word.Visible = 0
 # open Word doc to read
 word.Documents.Open(filepath)
 doc = word.ActiveDocument

 # access first table in Word doc. For subsequent tables, increase index.
 table = doc.Tables(1)

 # get (Word) and set (Excel) some data
 XLsheet.Cells(XLrow,1).Value = table.Cell(Row=1, Column=1).Range.Text

 # get (Word) and set (Excel) some more data
 XLsheet.Cells(XLrow,2).Value = table.Cell(Row=2, Column=3).Range.Text

 # move to next row
 XLrow = XLrow + 1
 # close the current Word doc
 doc.Close()

# exit the Word app
word.Quit()
del word
# save and close Excel app
XLbook.Close(True)
XL.Quit()
del XL

Raspberry Pi, Minecraft, & Python

mc3

I rediscovered my Raspberry Pi, the credit card-sized computer intended to make programming accessible to kids (and everyone), this weekend. After loading an SD card with a fresh copy of NOOBS (here), I was ready to go.

News to me, a free version of Minecraft is included in the NOOBS build, so I tried it out. Not surprisingly in my old age, I was unable to figure out the point of Minecraft without Googling a tutorial, which led me to discover that there is also a Minecraft Python API packaged in the Raspberry Pi, and here’s how I used it to insert a 3×3 pillar of new blocks below my player.

mc1

  • With a fresh world open in Minecraft (above), open Python IDLE 2.x.
  • Import the Minecraft Python library, which should have been installed with NOOBS.
from mcpi import minecraft
  • Create a connection to the currently open Minecraft game
mc = minecraft.Minecraft.create()
  • Get the player’s current position
x,y,z = mc.player.getPos()
  • Loop through the nine adjacent pixels (along the x and z directions; y is vertical)
for x1 in range (-1,2,1):
    for z1 in range (-1,2,1):
  • Get the height of the adjacent pixels – they may not all be at the same height as the player’s position
        h = mc.getHeight(x+x1,z+z1)
  • Set each of the adjacent pixels to a new block type. Block type IDs can be found in the API documentation. Below I set the new blocks to 3, which is dirt.
        mc.setBlock(x+x1,h,z+z1,3)
  • Continuing this pattern while moving the player upward results in a 3×3 pillar of blocks, as below.

mc2

The entire script above would look like so:

from mcpi import minecraft
 mc = minecraft.Minecraft.create()
 x,y,z = mc.player.getPos()
 for x1 in range (-1,2,1):
     for z1 in range (-1,2,1):
         h = mc.getHeight(x+x1,z+z1)
         mc.setBlock(x+x1,h,z+z1,3)