0

Possible Duplicate:
how to extract a text file into a dictionary

I have a text file where I would like to change it into a dictionary in python. The text file is as follows. Where I would like to have the keys as "sun" and "earth" and "moon" and then for the values the orbital radius, period and such so that I can implement an animation solar system into quickdraw.

RootObject: Sun

Object: Sun
Satellites: Mercury,Venus,Earth,Mars,Jupiter,Saturn,Uranus,Neptune,Ceres,Pluto,Haumea,Makemake,Eris
Radius: 20890260
Orbital Radius: 0

Object: Earth
Orbital Radius: 77098290
Period: 365.256363004
Radius: 6371000.0
Satellites: Moon

Object: Moon
Orbital Radius: 18128500
Radius: 1737000.10
Period: 27.321582

My code so far is

def file():
    file = open('smallsolar.txt', 'r')
    answer = {}
    text = file.readlines() 
    print(text)



text = file() 
print (text)

I'm not sure what do now. Any ideas?

Community
  • 1
  • 1
tom smith
  • 71
  • 3
  • 11
  • 2
    Have you tried to do anything with text? That'll contain the lines from your file... – Jon Clements Nov 21 '12 at 17:16
  • What the `text=file()` suppose to do? – Vader Nov 21 '12 at 17:19
  • `text` will be `None`, since your function doesn't return anything. Also, look at [this](http://stackoverflow.com/a/1710405/198633) – inspectorG4dget Nov 21 '12 at 17:22
  • @Vader bad things, there are at least 2 different meaning for file that the OP is using. Currently it looks like it opens a file and prints text, then doesn't close the file, but then assumes there's a return that's useable, then prints that. the method shouldn't be named file. – Jeff Langemeier Nov 21 '12 at 17:23
  • Didn't you just post this question [here](http://stackoverflow.com/questions/13486203/how-to-extract-a-text-file-into-a-dictionary) under 24 hours ago? Why the double-post? – inspectorG4dget Nov 21 '12 at 17:38

2 Answers2

3
answer = {} # initialize an empty dict
with open('path/to/file') as infile: # open the file for reading. Opening returns a "file" object, which we will call "infile"

    # iterate over the lines of the file ("for each line in the file")
    for line in infile:

        # "line" is a python string. Look up the documentation for str.strip(). 
        # It trims away the leading and trailing whitespaces
        line = line.strip()

        # if the line starts with "Object"
        if line.startswith('Object'):

            # we want the thing after the ":" 
            # so that we can use it as a key in "answer" later on
            obj = line.partition(":")[-1].strip()

        # if the line does not start with "Object" 
        # but the line starts with "Orbital Radius"
        elif line.startswith('Orbital Radius'):

            # get the thing after the ":". 
            # This is the orbital radius of the planetary body. 
            # We want to store that as an integer. So let's call int() on it
            rad = int(line.partition(":")[-1].strip())

            # now, add the orbital radius as the value of the planetary body in "answer"
            answer[obj] = rad

Hope this helps

Sometimes, if you have a number in decimal notation ("floating point numbers" in python-speak) in your file (3.14, etc), calling int on it will fail. In this case, use float() instead of int()

inspectorG4dget
  • 110,290
  • 27
  • 149
  • 241
  • OP is clearly a beginner, care to explain/comment your code a bit? – jadkik94 Nov 21 '12 at 17:27
  • answer = {} with open('smallsolar.txt') as infile: for line in infile: line = line.strip() if line.startswith('Object'): obj = line.partition(":")[-1].strip() elif line.startswith('Orbital Radius'): rad = int(line.partition(":")[-1].strip()) answer[obj] = rad elif line.startswith('Period'): per = int(line.partition(":")[-1].strip()) answer[obj] = per print (answer) – tom smith Nov 21 '12 at 17:30
  • i added period to the code but i get this error – tom smith Nov 21 '12 at 17:30
  • ValueError: invalid literal for int() with base 10: '365.256363004' – tom smith Nov 21 '12 at 17:31
  • @tomsmith: look at my edit. Use `float` instead of `int` – inspectorG4dget Nov 21 '12 at 17:35
  • okay thanks and one more thing once i add "per" it will only print the value of the period and not the orbital radius.. – tom smith Nov 21 '12 at 18:09
  • how would i like append the period value into the key – tom smith Nov 21 '12 at 18:09
  • It's better design to append it to the value instead of the key. You will need (1) another `elif` (2) when inserting a key, value pair, make sure that your value is a list/tuple of (radius, period). Give it a shot. I'll help if you can't get it right – inspectorG4dget Nov 21 '12 at 18:16
  • answer = {} with open('smallsolar.txt') as infile: for line in infile: line = line.strip() if line.startswith('Object'): obj = line.partition(":")[-1].strip() elif line.startswith('Orbital Radius'): rad = float(line.partition(":")[-1].strip()) answer[obj] = rad elif line.startswith('Period'): per = float(line.partition(":")[-1].strip()) answer[rad] = per print (answer) – tom smith Nov 21 '12 at 20:42
  • but doing that "answer[rad]" gives extra keys instead of addind the period value to the original earth of sun key – tom smith Nov 21 '12 at 20:43
  • @tomsmith: don't do `answer[rad]`. Do `answer[obj] = (rad, per)` instead. This way, you can get them back as `radius = answer[obj][0]` and `period = answer[obj][1]` – inspectorG4dget Nov 21 '12 at 20:47
  • answer = {} with open('smallsolar.txt') as infile: for line in infile: line = line.strip() if line.startswith('Object'): obj = line.partition(":")[-1].strip() elif line.startswith('Orbital Radius'): orad = float(line.partition(":")[-1].strip()) answer[obj] = orad elif line.startswith('Period'): per = float(line.partition(":")[-1].strip()) answer[obj] = orad, per elif line.startswith('Radius'): rad = float(line.partition(":")[-1].strip()) answer[obj] = orad, per, rad – tom smith Nov 21 '12 at 22:14
  • now i have this where orad is orbital radius per is period and rad is radius, but when i run it i get this error. – tom smith Nov 21 '12 at 22:15
  • Traceback (most recent call last): File "a4.py", line 15, in answer[obj] = orad, per, rad NameError: name 'orad' is not defined – tom smith Nov 21 '12 at 22:15
  • Only do `answer[obj] = orad, per, rad` once. Of course, you can only do so if `orad`, `per`, and `rad` are already defined. So you should do that in the last `elif` - the one that matches for the attribute that comes last in the txt file – inspectorG4dget Nov 21 '12 at 22:18
  • i am using answer[obj] = orad, per, rad once at the last elif statement ...? – tom smith Nov 21 '12 at 23:44
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/19913/discussion-between-inspectorg4dget-and-tom-smith) – inspectorG4dget Nov 22 '12 at 01:10
1

Read the file in one string instead of readlines() and then split on "\n\n", this way you will have a list of items, each describing your object.

Then you might want to create a class which does something like this:

class SpaceObject:
  def __init__(self,string):
    #code here to parse the string

    self.name = name
    self.radius = radius
    #and so on...

then you can create a list of such objects with

#items is the list containing the list of strings describing the various items
l = map(lambda x: SpaceObject(x),items).

And then simply do the following

d= {}
for i in l:
  d[i.name] = i
LtWorf
  • 7,286
  • 6
  • 31
  • 45