Some basic newbie questions...

J

jonathan.beckett

Hi all,

While working on support at work, I have been picking away at Python -
because I think it could be a valuable scripting tool for building
utilities from. I have been reading the python.org tutorials, and
playing around with some basic code, but I have ended up with a few
questions that probably have straightforward answers - any quick
explanations or assistance would be fantastic...


Question 1...
Given the code below, why does the count method return what it does?
How *should* you call the count method?
a = []
a.append(1)
print a.count


Question 2...
What is the correct way of looping through a list object in a class via
a method of it? (I've hit all sorts of errors picking away at this, and
none of the tutorials I've found so far cover it very well) - apologies
for the arbitrary class - it's the first example I thought up...

class Gun:
Shells = 10

class Battleship:
Gun1 = Gun()
Gun2 = Gun()
Guns = [Gun1,Gun2]

def getShellsLeft(self):
NumShells = 0
for aGun in Guns:
NumShells = NumShells + aGun.Shells
return NumShells

Bizmark = Battleship()

print Bizmark.getShellsLeft()


In the above code, I guess I'm just asking for the *correct* way to do
these simple kinds of things...
 
G

Grant Edwards

Hi all,

While working on support at work, I have been picking away at Python -
because I think it could be a valuable scripting tool for building
utilities from. I have been reading the python.org tutorials, and
playing around with some basic code, but I have ended up with a few
questions that probably have straightforward answers - any quick
explanations or assistance would be fantastic...


Question 1...
Given the code below, why does the count method return what it does?
How *should* you call the count method?
a = []
a.append(1)
print a.count
a.count(1)
a.count(2)

Question 2...
What is the correct way of looping through a list object in a class via
a method of it? (I've hit all sorts of errors picking away at this, and
none of the tutorials I've found so far cover it very well) - apologies
for the arbitrary class - it's the first example I thought up...

class Gun:
Shells = 10

What you wrote created a class variable: there's only a single
"Shells" object and it's shared by all instances of the class.
Based on the way you're using it, I presume you want each gun
to have it's own Shells value. You probably want something like
this:

class Gun:
def __init__(self):
self.Shells = 10
class Battleship:
Gun1 = Gun()
Gun2 = Gun()
Guns = [Gun1,Gun2]

def getShellsLeft(self):
NumShells = 0
for aGun in Guns:
NumShells = NumShells + aGun.Shells
return NumShells

Bizmark = Battleship()

print Bizmark.getShellsLeft()


In the above code, I guess I'm just asking for the *correct* way to do
these simple kinds of things...
 
C

Chris Mellon

Hi all,

While working on support at work, I have been picking away at Python -
because I think it could be a valuable scripting tool for building
utilities from. I have been reading the python.org tutorials, and
playing around with some basic code, but I have ended up with a few
questions that probably have straightforward answers - any quick
explanations or assistance would be fantastic...


Question 1...
Given the code below, why does the count method return what it does?
How *should* you call the count method?
a = []
a.append(1)
print a.count

print a.count(). There's a "Python for VB programmers" out there
somewhere, see if you can find it. In python, functions (and methods
which are special cases of functions) are first class objects, so
you're printing the function object, not calling it.
Question 2...
What is the correct way of looping through a list object in a class via
a method of it? (I've hit all sorts of errors picking away at this, and
none of the tutorials I've found so far cover it very well) - apologies
for the arbitrary class - it's the first example I thought up...

class Gun:
Shells = 10

class Battleship:
Gun1 = Gun()
Gun2 = Gun()
Guns = [Gun1,Gun2]

def getShellsLeft(self):
NumShells = 0
for aGun in Guns:
NumShells = NumShells + aGun.Shells
return NumShells

Bizmark = Battleship()

print Bizmark.getShellsLeft()


In the above code, I guess I'm just asking for the *correct* way to do
these simple kinds of things...

You have the right idea but you've got your object instantiation
wrong. As I write this, I see an email from Grant Edwards that sums
things up nicely, I'll let him explain it.

I suggest working through the Python tutorial and Dive Into Python,
which will introduce you to the concepts you're getting wrong here.
 
J

jonathan.beckett

Chris said:
Hi all,

While working on support at work, I have been picking away at Python -
because I think it could be a valuable scripting tool for building
utilities from. I have been reading the python.org tutorials, and
playing around with some basic code, but I have ended up with a few
questions that probably have straightforward answers - any quick
explanations or assistance would be fantastic...


Question 1...
Given the code below, why does the count method return what it does?
How *should* you call the count method?
a = []
a.append(1)
print a.count

print a.count(). There's a "Python for VB programmers" out there
somewhere, see if you can find it. In python, functions (and methods
which are special cases of functions) are first class objects, so
you're printing the function object, not calling it.
Question 2...
What is the correct way of looping through a list object in a class via
a method of it? (I've hit all sorts of errors picking away at this, and
none of the tutorials I've found so far cover it very well) - apologies
for the arbitrary class - it's the first example I thought up...

class Gun:
Shells = 10

class Battleship:
Gun1 = Gun()
Gun2 = Gun()
Guns = [Gun1,Gun2]

def getShellsLeft(self):
NumShells = 0
for aGun in Guns:
NumShells = NumShells + aGun.Shells
return NumShells

Bizmark = Battleship()

print Bizmark.getShellsLeft()


In the above code, I guess I'm just asking for the *correct* way to do
these simple kinds of things...

You have the right idea but you've got your object instantiation
wrong. As I write this, I see an email from Grant Edwards that sums
things up nicely, I'll let him explain it.

I suggest working through the Python tutorial and Dive Into Python,
which will introduce you to the concepts you're getting wrong here.

I'm not a VB programmer :) I'm just tooling around with Python while I
have time, figuring out how the syntax hangs together before I start
trying to do anything remotely clever with it.

I normally work with PHP, C#, Javascript, and the odd bit of C++, but
find myself doing christmas support, so am looking for something to
pick away at until the phone rings :)

One thing I would like to do is play with pySQLite, which looks like it
might be very handy indeed for making migration tools...
 
J

jonathan.beckett

Hi Grant, thanks for the code snippets - made total sense.

On the evidence of the last couple of hours, Python is still feeling
very alien, but I'm starting to get my head around it.

I'm just finding it a bit weird that some of the built in functions are
static, rather than methods of objects (such as len() being used to
find the length of a list).

Anyway - cheers again!

Jonathan
 
G

Grant Edwards

Given the code below, why does the count method return what it does?
How *should* you call the count method?
a = []
a.append(1)
print a.count

print a.count().

Which will cause an exception, BTW, since the count method
requires one parameter telling it what you want to count
occurrences of.
I'm not a VB programmer :)

He assumed you were because you were trying to call a function
without using parens. VB is probably the most common language
where you call something by writing

functionName

rather than

functionName()

IIRC Pascal precedures are called w/o parens, but if you pick
Joe Random off the 'net he's more likely to know VB than
Pascal.
I normally work with PHP, C#, Javascript, and the odd bit of C++,

Do any of them call functions w/o parens?
 
G

Grant Edwards

I'm just finding it a bit weird that some of the built in functions are
static, rather than methods of objects (such as len() being used to
find the length of a list).

Well, they actually are methods of objects (at least they are
now -- maybe they didn't used to be).

len(foo) is just syntactic sugar for foo.__len__()

I think.
 
S

Scott David Daniels

jonathan.beckett said:
Hi all,

While working on support at work, I have been picking away at Python -
because I think it could be a valuable scripting tool for building
utilities from. I have been reading the python.org tutorials, and
playing around with some basic code, but I have ended up with a few
questions that probably have straightforward answers - any quick
explanations or assistance would be fantastic...
Work through the tutorial; don't expect simply reading it to work.
Question 1...
Given the code below, why does the count method return what it does?
How *should* you call the count method?
a = []
a.append(1)
print a.count
count is a method, so this is a bound method expression.
What you _mean_ is:
a = []
a.append(1)
print a.count(1) # to count the ones.
Question 2...
What is the correct way of looping through a list object in a class via
a method of it? (I've hit all sorts of errors picking away at this, and
none of the tutorials I've found so far cover it very well) - apologies
for the arbitrary class - it's the first example I thought up...

class Gun:
Shells = 10

class Battleship:
Gun1 = Gun()
Gun2 = Gun()
Guns = [Gun1,Gun2]

def getShellsLeft(self):
NumShells = 0
for aGun in Guns:
NumShells = NumShells + aGun.Shells
return NumShells

Bizmark = Battleship()

print Bizmark.getShellsLeft()
Too many misconceptions here (I changed to a more PEP-8 style naming):

class Gun(object):
def __init__(self):
self.shells = 10

class Battleship(object):
def __init__(self):
self.guns = [Gun(), Gun()]

def getShellsLeft(self):
numShells = 0
for aGun in self.guns:
numShells += aGun.shells
return numShells

theBizmark = Battleship()
print theBizmark.getShellsLeft()

In the above code, I guess I'm just asking for the *correct* way to do
these simple kinds of things...

--Scott David Daniels
(e-mail address removed)
 
J

jonathan.beckett

Too many misconceptions here (I changed to a more PEP-8 style naming):
class Gun(object):
def __init__(self):
self.shells = 10

class Battleship(object):
def __init__(self):
self.guns = [Gun(), Gun()]

def getShellsLeft(self):
numShells = 0
for aGun in self.guns:
numShells += aGun.shells
return numShells

theBizmark = Battleship()
print theBizmark.getShellsLeft()

Excellent example - once upon a time I used to write very neat code
indeed, but exposure to C# had pretty much knackered that (where all
the framework object methods are capitalized).
 
S

Scott David Daniels

Excellent example - once upon a time I used to write very neat code
indeed, but exposure to C# had pretty much knackered that (where all
the framework object methods are capitalized).

Here's an improvement:

For Python 2.3: # using the "sum" primitive
...
def getShellsLeft(self):
return sum([aGun.shells for aGun in self.guns])
...

For Python 2.4 or later: # allows generator expressions
...
def getShellsLeft(self):
return sum(aGun.shells for aGun in self.guns)
...

--Scott David Daniels
(e-mail address removed)
 
D

Duncan Booth

jonathan.beckett said:
I'm just finding it a bit weird that some of the built in functions are
static, rather than methods of objects (such as len() being used to
find the length of a list).

When it comes down to it, its a design decision, so neither right nor wrong
in itself. You need to look a bit wider than just 'len' to understand it.

There is the historical attribute: as I understand it, once upon a time,
way back in the mists of time tuples didn't have methods at all, so you had
to use a global function if you wanted to get the length of a tuple. That
of course is no longer the case. However, ignoring for a moment that this
may have been part of the reason why Python started in the direction of
global helper functions, there are a lot of reasons why it turns out to
have been a good decision.

Consider 'sum' for a moment. The function needs to know how to iterate over
a sequence, but the sequence itself doesn't need to provide any support
apart from iteration to be supported by 'sum'. If 'sum' was a method then
you would have to implement it separately in every summable object;
implement it in a common base class to all iterables; provide a 'Summable'
mixin class requiring every designer of an iterable to decide at the outset
whether they want it to be summable; or provide an adaptor class which
takes an iterator and returns a summable iterator (which just adds a
needless extra layer of complexity over the global function we started
with).

'min', 'max', 'sorted', 'zip' are other functions which similarly provide
support to any kind of iterable without encumbering the iterable protocol
itself.

Next consider 'iter'. That's a global function which calls the __iter__
method, but it also has a fallback behaviour. Before Python had __iter__
iteration was define by calling __getitem__ with increasing index values,
and if you don't have an __iter__ method the iter builtin will try the old
protocol instead. So the global function has some more benefits: we can
change the protocol it implements and continue to provide backward
compatability, and we can have it do more than just calling the method
which does the implementation.

getattr is another example of a builtin which appears to do the job of a
method (__getattribute__) but actually does a whole lot more with fallback
and exception handling in the function. Converting an AttributeError
exception to a default value would be particularly nasty to get right if we
were depending on a direct call to a base class __getattribute__ which
might be overridden in the implemented class.

cmp is another good example: cmp(a,b) returns a.__cmp__(b), but if a
doesn't have an __cmp__ method then it tries to return -b.__cmp__(a) (and
has another fallback if even that fails).

There is also an argument that Python uses __ to distinguish internal
implementation details so that the internal methods are effectively kept
out of the user's namespace. The ordinary user shouldn't need to worry
about the presence of __ methods as they never need to call them directly.
In fact for beginners probably __init__ and "if __name__=='__main__':" are
the only things besides 'keep off the double underscores' that they need to
know about them.

So where does that leave 'len'? It is a function primarily for consistency
with the general idea that you call a builtin (or a function imported from
a support module) rather than calling a __ method directly. It does add
some minimal functionality over calling __len__ directly, but not such that
you'ld normally notice the difference.
 
D

Daniel Klein

Hi all,

Question 2...
What is the correct way of looping through a list object in a class via
a method of it?

Without peeking at any of the other responses, here is what I came up
with. I hope it helps...

class Gun(object):
def __init__(self, shells = 10):
self.shells = shells

class Battleship(object):
def __init__(self, shipname = '', guns = []):
self.shipname = shipname
self.guns = guns

def getShellsLeft(self):
numShells = 0
for gun in self.guns:
numShells += gun.shells
return numShells

if __name__ == '__main__':
aShip = Battleship(shipname = "Bizmark", guns = [Gun(), Gun(6)])
print "%s has %d shells left." \
% (aShip.shipname, aShip.getShellsLeft())


Dan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top