Skip to content

Commit

Permalink
Fixup function naming conventions
Browse files Browse the repository at this point in the history
  • Loading branch information
igable committed Apr 15, 2011
1 parent 7219deb commit ceba8f5
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 80 deletions.
45 changes: 23 additions & 22 deletions README.md
@@ -1,18 +1,19 @@
# data-gc-ca-api 0.2.2 README
# data-gc-ca-api 0.2.4 README

## Introduction
data-gc-ca-api: a simple python api for the Canada Open Data Portal

The Government of Canada recently released a number of open data sets at the website
[www.data.gc.ca](http://www.data.gc.ca/). This simple python package has tools
for accessing the [City Weather](http://goo.gl/Xkcqp) open data set. It could
be expanded to include more.
The Government of Canada recently released a number of open data sets at the
website [www.data.gc.ca](http://www.data.gc.ca/). This simple python package
has tools for accessing the [City Weather](http://goo.gl/Xkcqp) open data set.
It could be expanded to include more.

The data_gc_ca_api directory contains the file cityweather.py which has two classes City
and CityIndex. There two classes can be used to access all available quatities
published in the Environment Canada city XML files. Environment Canada provides
a [description](http://goo.gl/XD7w4) of what can be accessed but it's far easier
to look at an example [city XML](http://goo.gl/vyL7r).
The data_gc_ca_api directory contains the file cityweather.py which has two
classes City and CityIndex. There two classes can be used to access all
available quatities published in the Environment Canada city XML files.
Environment Canada provides a [description](http://goo.gl/XD7w4) of what can be
accessed but it's far easier to look at an example [city
XML](http://goo.gl/vyL7r).

## Installation

Expand Down Expand Up @@ -66,26 +67,26 @@ be found by visiting the [www.data.gc.ca](http://www.data.gc.ca/)

## Software License

This program is free software; you can redistribute it and/or modify
it under the terms of either:
This program is free software; you can redistribute it and/or modify it under
the terms of either:

a) the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any
later version, or

b) the Apache v2 License.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See either
the GNU General Public License or the Apache v2 License for more details.
This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See either the GNU General Public License or the Apache v2
License for more details.

You should have received a copy of the Apache v2 License with this
software, in the file named "LICENSE".
You should have received a copy of the Apache v2 License with this software, in
the file named "LICENSE".

You should also have received a copy of the GNU General Public License
along with this program in the file named "COPYING". If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA or visit their web page on the internet at
You should also have received a copy of the GNU General Public License along
with this program in the file named "COPYING". If not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA or visit their web page on the internet at
http://www.gnu.org/copyleft/gpl.html.

2 changes: 1 addition & 1 deletion data_gc_ca_api/__version__.py
@@ -1,2 +1,2 @@
version = "0.2.3"
version = "0.2.4"

59 changes: 29 additions & 30 deletions data_gc_ca_api/cityweather.py
Expand Up @@ -31,8 +31,7 @@ def __init__(self):
try:
urlhandle = urllib.urlopen(self.city_list_url)
except IOError:
print "[Error] Unable to open the data url: " + self.city_list_url
sys.exit(1)
raise IOError("Unable to open the data url: " + self.city_list_url)

cityListTree.parse(urlhandle)
siteList = cityListTree.findall("site")
Expand All @@ -46,46 +45,46 @@ def __init__(self):
'nameFr': site.findtext("nameFr").encode('utf-8') }


def isCity(self, name):
def is_city(self, name):
"""
Returns True if name is a valid city
"""
return name in self.cities

def getDataUrl(self,name):
def data_url(self,name):
"""
Returns resource URL for the city denoted by name
"""
if self.isCity(name):
return self.base_url + self.getProvince(name) + "/" + self.getSiteCode(name) + "_e.xml"
if self.is_city(name):
return self.base_url + self.province(name) + "/" + self.site_code(name) + "_e.xml"
return None

def getProvince(self,name):
def province(self,name):
"""
Returns Province code (e.g. 'ON', 'BC', etc) of the city denoted by name
"""
if self.isCity(name):
if self.is_city(name):
return self.cities[name]['provincecode']
return None

def getSiteCode(self,name):
def site_code(self,name):
"""
Returns the environment canada site for a city. For example Athabasca, AB
has the site code s0000001
"""
if self.isCity(name):
if self.is_city(name):
return self.cities[name]['sitecode']
return None

def getFrenchName(self,name):
if self.isCity(name):
def french_name(self,name):
if self.is_city(name):
return self.cities[name]['nameFr']
return None

def getEnglishCityList(self):
def english_city_list(self):
return self.cities.keys()

def getFrenchCityList(self):
def french_city_list(self):
return [v['nameFr'] for k, v in self.cities.iteritems()]


Expand All @@ -105,18 +104,18 @@ def __init__(self, dataurl):

self.tree.parse(urlhandle)

def getQuantity(self,path):
def get_quantity(self,path):
"""Get the quatity contained at the XML XPath"""
return self.tree.findtext(path)

def getAttribute(self, path, attribute):
def get_atrribute(self, path, attribute):
"""Get the atribute of the element at XPath path"""
element = self.tree.find(path)
if attribute in element:
return element['attribute']
return None

def getAvailableQuantities(self):
def get_available_quantities(self):
"""Get a list of all the available quatities in the form of their
XML XPaths
"""
Expand All @@ -125,24 +124,24 @@ def getAvailableQuantities(self):
# we are getting the full XPath with the attribute strings
# this output is pretty long so maybe it would be wise
# to also have an option to get the XPath without the attributes
# self._getAllXPaths(pathlist,"",self.tree.getroot())
# self._get_all_xpaths(pathlist,"",self.tree.getroot())

self._getAllXPathsWithAttributes(pathlist,"",self.tree.getroot())
self._get_all_xpaths_with_attributes(pathlist,"",self.tree.getroot())
return pathlist

# This nasty little function recursively traverses
# an element tree to get all the available XPaths
# you have to pass in the pathlist you want to contain
# the list
def _getAllXPaths(self, pathlist, path, element):
def _get_all_xpaths(self, pathlist, path, element):
children = element.getchildren()
if not children:
pathlist.append(path + "/"+element.tag)
else:
for child in children:
self._getAllXPaths(pathlist, path + "/" + element.tag, child)
self._get_all_xpaths(pathlist, path + "/" + element.tag, child)

def _makeAttributeList(self, attrib):
def _make_attribute_list(self, attrib):
xpathattrib = ""
for attribute, value in attrib.iteritems():
xpathattrib = xpathattrib + "[@" + attribute + "='" + value + "']"
Expand All @@ -153,33 +152,33 @@ def _makeAttributeList(self, attrib):
# an element tree to get all the available XPaths
# you have to pass in the pathlist you want to contain
# the list
def _getAllXPathsWithAttributes(self, pathlist, path, element):
def _get_all_xpaths_with_attributes(self, pathlist, path, element):
children = element.getchildren()
if not children:
xpathattrib = self._makeAttributeList(element.attrib)
xpathattrib = self._make_attribute_list(element.attrib)

if path == "":
pathlist.append(element.tag + xpathattrib)
else:
pathlist.append(path + "/" + element.tag + xpathattrib)

else:
xpathattrib = self._makeAttributeList(element.attrib)
xpathattrib = self._make_attribute_list(element.attrib)

for child in children:
# skip the root tag
if element.tag == "siteData":
self._getAllXPathsWithAttributes(pathlist, path, child)
self._get_all_xpaths_with_attributes(pathlist, path, child)
else:
# we avoid the opening / since we start below the root
if path == "":
self._getAllXPathsWithAttributes(pathlist, element.tag + xpathattrib, child)
self._get_all_xpaths_with_attributes(pathlist, element.tag + xpathattrib, child)
else:
self._getAllXPathsWithAttributes(pathlist, path + "/" + element.tag + xpathattrib, child)
self._get_all_xpaths_with_attributes(pathlist, path + "/" + element.tag + xpathattrib, child)

# This function will break is thre is any change in the city weather
# XML format
def getAvailableForecastNames(self):
def get_available_forecast_names(self):
forecasts = self.tree.findall('forecastGroup/forecast/period')
forecastnames = []
for forecast in forecasts:
Expand All @@ -188,7 +187,7 @@ def getAvailableForecastNames(self):

# This function will break is thre is any change in the city weather
# XML format
def getAvailableForecastPeriods(self):
def get_available_forecast_periods(self):
forecasts = self.tree.findall('forecastGroup/forecast/period')
forecastnames = []
for forecast in forecasts:
Expand Down
28 changes: 9 additions & 19 deletions testing/weathertest
Expand Up @@ -18,7 +18,7 @@ from data_gc_ca_api.__version__ import version
from optparse import OptionParser
from xml.etree.ElementTree import ElementTree

def getBestGuess(city, cityList):
def get_best_guess(city, cityList):
# Find the closest matching city including the case where the
# input city matches a complete sub string. For example the case where
# someone uses "Ottawa" but environment Canada uses the name
Expand Down Expand Up @@ -67,14 +67,11 @@ def main():

cityindex = CityIndex()

if options.list_quantities and options.list:
parser.error("Can't use -l and -a at the same time")
sys.exit(1)
if options.city and options.list:
parser.error("Can't use -c and -l at the same time")
sys.exit(1)
if options.list:
for cityname in cityindex.getEnglishCityList():
for cityname in cityindex.english_city_list():
print cityname
sys.exit(1)

Expand All @@ -84,35 +81,28 @@ def main():
else:
city = options.city

if options.list_quantities and options.quantity:
parser.error("Can use -q and -a at the same time.")
sys.exit(1)

if options.quantity:
quantity = options.quantity



if cityindex.isCity(city):
cityObject = City(cityindex.getDataUrl(city))
if options.list_quantities:
for q in cityObject.getAvailableQuantities():
print q
else:
if not options.quantity:
print "No requested quantity given, using temperature"
print quantity + " is: " + cityObject.getQuantity(quantity)
if cityindex.is_city(city):
cityObject = City(cityindex.data_url(city))
if not options.quantity:
print "No requested quantity given, using temperature"
print quantity + " is: " + cityObject.get_quantity(quantity)
else:
print city + " is not available"
bestGuess = getBestGuess(city,cityindex.getEnglishCityList())
bestGuess = get_best_guess(city,cityindex.english_city_list())
if bestGuess:
print "Did you mean: " + bestGuess
else:
print "Do 'weatherca --list' to get a list of cities"


# the following prints out all the available xpaths for testing purposes
for xpath in cityObject.getAvailableQuantities():
for xpath in cityObject.get_available_quantities():
# attributelist = ""
# if isinstance(xpath['attrib'],dict):
# for attribute,value in xpath['attrib'].iteritems():
Expand Down
16 changes: 8 additions & 8 deletions weatherca
Expand Up @@ -9,13 +9,13 @@

import sys
import difflib
from optparse import OptionParser
from difflib import SequenceMatcher
from data_gc_ca_api.cityweather import City, CityIndex
from data_gc_ca_api.__version__ import version
from optparse import OptionParser


def getBestGuess(city, cityList):
def get_best_guess(city, cityList):
# Find the closest matching city including the case where the
# input city matches a complete sub string. For example the case where
# someone uses "Ottawa" but environment Canada uses the name
Expand Down Expand Up @@ -80,7 +80,7 @@ def main():
parser.error("Can't use -c and -l at the same time")
sys.exit(1)
if options.list:
for cityname in cityindex.getEnglishCityList():
for cityname in cityindex.english_city_list():
print cityname
sys.exit(1)

Expand All @@ -99,18 +99,18 @@ def main():



if cityindex.isCity(city):
cityObject = City(cityindex.getDataUrl(city))
if cityindex.is_city(city):
cityObject = City(cityindex.data_url(city))
if options.list_quantities:
for q in cityObject.getAvailableQuantities():
for q in cityObject.get_available_quantities():
print q
else:
if not options.quantity:
print "No requested quantity given, using temperature"
print quantity + " is: " + cityObject.getQuantity(quantity)
print quantity + " is: " + cityObject.get_quantity(quantity)
else:
print city + " is not available"
bestGuess = getBestGuess(city,cityindex.getEnglishCityList())
bestGuess = get_best_guess(city,cityindex.english_city_list())
if bestGuess:
print "Did you mean: " + bestGuess
else:
Expand Down

0 comments on commit ceba8f5

Please sign in to comment.