0

How can i rewrite this program so i get all the data.txt to a list and so i can search after city and get time and local to that city using list objects and attributes?

Data.txt

City1
Time1
Local1
--------------
City2
Time2
Local2
--------------
City
Time
Local
--------------
City3
Time3
Local3
--------------

Program

class store:
    def __init__(self, city, time, local):
        self.city = city
        self.time = time
        self.local = local

    def readfile():
        row = "start"
        list = []
        infile = open("data.txt", "r", encoding="utf-8")
        while row != "":
            row = infile.readline()
            list.append(rad)
        infile.close()

store.readfile()
3
  • 4
    There are several major errors in your code. Did you consider reading a basic python howto? Commented Sep 7, 2013 at 18:05
  • Some of the "errors" was there because i forgot to rename everything =) Commented Sep 7, 2013 at 19:11
  • I did not mean syntax errors, but the conceptional ones. Your class definition makes absolutely no sense, that's why you should read some basic tutorials about python and object oriented programming. Commented Sep 8, 2013 at 10:42

4 Answers 4

1
class City(object):
    def __init__(self, name, time, local):
        self.name = name
        self.local = local
        self.time = time

class Store(object):
    def __init__(self):
        self.data = {}

    def readfile(self, filename):
        with open(filename, 'r') as datafile:
            subdata = []
            for line in datafile:
                if line.startswith('----'):
                    city = City(subdata[0], subdata[1], subdata[2])
                    self.data[subdata[0]] = city
                    subdata = []
                else:
                    subdata.append(line.rstrip())

    def city_named(self, city_name):
        return self.data[city_name]

store = Store()
store.readfile('Data.txt')

example_city = store.city_named('City1')

print(example_city.name)
print(example_city.time)
print(example_city.local)
Sign up to request clarification or add additional context in comments.

1 Comment

Been trying to solve this problem from your code. Local variable 'city' referenced before assignment. can't find the problem..
1

I would read the entire file and split it into strings like so:

with open('data.txt') as f:
    lst = f.read().split()

Then filter out the dash lines:

lst = [s for s in lst if not s.startswith('-')]

Then split the strings into groups of three, provided the number of strings is divisable by 3:

lst3 = [lst[i:i+3] for i in range(0, len(lst), 3)]

Finally assign the vars of your class:

for item in lst3:
    self.city, self.time, self.local = item

2 Comments

Or better yet, skip readlines() altogether and do lst = [s for s in f if not s.startswith('-')]?
Reading the entire thing then splitting it is more robust. For example, if there are 2 strings on the same line, or if there is am empty line, reading lines has to consider these cases, where split doesn't. Indeed, if each line can more than one string, then the correct solution would be line oriented.
0

If the file maintains that simple rigorous structure, this will do the trick:

def info_from_city(file,city):
    city += '\n'
    list = fh.readlines()
    city_index = list.index(city)
    time_index = list[city_index+1]
    local_index = list[city_index+2]

    return (time_index,local_index)

fh = open('data.txt')

print 'Time and local:'
print info_from_city(fh,'City2')

output is:

Time and local:
('Time2\n', 'Local2\n')

(note the newline chars - you may want to get rid of them using .replace('\n', ''))

the .index() method of a list returns the index of earliest instance of a particular string (any object or immutable type actually).

Comments

0

The key idea: you want to process a file in sections, each having the same number of lines. So let's write a general-purpose method to do that:

def section_reader(file_name, n):
    # Takes a file name and an integer.
    # Will yield sections, each with N lines, until the file is exhausted.
    with open(file_name) as fh:
        while True:
            section = [fh.readline() for _ in xrange(n)]
            if len(section[0]): yield section
            else:               return

With that in place, the rest of the code is perfectly boring: a class definition, a utility method to clean up the lines in a section, etc.

class City(object):
    def __init__(self, name, time, local):
        self.name  = name
        self.local = local
        self.time  = time

def clean(section):
    return [line.strip() for line in section[0:3]]

cities = [ City(*clean(s)) for s in section_reader('data.txt', 4) ]

for c in cities:
    print [c.name, c.local, c.time]

5 Comments

I guess you sitting in python 2.7? I get global name clean is not defined?
@user73379 If you're using Python 3, you only need to make 3 changes to the code I posted: (a) City does not inherit from object; (b) change xrange to range; (c) convert print to print(). As far as not finding clean, that has nothing to do with Python 2 vs 3. Not sure how you've put the code together. You must be calling clean in a content where it's not available. Is it in a separate file or class?
I only run your code and changed the things like range and so on. Even then i get global name "clean" is not defined. pastebin.com/1BHVcHgj
@user73379 You've nested the clean function inside the City class. That's why your top-level code can't see it. Move the function out to the top-level, and it will work. As a side note, your code is mixing tabs and spaces for indentation. You should do one or the other consistently (I recommend spaces).
Will fix and try out this code tomorrow, need some sleep hehe.. Thanks for replaying!!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.