Reputation: 39
I have a spreadsheet of values for subway lines and their stops. Basically, I am trying to iterate over the CSV file so that when you input a train line it spits out all the stops. I am doing this by creating a dictionary where the key is the train line and the values are a list of the stops. I am telling the function to append but when I print it only shows the last value on the sheet. Thanks for your help!
import os;
class MTALines:
def __init__(self,train="",stop_name=""):
self.__points=[];
self.train=train;
self.stop_name=stop_name;
def addLine(self,stop_name):
self.__points.append(self.stop_name);
def __repr__(self):
string=""
for item in self.__points:
string+=item+","
return string
def main():
inFile = open("hw8 - mta train stop data.csv", "r")
header = inFile.readline();
MTA={};
for line in inFile:
parts = line.split(',');
stop_id=parts[0]
train=stop_id[0]
stop_name=parts[2]
getstops = MTALines(train,stop_name);
getstops.addLine(stop_name);
MTA[train] = getstops;
trainline=""
while trainline!="done":
trainline=input("Please enter a train line, or 'done' to stop: ")
print(trainline,"line:",MTA[trainline])
main();
Update:
As requested here are a few lines of the CSV file:
stop_id,stop_code,stop_name,stop_desc,stop_lat,stop_lon,zone_id,stop_url,location_type,parent_station
101,,Van Cortlandt Park - 242 St,,40.889248,-73.898583,,,1,
101N,,Van Cortlandt Park - 242 St,,40.889248,-73.898583,,,0,101
101S,,Van Cortlandt Park - 242 St,,40.889248,-73.898583,,,0,101
209S,,Burke Av,,40.871356,-73.867164,,,0,209
210,,Allerton Av,,40.865462,-73.867352,,,1,
210N,,Allerton Av,,40.865462,-73.867352,,,0,210
210S,,Allerton Av,,40.865462,-73.867352,,,0,210
Upvotes: 0
Views: 1109
Reputation: 55469
I think you're making this task a little more complicated than it needs to be. You don't really need a custom MTALines class, you can store the data for each stop in a dict, each line can be a list of those dicts, and each line list can live in the MTA dict. It's convenient to use a defaultdict
for MTA, as that will automatically create new lists as needed.
Also, there's no need to parse the CSV file data by hand, there's a csv
module for that. And by using its DictReader
class we can get it to read the data into a dict. It actually uses OrderedDict, to preserve the order of the fields.
Here's my version of your code. I changed the name of the CSV file because I hate filenames with spaces in them. ;) Because we're using a defaultdict of lists for MTA if we try to look up a non-existent line we get an empty list.
import csv
from collections import defaultdict
def main():
MTA = defaultdict(list)
with open("train_data.csv", "r") as inFile:
reader = csv.DictReader(inFile)
#print(reader.fieldnames)
for row in reader:
# Get the line id from the stop id
train = row['stop_id'][0]
# Extract the desired fields to a new dict
data = {'stop_id': row['stop_id'], 'stop_name': row['stop_name']}
MTA[train].append(data)
while True:
line_id = input("Please enter a train line, or 'done' to stop: ")
if line_id == "done":
break
print("line:", line_id)
for stop in MTA[line_id]:
print(stop['stop_id'], stop['stop_name'])
main()
demo output
Please enter a train line, or 'done' to stop: 1
line: 1
101 Van Cortlandt Park - 242 St
101N Van Cortlandt Park - 242 St
101S Van Cortlandt Park - 242 St
Please enter a train line, or 'done' to stop: 2
line: 2
209S Burke Av
210 Allerton Av
210N Allerton Av
210S Allerton Av
Please enter a train line, or 'done' to stop: 3
line: 3
Please enter a train line, or 'done' to stop: done
Upvotes: 2
Reputation: 3409
Your problem is that you made __points as an instance variable. It will only be available for the instance. Obviously you will get the last stop or last instance value. For a quick fix, use __points as class variable like below.
class MTALines:
__points=[];
def __init__(self,train="",stop_name=""):
self.train=train;
self.stop_name=stop_name;
def addLine(self,stop_name):
MTALines.__points.append(self.stop_name);
def __repr__(self):
string=""
for item in self.__points:
string+=item+","
return string
At the end you can use your list as MTALines.__points
Upvotes: 0
Reputation: 39354
I think you may need a defaultdict
to collect lists of MTALines
instances.
It looks like your dict MTA
may overwrite entries if the same train
occurs multiple times.
Try this:
from collections import defaultdict
...
def main():
inFile = open("hw8 - mta train stop data.csv", "r")
header = inFile.readline()
MTA = defaultdict(list) # create defaultdict here
for line in inFile:
parts = line.split(',')
stop_id = parts[0]
train = stop_id[0]
stop_name = parts[2]
getstops = MTALines(train,stop_name)
getstops.addLine(stop_name)
MTA[train].append(getstops) # append to list of MTALines
...
Now the 'problem' might be how to format an entry from the MTA
collection:
print(trainline, "line:", MTA[trainline])
Upvotes: 1