[Tutor] "farkadoodle" or: unique global names, was Re: Data persistence problem

2013-06-22 Thread Peter Otten
Jim Mooney wrote:

> dictnumfarkadoodle = listnumfarkadoodle = setnumfarkadoodle = 0
> # Since these are global I'm using words not likely to be duplicated
> until I figure a different way and
> # replace 'farkadoodle' with '' ;')

Name clashes are generally not a problem if 

(1) you keep module size manageable and 
(2) use descriptive names

I'd suggest

_dictname_index

or

_makeseq_dictname_index


If you want to follow the generator approach you can use default arguments:

>>> from itertools import count
>>> def make_nextname(template):
... return map(template.format, count()).__next__
... 
>>> f = make_nextname("farkadoodle{}")
>>> f()
'farkadoodle0'
>>> f()
'farkadoodle1'
>>> f()
'farkadoodle2'
>>> def make_seq(text, type, next_setname=make_nextname("set{}")):
... if type == set:
... print(next_setname(), "=", set(text.split()))
... else:
... raise ValueError("unsupported type")
... 
>>> make_seq("alpha beta gamma", set)
set0 = {'alpha', 'beta', 'gamma'}
>>> make_seq("alpha beta gamma", set)
set1 = {'alpha', 'beta', 'gamma'}
>>> make_seq("alpha beta gamma", set)
set2 = {'alpha', 'beta', 'gamma'}

Here's an alternative implementation of make_nextname() which may be easier 
to understand:

>>> def make_nextname(template):
... counter = -1
... def nextname():
... nonlocal counter
... counter += 1
... return template.format(counter)
... return nextname
... 
>>> f = make_nextname("foo{:03}")
>>> f()
'foo000'
>>> f()
'foo001'
>>> f()
'foo002'

This technique of nesting a function inside another function ("closure") can 
also be used on make_seq directly:

def make_make_seq():
set_index = 0
...
def make_seq(text, type):
nonlocal set_index
if type == set:
print("set%s" % set_index, "=", set(text.split()))
set_index += 1
...
return make_seq

make_seq = make_make_seq()
make_seq("a b c", set) # set0 = {'c', 'b', 'a'}
make_seq("a b c", set) # set1 = {'c', 'b', 'a'}


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


Re: [Tutor] Data persistence problem

2013-06-22 Thread Alan Gauld

On 22/06/13 03:26, Jim Mooney wrote:


if isinstance(dict(),typein):
try: newdict = dict(zip(dl[::2],dl[1::2]))
except TypeError:
 raise ValueError("input lists must be an even length")


Not sure why TypeError and ValueError is used.


I used them because that's what I got in my testing of dict
on Python 2.7. The zip() may actually obviate the need since
it stops zipping when it runs out of matches.

And the reason I changed from your Exception type is that using the base 
Exception is nearly always wrong. It means that you then have

to catch the top level Exception which will include every possible
error that could occur. So if somebody hits Ctl-C for instance 
(KeyboardInterrupt) you will still be telling them to pass even

length input. So it's better to either use a standard exception
type or invent a new one. In this case TypeError was what it was 
throwing and ValueError seemed to me to describe an invalid

length list...


StopIteration


This is usually used to force a stop of a loop - usually because
you've ran out of data. Since I wasn't using an explicit loop it
didn't seem appropriate but I could see how you might consider
it an option. Certainly better than Exception..



iterables in the zip, but it looks like dict knows tostop


No, it's zip() that knows when to stop.

In 2.7 I get:

>>> dict([1,2],[1,2,3])
Traceback (most recent call last):
  File "", line 1, in 
TypeError: dict expected at most 1 arguments, got 2
>>> zip([1,2],[1,2,3])
[(1, 1), (2, 2)]
>>>

The behaviour may have changed in 3.3...


--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/

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


Re: [Tutor] Writing logfile data to a user opened file

2013-06-22 Thread Alan Gauld

On 22/06/13 02:42, Matt D wrote:


 if dlg.ShowModal() == wx.ID_OK:
 path = dlg.GetPath()
 mypath = os.path.basename(path)
 with open(mypath, "a") as f:
 f.writelines(self.log_array)

so thats how i used what you said, "with open() as f:".  is this the
right way to open the file?


You need to indent the writelines() call so its inside
the 'with' block.

  with open(mypath, "a") as f:
   f.writelines(self.log_array)

This means you don't need to call f.close() each time - which you were 
missing from your earlier code.


--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/

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


[Tutor] Global Variables

2013-06-22 Thread Jack Little
Is there a way to keep a global throughout multiple def statements?
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Global Variables

2013-06-22 Thread Steven D'Aprano

On 22/06/13 18:09, Jack Little wrote:

Is there a way to keep a global throughout multiple def statements?


I don't understand the question. The only way to *not* keep a global through 
multiple def statements is if you delete the global:


x = 1  # Global.

def function_one():
code goes here...

def function_two():
code goes here...

del x

def function_three():
code goes here...


But I suspect that this is not what you mean. Can you explain in more detail 
what you mean?




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


Re: [Tutor] Data persistence problem

2013-06-22 Thread Steven D'Aprano

On 22/06/13 00:32, Wolfgang Maier wrote:

Arijit Ukil  tcs.com> writes:



I have following random number generation
function
def
rand_int ():
 rand_num = int(math.ceil
(random.random()*1000))
 return
rand_num
I like to make the value of rand_num
(return of rand_int) static/ unchanged after first call even if it is called
multiple times. If x=  rand_int () returns 45 at the first call, x
should retain 45 even in multiple calls.


Sifting through the random module documentation a bit:

def rand_int(update=False):
 if update:
 dummy = random.random()
 oldstate=random.getstate()
 rand_num = random.randint(0,1000)
 random.setstate(oldstate)

 return rand_num

This will return a constant number when called with a False value for update
(the default), but will switch to returning a new number when called
with a True value once.



You really don't want to do this! By doing this, every time you call your 
rand_int() function, you will reset the application-wide pseudo-random number 
generator, possibly making a mess of other parts of your application and the 
standard library.

You also throw away a random value, which probably won't make a difference for 
the default Python PRNG, but may be bad if you're using a lousy PRNG.

There is a much simpler ways of doing this (see below), but if you must use 
getstate and setstate, then you should create your own personal random number 
generator rather than use the system-wide default PRNG.


myrandom = random.Random()

def rand_int(update=False):
if update:
  dummy = myrandom.random()
oldstate = myrandom.getstate()
rand_num = myrandom.randint(0, 1000)
myrandom.setstate(oldstate)
return rand_num


This doesn't look like much, but it's actually an awful lot of work just to 
return a fixed, constant number! The PRNG used by Python is *very good*, which 
means it is also computationally quite expensive. Here's a cheaper way to get 
the same effect, using a mutable default argument to store the last result, 
then only call the PRNG when you actually need to:

def rand_int(update=False, seed=[None]):
if update or seed[0] is None:
seed[0] = random.randint(0, 1000)
return seed[0]



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


Re: [Tutor] Data persistence problem

2013-06-22 Thread Steven D'Aprano

On 22/06/13 11:10, Jim Mooney wrote:


The ultimate in laziness would be to get the program to
append to itself so I,don't have to cut and paste from the
interpreter, but I'm running into some tacky problems. Although some
of them are from the IDE. But others might be from the OS, and there
are different OSes so this wouldn't be portable.



Sounds to me like you are experimenting with "Do What I Mean" software. Here's 
a cautionary tale about DWIM:

http://www.catb.org/jargon/html/D/DWIM.html



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


Re: [Tutor] Global Variables

2013-06-22 Thread Steven D'Aprano

On 22/06/13 18:09, Jack Little wrote:

Is there a way to keep a global throughout multiple def statements?


Oh, a further thought! Perhaps you mean something like this?


x = 42  # Global value.

def function_one():
global x  # Define it once.
code using global x goes here...

def function_two():
# x is already declared global, so no need to do it again
code using global x goes here...


# Run the code.
function_one()
function_two()


If that's what you mean, the answer is, thank goodness, no, there is no way to 
do this!

Relying on global variables is, as a general rule, a good way to end up with 
unmaintainable, buggy code that cannot easily be tested and is frustrating to 
debug. Sixty years of experience in programming has lead to the conclusion that 
global variables are best avoided.

To be precise, it is not so much the *global variable* part that is harmful, 
but the reliance on side-effects in the code: calling a function invisibly gets 
input from a global, and outputs to a global. We can get better, safer, easier 
to understand code by using explicit input arguments and a return result:


def function_one(arg):
code using argument "arg" goes here...
return result of calculation

def function_two(arg):
code using "arg" goes here...
return result of calculation


# Run the code.
x = 42
x = function_one(x)
y = function_two(x)


In this case, we can see that the value of x is passed to function_one as 
input. There's no need to guess that it magically uses some global variable. We 
can also see that the result of that calculation is stored back into x. Then in 
the next line, the new value of x is passed to function_two as input, and the 
result is stored in a different variable, y.


Although there is a very slight increase in the amount of typing, with practice 
and experience this leads to more maintainable, more easily debugged code.


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


Re: [Tutor] Data persistence problem

2013-06-22 Thread Steven D'Aprano

On 22/06/13 09:00, Jim Mooney wrote:

On 21 June 2013 14:59, ALAN GAULD  wrote:



Give us a clue, show us your code!


I was hoping you wouldn't say that since it's another of my insane
Lazy Typer programs to avoid typing, which are no doubt considered
frivolous. Although I'm learning a lot doing them ;')


Well, perhaps not *frivolous*. After all, Python itself might be said to be a "lazy 
typer" programming language, compared to some such as Pascal, C, or especially Java.

Compare the archetypal "Hello World" program in Java versus Python:


=== Java version ===

public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World");
}
}


=== Python version ===

print("Hello, World")



Speaking of Java, I get a kick out of this article and love to link to it on 
every possible opportunity:

http://steve-yegge.blogspot.com.au/2006/03/execution-in-kingdom-of-nouns.html

:-)





Okay, I have a snippet that posts the below text in automatically. I
can use it to make any number of dicts, lists, or sets, from just
tokens in a single string, and they are printed out as the different
types, named and and numbered so they have different program names.
That way I don't have to type in quotes, commas, colons, and so forth.
Once the interpreter prints them out, I just select all and paste them
into my program, replacing what's below. Kind of a manual
meta-programming ;')

= pasted in snippet 

## Output sequence will be all strings. The first type in the 2nd
parameter list will be the
## default due to 'or" short circuiting, so you can just delete to get
what you want.
## You MUST have an even number of tokens for a dict or you'll get an exception.

from maker import makeseq
makeseq("Replace me, even number of tokens for dict", dict or list or set)



I think that a better design here would be three functions that explicitly tell 
you what they do:

makedict
makelist
makeset

The three of them could call an underlying internal function that does most of 
the work. Or not, as the case may be.




= end snippet 

 From this I can create any number of numbered dicts, lists or sets


*Numbered* variables? Oh wow, is it 1975 again? I didn't think I'd be 
programming in BASIC again...

:-)



(The 'or' short circuit means I get dicts as default, and only have to
delete from the front to get the others - dicts are default since
they're the most annoying to type - now That's lazy.)


Surely typing one of "dict", "list" or "set" is not too much effort?

makeseq("stuff goes here ...", dict)
makeseq("stuff goes here ...", list)
makeseq("stuff goes here ...", set)
makeseq("stuff goes here ...", tuple)
makeseq("stuff goes here ...", frozenset)


You don't even need to put quotes around the type. In fact, you *shouldn't* put 
quotes around the type, since that will stop it from working.


[...]

makeseq("this is a list and it is not a very big list", list or set)



Creating your own tools is fine, but they ought to do a little more than just 
duplicate the functionality of built-in tools. I'll come back to the dict case 
again further down, but the list and set cases are trivial:


L1 = "this is a list and it is not a very big list".split()

L2 = "Yet another list to show the different types increment separately".split()

S1 = set("and finally some sets".split())

Best of all, the time you save not having to type "makeseq" can now be used to 
think of meaningful, descriptive names for the variables :-)


Here are some improvements to your makeseq function:



dictnumfarkadoodle = listnumfarkadoodle = setnumfarkadoodle = 0
# Since these are global I'm using words not likely to be duplicated
until I figure a different way and
# replace 'farkadoodle' with '' ;')

def makeseq(instring, typein):
 global dictnumfarkadoodle, listnumfarkadoodle, setnumfarkadoodle
 if isinstance(dict(), typein):


Rather than create a new dict, then check to see if it is an instance of 
typein, you can just do this:

if typein is dict:
...
elif typein is list:
...
elif typein is set:
...

and similar for tuple and frozenset.



 newdict = {}
 dl = instring.split()
 if len(dl) % 2 != 0:
 raise Exception ("list entries must be even") # so they match


It is normally better to use a more specific exception. In this case, I 
recommend using TypeError, since TypeError is used for cases where you pass the 
wrong number of arguments to a type constructor (among other things).



 for idx in range(0,len(dl),2):
 newdict[dl[idx]] = dl[idx+1]


In general, any time you find yourself channeling Pascal circa 1984, you're 
doing it wrong :-) There is very rarely any need to iterate over index numbers 
like this. The preferred Python way would be to slice the list into two halves, 
then zip them together:

  keys = d1[0::2]  # Every second item, starti

Re: [Tutor] "farkadoodle" or: unique global names, was Re: Data persistence problem

2013-06-22 Thread Steven D'Aprano

On 22/06/13 17:04, Peter Otten wrote:

This technique of nesting a function inside another function ("closure")


To be pedantic, not all nested functions are closures. Here's one which is not:


def outer(arg):
def inner(x):
return x + 1
assert inner.__closure__ is None
return inner(arg)


In this case, the inner function does not refer to any variables defined in the 
outer function. Instead, it is explicitly passed the value it needs as an 
argument.

Here's one which is a closure:


def outer(arg):
def inner():
return arg + 1
assert inner.__closure__ is not None
return inner()


The function attribute "__closure__" is set to None for regular functions. For closures, 
it is set to a bunch of stuff needed for the inner function to work correctly. (No user serviceable 
parts inside.) Basically, the inner function needs to carry around with it a little piece of its 
environment, so it can retrieve the value of "arg" when required.



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


Re: [Tutor] Data persistence problem

2013-06-22 Thread Steven D'Aprano

On 22/06/13 12:26, Jim Mooney wrote:

On 21 June 2013 16:56, ALAN GAULD  wrote:



if isinstance(dict(),typein):
try: newdict = dict(zip(dl[::2],dl[1::2]))
except TypeError:
 raise ValueError("input lists must be an even length")


Not sure why TypeError and ValueError is used. I would have thought
StopIteration but explain your logic on that as I'm unclear. But the
Exception never tripped, either way. I tried different length
iterables in the zip, but it looks like dict knows tostop before it
trip thems. Only next() does raises the exception. Unless I am
confused ;')


It's not dict which is smart in this case, but zip(), which stops when one of 
the sequences has run out:

py> zip("abcdefg", "1234", "ABCDEFGHIJKLMN")
[('a', '1', 'A'), ('b', '2', 'B'), ('c', '3', 'C'), ('d', '4', 'D')]


In Python 3, zip is "lazy" and only returns items on request, rather than 
"eager" returning them all at once in a list. To get the same result in Python 3, use 
list(zip(...)) instead.


If you arrange for dict to see a missing value, it will raise ValueError:


py> dict([('a', 1), ('b', 2), ('c',)])
Traceback (most recent call last):
  File "", line 1, in 
ValueError: dictionary update sequence element #2 has length 1; 2 is required




zippy = zip([1,2],[3,4,5,6,7,8,9])
D = dict(zippy)
D

{1: 3, 2: 4} # dict works fine

next(zippy) # exhausting zippy raises StopIteration

Traceback (most recent call last):
   File "", line 301, in runcode
   File "", line 1, in 
StopIteration


That's because zippy is already exhausted by dict, and once exhausted, it stays 
exhausted.



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


Re: [Tutor] Best Code testing practice?

2013-06-22 Thread Steven D'Aprano

On 22/06/13 04:17, Matt D wrote:


Hey guys!
Have decided that it is probably going to be better for my purposes to
simply crack open a terminal, cd into the appropriate directory, and do
the 'python test_code.py' or whatever the file name is from the command
line. I feel it is better for me to learn how to write code in gedit
before i use an IDE.


Nicely said!


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


Re: [Tutor] Writing logfile data to a user opened file

2013-06-22 Thread Matt D
On 06/22/2013 03:47 AM, Alan Gauld wrote:
> On 22/06/13 02:42, Matt D wrote:
> 
>>  if dlg.ShowModal() == wx.ID_OK:
>>  path = dlg.GetPath()
>>  mypath = os.path.basename(path)
>>  with open(mypath, "a") as f:
>>  f.writelines(self.log_array)
>>
>> so thats how i used what you said, "with open() as f:".  is this the
>> right way to open the file?
> 
> You need to indent the writelines() call so its inside
> the 'with' block.
> 
>   with open(mypath, "a") as f:
>f.writelines(self.log_array)
> 
> This means you don't need to call f.close() each time - which you were
> missing from your earlier code.
> 
Thanks!  That is how i had it; not sure how the indent got nixed when
pasted to my mail.
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] "farkadoodle" or: unique global names, was Re: Data persistence problem

2013-06-22 Thread eryksun
On Sat, Jun 22, 2013 at 7:10 AM, Steven D'Aprano  wrote:
> The function attribute "__closure__" is set to None for regular functions.
> For closures, it is set to a bunch of stuff needed for the inner function to
> work correctly. (No user serviceable parts inside.) Basically, the inner
> function needs to carry around with it a little piece of its environment, so
> it can retrieve the value of "arg" when required.

Using a tuple of cells (loaded from __closure__) allows for fast
lookups. If you check with dis, you'll see the ops used with cells are
LOAD_DEREF and STORE_DEREF. These handle the indirection through the
cell object, which is a flat cost. It's not a function of nesting
level. Using cells also avoids referencing the outer frame(s), which
would interfere with garbage collection (GC).

One catch with Python nested scopes is that binding a name defaults to
the local scope. You can get around this by using a mutable container,
just as was done with globals before the "global" keyword was added in
version 0.9.4 (1991). The better solution is a new keyword, but adding
keywords is radical surgery. The "nonlocal" keyword, as Peter used,
had to wait for 3.x.
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] EXE Problem

2013-06-22 Thread eryksun
On Wed, Jun 19, 2013 at 6:58 PM, Alan Gauld  wrote:
> On 19/06/13 17:41, Jim Mooney wrote:
>
>> you should use forward slashes. I have no idea why Bill Gates thought
>> backslashes were kewl
>
> Because MS DOS was copying CP/M which didn't have directory paths
> (it was used with 180K floppy disks that stored everything at the top
> level) but did have command options that were indicated by a
> forward slash
>
> DIR /S
>
> was a sorted directory listing etc.
>
> So MS DOS inherited / as an options marker which precluded
> it's later use as a path separator...

CP/M didn't have a hierarchical file system, but it did have up to 16
USER areas. As to / switches, maybe at some point someone confused
CP/M with DEC's TOPS-10, which used switches quite a lot (it even had
SWITCH.INI for defaults). TOPS-10 would have been familiar to many
1970s programmers. Its DIR command had over 70 switches, such as /SORT
(default) and /NOSORT. In contrast, DIR on CP/M used options in square
brackets, such as the following example:

   DIR [DRIVE=B,USER=ALL,EXCLUDE,NOSORT] *.DAT

This would list all files on B: in all USER areas exluding DAT files,
without sorting.

The USER areas in CP/M are reminiscent of TOPS-10 user-file
directories. A UFD was designated by a [project, programmer] number
(PPN), and could have up to 5 levels of sub-file directories (SFD).
For example, DSKB:FOO.TXT[14,5,BAR,BAZ], where 14,5 is a PPN. In VMS
style it's DSKB:[USER.BAR.BAZ]FOO.TXT. In comparison, slash vs.
backslash seems trivial.
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


[Tutor] appending/updating values dict key value pairs

2013-06-22 Thread Sivaram Neelakantan

What's the best way to append to the list which is the value to a dict
key?

I did the following based on the docs and I'm not sure why it works

>>> b = { 'a': [4, 5]} 
>>> list.append(b.get('a'),'c')
>>> b
{'a': [4, 5, 'c']}
>>> 


as in, shouldn't it be

b['a'] = list.append(b.get('a'),'c')

which doesn't seem to work.

 sivaram
 -- 

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


Re: [Tutor] appending/updating values dict key value pairs

2013-06-22 Thread Mark Lawrence

On 22/06/2013 17:56, Sivaram Neelakantan wrote:


What's the best way to append to the list which is the value to a dict
key?

I did the following based on the docs and I'm not sure why it works


b = { 'a': [4, 5]}
list.append(b.get('a'),'c')
b

{'a': [4, 5, 'c']}





as in, shouldn't it be

b['a'] = list.append(b.get('a'),'c')

which doesn't seem to work.

  sivaram
  --


b['a'].append('c')

--
"Steve is going for the pink ball - and for those of you who are 
watching in black and white, the pink is next to the green." Snooker 
commentator 'Whispering' Ted Lowe.


Mark Lawrence

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


Re: [Tutor] appending/updating values dict key value pairs

2013-06-22 Thread Sivaram Neelakantan
On Sat, Jun 22 2013,Mark Lawrence wrote:


[snipped 7 lines]

> b = { 'a': [4, 5]}
> list.append(b.get('a'),'c')
> b
>> {'a': [4, 5, 'c']}
>
>>
>>
>> as in, shouldn't it be
>>
>> b['a'] = list.append(b.get('a'),'c')
>>
>> which doesn't seem to work.
>>
>>   sivaram
>>   --
>
> b['a'].append('c')


arrgh! I should have known this.  Thank you for making it obvious to
 the noob.

 sivaram
 -- 

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


Re: [Tutor] Data persistence problem

2013-06-22 Thread Jim Mooney
On 22 June 2013 04:00, Steven D'Aprano  wrote:


> Speaking of Java, I get a kick out of this article and love to link to it on
> every possible opportunity:
>
> http://steve-yegge.blogspot.com.au/2006/03/execution-in-kingdom-of-nouns.html

Funny. Speaking of Java, I saw a used book on design patterns, that
wasn't too old, but all the examples were in Java. Why not just hit
myself in the head with a brick?

Except for a really old general book, all the recent books on design
patterns, which I was curious about, are on specific languages -
design patterns for Java (speak of the devil), Visual Basic, Tcl, even
Android. But I couldn't fine One on Python. Is there a reason for
this? Don't they play well with Python, or did I miss the book
somehow?

I think Java is all nouns since it's a "business" language and
managers do love their nouns. (There is a big difference between
managers and entrepreneurs, which an entrepreneur once pointed out to
me, though.)

-- 
Jim
A pride of lions, a gaggle of geese, a pack of wolves, a sewer of bankers.
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] appending/updating values dict key value pairs

2013-06-22 Thread Albert-Jan Roskam



> From: Sivaram Neelakantan 
>To: tutor@python.org 
>Sent: Saturday, June 22, 2013 7:52 PM
>Subject: Re: [Tutor] appending/updating values dict key value pairs
> 
>
>On Sat, Jun 22 2013,Mark Lawrence wrote:
>
>
>[snipped 7 lines]
>
>> b = { 'a': [4, 5]}
>> list.append(b.get('a'),'c')
>> b
>>> {'a': [4, 5, 'c']}
>>
>>>
>>>
>>> as in, shouldn't it be
>>>
>>> b['a'] = list.append(b.get('a'),'c')
>>>
>>> which doesn't seem to work.
>>>
>>>   sivaram
>>>   --
>>
>> b['a'].append('c')
>
>
>arrgh! I should have known this.  Thank you for making it obvious to
>the noob.

I use dict.setdefault fairly often for things like this:

>>> d = {}
>>> d.setdefault("aKey", []).append("aValue")
>>> d.setdefault("aKey", []).append("anotherValue")
>>> d
{'aKey': ['aValue', 'anotherValue']}
>>> d.setdefault("anotherKey", []).append("aValue")
>>> d
{'aKey': ['aValue', 'anotherValue'], 'anotherKey': ['aValue']}
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] "farkadoodle" or: unique global names, was Re: Data persistence problem

2013-06-22 Thread Albert-Jan Roskam



 
> One catch with Python nested scopes is that binding a name defaults to
> the local scope. You can get around this by using a mutable container,
> just as was done with globals before the "global" keyword was added in
> version 0.9.4 (1991). The better solution is a new keyword, but adding
> keywords is radical surgery. The "nonlocal" keyword, as Peter used,
> had to wait for 3.x.

I was playing around with this a bit and arrived at the following surprising 
(for me at least) result. I thought the global/local/nonlocal keywords could be 
used to get values from another scope. Though this could also happen 
implicitly, e.g. if only x = "I am global" is defined and x is used (and not 
redefined) inside a function, then python still knows this variable inside that 
function. 

Is there any way to make this work? (it may not be desirable, though)

#Python 3.2.3 (default, Apr 10 2013, 05:29:11) [GCC 4.6.3] on linux2
>>> x = "I am global"
>>> def outer():
... x = "I am nonlocal"
... def inner():
... x = "I am local"
... print(x)  # expecting to print 'I am local' 
... nonlocal x
... print(x)  # expecting to print 'I am nonlocal' 
... global x
... print(x)  # expecting to print 'I am global' 
... inner()
... 
:6: SyntaxWarning: name 'x' is assigned to before nonlocal declaration
:8: SyntaxWarning: name 'x' is assigned to before global declaration
SyntaxError: name 'x' is nonlocal and global
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


[Tutor] How convert an int to a string

2013-06-22 Thread Jim Byrnes
I need to convert a series of digits like 060713 to a string so I can 
make it look like a date 06-07-13.


>>> a = 060713
>>> a[:2]
Traceback (most recent call last):
  File "", line 1, in 
TypeError: 'int' object has no attribute '__getitem__'
>>> b = str(a)
>>> b[:2]
'25'
>>> b
'25035'
>>>

I was confused at first but then realized that the  0  makes it octal. I 
thought str() would do it but it didn't. Reading about str() it talks of 
string representation.  So how can I convert it to a true string I can 
slice and build my date look a like?


Thanks,  Jim

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


Re: [Tutor] Data persistence problem

2013-06-22 Thread Alan Gauld

On 22/06/13 12:00, Steven D'Aprano wrote:


Speaking of Java, I get a kick out of this article and love to link to
it on every possible opportunity:

http://steve-yegge.blogspot.com.au/2006/03/execution-in-kingdom-of-nouns.html


 This could get seriously OT here...

I found that an interesting blog in that I agreed with half of it, 
disagreed with half and couldn't make up my mind about the other

half!!! :-)

But I also found the followup comments interesting.

And most interesting of all, despite the verbiage on natural languages, 
 nobody commented on the distinction  between

classes and objects.

My peeve with Java is that it is Class oriented rather than
Object oriented. Classes are common nouns (eg river), objects
are proper nouns (eg Nile).

My other peeve is static typing. I've been using OOP since
1985 in a mix of static and dynamic languages(*) and have come
to the conclusion that OOP only works properly in a dynamic
typed environment. Smalltalk, Objective C  and Python have very 
different object models and OOP idioms but all three can

produce clean elegant OOP solutions. ObjectPascal, C++ and Java
equally have different object models but all run into similar
problems with OOP. You wind up creating lots of wrapper/interface 
classes just to get round the limitations of the type strictures.


However, all successful OOP languages I've used have got
round the need for free functions by simply defining a top level 
container class called App or system or some such (or by having

functions as first class objects!). It really doesn't need to
be as big an issue as the blog makes out. The real problem
is the way the Java community have regimented the use of OOP.

(*) In approximately this order:
Smalltalk, ObjectPascal(Apple), C++, Lisp(Flavors),
ObjectiveC, ADA, Eiffel, Modula 2/3, Actor, PL/SQL,
Java, ObjectPascal(Delphi), COBOL(yes really!), Tcl(incTcl),
Python, Perl, Ruby, C#, VB, JavaScript, Lisp(CLOS).

--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/

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


Re: [Tutor] appending/updating values dict key value pairs

2013-06-22 Thread Alan Gauld

On 22/06/13 17:56, Sivaram Neelakantan wrote:


list.append(b.get('a'),'c')



Lets look at what this is doing in simplistic terms.

'list' is the class and 'append' is a method of the class.
When we call a method via the class we have to provide the 'self' 
argument explicitly so in this case self is


b.get('a')

which is the result of getting the value associated with the key 'a'; in b.

or put another way it is b['a']

so we can simplify a little to

list.append(b['a'], 'c')

But we normally call methods via the object instance rather than the 
class so simplifying this further we get:


b['a'].append('c')

Which is how we would normally do it.

HTH
--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/

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


Re: [Tutor] Data persistence problem

2013-06-22 Thread Mark Lawrence

On 22/06/2013 19:29, Jim Mooney wrote:

On 22 June 2013 04:00, Steven D'Aprano  wrote:



Speaking of Java, I get a kick out of this article and love to link to it on
every possible opportunity:

http://steve-yegge.blogspot.com.au/2006/03/execution-in-kingdom-of-nouns.html


Funny. Speaking of Java, I saw a used book on design patterns, that
wasn't too old, but all the examples were in Java. Why not just hit
myself in the head with a brick?

Except for a really old general book, all the recent books on design
patterns, which I was curious about, are on specific languages -
design patterns for Java (speak of the devil), Visual Basic, Tcl, even
Android. But I couldn't fine One on Python. Is there a reason for
this? Don't they play well with Python, or did I miss the book
somehow?


Loads of the design pattern stuff is written to help programmers get 
around the straight jacket that languages can impose, whereas 
implementating the same patterns in Python is often ludicrously easy.


If you want to dig further, I suggest you arm yourself with plenty of 
coffee and sandwiches, then use your favourite search engine to hunt for 
"Python patterns Alex Martelli".  Enjoy :)


--
"Steve is going for the pink ball - and for those of you who are 
watching in black and white, the pink is next to the green." Snooker 
commentator 'Whispering' Ted Lowe.


Mark Lawrence

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


Re: [Tutor] EXE Problem

2013-06-22 Thread Alan Gauld

On 22/06/13 16:58, eryksun wrote:


In contrast, DIR on CP/M used options in square
brackets, such as the following example:

DIR [DRIVE=B,USER=ALL,EXCLUDE,NOSORT] *.DAT


You are right, CP/M did use square brackets for flags,
I'd forgotten those. But it did have some / switches too.
(or at least CP/M 3 (aka CP/M plus), which was the only
version I used, did.)

So, my example of DIR /S was wrong. But I got the concept
from my old CP/M programming manual which says...

A> mbasic5 /m:&hc000

Which tells mbasic to protect memory location hc000...

But mbasic isn't really part of CP/M it was a BASIC interpreter
written by  Microsoft! So maybe DOS got its / flags because
they were already using them for their BASIC...


The USER areas in CP/M


Weren't USER areas a late introduction to CP/M? (Version 3
again I think...) But I agree very similar to the DEC setup.
But then most of the early OS developers were working on DEC
kit back then, DEC had most of the research hardware market
sown up in the '70s. CP/M came from Dartmouth Navy Labs,
Unix from Bell labs, Microsoft from Harvard(very indirectly).

Anyways, apologies for my earlier misinformation - the old
grey cells are a little older than they used to be!

--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/

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


Re: [Tutor] How convert an int to a string

2013-06-22 Thread Peter Otten
Jim Byrnes wrote:

> I need to convert a series of digits like 060713 to a string so I can
> make it look like a date 06-07-13.
> 
>  >>> a = 060713
>  >>> a[:2]
> Traceback (most recent call last):
>File "", line 1, in 
> TypeError: 'int' object has no attribute '__getitem__'
>  >>> b = str(a)
>  >>> b[:2]
> '25'
>  >>> b
> '25035'
>  >>>
> 
> I was confused at first but then realized that the  0  makes it octal. I
> thought str() would do it but it didn't. Reading about str() it talks of
> string representation.  So how can I convert it to a true string I can
> slice and build my date look a like?

>>> a = 060713
>>> "%06o" % a
'060713'
>>> "{:06o}".format(a)
'060713'


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


Re: [Tutor] How convert an int to a string

2013-06-22 Thread Albert-Jan Roskam


--- Original Message -

> From: Jim Byrnes 
> To: tutor@python.org
> Cc: 
> Sent: Saturday, June 22, 2013 11:01 PM
> Subject: [Tutor] How convert an int to a string
> 
> I need to convert a series of digits like 060713 to a string so I can 
> make it look like a date 06-07-13.
> 
  a = 060713
  a[:2]
> Traceback (most recent call last):
>    File "", line 1, in 
> TypeError: 'int' object has no attribute '__getitem__'
  b = str(a)
  b[:2]
> '25'
  b
> '25035'
 
> 
> I was confused at first but then realized that the  0  makes it octal. I 
> thought str() would do it but it didn't. Reading about str() it talks of 
> string representation.  So how can I convert it to a true string I can 
> slice and build my date look a like?

weird indeed. Can wait to hear more about it. But oct() does the trick.

>>> a = 060713
>>> a
25035
>>> import time
>>> time.strftime("%d-%m-%y", time.strptime(oct(a), "%d%m%y"))
'06-07-13'
>>> b = str(oct(a))
>>> "%02s-%02s-%02s" % (b[:2], b[2:4], b[4:])
'06-07-13'
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] How convert an int to a string

2013-06-22 Thread Mark Lawrence

On 22/06/2013 22:44, Albert-Jan Roskam wrote:



--- Original Message -


From: Jim Byrnes 
To: tutor@python.org
Cc:
Sent: Saturday, June 22, 2013 11:01 PM
Subject: [Tutor] How convert an int to a string

I need to convert a series of digits like 060713 to a string so I can
make it look like a date 06-07-13.


  a = 060713
  a[:2]

Traceback (most recent call last):
File "", line 1, in 
TypeError: 'int' object has no attribute '__getitem__'

  b = str(a)
  b[:2]

'25'

  b

'25035'




I was confused at first but then realized that the  0  makes it octal. I
thought str() would do it but it didn't. Reading about str() it talks of
string representation.  So how can I convert it to a true string I can
slice and build my date look a like?


weird indeed. Can wait to hear more about it. But oct() does the trick.


a = 060713
a

25035

import time
time.strftime("%d-%m-%y", time.strptime(oct(a), "%d%m%y"))

'06-07-13'

b = str(oct(a))
"%02s-%02s-%02s" % (b[:2], b[2:4], b[4:])

'06-07-13'


How do you propose handling the errors that will occur when any of day, 
month or year have a non octal digit?


--
"Steve is going for the pink ball - and for those of you who are 
watching in black and white, the pink is next to the green." Snooker 
commentator 'Whispering' Ted Lowe.


Mark Lawrence

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


Re: [Tutor] How convert an int to a string

2013-06-22 Thread David Rock
* Jim Byrnes  [2013-06-22 16:01]:
> I need to convert a series of digits like 060713 to a string so I can 
> make it look like a date 06-07-13.
> 
>  >>> a = 060713
>  >>> a[:2]
> Traceback (most recent call last):
>File "", line 1, in 
> TypeError: 'int' object has no attribute '__getitem__'
>  >>> b = str(a)
>  >>> b[:2]
> '25'
>  >>> b
> '25035'
>  >>>
> 
> I was confused at first but then realized that the  0  makes it octal. I 
> thought str() would do it but it didn't. Reading about str() it talks of 
> string representation.  So how can I convert it to a true string I can 
> slice and build my date look a like?

Is there a requirement to store them as numbers in the first place?  Why
not just store them as a string?

a = '060713'

-- 
David Rock
da...@graniteweb.com


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


Re: [Tutor] "farkadoodle" or: unique global names, was Re: Data persistence problem

2013-06-22 Thread eryksun
On Sat, Jun 22, 2013 at 3:59 PM, Albert-Jan Roskam  wrote:
>
> I was playing around with this a bit and arrived at the following
> surprising (for me at least) result. I thought the global/local/nonlocal
> keywords could be used to get values from another scope. Though this
> could also happen implicitly, e.g. if only x = "I am global" is defined
> and x is used (and not redefined) inside a function, then python still
> knows this variable inside that function.
>
> Is there any way to make this work? (it may not be desirable, though)

local isn't a keyword. Maybe you're thinking of the locals() function.
The global and nonlocal keywords define the scope of a name for the
entire block. You can't flip it on and off like a toggle switch. That
would give me headaches. Anyway, try to avoid globals and use
descriptive names. If you still have a clash, use globals()[name].
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] How convert an int to a string

2013-06-22 Thread Dave Angel

On 06/22/2013 05:01 PM, Jim Byrnes wrote:

I need to convert a series of digits like 060713 to a string so I can
make it look like a date 06-07-13.



Where is this series of digits coming from?  Is it in the source code, 
or in a file, or coming from the user, or what?  If it's in source code, 
add quotes around it, and it'll be a string.  The whole octal nonsense 
is a non-starter, because it won't handle a date like September 18. 
Octal numbers only have digits zero through seven.


If the digits are coming from a file, then they're already a string. 
Don't waste the time converting to decimal and/or octal, just use them.


If they come from somewhere else, then tell us.  And while you're at it, 
tell us the Python version so we have a chance at matching the advice to 
what you're running.




 >>> a = 060713


That assignment will try to make it octal.  If there are digits bigger 
than 7, it'll fail.




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


Re: [Tutor] How convert an int to a string

2013-06-22 Thread Jim Byrnes

On 06/22/2013 05:10 PM, David Rock wrote:

* Jim Byrnes  [2013-06-22 16:01]:

I need to convert a series of digits like 060713 to a string so I can
make it look like a date 06-07-13.

  >>> a = 060713
  >>> a[:2]
Traceback (most recent call last):
File "", line 1, in 
TypeError: 'int' object has no attribute '__getitem__'
  >>> b = str(a)
  >>> b[:2]
'25'
  >>> b
'25035'
  >>>

I was confused at first but then realized that the  0  makes it octal. I
thought str() would do it but it didn't. Reading about str() it talks of
string representation.  So how can I convert it to a true string I can
slice and build my date look a like?


Is there a requirement to store them as numbers in the first place?  Why
not just store them as a string?

a = '060713'



Yes. I am scripting data entry in a spreadsheet.  I can enter the 6 
numbers quite rapidly using the number pad but entering the " - "'s to 
make it look like a date slows me down.  So I thought I would let python 
do that for me.


Regards,  Jim


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


Re: [Tutor] How convert an int to a string

2013-06-22 Thread Dave Angel

On 06/22/2013 07:03 PM, Jim Byrnes wrote:

On 06/22/2013 05:10 PM, David Rock wrote:

* Jim Byrnes  [2013-06-22 16:01]:

I need to convert a series of digits like 060713 to a string so I can
make it look like a date 06-07-13.

  >>> a = 060713
  >>> a[:2]
Traceback (most recent call last):
File "", line 1, in 
TypeError: 'int' object has no attribute '__getitem__'
  >>> b = str(a)
  >>> b[:2]
'25'
  >>> b
'25035'
  >>>

I was confused at first but then realized that the  0  makes it octal. I
thought str() would do it but it didn't. Reading about str() it talks of
string representation.  So how can I convert it to a true string I can
slice and build my date look a like?


Is there a requirement to store them as numbers in the first place?  Why
not just store them as a string?

a = '060713'



Yes. I am scripting data entry in a spreadsheet.  I can enter the 6
numbers


Six digits, not numbers.


quite rapidly using the number pad but entering the " - "'s to
make it look like a date slows me down.  So I thought I would let python
do that for me.



I don't have any experience with using Rxlorg to script the Gemdaddy 
spreadsheet program.  Maybe if you actually got specific, somebody would 
have familiarity with the ones you're using.


Most likely all you have to do is specify with the spreadsheet that the 
user is to enter a string.  If it makes some sort of assumption that 
strings cannot start with a digit, then it's just broken.


In some spreadsheets, the user enter a leading equals-sign to indicate 
the type of data to follow.



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


Re: [Tutor] Data persistence problem

2013-06-22 Thread Asokan Pichai
On Sun, Jun 23, 2013 at 2:45 AM, Mark Lawrence wrote:

> On 22/06/2013 19:29, Jim Mooney wrote:
>
>> On 22 June 2013 04:00, Steven D'Aprano  wrote:
>>
>>
>>  Speaking of Java, I get a kick out of this article and love to link to
>>> it on
>>> every possible opportunity:
>>>
>>> http://steve-yegge.blogspot.**com.au/2006/03/execution-in-**
>>> kingdom-of-nouns.html
>>>
>>
>> Funny. Speaking of Java, I saw a used book on design patterns, that
>> wasn't too old, but all the examples were in Java. Why not just hit
>> myself in the head with a brick?
>>
>> Except for a really old general book, all the recent books on design
>> patterns, which I was curious about, are on specific languages -
>> design patterns for Java (speak of the devil), Visual Basic, Tcl, even
>> Android. But I couldn't fine One on Python. Is there a reason for
>> this? Don't they play well with Python, or did I miss the book
>> somehow?
>>
>
> Loads of the design pattern stuff is written to help programmers get
> around the straight jacket that languages can impose, whereas
> implementating the same patterns in Python is often ludicrously easy.
>

 http://norvig.com/design-patterns/

Read this for an insight into how design patterns change for dynamic
languages ..

Asokan Pichai

"Expecting the world to treat you fairly because you are a good person is a
little like expecting the bull to not attack you because you are a
vegetarian"
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] "farkadoodle" or: unique global names, was Re: Data persistence problem

2013-06-22 Thread Steven D'Aprano

On 23/06/13 05:59, Albert-Jan Roskam wrote:


I was playing around with this a bit and arrived at the following surprising (for me at 
least) result. I thought the global/local/nonlocal keywords could be used to get values 
from another scope. Though this could also happen implicitly, e.g. if only x = "I am 
global" is defined and x is used (and not redefined) inside a function, then python 
still knows this variable inside that function.



No, Python does not work that way, unlike (say) Lua where you can write code 
that fetches a global variable x and assigns it to a local variable x.

In Python, the presence of keywords nonlocal and global affect the entire 
function body, not just lines following them. They're also only needed when you 
assign to a variable. Looking up the variable's name does not require a 
declaration.

The rule Python follows goes something like this:


* If you assign to a name (e.g. "spam = 42") anywhere inside the body of a 
function, then that name is treated as a local variable, which is a fast lookup.

* Otherwise, it is treated as unknown scope, and Python will search nesting 
functions (if any), globals, and finally builtins for the name.


An example:

py> import builtins
py> builtins.a = "builtins"  # Kids, don't do this at home!
py> b = c = d = "global"
py> def f():
... c = d = "nonlocal"
... def g():
... d = "local"
... print(a, b, c, d)
... g()
...
py> f()
builtins global nonlocal local



* If you wish to assign to a variable in another scope, you must declare it. 
You can only declare global and nonlocal. You cannot declare a variable is 
builtin (you're not supposed to write to the builtin scope), and there is no 
way to declare *which* nonlocal function scope you write to.

Other than that, you can write to the builtin scope directly, if you import it 
first, or the global scope by using globals(). But if you're doing either of 
these things, you probably shouldn't be.

Writing to the *local* scope via locals() is not guaranteed to work! It is a 
lot of fun (for some definition of fun) trying to determine under what 
circumstances it may or may not work, depending on the version and 
implementation of Python and even which scope you are in when you call locals().


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


[Tutor] random.choice() problem

2013-06-22 Thread Jack Little
I am trying to use random.choice for a text based game. I am using windows 7, 
64-bit python. Here is my code:

def lvl2():
    print "COMMANDER: Who should you train with?"
    trn=random.choice(1,2)
    if trn==1:
        lvl2_1()
        print "Squad One!"
    elif trn==2:
        lvl2_2()
        print "Squad Nine!"





Here is my error:

 File "C:\Users\Jack\Desktop\python\skye.py", line 20, in lvl2
    trn=random.choice(1,2)
TypeError: choice() takes exactly 2 arguments (3 given)
>>> 



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


Re: [Tutor] random.choice() problem

2013-06-22 Thread Steven D'Aprano

On 23/06/13 16:18, Jack Little wrote:

I am trying to use random.choice for a text based game. I am using windows 7, 
64-bit python. Here is my code:

def lvl2():
 print "COMMANDER: Who should you train with?"
 trn=random.choice(1,2)

[...]


Here is my error:

  File "C:\Users\Jack\Desktop\python\skye.py", line 20, in lvl2
 trn=random.choice(1,2)
TypeError: choice() takes exactly 2 arguments (3 given)



Alas, here you have stumbled over one of those corners of Python where things do not work 
*quite* as well as they ought to. Even though random.choice looks like a function, it is 
actually a method, and methods have an extra argument, automatically generated by Python, 
called "self".

So when you call random.choice(1, 2) Python provides three, not two, arguments:

self, 1, 2

hence the error message about "3 given". Since random.choice takes two 
arguments, and Python provides one of them, that only leaves one argument for you to 
provide. What should that be? Well, if you read the documentation, it tells you. At the 
interactive interpreter, you can enter

help(random.choice)


which will give you:

Help on method choice in module random:

choice(self, seq) method of random.Random instance
Choose a random element from a non-empty sequence.


Ignoring "self", you have to give a *sequence* of values. A list is a good 
sequence to use:

# Incorrect:
random.choice(1, 2)


# Correct:
random.choice([1, 2])



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