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

2019-02-26 Thread AdamC
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"}

and these are the functions that help load that file:

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:
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)
# 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)

(This isn't the order that the functions are held in the module).
Why would I only get one object in media, even though all three are created?

Adam

--
You back your data up on the same planet?
http://kabads.monkeez.org 
PGP key: 0x7111B833
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


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

2019-02-26 Thread Steven D'Aprano
On Tue, Feb 26, 2019 at 09:09:56AM +, AdamC wrote:

> 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

This cannot be the code you are actually using, because that raises 
UnboundLocalError. count is never initialised, so that function you give 
cannot possibly run as shown.


py> def test():
... count = count + 1
...
py> test()
Traceback (most recent call last):
  File "", line 1, in 
  File "", line 2, in test
UnboundLocalError: local variable 'count' referenced before assignment


There's no point us trying to debug code you aren't actually running. 
Try again with the actual working code. It might help if you read this:

http://www.sscce.org/



-- 
Steven
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


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

2019-02-26 Thread Peter Otten
AdamC 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"}
> 
> and these are the functions that help load that file:
> 
> 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:
> 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)
> # 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)
> 
> (This isn't the order that the functions are held in the module).
> Why would I only get one object in media, even though all three are
> created?

Only one record in your jsonl sample has a 'tpe' handled by createObjects(). 
To make it easier to catch this problem (invalid or unsuspected data) I 
suggest that you rewrite the

> 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)

part of your code as

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:
# Instead of the error message you may also raise an exception.
print(
"Warning: unknown tpe={!r}".format(data["tpe"]),
file=sys.stderr
)

The unconditional else allows you to ensure that every line will be handled.

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


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

2019-02-26 Thread Cameron Simpson

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  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 
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


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

2019-02-26 Thread AdamC
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  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  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}
>

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

2019-02-26 Thread Tobiah




On 2/26/19 6:39 AM, AdamC wrote:

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

It should be:


As was pointed out, the problem is not in your code.  It's in your
data.  You only have one record with a proper 'tpe' value, so that's
all you get in your media list.


Toby
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


[Tutor] Doubt

2019-02-26 Thread Maninath sahoo
is it possible reverse inheritance?
mean child class to parent class
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


[Tutor] I flip a coin 1 million times what is the consecutive times it will come up head and come up tails

2019-02-26 Thread shaeffer
I am learning python.  I wanted to test my ability by making a program to
keep track of the flip of a coin to find how many consecutive times it came
up heads and tails.

 

Just want some criticism on what I have done.

 

 

 

 

 

import random

Hn = {}

Tn = {}

for i in range (0,31):

vars()["Hn"+str(i)] = 0

for i in range (0,31):

vars()["Tn"+str(i)] = 0

total_Heads = 0

total_tails= 0 

tails_number = 0

Heads_number = 0

tries = 0

while tries < 1:

tries += 1

coin = random.randint(1, 2)   #  Flip coin



if coin == 1:

Heads_number += 1 #  Incroment Heads count

total_Heads += 1

if tails_number > 0 :

 

vars()["Tn"+ str(tails_number)] += 1   #  Incroment tails
consecutive count

tails_number = 0

 

if coin == 2:

tails_number += 1   #  Incroment Talies count

total_tails += 1

if Heads_number > 0:



vars()["Hn"+ str(Heads_number)] += 1  #  Incroment Heads
consecutive count

Heads_number = 0



print (tries)

print (total_tails, total_Heads)

for i in range (30):



print ('%-15s %-15s' %(("Tn"+str(i)+"
"+str(eval("Tn"+str(i,("Hn"+str(i)+" "+str(eval("Hn"+str(i))

 

 

 

 

print out

 

1

5259 4741

Tn0 0   Hn0 0  

Tn1 12497339Hn1 12500186   

Tn2 6257043 Hn2 6251565

Tn3 3120686 Hn3 3127257

Tn4 1563418 Hn4 1561175

Tn5 781938  Hn5 779381 

Tn6 390943  Hn6 389768 

Tn7 195569  Hn7 196513 

Tn8 97091   Hn8 97858  

Tn9 48717   Hn9 48745  

Tn10 24493  Hn10 24429 

Tn11 11966  Hn11 12237 

Tn12 6070   Hn12 6062  

Tn13 3021   Hn13 3039  

Tn14 1540   Hn14 1556  

Tn15 679Hn15 726   

Tn16 403Hn16 389   

Tn17 179Hn17 206   

Tn18 94 Hn18 105   

Tn19 49 Hn19 45

Tn20 26 Hn20 24

Tn21 16 Hn21 13

Tn22 5  Hn22 2 

Tn23 1  Hn23 3 

Tn24 2  Hn24 3 

Tn25 1  Hn25 2 

Tn26 0  Hn26 0 

Tn27 0  Hn27 0 

Tn28 0  Hn28 0 

Tn29 0  Hn29 0 

 

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Doubt

2019-02-26 Thread Alan Gauld via Tutor
On 26/02/2019 18:36, Maninath sahoo wrote:
> is it possible reverse inheritance?
> mean child class to parent class

I have no idea what you mean by that. How would it work?
Can you give an example of the kind of thing you want to do?

For example Circles and Rectangles are kinds of Shape
so their classes inherit from class Shape. How would you reverse
the inheritance in that scenario? What would you do with it?

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] I flip a coin 1 million times what is the consecutive times it will come up head and come up tails

2019-02-26 Thread Alan Gauld via Tutor
On 26/02/2019 20:34, shaef...@q.com wrote:
> I am learning python. 

I assume you are coming from some other language?
If not you have managed to come up with the most
convoluted and un-pythonic way imaginable to do
a fairly simple task!

>  I wanted to test my ability by making a program to
> keep track of the flip of a coin to find how many consecutive times it came
> up heads and tails.
> 
> import random
> 
> Hn = {}
> Tn = {}
> 
> for i in range (0,31):
> vars()["Hn"+str(i)] = 0

This is insane!
Just use a list which is indexed by number.
No need for string conversions and no need for
the cumbersome access to vars

Hn = [0 for i in range(31)]

You can then access each cell using

Hn[num]

Instead of having to compute the name every time
and then access a dictionary.

> for i in range (0,31):
> vars()["Tn"+str(i)] = 0

Same here.

> total_Heads = 0
> total_tails= 0 
> tails_number = 0
> Heads_number = 0

> tries = 0
> while tries < 1:
> tries += 1
This is essentially a for loop:

for tries in range(1):

> coin = random.randint(1, 2)   #  Flip coin
> if coin == 1:
> Heads_number += 1 #  Incroment Heads count
> total_Heads += 1
> if tails_number > 0 :
> vars()["Tn"+ str(tails_number)] += 1   #  Incroment tails
> consecutive count

This becomes

Tn[tails_number] += 1

But why are you incrementing the head counts above but the tails_number
value here? That doesn't make sense. I assume you are trying to
terminate the count of consecutive values?

> tails_number = 0

> if coin == 2:
> tails_number += 1   #  Incroment Talies count
> total_tails += 1
> if Heads_number > 0:
> vars()["Hn"+ str(Heads_number)] += 1  #  Incroment Heads
> consecutive count

Hn[heads_number] += 1

> Heads_number = 0

> print (tries)
> print (total_tails, total_Heads)
> for i in range (30):
> print ('%-15s %-15s' %(("Tn"+str(i)+"

  print('Tn[%d] %d   \tHn[%d] %d' % (i,Tn[i],i, Hn[i])

I think. Your code is so complex that I may have misread it.

> "+str(eval("Tn"+str(i,
> ("Hn"+str(i)+" "+str(eval("Hn"+str(i))

Using eval() should hardly ever (never?) be necessary
in normal coding and poses a significant security risk.
Any time you think you need to use it ask for help
because you are probably wrong and there will be a
better option.


> print out
> 1
> 
> 5259 4741
> 
> Tn0 0   Hn0 0  
> 
> Tn1 12497339Hn1 12500186   
> 
> Tn2 6257043 Hn2 6251565
> 
> Tn3 3120686 Hn3 3127257

Given you only looped to 10,000 these results seem
rather suspect.

Even if your algorithm is correct, which I suspect
it may not be, the code is way too complex.

If all you want is the max count of consecutive head
and tails you only need to keep one counter for each
and update it each time a new max is reached. Keep
track of the last face. If the new toss is the same
increment the appropriate count. If its not then check
if the current count is greater than the previous max
for that face and if necessary update it. Then reset
the current count and face.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Doubt

2019-02-26 Thread Mats Wichmann

On 2/26/19 11:36 AM, Maninath sahoo wrote:

is it possible reverse inheritance?
mean child class to parent class



Well, it's Python, so you can do all sorts of things, some of them good 
ideas, some bad...


Like Alan says, the question as asked doesn't really make a lot of sense 
to us, but the way classes (really, user-defined types) work does give 
you a lot of flexibility.  Some people feel like we should express it as 
code reuse at a sophisticated level: if you see a method in another 
class that you'd like to use for your own class, you can inherit that 
method by listing the class in your definition.  Or, if you don't want 
to do so, you write your own method.  So while I wouldn't call it 
reverse inheritance, you as author of your class have all the control of 
what you do and don't take from other classes, and maybe it's not 
entirely accurate to call them child and parent classes because of that?


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor