# Parses XML to return the bus times at specified bus stop

The code uses the XML-based OC Transpo data feed to create a list of the bus name, where it's headed, and the times. Keep in mind that I am a beginner at python so any advice at all is appreciated.

import subprocess, pprint
from bs4 import BeautifulSoup

def format_set(result_set):
new_set = []
for el in result_set:
new_set.append(str(el.get_text()))
return new_set

def get_stop_number():
stop_numb = raw_input('> ')
try:
return int(stop_numb)
except:
print('Exiting...')
return 'quit'

def get_stop_info(stopNo):
try:
output = subprocess.check_output(('curl -d "appID=ba91e757&apiKey=…'
'&stopNo={}&format=xml" https://api.octranspo1.com/v1.2/GetNextTripsForStopAllRoutes').format(stopNo), shell=True)
soup = BeautifulSoup(output, 'xml')
except:
print('An error occured!')
return None
summary = []
for el in soup.find_all('Route'):
routeNo = int(el.find('RouteNo').get_text())
times = format_set(el.find_all('TripStartTime'))
summary.append(x)
return summary

def is_empty(any_structure):
if any_structure:
return False
else:
return True

if __name__ == '__main__':
while True:
stop_number = get_stop_number()
if stop_number == 'quit':
break
summary = get_stop_info(stop_number)
pprint.pprint(summary)


Sample output:

Please enter your desired stop number (or 'quit'):
> 3058
% Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
100  7756  100  7679  100    77   4654     46  0:00:01  0:00:01 --:--:--  4656
[[92, 'St-Laurent', ['11:30', '12:00', '12:30']],
[92, 'Stittsville', []],
[96, 'St-Laurent', ['10:51', '11:21', '11:51']],
[96, 'Terry Fox', ['10:09', '10:39', '11:09']],
[118, 'Hurdman', ['11:20', '11:40', '12:00']],
[118, 'Kanata', []],
[162, 'Stittsville', ['11:55', '12:55', '13:55']],
[162, 'Terry Fox', []],
[168, 'Bridlewood', ['11:35', '12:05', '12:35']],
[168, 'Terry Fox', []]]
> quit
Exiting...


• Imports are okay, you'll find different advice about whether to import individual functions, so I'll say no more.
• You have __name__ ..., good, perhaps just move the contained block into another function main so that you can easily invoke it from the REPL.
• is_empty is obsolete, at some point you'll just remember that empty lists are False in a boolean context. Oh and it's unused as well.
• You have a lot of quoting options in Python, so if you need a literal ' in a string, consider delimiting it with " instead of using the backslash syntax.
• You're in Python, so perhaps also use the built-in HTTP library instead of shelling out to curl.
• format_set is more easily written with a list comprehension, e.g.:

def format_set(result_set):
return [str(el.get_text()) for el in result_set]

• Technically get_stop_number accepts more than just numbers and 'quit', so just be aware of that. I'd inline the stop_numb variable as well (n.b. why care about saving two characters there?)

...
return int(raw_input('> '))

• get_stop_info has a camel-case variable s, that's inconsistent with the rest and in general not advised in Python. Again, the loop can be a list comprehension, but maybe that'll be a bit too dense, your choice. In general returning an unstructured list like is will also prevent the reader from getting a clearer understanding of the code, but if it's just for display purposes that's fine.

...
return [[int(el.find('RouteNo').get_text()),

• I'm a fan of aggressively factoring out common code, you can try and see how you like e.g. creating smaller functions for int(el.find(name).get_text()) and so on; that can be helpful later on as your program(s) grow(s).