[Tutor] Only appending one object to list, when I am expecting more than 1

AdamC kabads at gmail.com
Tue Feb 26 09:39:55 EST 2019


Sorry folks - my code didn't work due to my debug var count to ensure that
I was looping properly.

It should be:
media = []

def loadFile():
    filename = input('Filename? ')
    f = open(filename, 'r')
    createObjects(f)

def createObjects(f):
    '''Takes a file object and iterates through entries, passing them to
create
    object, depending on what object it is.'''
    for line in f:
        data = json.loads(line)
        print(type(data['tpe']))
        name = data['name']
        platform = data['platform']
        dateAdded = data['dateAdded']
        tpe = data['tpe']
        if data['tpe'] == 'Game':
            a = createGame(name, platform, dateAdded,tpe)
            game = {a: tpe}
            media.append(game)
        if data['tpe'] == 'Film':
            a = createFilm(name, platform, dateAdded,tpe)
            film = {a: tpe}
            media.append(film)
    # For some reason I'm only getting one object at a time now when
appending to media
    print(len(media))

def createGame(name, platform, dateAdded, tpe):
    return Game(name, platform, dateAdded)

def createFilm(name, platform, dateAdded, tpe):
    return Film(name, platform, dateAdded)

Also, there is a bug that places an instance variable of dateAdded to tpe,
which is causing an error. This might be why I'm not getting more objects
than I expect.

My class is:

import datetime
class Media:
    def __init__(self, name, platform, tpe):
        self.name = name
        self.platform = platform
        date = datetime.datetime.now()
        datestring = date.strftime("%Y:%m:%d:%H:%M:%s")
        self.dateAdded = datestring
        self.tpe = tpe
        #self.dateAdded = datetime.datetime.now()

and

from . import media
#import media
class Game(media.Media):
    #tpe = 'game'
    # def __init__(self):
    #    self.type = 'game'

Thanks.
Adam


On Tue, 26 Feb 2019 at 10:02, Cameron Simpson <cs at cskk.id.au> wrote:

> Thank you for a well formed problem description.
>
> However, as Steven has remarked the code you've included doesn't run.
> Can you follow up/reply with your actual working script, and also
> include some of the output you get.
>
> That said, I've a few small remarks about the code you have posted:
>
> On 26Feb2019 09:09, AdamC <kabads at gmail.com> wrote:
> >I'm creating lots of objects from json in a file. Part of reading the json
> >back means that it iterates over the file and loads a json object and then
> >creates the object from the dictionary.
> >
> >This is my  file:
> >
> >{"name": "Dwarf Fortress", "platform": "steam", "dateAdded":
> >"2019:02:25:16:56:1551113768", "tpe": "2019:02:21:13:49:1550756942"}
> >{"name": "Jaws", "platform": "Netflix", "dateAdded":
> >"2019:02:25:16:56:1551113768", "tpe": "2019:02:21:13:49:1550756960"}
> >{"name": "Wargames", "platform": "CLI", "dateAdded":
> >"2019:02:25:16:59:1551113984", "tpe": "Game"}
>
> BTW, I notice that only one of these rows has the "tpe" field set to
> "Game" or "Film", specificly the last one. So based on your code below,
> only one of these rows gets appended to the media array. Remarks below
> on writing code which is less prone to hiding this kind of problem.
>
> >and these are the functions that help load that file:
> >
> >media = []
> >
> >def loadFile():
> >    filename = input('Filename? ')
> >    f = open(filename, 'r')
> >    createObjects(f)
>
> This f=open code would normally be written like this:
>
>     with open(filename, 'r') as f:
>         createObjects(f)
>
> That construction ensures that the file gets closed after running
> "createObjects()". As it is in your code the file is not explicitly
> closed; the CPython interpreter will, as it happens, close the file
> pretty promptly when "f" goes out of scope, but the language definition
> doesn't require such immediacy.
>
> >def createObjects(f):
> >    '''Takes a file object and iterates through entries, passing them to
> >create
> >    object, depending on what object it is.'''
> >    for line in f:
> >        count = count + 1
> >        data = json.loads(line)
> >        print(type(data['tpe']))
> >        name = data['name']
> >        platform = data['platform']
> >        dateAdded = data['dateAdded']
> >        tpe = data['tpe']
> >        if data['tpe'] == 'Game':
> >            a = createGame(name, platform, dateAdded,tpe)
> >            game = {a: tpe}
> >            media.append(game)
> >        if data['tpe'] == 'Film':
> >            a = createFilm(name, platform, dateAdded,tpe)
> >            film = {a: tpe}
> >            media.append(film)
>
> These if statements don't cover the case when "tpe" isn't "Game" or
> "Film", and (in other circumstances) could conceivably add two objects.
> If you construct it like this instead:
>
>         if data['tpe'] == 'Game':
>             a = createGame(name, platform, dateAdded,tpe)
>             game = {a: tpe}
>             media.append(game)
>         elif data['tpe'] == 'Film':
>             a = createFilm(name, platform, dateAdded,tpe)
>             film = {a: tpe}
>             media.append(film)
>         else:
>             print("Unhandled tpe value:", repr(tpe))
>
> then (a) only 1 branch can ever apply and (b) reports any unexpected
> values which would otherwise _silently_ get ignored. By always having a
> final "else" in an if/elif/..../else chain you can catch/observe these
> unhandled situations.
>
> >def createGame(name, platform, dateAdded, tpe):
> >    return Game(name, platform, dateAdded)
> >
> >def createFilm(name, platform, dateAdded, tpe):
> >    return Film(name, platform, dateAdded)
>
> Unless there's more stuff happening in these functions which you've
> stripped out for clarity you could just call the object constructors
> directly from the if statements:
>
>     if data['tpe'] == 'Game':
>         a = Game(name, platform, dateAdded)
>         game = {a: tpe}
>         media.append(game)
>
> >Why would I only get one object in media, even though all three are
> >created?
>
> As you may gather, all three input lines are processed, but only one
> gets turned into an object to add to media. Change the if/if into an
> if/elif/else and see if things become more obvious.
>
> Cheers,
> Cameron Simpson <cs at cskk.id.au>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>


-- 
--
You back your data up on the same planet?
http://www.monkeez.org
PGP key: 0x7111B833


More information about the Tutor mailing list