[Tutor] class function problem

2010-09-22 Thread Roelof Wobben


HEllo, 
 
I have this exercise :
 
3.Rewrite the increment function so that it doesn’t contain any loops.
 
The increment function looks like this :
 
def increment(time, seconds):
time.seconds = time.seconds + seconds
while time.seconds>= 60:
time.seconds = time.seconds - 60
time.minutes = time.minutes + 1
while time.minutes>= 60:
time.minutes = time.minutes - 60
time.hours = time.hours + 1

 
So I thought that recursion can do the job.
 
So I wrote this :
 
class tijd :
pass
 
def incrememt_seconds(time): 
   time.seconds = time.seconds - 60 
   time.minutes =  time.minutes + 1 
   if time.seconds>= 60 :
   increment_seconds(time,seconds, minutes)
   return  time 
   
def increment_minutes(time):
time.minutes = time.minutes - 60
time.hours = time.hours + 1
if time.minutes>= 60 :
increment_minutes(time, minutes,hours)
return time
 
def increment(time, seconds):
time.seconds = time.seconds + seconds 
if time.seconds>= 60 :
increment_seconds(time)
if time.minutes>= 60 :
increment_minutes(time)
return time
 
time = tijd()
time.hour = 20 
time.minutes = 20
time.seconds = 20 
seconds = 20
uitkomst = increment(time, seconds)
 
But how can i Check the outcome.
print uitkomst gives the object and print time(uitkomst) gives this error 
message :
 
Traceback (most recent call last):
  File "C:\Users\wobben\workspace\oefeningen\src\test.py", line 34, in 
print time(uitkomst)
AttributeError: tijd instance has no __call__ method
 
Roelof
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Test Drive Development, DocTest, UnitTest

2010-09-22 Thread Walter Prins
You might also have a look at some of the other popular testing frameworks
e.g. Nose (http://somethingaboutorange.com/mrl/projects/nose/0.11.2/) and
py.test (http://wiki.python.org/moin/PyTest)  Both of these have the
advantage that they're discovery based, so they'll go and sniff out tests
from your source, whererver they may be.

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


Re: [Tutor] Test Drive Development, DocTest, UnitTest

2010-09-22 Thread Tino Dai
>
> The *primary* purpose of doctests are to be executable examples. When
> you write documentation, including example code is the most natural
> thing in the world. doctest lets you execute those examples, to ensure
> that they work. They're certainly not meant as an exhaustive test of
> every single feature in the program, but as *documentation* that
> happens to also work as tests.
>
> Unit tests can be a little heavyweight, but they're designed for
> exhaustive tests of the *entire* program, not just the parts with
> user-documentation. You should write whitebox tests, not just blackbox
> tests. That means don't just write tests for the published interface,
> but write tests for the unpublished internal details as well.
>

So, the gist is write tests for everything and the "external testing" should
be
handled by unit tests and the "internal testing" by doctests. Is that
correct?

>
> E.g. if your function has special processing to deal with lists of
> strings, then you need a test for input that is a list of strings. But
> it's not necessary to document that fact in the doc string. What do the
> users care that your function calls a special subroutine to deal with
> lists of strings? So it would be inappropriate to draw attention to
> this fact with a doctest.
>
> Doctests don't just execute themselves. If your developers, junior or
> otherwise, don't know about the tests, don't keep the tests up to date,
> and don't run the tests, then it doesn't matter what testing framework
> you use.
>

Point taken...

>
> Doctests and unittests are complementary. They work well together. In
> fact, the unittest module can even execute doctests.
>
>
This I didn't know this. I will have to do more investigation about this
today. I did find that
the Django doctest's were kind of limiting (at the documentation that I
read). This opens
up more possibilities to unify my tests.


Thanks Steven for the pointers
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Test Drive Development, DocTest, UnitTest

2010-09-22 Thread Tino Dai
On Wed, Sep 22, 2010 at 3:53 AM, Walter Prins  wrote:

> You might also have a look at some of the other popular testing frameworks
> e.g. Nose (http://somethingaboutorange.com/mrl/projects/nose/0.11.2/) and
> py.test (http://wiki.python.org/moin/PyTest)  Both of these have the
> advantage that they're discovery based, so they'll go and sniff out tests
> from your source, whererver they may be.
>
> Walter
>
> I will have to check this out. Django and doctest's seem kind of limited.
:( -Thanks, Tino
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


[Tutor] Help-Embedding Python in C#

2010-09-22 Thread ranjan das
Please Advise:

I need to run/execute python module in C#.  I am using python 2.6 and visual
studio 10


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


Re: [Tutor] Help-Embedding Python in C#

2010-09-22 Thread Wayne Werner
On Wed, Sep 22, 2010 at 7:55 AM, ranjan das  wrote:

>
> Please Advise:
>
> I need to run/execute python module in C#.  I am using python 2.6 and
> visual studio 10
>

You should check out IronPython
http://www.ironpython.com/

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


Re: [Tutor] class function problem

2010-09-22 Thread Hugo Arts
On Wed, Sep 22, 2010 at 9:10 AM, Roelof Wobben  wrote:
>
>
> HEllo,
>
> I have this exercise :
>
> 3.Rewrite the increment function so that it doesn’t contain any loops.
>
> The increment function looks like this :
>
> def increment(time, seconds):
>    time.seconds = time.seconds + seconds
>    while time.seconds>= 60:
>        time.seconds = time.seconds - 60
>        time.minutes = time.minutes + 1
>    while time.minutes>= 60:
>        time.minutes = time.minutes - 60
>        time.hours = time.hours + 1
>
>
> So I thought that recursion can do the job.
>

That's very clever. But you might argue that recursion is technically
still a loop, albeit an implicit one. There is a simpler way to do
this, without loops entirely.

Hint: repeated subtraction while your number is greater than some
constant, what you are doing, is essentially the same as doing one
division operation.

>
> But how can i Check the outcome.
> print uitkomst gives the object and print time(uitkomst) gives this error 
> message :
>
> Traceback (most recent call last):
>  File "C:\Users\wobben\workspace\oefeningen\src\test.py", line 34, in 
>    print time(uitkomst)
> AttributeError: tijd instance has no __call__ method
>

You can do "print uitkomst.seconds, uitkomst.minutes, uitkomst.hours".

Alternatively, write a suitable __str__ method for your tijd class.
Then you can just do "print uitkomst"

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


[Tutor] Best practice for API design handeling collections and single objects

2010-09-22 Thread Knacktus

Hi all,

I've got a question for you about how to best design an API that has to 
handle requests for single objects and collections of those objects.


My naming conventions are: Plural nouns for collections, singular nouns 
for single objects. "Key_to_value"-style for dictionaries. So I normaly 
know in my code wether I'm handling collections, dicts or single types.


So, here's an simplified example:
#---
class Meals(object):

def __init__(self, id_on_menu_to_meal):
self.id_on_menu_to_meal = id_on_menu_to_meal

#---

Now I need to return one meal by one id_on_menu and also several meals 
by several ids_on_menu.


I can think of three options:

1) create two methods:
#---
def get_meal_by_ident(self, ident):
return self.id_on_menu_to_meal[ident]

def get_meals_by_idents(self, idents):
return [self.get_meal_by_ident(ident) for ident in idents]

#---


2) create one method, which is smart enough to discriminate between the 
input (having fun with the naming conventions ;-)):

#---
def get_meal_or_meals_by_ident_or_idents(self, ident_or_idents):
try:
return self.id_on_menu_to_meal[ident_or_idents]
except KeyError:
return [self.id_on_menu_to_meal[ident] for
ident in ident_or_idents]

#---


3) handle by convention application-wide only collections:
#---
def get_meals_by_idents(self, idents):
return [self.id_on_menu_to_meal[ident] for ident in idents]

#---

Without having too much experience on things like that, my gut feeling 
tells me to use option 1). What would you guys consider as a best 
practice here?


Thanks in advance and cheers,

Jan

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


Re: [Tutor] class function problem

2010-09-22 Thread Roelof Wobben




> From: hugo.yo...@gmail.com
> Date: Wed, 22 Sep 2010 16:16:45 +0200
> Subject: Re: [Tutor] class function problem
> To: rwob...@hotmail.com
> CC: tutor@python.org
>
> On Wed, Sep 22, 2010 at 9:10 AM, Roelof Wobben wrote:
>>
>>
>> HEllo,
>>
>> I have this exercise :
>>
>> 3.Rewrite the increment function so that it doesn’t contain any loops.
>>
>> The increment function looks like this :
>>
>> def increment(time, seconds):
>> time.seconds = time.seconds + seconds
>> while time.seconds>= 60:
>> time.seconds = time.seconds - 60
>> time.minutes = time.minutes + 1
>> while time.minutes>= 60:
>> time.minutes = time.minutes - 60
>> time.hours = time.hours + 1
>>
>>
>> So I thought that recursion can do the job.
>>
>
> That's very clever. But you might argue that recursion is technically
> still a loop, albeit an implicit one. There is a simpler way to do
> this, without loops entirely.
>
> Hint: repeated subtraction while your number is greater than some
> constant, what you are doing, is essentially the same as doing one
> division operation.

 
Sorry. I don't get it.
When I have 62 seconds that's 1 minutes and 2 seconds.
I have no clue how I can this with a division.
 
 
>
>>
>> But how can i Check the outcome.
>> print uitkomst gives the object and print time(uitkomst) gives this error 
>> message :
>>
>> Traceback (most recent call last):
>> File "C:\Users\wobben\workspace\oefeningen\src\test.py", line 34, in 
>> print time(uitkomst)
>> AttributeError: tijd instance has no __call__ method
>>
>
> You can do "print uitkomst.seconds, uitkomst.minutes, uitkomst.hours".
>
> Alternatively, write a suitable __str__ method for your tijd class.
> Then you can just do "print uitkomst"
>
>> Roelof

 
Oke, thanks for the tip. Stupid I could thought that myself.
 
 
Roelof
  
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] class function problem

2010-09-22 Thread Hugo Arts
On Wed, Sep 22, 2010 at 5:17 PM, Roelof Wobben  wrote:
>>
>> That's very clever. But you might argue that recursion is technically
>> still a loop, albeit an implicit one. There is a simpler way to do
>> this, without loops entirely.
>>
>> Hint: repeated subtraction while your number is greater than some
>> constant, what you are doing, is essentially the same as doing one
>> division operation.
>
>
> Sorry. I don't get it.
> When I have 62 seconds that's 1 minutes and 2 seconds.
> I have no clue how I can this with a division.
>

okay, let's take as an example 314 seconds. We need to convert that
into minutes and seconds:

>>> seconds = 314
>>> seconds / 60.0
5.2334

See what I did there? This means I can fit 5.2 minutes in 314
seconds.No loops or anything. I'm only interested in the whole
minutes, so I can use the "//" operator for integer division:

>>> seconds // 60
5

That's our minutes. Now all you need to do is find the number of
seconds left over. The remainder (that's another hint). See if you can
figure that one out for yourself.

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


Re: [Tutor] how to create a persistent dictionary w/ cpickle?

2010-09-22 Thread Carter Danforth
Dave, Steve, and Alan: late reply here, but thanks a lot guys - really
appreciate the feedback. I had no idea what I was doing w/ that class in the
addressbook, needed to read up more, and I got the dictionary figured out w/
cpickle and now it's all working.

Thanks again, this input's really helping my learning curve.


On Thu, Sep 9, 2010 at 2:19 AM,  wrote:

> Send Tutor mailing list submissions to
>tutor@python.org
>
> To subscribe or unsubscribe via the World Wide Web, visit
>http://mail.python.org/mailman/listinfo/tutor
> or, via email, send a message with subject or body 'help' to
>tutor-requ...@python.org
>
> You can reach the person managing the list at
>tutor-ow...@python.org
>
> When replying, please edit your Subject line so it is more specific
> than "Re: Contents of Tutor digest..."
>
>
> Today's Topics:
>
>   1. Re: how to create a persistent dictionary w/ cpickle?
>  (Steven D'Aprano)
>   2. Re: how to create a persistent dictionary w/ cpickle? (Dave Angel)
>   3. Re: how to create a persistent dictionary w/ cpickle? (Alan Gauld)
>   4. Re: slicing a string (Sandip Bhattacharya)
>   5. Re: slicing a string (Evert Rol)
>   6. Re: slicing a string (Sandip Bhattacharya)
>
>
> --
>
> Message: 1
> Date: Thu, 9 Sep 2010 07:50:13 +1000
> From: Steven D'Aprano 
> To: tutor@python.org
> Subject: Re: [Tutor] how to create a persistent dictionary w/ cpickle?
> Message-ID: <201009090750.14230.st...@pearwood.info>
> Content-Type: text/plain;  charset="utf-8"
>
> On Thu, 9 Sep 2010 03:43:42 am Carter Danforth wrote:
> > Hi, I'm trying to a create a basic addressbook for practice. I'm
> > using a dictionary with cpickle, though I'm not sure how to
> > persistently store each instance in the dictionary. Below is the code
> > I have so far.
> >
> > If I run it once and add a contact and the details, it's fine.
> > p.load(f) shows the details next time I run it, but if I add another
> > contact, and run it again, the previous key:value doesn't show. It
> > gets replaced by the new one.
>
> Where do you think you are *adding* a new contact? You don't. You
> *replace* the existing contact with a brand new one, every time.
>
> The problem has nothing to do with pickle, or storing "each instance in
> the dictionary". Pickle is already storing each instance in the
> dictionary. The problem is that you never *add* anything to the address
> book, you *replace* it each time, so there is never more than two
> instances in the dictionary (one key, one value).
>
> You don't have an address BOOK, you only have a single address.
>
>
> > How can I fix this so that it adds the new key:value to the
> > dictionary instead of replacing the existing one? Appreciate any
> > help, thanks.
>
> I would dump the entire address class for now and just go for something
> nice and minimal. Get that working first, and then, *if necessary*,
> wrap it in a class. This is Python, not Java -- we use whatever works,
> and don't force everything to be a class when it doesn't have to be.
>
> What's the simplest address record you might have? How about a name
> linked to a telephone number and email?
>
> address_book = {name: (tel, email), another_name: (tel, email), ...}
>
> So, here's the basic algorithm:
>
> (1) Look for the address-book. If it doesn't exist, create an empty
> dictionary, and pickle it as the address-book.
>
> (2) Read the address-book from the pickle file. It will be a dictionary,
> possibly empty.
>
> (3) Add an address to the dictionary. Don't create a new dictionary:
>
> >>> addresses = {}  # creates a new, empty address book
> >>> addresses["Fred"] = ("1234 5678", "f...@example.com")
> >>> addresses["Betty"] = ("2468 1357", "be...@nowhere.com")
> >>> addresses  # not empty any more
> {'Betty': ('2468 1357', 'be...@nowhere.com'), 'Fred': ('1234
> 5678', 'f...@example.com')}
>
> (3) Save the dictionary to the pickle file.
>
>
> Once you have those steps happening manually, then wrap it into a class
> so they happen automatically.
>
>
> Some more comments on your code:
>
>
> > import cPickle as p
>
> Now that's just lazy. While laziness in a programmer in a good thing,
> this is taking it to extremes!!! You use pickle twice, three times if
> you count the import. Is it really such a burden on you to
> type "cPickle" (or "pickle") two more times, that you need to rename
> it "p"?
>
> Excessive use of one-character names is one of the worst programming
> habits you can have. Don't do this.
>
>
> > addressbook = 'addressbook.data'
>
> Misleading variable name. "addressbook" isn't an addressbook at all,
> it's a filename.
>
> > f = file(addressbook, 'r+')
>
> You shouldn't keep the file open for large periods of time. On Windows,
> it may mean that it will be locked from any other program accessing it
> during that time, and it risks data corruption if your program crashes
> or the power goes out.
>
> Open and close the file

Re: [Tutor] list.append(x) but at a specific 'i'

2010-09-22 Thread Steven D'Aprano
On Wed, 22 Sep 2010 08:30:09 am Norman Khine wrote:

> hello, how do i extend a python list but from a given [i], 

Do you mean to modify the list in place, like append() and extend() do, 
or do you mean to create a new list, like + does?


> for example: 
> >>> a = ['a', 'b', 'e']
> >>> b = ['c', 'd']
> >>>
> >>> a + b
>
> ['a', 'b', 'e', 'c', 'd']
>
>
> but i want to put the items of 'b' at [-2] for example.

When you ask a question, it usually helps to show the output you *want*, 
not the output you *don't want*, rather than to make assumptions about 
what other people will understand.

When you say that you want the items of b *at* -2, taken literally that 
could mean:

>>> a = ['a', 'b', 'e']
>>> b = ['c', 'd']
>>> a.insert(-2+1, b)
>>> print(a)
['a', 'b', ['c', 'd'], 'e']

Note that the items of b are kept as a single item, at the position you 
ask for, and the index you pass to insert() is one beyond when you want 
them to appear.

To create a new list, instead of insert() use slicing:

>>> a[:-2+1] + [b] + a[-2+1:]
['a', 'b', ['c', 'd'], 'e']


If you want the items of b to *start* at -2, since there are exactly two 
items, extend() will do the job for in-place modification, otherwise +. 
But you already know that, because that was your example.

If you want the items of b to *end* at -2, so that you get 
['a', 'b', 'c', 'd', 'e'] then you could use repeated insertions:

for c in b:
a.insert(-2, c)

but that will likely be slow for large lists. Better to use slicing. To 
create a new list is just like the above, except you don't create a 
temporary list-of-b first:

>>> a[:-2+1] + b + a[-2+1:]
['a', 'b', 'c', 'd', 'e']


To do it in place, assign to a slice:

>>> a[-2:-2] = b
>>> print(a)
['a', 'c', 'd', 'b', 'e']



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


Re: [Tutor] class function problem

2010-09-22 Thread Steven D'Aprano
On Thu, 23 Sep 2010 01:17:59 am Roelof Wobben wrote:

> Sorry. I don't get it.
> When I have 62 seconds that's 1 minutes and 2 seconds.
> I have no clue how I can this with a division.

If you have 60 seconds, you have one minute.

If you have 120 minutes, you have two minutes. Can you get from 120 to 2 
using a division?

You will find the divmod() function useful. divmod(a, b) returns two 
numbers:

a/b as a whole number, any remainder left only



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


[Tutor] Dict of function calls

2010-09-22 Thread Pete
For a plugin mechanism, I'm populating a dict with calls to the implemented 
plugins. 

Consider this:

>>> class foo:
... def do(self):
... print 'do foo'
... 
>>> class bar:
... def do(self):
... print 'do bar'
... 
>>> list = { 'foo': foo.do(), 'bar': bar.do() }
Traceback (most recent call last):
  File "", line 1, in 
TypeError: unbound method do() must be called with foo instance as first 
argument (got nothing instead)

===

Now I get that I need to instantiate foo and bar first before I can refer to 
them in the dict.

so something like

foo_instance = foo()
bar_instance = bar()

list = { 'foo': foo_instance.do(), 'bar': bar_instance.do() }

would probably work. But is that the best/pythonic way to do it? 
I first implemented "do" as a static method but that seemed... wrong (also 
because it needs to access some variables from the instance).

Any hints would be appreciated,

Pete


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


Re: [Tutor] class function problem

2010-09-22 Thread Steven D'Aprano
On Thu, 23 Sep 2010 05:55:36 am Steven D'Aprano wrote:

> You will find the divmod() function useful. divmod(a, b) returns
> two numbers:
>
> a/b as a whole number, any remainder left only

Arggh! Of course I meant any reminder left OVER.


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


Re: [Tutor] Dict of function calls

2010-09-22 Thread Steven D'Aprano
On Thu, 23 Sep 2010 06:07:21 am Pete wrote:
> For a plugin mechanism, I'm populating a dict with calls to the
> implemented plugins.
[...]
> Now I get that I need to instantiate foo and bar first before I can
> refer to them in the dict.
>
> so something like
>
> foo_instance = foo()
> bar_instance = bar()
>
> list = { 'foo': foo_instance.do(), 'bar': bar_instance.do() }
>
> would probably work. But is that the best/pythonic way to do it?

(1) It's generally a bad idea to "shadow" the name of a built-in 
function like list. Particularly since your variable list isn't 
actually a list, but a mapping of name:function. Find a better 
name :)

(2) You end up calling the do() methods inside the dict. You probably 
mean to save the method itself as a callback function.

(3) There's no need to keep the instances floating around as 
independent names, unless you need direct access to them.

Putting these together, we get:

dispatch_table = { 'foo': foo().do, 'bar': bar().do }

Which you then later call using:

dispatch_table[name](args)

where name is "foo" or "bar", and args is anything you need to pass to 
the do() method.

Oh, and (4)... in Python circles, it's traditional but not compulsory 
to use metasyntactic variables named after Monty Python sketches 
rather than foo and bar. So spam, ham, eggs, parrot (dead or 
otherwise), names of cheeses, aardvark..., although there is no 
standard order.

  Indeed, when I design my killer language, the identifiers "foo" and
  "bar" will be reserved words, never used, and not even mentioned in
  the reference manual. Any program using one will simply dump core
  without comment. Multitudes will rejoice. -- Tim Peters, 29 Apr 1998

-- 
Steven D'Aprano 
Operations Manager 
Cybersource Pty Ltd, ABN 13 053 904 082 
Level 1, 130-132 Stawell St, Richmond VIC 3121 
Tel: +61 3 9428 6922   Fax: +61 3 9428 6944 
Web: http://www.cybersource.com.au 
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Test Drive Development, DocTest, UnitTest

2010-09-22 Thread Steven D'Aprano
On Wed, 22 Sep 2010 09:44:17 pm Tino Dai wrote:
> > The *primary* purpose of doctests are to be executable examples.
> > When you write documentation, including example code is the most
> > natural thing in the world. doctest lets you execute those
> > examples, to ensure that they work. They're certainly not meant
> > as an exhaustive test of every single feature in the program, but
> > as *documentation* that happens to also work as tests.
> >
> > Unit tests can be a little heavyweight, but they're designed for
> > exhaustive tests of the *entire* program, not just the parts with
> > user-documentation. You should write whitebox tests, not just
> > blackbox tests. That means don't just write tests for the
> > published interface, but write tests for the unpublished internal
> > details as well.
>
> So, the gist is write tests for everything and the "external
> testing" should be
> handled by unit tests and the "internal testing" by doctests. Is
> that correct?

I'm not sure I understand what you mean by "external" and "internal", 
but if I do understand, you should swap them around.

What I mean is this:

Functions and classes have (or at least should have) a published 
interface, the API, which tell the user what they can expect the 
function to do and what arguments they need to provide. This is the 
external interface. It could be as simple as:

parrot.colour
Read-only attribute giving the colour of the parrot. The 
default colour is "blue".

or it could be thirty pages of tightly-written documentation. Either 
way, a small number of examples are useful, and having those examples 
be executable is even better:

>>> p = Parrot()
>>> p.colour
'blue'

This should go in the function's __doc__ string, where it is easily 
discoverable by users using the interactive help() function, as well 
as documentation discovery tools.

But there's no need to give an example of *every* tiny facet of 
behaviour, even if your documentation specifically mentions it. 
There's very little gained from having *both* these additional tests, 
as far as documentation is concerned:

>>> Parrot('light green').colour
'light green'
>>> Parrot('   LIGHT GREEN   ').colour
'light green'

If you find yourself saying "Yes, yes, I get the point!" while reading 
documentation, then you've got too many examples and some tests need 
to be removed.

But you do need to have those tests *somewhere*, otherwise, how do you 
know they work as expected? You need to verify the promises you have 
made, that is, test the external interface. This is "blackbox 
testing": you can't see inside the function, only the outside 
behaviour:

>>> Parrot().colour
'blue'
>>> Parrot(None).colour
'blue'
>>> Parrot('').colour
'blue'
>>> Parrot('BLUE').colour
'blue'
>>> Parrot(' \\v\\r  red   \\n\\t   ').colour
'red'
>>> Parrot('rEd').colour
'red'
>>> Parrot('yellow').colour
'yellow'
>>> p = Parrot()
>>> p.resting = False
>>> p.colour
'blue'
>>> p.resting = True
>>> p.colour
'blue'
>>> Parrot(state='transparent').colour
Traceback (most recent call last):
  ...
ParrotError: invisible parrots don't have colour
>>> Parrot(species='Norwegian Blue').colour  # are we bored yet?
'blue'
>>> Parrot(species='Giant Man-eating Kakapo').colour
'green'


Nobody needs to see *all* of that in a docstring, but it does need to 
be tested somewhere. You can use doctest for that, in an external 
file rather than the __doc__ string, but often unit tests give you 
more power and flexibility.

Blackbox testing is good, but it's not complete. You should also use 
whitebox testing, where you are expected to consider all the paths 
the code might take, and ensure that each and every one of those are 
tested. (At least that's the ideal, in practice sometimes you can't 
test *every* corner of the code. But you should try.) This is testing 
the internal implementation, and it certainly doesn't belong in the 
external documentation!

Real world example: Python's list.sort() method and sorted() functions 
use a custom-made, high-performance sort algorithm written by Tim 
Peters, but it only kicks in for sufficiently large lists. For small 
lists, they use a simpler sort algorithm. Whitebox testing needs to 
have tests for both cases, but you don't want to make the cutoff 
between the two part of your published external interface:

>>> # test a small list that uses algorithm 1
... sorted([1, 5, 3, 5, 9])
[1, 3, 5, 5, 9]
>>> # and test a big list that uses algorithm 2
... sorted([1, 5, 3, 5, 9, 8])
[1, 3, 5, 5, 8, 9]


What if the cutoff changes? You will have to revise your manuals! Why 
do you think the users of sort() need to know exactly where the 
cutoff is? Nobody cares what the exact value is. (It's not 5 items, 
by the way.)

For whitebox testing, doctests are often too limiting, and they're 
certainly too noisy to

Re: [Tutor] Dict of function calls

2010-09-22 Thread Pete

On 2010-09-22, at 5:50 PM, Steven D'Aprano wrote:

> On Thu, 23 Sep 2010 06:07:21 am Pete wrote:
>> For a plugin mechanism, I'm populating a dict with calls to the
>> implemented plugins.
> [...]
>> Now I get that I need to instantiate foo and bar first before I can
>> refer to them in the dict.
>> 
>> so something like
>> 
>> foo_instance = foo()
>> bar_instance = bar()
>> 
>> list = { 'foo': foo_instance.do(), 'bar': bar_instance.do() }
>> 
>> would probably work. But is that the best/pythonic way to do it?
> 
> (1) It's generally a bad idea to "shadow" the name of a built-in 
> function like list. Particularly since your variable list isn't 
> actually a list, but a mapping of name:function. Find a better 
> name :)

That was just for the example, of course, but point taken :)

> (2) You end up calling the do() methods inside the dict. You probably 
> mean to save the method itself as a callback function.

I did.

> (3) There's no need to keep the instances floating around as 
> independent names, unless you need direct access to them.
> 
> Putting these together, we get:
> 
> dispatch_table = { 'foo': foo().do, 'bar': bar().do }
> 
> Which you then later call using:
> 
> dispatch_table[name](args)
> 
> where name is "foo" or "bar", and args is anything you need to pass to 
> the do() method.

I see. And are those methods then unbound? (Because when instantiating the 
object it needs to do some initialization of instance variables,
and I think those were not available when calling an unbound method. (My 
understanding of the bound/unbound method distinction is rather vague at this 
point,
I apologise)

> Oh, and (4)... in Python circles, it's traditional but not compulsory 
> to use metasyntactic variables named after Monty Python sketches 
> rather than foo and bar. So spam, ham, eggs, parrot (dead or 
> otherwise), names of cheeses, aardvark..., although there is no 
> standard order.
> 
>  Indeed, when I design my killer language, the identifiers "foo" and
>  "bar" will be reserved words, never used, and not even mentioned in
>  the reference manual. Any program using one will simply dump core
>  without comment. Multitudes will rejoice. -- Tim Peters, 29 Apr 1998

THANK YOU! 

It's this kind of knowledge that I crave, sir.

:)

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


Re: [Tutor] Dict of function calls

2010-09-22 Thread Steven D'Aprano
On Thu, 23 Sep 2010 09:21:27 am Pete wrote:

> > (3) There's no need to keep the instances floating around as
> > independent names, unless you need direct access to them.
> >
> > Putting these together, we get:
> >
> > dispatch_table = { 'foo': foo().do, 'bar': bar().do }
[...]
> I see. And are those methods then unbound?

No, they're bound methods.


> (Because when 
> instantiating the object it needs to do some initialization of
> instance variables, and I think those were not available when
> calling an unbound method. (My understanding of the bound/unbound
> method distinction is rather vague at this point, I apologise)

Don't apologise :)  This is a tutor list, and the bound/unbound thing 
is one of the trickier parts of Python. This is what we're here for!

The def keyword always creates a function, whether you are outside a 
class or inside. So *inside* a class, at *creation* time, a "method" 
is really an ordinary function. Here's an example that prints the 
so-called method while the class is being built:


>>> class Test(object):
... def spam(self, n):
... return 'spam'*n
... print spam
...



Once the class is created, the function object is wrapped to become a 
method. Methods can be bound or unbound. If you get the method from 
the class object itself, it will be unbound:

>>> Test.spam


You can still get access to the original function object like this:

>>> Test.spam.im_func



If you then try to call the method, or the underlying function, you 
need to supply something as the "self" attribute. Method objects 
enforce that this first argument must be an instance of Test, but the 
underlying function object doesn't, so you can try passing anything 
you like and hope it works :)

Unbound methods are useful for when you know what method you want to 
call, but not which instance you want to call it on:

>>> func = str.upper
>>> # much later
...
>>> func("do you have any cheese, my good man?")
'DO YOU HAVE ANY CHEESE, MY GOOD MAN?'


If you get the method from an instance, it will be bound to that 
instance:

>>> Test().spam
>

and self will automatically be provided when you call the method.


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


Re: [Tutor] Help-Embedding Python in C#

2010-09-22 Thread ranjan das
Hi Wayne,

Thanks for your reply. The problem is a bit more specific. I have come
across ironpython and I ran a test file and it works fine as far as the
wrapping is concerned.

What I want to do is write my code completely in Python (as gainst iron
python), copy it to the visual studio editor and create a web based
application (I want it to be interactive) as against building an exe file
which would mean params would have to be hard coded.

While trying this I faced problems. I would prefer to do it in pure python
code rather than resorting to iron python. Is that possible?

Objective: Write the code completely in python and then from it create a
windows web based application.

Any help is appreciated

Regards,
Ranjan




On Wed, Sep 22, 2010 at 6:38 PM, Wayne Werner wrote:

> On Wed, Sep 22, 2010 at 7:55 AM, ranjan das  wrote:
>
>>
>> Please Advise:
>>
>> I need to run/execute python module in C#.  I am using python 2.6 and
>> visual studio 10
>>
>
> You should check out IronPython
> http://www.ironpython.com/
>
> HTH,
> Wayne
>



-- 
The inherent vice of capitalism is the unequal sharing of blessings; the
inherent virtue of socialism is the equal sharing of miseries.

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


[Tutor] Windows printing

2010-09-22 Thread Rance Hall
I'm using this page as a reference:
http://timgolden.me.uk/python/win32_how_do_i/print.html

I'm able to print to the default printer ok, but I can't seem to find
out how to get to pick the printer I want to use.

This is from a CLI app, so there is no gui.

win32print seems like it has everything I need, I just can't quite see
how to put it together

I'd like to have my python app ask which printer to use as opposed to
just using the default printer.

win32print.EnumPrinters() does give me a list, but its not just a list
of names. the list also includes other items like network paths
depending on the level of detail you specify in EnumPrinters.


Tim has two possible ways to print.  Tim shows how to use the win32api
to pass a ShellExecute command that prints.  The catch to this command
is you have to print a file type and it has to be the default type for
an app to open.

He also shows a way to skip the ShellExecute and use the print api
directly to gain some more control.

Based on my needs, I'm pretty sure that I'll need to use win32print,


Tim's how-to is likely not for my version of python (mine is 3.1)
since some of his command fail on my system because mine wants options
or parameters that Tim doesn't mention.

I'm going to be printing automatically generated check-in tickets.

I can make the ticket, save it as a temp file, but I can not print to
the default printer, I must be able to select the destination printer.

My plan is to ask the user what printer to use for the session, and
save that printer name in a variable and direct all automated prints
to that printer.

As we move the laptop from place to place the default printer is not
always available.  And the available printer changes depending on
location.

Ideally there would be a variation of the ShellExecute command that
would let me specify a printer name.

Windows 7 is the predominate windows platform we are using.

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