Ole Jensen | 1 Sep 2003 04:27
Picon

WAIDW - copying list within a recursive function

WAIDW == (W)hat (A)m (I) (D)oing (W)rong
 
(Question put short:
Why does this function return; None?
###
def shuffle(i=24, deck=[]):
    a = [ace, 2, 3, 4, 5, 6, 7, 8, 9, 10, jack, queen, king]
    deck.append(a[:])
    print deck
    if i > 0:
        print "if i > 0"
        shuffle(i-1, deck)
    elif i == 0:
        print "elif i == 0"
        print deck
        return deck
    else: print "failsafe"
###
 
Read below for more detailed describtion of my wrong doings ;)
)
 
I'm trying to create a list representing a stack of cards containing six card decks, I do not really care much of the about colour so my stack would come to look like this:
 
###
stack = [[ace, 2, 3,....., king], [ace, 2, 3,....., king],........,[ace, 2, 3,...., king]
###
 
The above should symbolise a list (stack) with 24 lists of different colours (allthough the colours e.g. clubs or hearts, are not shown as such).
 
Now call me lazy but I would prefer not to type all those those identical lists manually (both easthatically and labour wise), so I saw this as a good time to try to play around  with recursive functions (easily done in a forloop with two lines, but now I'm stubborn).
The best bit of code I have come up with untill now is this:
 
###
def shuffle(i=24, deck=[]):
    a = [ace, 2, 3, 4, 5, 6, 7, 8, 9, 10, jack, queen, king]
    deck.append(a[:])
    print deck
    if i > 0:
        print "if i > 0"
        shuffle(i-1, deck)
    elif i == 0:
        print "elif i == 0"
        print deck
        return deck
    else: print "failsafe"
###
(The print statements are for testing)
 
Which of course doesn't work (Otherwise I wouldn't be writing this mail)!
The the output ends up like this:
[[11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10]]
if i > 0
[[11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10], [11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10]]
if i > 0
etc. etc.
These few lines above shows me that everything shaping about nicely, the list is looking the way it's supposed to.
 
In the end of the output i finally equals 0, and the list is printed a final time looking complete (len(deck) == 24). When the next command in the sourcecode reads: return deck.
 
###
elif i == 0:
    print "elif i == 0"
    print deck
    return deck
###
 
My question is this:
If the list "deck" is as it is supposed to (and it looks to be), then why does the function return; None?
 
In advance thanks for any enlightment.
 
_______________________________________________
Tutor maillist  -  Tutor <at> python.org
http://mail.python.org/mailman/listinfo/tutor
Lloyd Kvam | 1 Sep 2003 05:21
Favicon

Re: WAIDW - copying list within a recursive function

This function will return a None if it ends though your failsafe else OR
if it ends through a non-zero i.  It is not ending through the failsafe
branch since we do not see the printing of failsafe.

When the i==0 path returns the deck, it is returning it to the i==1
invocation of shuffle. That invocation does NOT have an explicit return,
so it returns None to the i == 2 invocation and so on.

The fix is:
....
     if i > 0:
         print "if i > 0"
         shuffle(i-1, deck)
         return deck
....

Ole Jensen wrote:

> WAIDW == (W)hat (A)m (I) (D)oing (W)rong
>  
> (Question put short:
> Why does this function return; None?
> ###
> def shuffle(i=24, deck=[]):
>     a = [ace, 2, 3, 4, 5, 6, 7, 8, 9, 10, jack, queen, king]
>     deck.append(a[:])
>     print deck
>     if i > 0:
>         print "if i > 0"
>         shuffle(i-1, deck)
>     elif i == 0:
>         print "elif i == 0"
>         print deck
>         return deck
>     else: print "failsafe"
> ###
>  
> Read below for more detailed describtion of my wrong doings ;)
> )
>  
> I'm trying to create a list representing a stack of cards containing six 
> card decks, I do not really care much of the about colour so my stack 
> would come to look like this:
>  
> ###
> stack = [[ace, 2, 3,....., king], [ace, 2, 3,....., king],........,[ace, 
> 2, 3,...., king]
> ###
>  
> The above should symbolise a list (stack) with 24 lists of different 
> colours (allthough the colours e.g. clubs or hearts, are not shown as such).
>  
> Now call me lazy but I would prefer not to type all those those 
> identical lists manually (both easthatically and labour wise), so I saw 
> this as a good time to try to play around  with recursive functions 
> (easily done in a forloop with two lines, but now I'm stubborn).
> The best bit of code I have come up with untill now is this:
>  
> ###
> def shuffle(i=24, deck=[]):
>     a = [ace, 2, 3, 4, 5, 6, 7, 8, 9, 10, jack, queen, king]
>     deck.append(a[:])
>     print deck
>     if i > 0:
>         print "if i > 0"
>         shuffle(i-1, deck)
>     elif i == 0:
>         print "elif i == 0"
>         print deck
>         return deck
>     else: print "failsafe"
> ###
> (The print statements are for testing)
>  
> Which of course doesn't work (Otherwise I wouldn't be writing this mail)!
> The the output ends up like this:
> [[11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10]]
> if i > 0
> [[11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10], [11, 2, 3, 4, 5, 6, 7, 8, 
> 9, 10, 10, 10, 10]]
> if i > 0
> etc. etc.
> These few lines above shows me that everything shaping about nicely, the 
> list is looking the way it's supposed to.
>  
> In the end of the output i finally equals 0, and the list is printed a 
> final time looking complete (len(deck) == 24). When the next command in 
> the sourcecode reads: return deck.
>  
> ###
> elif i == 0:
>     print "elif i == 0"
>     print deck
>     return deck
> ###
>  
> My question is this:
> If the list "deck" is as it is supposed to (and it looks to be), then 
> why does the function return; None?
>  
> In advance thanks for any enlightment.
>  
> 
> 
> ------------------------------------------------------------------------
> 
> _______________________________________________
> Tutor maillist  -  Tutor <at> python.org
> http://mail.python.org/mailman/listinfo/tutor

--

-- 
Lloyd Kvam
Venix Corp.
1 Court Street, Suite 378
Lebanon, NH 03766-1358

voice:	603-443-6155
fax:	801-459-9582

_______________________________________________
Tutor maillist  -  Tutor <at> python.org
http://mail.python.org/mailman/listinfo/tutor

Diego Galho Prestes | 1 Sep 2003 21:01

WxArt2d

Hi! Someone know if I can use wxart2d in Python?

Diego

_______________________________________________
Tutor maillist  -  Tutor <at> python.org
http://mail.python.org/mailman/listinfo/tutor

Alan Gauld | 1 Sep 2003 22:23
Picon
Favicon

Re: using the modules and command prompt

> use the winsound module - but i dont know how. 

Neither do I sorry...

> I would also like to know/if how you can python to open 
> up cmd.exe or similar and run commands such as ping.

First, ping is not in cmd.exe it's a separate exe file.
(C:\WINDOWS\System32\ping.exe on my system)

You can execute ping from python using 

os.system('ping www.python.org')

or to capture the output for later processing use os.popen()
There is also a recent addition to Python that makes this 
easier but I've forgotten its name, maybe someone else can 
advise...

But CD,MD etc for example are builtin commands of cmd.exe and 
to execute those you may need to use the command flags of CMD.EXE
Try typing HELP CMD at the DOS prompt. Usually  /C suffices:

os.system(r"CMD.EXE /C CD C:\TEMP")

HTH,

Alan G
Author of the Learn to Program web tutor
http://www.freenetpages.co.uk/hp/alan.gauld

_______________________________________________
Tutor maillist  -  Tutor <at> python.org
http://mail.python.org/mailman/listinfo/tutor

Bob Gailer | 2 Sep 2003 03:29
Picon

Re: regular expression question

At 09:46 AM 8/31/2003 +0000, nihilo wrote:

>hi,
>
>I'm stuck on a regular expression. I want to match everything starting 
>from a word up to and including the next occurence of the word.
>
>If the word were a single character (say 'a'), then I could do the following:
>
>pat = re.compile('a[^a]*a')
>
>The problem is that I haven't been able to find out how to exclude the 
>word if it is more than one character. [^word] excludes the individual 
>letters, not the word as a whole, and I tried grouping with braces and 
>parentheses  [^(word)], but these don't work.  I've checked many re 
>tutorials, and they all say how to exclude a single character from the set 
>of characters inside the brackets, but not how to exclude more than 1 
>character.

Instead of asking it to exclude the word just match from word to word:
re.findall(r'.*?(word.*?word).*', 'A word to the wise is word enough')
gives:
['word to the wise is word']

Bob Gailer
bgailer <at> alum.rpi.edu
303 442 2625

---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.506 / Virus Database: 303 - Release Date: 8/1/2003
_______________________________________________
Tutor maillist  -  Tutor <at> python.org
http://mail.python.org/mailman/listinfo/tutor
Bob Gailer | 2 Sep 2003 04:02
Picon

Re: problems with win32com.client and excel.

At 09:01 PM 8/31/2003 +1200, Thomi Richards wrote:
>For the last month or so I've been trying to develop a piece of a program
>which enters numbers into an excel spreadsheet. I've managed to get it to go
>from the interactive interpreter, but as soon as I put those same commands
>into a file, I get errors:
>
>--<snip>--
>Traceback (most recent call last):
>   File "wedderburn.py", line 467, in idle
>     self.xlapp.adddata((command,args))
>   File "C:\Documents and
>Settings\Administrator\Desktop\wedderburn\excelspread.py", line 58, in
>adddata
>     self.app.ActiveSheet.Cells(self.x,self.y).Value = d #insert the data 
> into
>the sheet.
>   File "C:\PYTHON23\lib\site-packages\win32com\client\dynamic.py", line 154,
>in __call__
>     return
>self._get_good_object_(self._oleobj_.Invoke(*allArgs),self._olerepr_.defaultDispatchName,None)
>pywintypes.com_error: (-2147352567, 'Exception occurred.', (0, None, None,
>None, 0, -2146827284), None)
>--</snip>--
>
>This is the file "excelspread.py":
>
>-<snip>-
>#!/usr/bin/python
>
>import os,sys
>
>if os.name != 'nt':
>         print "we're not in a win32 environment, so excel logging will 
> not be
>available."
>         sys.exit(1)
>
>try:
>         import win32com.client
>except:
>                 print "you don't seem to have the python windows/COM 
> extensions
>installed!\n\nget them from: http://www.python.org/windows/"
>                 sys.exit(1)
>
>
>'''This file contains functions and classes to append information to an excel
>spreadsheet.'''
>
>class app:
>         def __init__(self,title="Weight SpreadSheet:"):
>
>                 #we have to start excel with a spreadsheet, and put up 
> the title.
>
>                 self.x = self.y = self.width = 0
>
>                 self.app = win32com.client.Dispatch("Excel.Application")
>                 self.app.Visible = 1
>                 self.app.Workbooks.Add()
>
>                 #set the title:
>                 self.app.ActiveSheet.Cells(1,1).Value = title
>                 self.y += 1
>
>                 self.initial = 1
>                 self.cols = {}
>
>
>                 #that's it as far as initialisation goes...
>
>         def adddata(self,values):
>                 # values will be a two part list. he first part will 
> always contain the
>                 # text string 'DATA'. THe second part will be a list of 
> lists. these
>                 # inner lists will contain two values. the first will be 
> a header code,
>                 # the second item will be the actual data. this from the 
> dummy driver:
>                 #
>                 # return
>['DATA',[['CODENO','0125846'],['NETWEIGHT',netw],['GROSSWEIGHT',grossw],['TARE',tare]]]
>                 #
>                 code,data = values      #unpack the values.
>
>                 self.x = 0
>                 self.y += 1
>
>                 if self.initial:
>                         #this is the first time we have added data to the 
> spreadsheet. we need to
>set up
>                         #the column headers.
>                         for chunk in data:
>                                 c,d = 
> chunk                                             #unpack the code chunk
>                                 self.cols[c] = 
> self.x                   #add entry to cols dictionary.
> 
>self.app.ActiveSheet.Cells(self.x,self.y).Value = d     #insert the data into
>the sheet.
>                                 self.x += 
> 1                                     #incriment the x column
>                         self.initial = 0
>                 else:
>                         for chunk in data:
>                                 c,d = chunk #unpack the code chunk.
>                                 self.x = self.cols.get(c,10)    #put 
> error messages in col 10
> 
>self.app.ActiveSheet.Cells(self.x,self.y).Value = d
>
>
>if __name__ == '__main__':
>         xl = app()
>         # this is the format that data is sent to the class:
>
>xl.adddata(['DATA'[['HEADER1','VALUE1'],['HEADER2','VALUE2'],['HEADER3','VALUE3'],['HEADER4','VALUE','4']]])

This is as far as I got running the program in PythonWin.
Traceback (most recent call last):
   File "J:\samis\python\xl.py", line 53, in ?
     xl.adddata(['DATA'[['HEADER1','VALUE1'],['HEADER2','VALUE2'],['HEADER3','VALUE3'],['HEADER4','VALUE','4']]])
TypeError: sequence index must be integer

To get past that error I had t add a comma after data:
     xl.adddata(['DATA',[['HEADER1','VALUE1'],['HEADER2','VALUE2'],['HEADER3','VALUE3'],['HEADER4','VALUE','4']]])

[snip]
Also I wonder why this line is not indented the same as xl = app(). This 
will not stop the program from working as long as its name is __main__, but 
if you import it, you'll get NameError: name 'xl' is not defined

Even in PythonWin the program then gets the error you posted. The reason is 
that you are indexing Cells(0,1) and Excel Cell indexing starts at 1.
I changed self.x = 0 to self.x = 1. Then I got yet another error that 
required me to change ['HEADER4','VALUE','4'] ot ['HEADER4','VALUE4'].

Then it works fine as a module.

I wonder how you got it to run at all!

Bob Gailer
bgailer <at> alum.rpi.edu
303 442 2625

---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.506 / Virus Database: 303 - Release Date: 8/1/2003
_______________________________________________
Tutor maillist  -  Tutor <at> python.org
http://mail.python.org/mailman/listinfo/tutor
Brian Christopher Robinson | 2 Sep 2003 06:50

for x in myClass

A friend of mine had an assignment to write a program that would take an 
array and create another array containing indexes into the first array, 
then sort the second array according to the values in the first array.  So, 
if you have the array:

[1, 50, 0, 42]

Your second array, called the tag array, would start out unsorted as:

[0, 1, 2, 3]

Then sorted it would be:

[2, 0, 3, 1]

I wanted to create a TagArray (really TagList, but he's working in VB and 
I'm working in Python, oh well) class.  So I wrote this:

class TagArray(list):
     def __init__(self, array):
         self.array = array
         for i in range(len(array)):
             self.append(i)

     def __getitem__(self, k):
         return self.array[list.__getitem__(self, k)]

     def __contains__(self, k):
         return k in self.array

This correctly refers to the original array when you use the bracket 
notation to get an element.  However, if you loop through it, you get the 
indexes instead of the values they're pointing to in the original array.  I 
overrode __contains__ which is the "in" statement, but apparently that's 
not the same one used when you do a for loop.  How can I override the 
elements returned when you have a statement like:

tag = TagArray([20, 30, 10, 0])
for x in tag:
         print x

this should print 20, 30, etc., not 0, 1, etc.  Also, will this cause the 
sort() method to work?

--

-- 
reaching out to embrace whatever may come 

_______________________________________________
Tutor maillist  -  Tutor <at> python.org
http://mail.python.org/mailman/listinfo/tutor

Thomi Richards | 2 Sep 2003 09:21
Picon

Re: problems with win32com.client and excel.

>
> To get past that error I had t add a comma after data:
>     
> xl.adddata(['DATA',[['HEADER1','VALUE1'],['HEADER2','VALUE2'],['HEADER3','V
>ALUE3'],['HEADER4','VALUE','4']]])
>

DOH!!

It never ceases to amaze me what really *stupid* mistakes I make, and 
compltely fail to notice them, until someone else notices... Not only is it 
annoying, it's very embarrasing as well ;)

> [snip]
> Also I wonder why this line is not indented the same as xl = app(). This
> will not stop the program from working as long as its name is __main__, but
> if you import it, you'll get NameError: name 'xl' is not defined
>

In the original file it is, But my mail client wraps lines at 79 characters or 
so, and so it wasn't pasted correctly...

> Even in PythonWin the program then gets the error you posted. The reason is
> that you are indexing Cells(0,1) and Excel Cell indexing starts at 1.
> I changed self.x = 0 to self.x = 1. Then I got yet another error that
> required me to change ['HEADER4','VALUE','4'] ot ['HEADER4','VALUE4'].
>
Yet another really dumb mistake I'm afraid *sigh*

Thank you every so much.. I was completely stuck ;)

Thanks again.

--

-- 
Thomi Richards,
http://once.sourceforge.net/

_______________________________________________
Tutor maillist  -  Tutor <at> python.org
http://mail.python.org/mailman/listinfo/tutor

Danny Yoo | 2 Sep 2003 09:27
Picon

Re: for x in myClass


On Tue, 2 Sep 2003, Brian Christopher Robinson wrote:

> A friend of mine had an assignment to write a program that would take an
> array and create another array containing indexes into the first array,
> then sort the second array according to the values in the first array.

Hi Brian,

It looks like you're doing this just out of curiosity, so I'm not too
concerned about this being a homework assignment.  But if you are doing
doing this for homework, please tell us --- we are prohibited from helping
much with homework.

> So, if you have the array:
>
> [1, 50, 0, 42]
>
> Your second array, called the tag array, would start out unsorted as:
>
> [0, 1, 2, 3]
>
> Then sorted it would be:
>
> [2, 0, 3, 1]

Ok, this looks like the sort is preceding in decending order.  Just wanted
to raise that point, since most references to "sorting" assume that we
want things in ascending (or more correctly, "nondecending") order.

> I wanted to create a TagArray (really TagList, but he's working in VB and
> I'm working in Python, oh well) class.  So I wrote this:
>
> class TagArray(list):
>      def __init__(self, array):
>          self.array = array
>          for i in range(len(array)):
>              self.append(i)

Those last two statements can also be written as:

     self.extend(range(len(array)))

extend() is a method that can append multiple elements at a time to a
list.  One line isn't much, but every bit helps.  *grin*


>      def __getitem__(self, k):
>          return self.array[list.__getitem__(self, k)]
>
>      def __contains__(self, k):
>          return k in self.array
>
> This correctly refers to the original array when you use the bracket
> notation to get an element.  However, if you loop through it, you get
> the indexes instead of the values they're pointing to in the original
> array.  I overrode __contains__ which is the "in" statement, but
> apparently that's not the same one used when you do a for loop.

Yes.  When we do:

     for x in L: ...                   ## Case 1

the 'in' is not the same 'in' as:

     x in L                            ## Case 2

and I think the confusion is that they share the same keyword in there.

In Case 1, you'll want to override the __iter__() method, which Python
uses to get an iterator when it does a 'for' loop:

###
>>> class testlist(list):
...     def __iter__(self):
...         print "Hi, I'm __iter__()!"
...         return list.__iter__(self)
...
>>> L = testlist([1,2,3])
>>> for x in L:
...     print x
...
Hi, I'm __iter__()!
1
2
3
###

Case 2 is the one that's handled by __contains__(), so that's why we can
see it when we do checks for in-clusion.

> Also, will this
    [overriding __setattr__ and __getattr__]
> cause the sort() method to work?

This is sorta iffy.  This inheritance approach feels fragile to me,
because it assumes that sort() will use __getitem__() and __setitem__()
during the sort()ing process.  There's no such guarantee that sort() will
do this, since I don't see any documentation about it in the Library
Reference:

    http://www.python.org/doc/lib/typesseq-mutable.html

But let's check this, just to see if it works:

###
>>> class test_sort(list):
...     def __getitem__(self, index):
...         print "I'm __getitem__()!"
...         return list.__getitem__(self, index)
...     def __setitem__(self, index, value):
...         print "I'm __setitem__()!"
...         list.__setitem__(self, index, value)
...
>>> l = test_sort([3,1,4,1,5,9,2,6])
>>> l.sort()
>>> l
[1, 1, 2, 3, 4, 5, 6, 9]
###

Nope, no go.  Looks like sort() does some kind of internal lookup that
doesn't use __getitem__() or __setitem__().

It might be better to avoid inheritance here.  The approach above tries to
augment the list class.  But it might be easier to try augmenting the list
instance instead.

For example, we can "decorate" the original list with indices.

###
def decorate_with_indices(L):
    "Destructively appends L's elements with index numbers."
    for i in range(len(L)):
        L[i] = (L[i], i)
###

This is something that isn't invisible or transparent --- it does
hideously mutate L --- but it's something that's very reversable.

Somehow, though, I don't think the original assigment anticipated that
sort() was available for use... *grin*


Good luck to you.

_______________________________________________
Tutor maillist  -  Tutor <at> python.org
http://mail.python.org/mailman/listinfo/tutor

Danny Yoo | 2 Sep 2003 09:40
Picon

Re: for x in myClass


Hi Brian,

>> Your second array, called the tag array, would start out unsorted as:
>>
>> [0, 1, 2, 3]
>>
>> Then sorted it would be:
>>
>> [2, 0, 3, 1]
>
> Ok, this looks like the sort is preceding in decending order.  Just
> wanted to raise that point, since most references to "sorting" assume
> that we want things in ascending (or more correctly, "nondecending")
> order.

I'm totally, completely wrong here.  I don't know what the heck I was
thinking.  The sort above is definitely nondecending, not decending.
Sorry about that.

> Somehow, though, I don't think the original assigment anticipated that
> sort() was available for use... *grin*

Iff sort() were available to us, then there's an embarassingly simply way
to solve this problem.

###
>>> def create_tag_array(L):
...     tag_array = range(len(L))
...     def mycmp(x, y):
...         return cmp(L[x], L[y])
...     tag_array.sort(mycmp)
...     return tag_array
...
>>> create_tag_array([1, 50, 0, 42])
[2, 0, 3, 1]
###

There are other really silly approaches to generate the sorted tag array,
and all of the silly approaches involve using sort().  So I'd rather hope
that the original assignment does not allow sort() at all.  *grin*


_______________________________________________
Tutor maillist  -  Tutor <at> python.org
http://mail.python.org/mailman/listinfo/tutor


Gmane