Re: [Tutor] python scripting using "./"

2011-05-25 Thread Wolf Halton
An oddity of the PATH variable in Linux (or at least Ubuntu) is that there
is a folder in PATH called /home/~/bin.  The ~ is replaced with your profile
name.  If you create that folder and put the file into it, you can invoke it
from anywhere in the filesystem with just its name.

On Tue, May 24, 2011 at 10:39 AM, Walter Prins  wrote:

> Hi Hank,
>
> On 24 May 2011 15:15, Hank Wilkinson  wrote:
>
>> Yes, I would love to know why it doesn't work, or what I'm doing wrong.
>>
>> John-Wilkinsons-iMac:p31summerfield wilkinson$ cat hello.py
>> #!/usr/bin/env python
>>
>> print("Hello world")
>> John-Wilkinsons-iMac:p31summerfield wilkinson$ chmod +X hello.py
>> John-Wilkinsons-iMac:p31summerfield wilkinson$ ./hello.py
>> -bash: ./hello.py: Permission denied
>>
>
> OK you had me scratching my head for a couple of minutes, but then I tried
> your steps on my Ubuntu box and managed to reproduce it.
>
> The problem here is you're using +X (capital X) when setting the file
> execute permission.  You should be using +x (lowercase x) when setting the
> script to be executable.  Capital X will only set the file to be executable
> if it's **already** executable for some other user/group (which is not the
> case in your new script's case.)  Lowercase x will set it executable full
> stop.
>
> Cheers
>
> Walter
>
> ___
> Tutor maillist  -  Tutor@python.org
> To unsubscribe or change subscription options:
> http://mail.python.org/mailman/listinfo/tutor
>
>


-- 
This Apt Has Super Cow Powers - http://sourcefreedom.com
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Python Variables Changing in Other Functions

2011-05-25 Thread Wayne Werner
On Tue, May 24, 2011 at 11:14 PM, Rachel-Mikel ArceJaeger <
arcejae...@gmail.com> wrote:

> Hello,
>
> I am having trouble with determining when python is passing by reference
> and by value and how to fix it to do what I want:
>

Andre already mentioned that you shouldn't think of Python as
'pass-by-reference' or 'pass-by-value', but this link should help you
understand why not: http://effbot.org/zone/call-by-object.htm


> The issue is this: random.shuffle() mutates the list in place, rather than
> creating a new copy. This is fine, but rather than modifying just the local
> copy of my titles, it is modifying it in the other functions, too. For
> instance, rankRandom() is called by main(), which passes it listOfTitles.
> When rankRandom() returns, listOfTitles has been changed to the randomized
> version of titles.
>
> To fix this, I tried copying the original title list and then assigning it
> to the mutated version right before the rankRandom() function returns. The
> local version of titles in rankRandom() does indeed regain its original
> value, but listOfTitles in main() is still being assigned to the randomized
> version, and not to the original version. This boggles me, since it seems
> like shuffle is mutating the titles as if it were a global variable, but
> assignment is treating it only as a local.
>
> What exactly is going on here, and how do I avoid this problem?
>

Well, you also have some non-idiomatic code, so I'll go through and comment
on the whole thing


> 
>
> import xlwt as excel
> import random
> import copy
>
> def getTitleList():
>""" Makes a list of all the lines in a file """
>
>filename = raw_input("Name and Extension of File: ")
>
>myFile = open( filename )
>
>titles = []
>

You can eliminate from here...

>title = "none"
>
>while title != "":
>
>title = myFile.readline()
>

to here, by iterating over your file object directly. The for loop in Python
is quite powerful, and in this case you can simply say:

for title in myFile:

This is easier to read, especially by other Python programmers. You could
call it a design pattern - when you want to read  a file line by line you
can say:

for line in filehandle:
# do something with line


>
>if title not in ["\n",""]:
>titles.append(title)
>
>return titles
>

It also turns out that you can replace almost this entire function with a
list comprehension. Because doing this sort of thing:

collection = []
for item in another_collection:
if item == criteria:
collection.append(item)

is so common, there is a shortcut - you basically put the loop inside the []
braces and you get the same result:

collection = [item for item in another_collection if item == criteria]

The syntax is much more terse, but once you understand what's happening,
they are much cleaner to both read and write (IMO - some people disagree)

So for your program you could say:

titles = [title for title in myFile if title not in ["\n",""]]

Much shorter than your original function!


>
> def rank( titles ):
>""" Gets a user-input ranking for each line of text.
>Returns those rankings
>"""
>
>ranks = []
>
>for t in titles:
>
>rank = raw_input(t + " ")
>ranks.append(rank)
>

What happens if someone inputs "Crunchy Frog" for their rank? What would you
expect to happen?


>
>return ranks
>
> def rankRandom( titles ):
>""" Takes a list of titles, puts them in random order, gets ranks, and
> then
>returns the ranks to their original order (so that the rankings
> always
>match the correct titles).
>"""
>
>finalRanks = [0]*len(titles)
>
>origTitles = copy.copy(titles)
>#print "Orign: ", origTitles
>
>random.shuffle(titles)  # Shuffle works in-place
>ranks = rank(titles)
>
>i = 0
>for t in titles:
>
>finalRanks[ origTitles.index(t) ] = ranks[i]
>i += 1
>

This code looks clunky. And usually when code looks clunky, that means
there's a better way to do it!

In your case, I would strongly recommend using a dictionary. As a matter of
fact, your problem just begs to use a dictionary, which is a collection of
related items, such as a title and a rank. So in your case, you could have
something like:

finalRanks = {}
for title, rank  in zip(titles, ranks):   # you really should avoid
1-letter variables, except maybe in the case of axes in a graph
finalRanks[title] = rank

Which would give you something like:

{'Gone With the Wind': 2, 'Dune': 1, 'Harold and the Purple Crayon': 3}



>
>titles = origTitles # Must restore, since python passes by reference,
> not
># value, and the original structure was changed by
># shuffle
>#print "t: ", titles
>
>return finalRanks
>
> def writeToExcel(titles, allRanks):
>
># Open new workbook
>mydoc = excel.Workbook()
>
># Add a worksheet
>mysheet = myd

Re: [Tutor] Parsing an XML document using ElementTree

2011-05-25 Thread Sithembewena Lloyd Dube
Hi Everyone,

Thanks for all your suggestions. I read up on gzip and urllib and also
learned in the process that I could use urllib2 as its the latest form of
that library.

Herewith my solution: I don't know how elegant it is, but it works just
fine.

def get_contests():
 url = '
http://xml.matchbook.com/xmlfeed/feed?sport-id=&vendor=TEST&sport-name=&short-name=Po
'
 req = urllib2.Request(url)
 req.add_header('accept-encoding','gzip/deflate')
 opener = urllib2.build_opener()
 response = opener.open(req)
 compressed_data = response.read()
 compressed_stream = StringIO.StringIO(compressed_data)
 gzipper = gzip.GzipFile(fileobj=compressed_stream)
 data = gzipper.read()
 current_path = os.path.realpath(MEDIA_ROOT + '/xml-files/d.xml')
 data_file = open(current_path, 'w')
 data_file.write(data)
 data_file.close()
 xml_data = ET.parse(open(current_path, 'r'))
 contest_list = []
 for contest_parent_node in xml_data.getiterator('contest'):
  contest = Contest()
  for contest_child_node in contest_parent_node:
   if (contest_child_node.tag == "name" and
contest_child_node.text is not None and contest_child_node.text != ""):
contest.name = contest_child_node.text
   if (contest_child_node.tag == "league" and
contest_child_node.text is not None and contest_child_node.text != ""):
   contest.league = contest_child_node.text
   if (contest_child_node.tag == "acro" and
contest_child_node.text is not None and contest_child_node.text != ""):
   contest.acro = contest_child_node.text
   if (contest_child_node.tag == "time" and
contest_child_node.text is not None and contest_child_node.text != ""):
   contest.time = contest_child_node.text
   if (contest_child_node.tag == "home" and
contest_child_node.text is not None and contest_child_node.text != ""):
   contest.home = contest_child_node.text
   if (contest_child_node.tag == "away" and
contest_child_node.text is not None and contest_child_node.text != ""):
   contest.away = contest_child_node.text
  contest_list.append(contest)
 try:
  os.remove(current_path)
 except:
  pass
 return contest_list

Many thanks!

On Tue, May 24, 2011 at 12:35 PM, Stefan Behnel  wrote:

> Sithembewena Lloyd Dube, 24.05.2011 11:59:
>
>  I am trying to parse an XML feed and display the text of each child node
>> without any success. My code in the python shell is as follows:
>>
>> >>> import urllib
>> >>> from xml.etree import ElementTree as ET
>>
>> >>> content = urllib.urlopen('
>>
>> http://xml.matchbook.com/xmlfeed/feed?sport-id=&vendor=TEST&sport-name=&short-name=Po
>> ')
>> >>> xml_content = ET.parse(content)
>>
>> I then check the xml_content object as follows:
>>
>> >>> xml_content
>> 
>>
>
> Well, yes, it does return an XML document, but not what you expect:
>
>  >>> urllib.urlopen('URL see above').read()
>  "\r\n  you must add 'accept-encoding' as
>  'gzip,deflate' to the header of your request\r
>  \n"
>
> Meaning, the server forces you to pass an HTTP header to the request in
> order to receive gzip compressed data. Once you have that, you must
> decompress it before passing it into ElementTree's parser. See the
> documentation on the gzip and urllib modules in the standard library.
>
> Stefan
>
>
> ___
> Tutor maillist  -  Tutor@python.org
> To unsubscribe or change subscription options:
> http://mail.python.org/mailman/listinfo/tutor
>



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


Re: [Tutor] Parsing an XML document using ElementTree

2011-05-25 Thread Stefan Behnel

Sithembewena Lloyd Dube, 25.05.2011 14:40:

Thanks for all your suggestions. I read up on gzip and urllib and also
learned in the process that I could use urllib2 as its the latest form of
that library.

Herewith my solution: I don't know how elegant it is, but it works just
fine.

def get_contests():
  url = '
http://xml.matchbook.com/xmlfeed/feed?sport-id=&vendor=TEST&sport-name=&short-name=Po
'
  req = urllib2.Request(url)
  req.add_header('accept-encoding','gzip/deflate')
  opener = urllib2.build_opener()
  response = opener.open(req)


This is ok.



  compressed_data = response.read()
  compressed_stream = StringIO.StringIO(compressed_data)
  gzipper = gzip.GzipFile(fileobj=compressed_stream)
  data = gzipper.read()


This should be simplifiable to

   uncompressed_stream = gzip.GzipFile(fileobj=response)



  current_path = os.path.realpath(MEDIA_ROOT + '/xml-files/d.xml')
  data_file = open(current_path, 'w')
  data_file.write(data)
  data_file.close()
  xml_data = ET.parse(open(current_path, 'r'))


And this subsequently becomes

   xml_data = ET.parse(uncompressed_stream)



  contest_list = []
  for contest_parent_node in xml_data.getiterator('contest'):


Take a look at ET.iterparse().



   contest = Contest()
   for contest_child_node in contest_parent_node:
if (contest_child_node.tag == "name" and
contest_child_node.text is not None and contest_child_node.text != ""):
 contest.name = contest_child_node.text
if (contest_child_node.tag == "league" and
contest_child_node.text is not None and contest_child_node.text != ""):
contest.league = contest_child_node.text
if (contest_child_node.tag == "acro" and
contest_child_node.text is not None and contest_child_node.text != ""):
contest.acro = contest_child_node.text
if (contest_child_node.tag == "time" and
contest_child_node.text is not None and contest_child_node.text != ""):
contest.time = contest_child_node.text
if (contest_child_node.tag == "home" and
contest_child_node.text is not None and contest_child_node.text != ""):
contest.home = contest_child_node.text
if (contest_child_node.tag == "away" and
contest_child_node.text is not None and contest_child_node.text != ""):
contest.away = contest_child_node.text


This is screaming for a simplification, such as

   for child in contest_parent_node:
   if child.tag in ('name', 'league', ...): # etc.
   if child.text:
   setattr(context, child.tag, child.text)


Stefan

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


[Tutor] Cherrypy

2011-05-25 Thread Bryton
Is anyone having a step by step tutorial of cherrypy(or book title).I 
have used the tutorial in their site as well as the book (cherrypy 
essentials) and I would like to have a one that is a bit more step by 
step...Please help...


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


[Tutor] Clunky Password maker

2011-05-25 Thread Wolf Halton
Is there a less clunky way to do this?
[code]
def new_pass():
series = ['`', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-',
'=', \
  '~', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_',
'+', \
  'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']',
'\\', \
  'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}',
'|', \
  'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', "'", \
  'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', \
  'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', \
  'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?']
passwd = []
p = input("Enter the length you want your password to be: ")
  # length of password
for i in range(p):
r = random.randint(0, 94)
passwd.append(series[r]) # Append a random char from series[] to
passwd
#print passwd
#print passwd[0], passwd[1], passwd[2], passwd[3]
print ""
print "".join(map(str, passwd)), " is your new password. \n"
[/code]

[output]
>>>
Enter 1 to run a MD5hash on your password
Enter 2 to run a SHA1   hash on your password
Enter 3 to run a SHA224 hash on your password
Enter 9 to get a new randomy password
Enter 10 to run away...  he he he

Enter your choice here> 9
Enter the length you want your password to be: 4

!bnR  is your new password.
>>>
[/output]

-- 
This Apt Has Super Cow Powers - http://sourcefreedom.com


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


Re: [Tutor] Clunky Password maker

2011-05-25 Thread Noah Hall
On Wed, May 25, 2011 at 6:25 PM, Wolf Halton  wrote:
> Is there a less clunky way to do this?
> [code]
> def new_pass():
>     series = ['`', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-',
> '=', \
>               '~', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_',
> '+', \
>               'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']',
> '\\', \
>               'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}',
> '|', \
>               'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', "'", \
>               'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', \
>               'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', \
>               'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?']
>     passwd = []
>     p = input("Enter the length you want your password to be: ")
>               # length of password
>     for i in range(p):
>         r = random.randint(0, 94)
>         passwd.append(series[r]) # Append a random char from series[] to
> passwd
>     #print passwd
>     #print passwd[0], passwd[1], passwd[2], passwd[3]
>     print ""
>     print "".join(map(str, passwd)), " is your new password. \n"
> [/code]

I suggest you read up on the random module - there's two things that
you'll find immediately useful - random.choice and random.sample. I
suggest you use sample instead of the for loop you're using. Also,
when you print the output, there's no need to use map - everything in
your series.
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Clunky Password maker

2011-05-25 Thread Sander Sweers
On Wed, 25 May 2011, 19:25:59 CEST, Wolf Halton  wrote:
> [code]
> def new_pass():
>         series = ['`', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-',
> '=', \
>                             '~', '!', '@', '#', '$', '%', '^', '&', '*', '(', 
>')', '_',
> '+', \
>                             'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', 
>'[', ']',
> '\\', \
>                             'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', 
>'{', '}',
> '|', \
>                             'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', 
>"'", \
>                             'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', 
>'"', \
>                             'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 
>\
>                             'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?']

Have a look at the string module as it has all the above already.

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


Re: [Tutor] Clunky Password maker

2011-05-25 Thread Martin A. Brown


Hello,

: Is there a less clunky way to do this?

Yes.  There are probably many ways to do this, and this is just 
something I cooked up at a moment's notice in reply to your 
question, and probably could be significantly improved upon.


: def new_pass():

Your function takes no arguments.  Maybe this is something to 
reconsider.  Keep reading.


: series = ['`', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', 
'=', \
:   '~', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', 
'+', \
:   'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', 
'\\', \
:   'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', 
'|', \
:   'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', "'", \
:   'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', \
:   'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', \
:   'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?']

So, if I were staring at my keyboard and starting to type in the 
characters (not a QWERTZ or AZERTY keyboard, it seems), I would ask 
myself the question--is there any module that has the complete set 
of characters that are available to me already, so I don't have to 
type them all in?


Indeed, there is?  I found the module called 'string'.  In that 
module, the following are available to you:


   ascii_letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
   ascii_lowercase = 'abcdefghijklmnopqrstuvwxyz'
   ascii_uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
   digits = '0123456789'
   hexdigits = '0123456789abcdefABCDEF'
   letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
   lowercase = 'abcdefghijklmnopqrstuvwxyz'
   octdigits = '01234567'
   printable = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTU...
   punctuation = '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'
   uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
   whitespace = '\t\n\x0b\x0c\r '

OK, so because I believe in strong (or, at least, reasonably strong) 
passwords, I'll concatenate a few of these to make the set of 
characters that I would like to produce in a password.  To me, the 
'printable' set seems a bit, well, difficult for the person typing a 
password, so I'll stick with the following:


 validchars = string.ascii_letters + string.digits + string.punctuation
 series = list( validchars )

: passwd = []
: p = input("Enter the length you want your password to be: ")
:   # length of password

Maybe you could make the function 'new_pass' take as an argument the 
number of characters.  That way, your function would not need to 
read input from anyplace else (the console).  It could generate 
passwords of any length regardless of whether it was called from a 
CGI or command-line or even used from a bulk password generation 
system.


: for i in range(p):
: r = random.randint(0, 94)

Uh-oh!  You had already counted and hard-coded the length of your 
variable 'series'!  What happens if I want to add a few characters 
at the end?  Like maybe the €, the £ or the ¥.  I am currently 
obsessed with (con)currency.


If you were to let Python count the elements in your variable 
'series', then you would not have to have counted all 94 elements 
yourself.  So, think about why this might be better (more 
maintainable):


: passwd = []
: for i in range(p):
: r = random.randint(0, len(series))
: passwd.append(series[r]) # Append a random char from series[] to 
passwd

Now, in the (admittedly, revised loop, above), you generate a single 
random.randint() for each of the elements that you wish to extract.  
Chances are that somebody has already implemented a feature to do 
this sort of thing.  Doesn't it seem like a pretty rational sort of 
thing to have a compute do?  Select a bunch of elements randomly 
from an input set?


So, let's try this one of two different ways.  Using option A, you 
can mix up your data and repeatedly pull out the same result 
for the N items:


 random.shuffle(series)
 ''.join(series[0:p])

In option B, you would get a different result each time:

 ''.join(random.sample(validchars,p))

So, I would rewrite your function to be (substituting 'charcount' 
for 'p'):


 #! /usr/bin/env python
 
 import string

 import random
 
 def new_pass(charcount):

 validchars = string.ascii_letters + string.digits + string.punctuation
 series = list( validchars )
 random.shuffle(series)
 print ''.join(series[0:charcount])
 
 if __name__ == '__main__':

 new_pass(int(input("Enter the length you want your password to be: ")))

Two others have already suggested that you look at the string and 
random modules.  Here's just one example of how you could use them 
together.  Now, let's see what you do with MD5 and SHA.  (You are 
looking at 'hashlib', correct?)


Good luck,

-Martin

--
Martin A. Brown
http://linux-ip.net/___
Tutor maillist  -  Tutor@python.

Re: [Tutor] Clunky Password maker

2011-05-25 Thread Modulok
On 5/25/11, Wolf Halton  wrote:
> Is there a less clunky way to do this?
> [code]
> def new_pass():
> series = ['`', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-',
> '=', \
>   '~', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_',
> '+', \
>   'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']',
> '\\', \
>   'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}',
> '|', \
>   'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', "'", \
>   'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', \
>   'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', \
>   'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?']
> passwd = []
> p = input("Enter the length you want your password to be: ")
>   # length of password
> for i in range(p):
> r = random.randint(0, 94)
> passwd.append(series[r]) # Append a random char from series[] to
> passwd
> #print passwd
> #print passwd[0], passwd[1], passwd[2], passwd[3]
> print ""
> print "".join(map(str, passwd)), " is your new password. \n"
> [/code]
>
> [output]

> Enter 1 to run a MD5hash on your password
> Enter 2 to run a SHA1   hash on your password
> Enter 3 to run a SHA224 hash on your password
> Enter 9 to get a new randomy password
> Enter 10 to run away...  he he he
>
> Enter your choice here> 9
> Enter the length you want your password to be: 4
>
> !bnR  is your new password.

> [/output]

Depending on what your passwords are going to be protecting, be aware that the
default generator in the random module is:

"...completely unsuitable for cryptographic purposes."

Instead, create an instance of the 'SystemRandom' class. You also don't need to
create a list of all of your values. A simple string will do. You should also
look into the 'string' module, as it defines 'letters', 'digits' and
'punctuation' characters for you. Thus, your code be something like:

import random
import string
passlen = 10 # How long should it be?

r = random.SystemRandom()
chars = string.letters + string.digits + string.punctuation
passwd = ""
for i in range(passlen):
passwd += r.choice(chars)
print passwd

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


Re: [Tutor] Clunky Password maker

2011-05-25 Thread Alan Gauld


"Wolf Halton"  wrote


Is there a less clunky way to do this?



def new_pass():
   series = ['`', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 
'-',

'=', \
 '~', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', 
'_',

'+', \
 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', 
']',

'\\', \
 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', 
'}',

'|', \
 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', "'", 
\
 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', 
\

 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', \
 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?']


You don't need a list here a simple string would
do and be easier to type and use. You can index
a string as easily as a list.


   passwd = []
   p = input("Enter the length you want your password to be: ")
 # length of password
   for i in range(p):
   r = random.randint(0, 94)
   passwd.append(series[r]) # Append a random char from series[] 
to

passwd


You could do this with a list comprehension and using
the choice() function from the whrandom module.

passwd = [whrandom.choice(series) for n in range(p)]


   print "".join(map(str, passwd)), " is your new password. \n"


You might want to return the string rather than print it.
Then you can print with

new_p = new_pass()
print new_p, 'is your new password'

I'd also move the length question out of the function
and make it a parameter so your final code looks like:

ln = raw_input("Length of password?")
np = new_pass(ln)
print np, 'is your new password'


For extra points make the alphabet a parameter with
a default value so you can use it for non latin alphabets
too...

klingon = "..."
ln = raw_input(klingon_phrases['length'])
np = new_pass(ln, klingon)
print np, klingon_phrases['new']

HTH,


--
Alan Gauld
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] Clunky Password maker

2011-05-25 Thread Adam Bark

On 25/05/11 19:54, Modulok wrote:

Depending on what your passwords are going to be protecting, be aware that the
default generator in the random module is:

"...completely unsuitable for cryptographic purposes."
If he's just planning on making a few passwords I think the period of 
2**19937-1 of the Mersenne twister is plenty large enough not to worry 
about.

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


Re: [Tutor] Python Variables Changing in Other Functions

2011-05-25 Thread Prasad, Ramit
>> Having lots of += hanging around is a perfect example of a code smell (i.e. 
>> something in this code stinks, and we should change >>it). Part of being a 
>> good programmer is learning to recognize those bad smells and getting rid of 
>> them. Turns out, Python has a lot >>of nice built-in functions for the 
>> elimination of code smells.  In this case, it's the enumerate function:

What happens if you are trying to write to an excel document with several 
different sections and need to keep track of things like last written row / 
current row? I could keep track of enumerations and then save them to a local 
variable and then append it but that seems about as funky. Is there a better 
way?

# pseudocode-ish
# Is this better?
blah = enumerate(raw_data)
For enumerate_value, data in blah:
 sheet.write (base_row + enumerate_value , column, data)
base_row = blah[-1][0]

Ramit



Ramit Prasad | JPMorgan Chase Investment Bank | Currencies Technology
712 Main Street | Houston, TX 77002
work phone: 713 - 216 - 5423


This communication is for informational purposes only. It is not
intended as an offer or solicitation for the purchase or sale of
any financial instrument or as an official confirmation of any
transaction. All market prices, data and other information are not
warranted as to completeness or accuracy and are subject to change
without notice. Any comments or statements made herein do not
necessarily reflect those of JPMorgan Chase & Co., its subsidiaries
and affiliates.

This transmission may contain information that is privileged,
confidential, legally privileged, and/or exempt from disclosure
under applicable law. If you are not the intended recipient, you
are hereby notified that any disclosure, copying, distribution, or
use of the information contained herein (including any reliance
thereon) is STRICTLY PROHIBITED. Although this transmission and any
attachments are believed to be free of any virus or other defect
that might affect any computer system into which it is received and
opened, it is the responsibility of the recipient to ensure that it
is virus free and no responsibility is accepted by JPMorgan Chase &
Co., its subsidiaries and affiliates, as applicable, for any loss
or damage arising in any way from its use. If you received this
transmission in error, please immediately contact the sender and
destroy the material in its entirety, whether in electronic or hard
copy format. Thank you.

Please refer to http://www.jpmorgan.com/pages/disclosures for
disclosures relating to European legal entities.___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Clunky Password maker

2011-05-25 Thread Wolf Halton
Now I see. I am going to go woodshed this. Thanks y'all for all the cool
ideas!

Wolf

On May 25, 2011 4:05 PM, "Adam Bark"  wrote:
> On 25/05/11 19:54, Modulok wrote:
>> Depending on what your passwords are going to be protecting, be aware
that the
>> default generator in the random module is:
>>
>> "...completely unsuitable for cryptographic purposes."
> If he's just planning on making a few passwords I think the period of
> 2**19937-1 of the Mersenne twister is plenty large enough not to worry
> about.
> ___
> Tutor maillist - Tutor@python.org
> To unsubscribe or change subscription options:
> http://mail.python.org/mailman/listinfo/tutor
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Python Variables Changing in Other Functions

2011-05-25 Thread Rachel-Mikel ArceJaeger
I'm not quite certain I understand. When you say sections, do you mean 
different worksheets? If so, you should finish writing on one worksheet first, 
and then move to another. If you're talking about writing to row 5, and then 
jumping to row 50, enumerate lets you do that by allowing you to determine 
where to start indexing.

btw, my improved code is below. Maybe it will offer some clarification?
Rachel

---

import xlwt as excel
import random
import copy

# Note: When python takes in arguments to a function, it passes in the entire 
# object, so any modifications made to that object will be retained after the 
# function terminates without you having to explicity return the object. You  
# only have to return an object if it wasn't passed in as an argument to the 
# function and you need to use in in another function.



def getTitleList():
""" Makes a list of all the lines in a file """

filename = raw_input("Name and Extension of File: ")

myFile = open( filename )

dictOfTitles = {}
for title in myFile:
if title not in ["\n",""]:
dictOfTitles[title] = []

return dictOfTitles


def rank( randomizedTitles, dictOfTitles ):
""" Gets a user-input ranking (0-10) for each line of text. 
Returns those rankings 
"""

for title in randomizedTitles:

while True:

rank = raw_input(title + " ")

if not rank.isdigit():
continue
elif ( int(rank) > 10 ):
continue

dictOfTitles[title].append(rank)
break


def rankRandom( dictOfTitles ):
""" Takes a list of titles, puts them in random order, gets ranks, and then
returns the ranks to their original order (so that the rankings always  
match the correct titles).
"""

randomizedTitles = dictOfTitles.keys()
random.shuffle(randomizedTitles)# Shuffle works in-place.
rank(randomizedTitles, dictOfTitles)


def writeToExcel(dictOfTitles):
""" Writes the titles and ranks to Excel """

# Open new workbook
mydoc = excel.Workbook()

# Add a worksheet
mysheet = mydoc.add_sheet("Ranks")

# Make header style 
header_font = excel.Font() # Make a font object
header_font.bold = True
header_font.underline = True
header_style = excel.XFStyle(); header_style.font = header_font

# Write headers and ranks to Excel. Indexing is 0-based
# write( row, col, data, style )
for col, title in enumerate(dictOfTitles):
mysheet.write(0, col, title, header_style)
for row, rank in enumerate( dictOfTitles[title], 1 ):
mysheet.write(row, col, rank)

# Save file. You don't have to close it like you do with a file object
mydoc.save("r.xls")


def main():

dictOfTitles = getTitleList()

done = ""
while done.lower() != "y":
rankRandom( dictOfTitles )
done = raw_input("Done? (y/[n]): ")

writeToExcel(dictOfTitles)
 

if __name__ == "__main__" : main()





On May 25, 2011, at 1:49 PM, Prasad, Ramit wrote:

> >> Having lots of += hanging around is a perfect example of a code smell 
> >> (i.e. something in this code stinks, and we should change >>it). Part of 
> >> being a good programmer is learning to recognize those bad smells and 
> >> getting rid of them. Turns out, Python has a lot >>of nice built-in 
> >> functions for the elimination of code smells.  In this case, it's the 
> >> enumerate function:
>  
> What happens if you are trying to write to an excel document with several 
> different sections and need to keep track of things like last written row / 
> current row? I could keep track of enumerations and then save them to a local 
> variable and then append it but that seems about as funky. Is there a better 
> way?
>  
> # pseudocode-ish
> # Is this better?
> blah = enumerate(raw_data)
> For enumerate_value, data in blah:
>  sheet.write (base_row + enumerate_value , column, data)
> base_row = blah[-1][0]
>  
> Ramit
>  
>  
>  
> Ramit Prasad | JPMorgan Chase Investment Bank | Currencies Technology
> 712 Main Street | Houston, TX 77002
> work phone: 713 - 216 - 5423
> This communication is for informational purposes only. It is not intended as 
> an offer or solicitation for the purchase or sale of any financial instrument 
> or as an official confirmation of any transaction. All market prices, data 
> and other information are not warranted as to completeness or accuracy and 
> are subject to change without notice. Any comments or statements made herein 
> do not necessarily reflect those of JPMorgan Chase & Co., its subsidiaries 
> and affiliates. This transmission may contain information that is privileged, 
> confidential, legally privileged, and/or exempt from disclosure under 
> applicable law. If you are not the intended recipient, you are hereby 
> notifi

Re: [Tutor] Python Variables Changing in Other Functions

2011-05-25 Thread Prasad, Ramit
>>> I'm not quite certain I understand. When you say sections, do you mean 
>>> different worksheets? If so, you should finish writing on one worksheet 
>>> first, and then move to another. If you're talking about writing to row 5, 
>>> and then jumping to row 50, enumerate lets you do that by allowing you to 
>>> determine where to start indexing.

I really mean neither, but jumping is a good enough analogy. I meant from 
different sections in my code. The enumerate function would work, but still not 
as helpful since I have to keep track of the last enumeration. Or rewrite so 
that there is only one entry point for writing to excel and it only gets called 
once per sheet, but that seems like a more annoying limitation than keeping 
track of the row manually.

Why is enumerate more pythonic? Is it really faster or just easier to read?


Ramit



Ramit Prasad | JPMorgan Chase Investment Bank | Currencies Technology
712 Main Street | Houston, TX 77002
work phone: 713 - 216 - 5423



This communication is for informational purposes only. It is not
intended as an offer or solicitation for the purchase or sale of
any financial instrument or as an official confirmation of any
transaction. All market prices, data and other information are not
warranted as to completeness or accuracy and are subject to change
without notice. Any comments or statements made herein do not
necessarily reflect those of JPMorgan Chase & Co., its subsidiaries
and affiliates.

This transmission may contain information that is privileged,
confidential, legally privileged, and/or exempt from disclosure
under applicable law. If you are not the intended recipient, you
are hereby notified that any disclosure, copying, distribution, or
use of the information contained herein (including any reliance
thereon) is STRICTLY PROHIBITED. Although this transmission and any
attachments are believed to be free of any virus or other defect
that might affect any computer system into which it is received and
opened, it is the responsibility of the recipient to ensure that it
is virus free and no responsibility is accepted by JPMorgan Chase &
Co., its subsidiaries and affiliates, as applicable, for any loss
or damage arising in any way from its use. If you received this
transmission in error, please immediately contact the sender and
destroy the material in its entirety, whether in electronic or hard
copy format. Thank you.

Please refer to http://www.jpmorgan.com/pages/disclosures for
disclosures relating to European legal entities.___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Python Variables Changing in Other Functions

2011-05-25 Thread Alan Gauld


"Rachel-Mikel ArceJaeger"  wrote

I'm not sure I like this one much...

def rank( randomizedTitles, dictOfTitles ):
   """ Gets a user-input ranking (0-10) for each line of text. 
   Returns those rankings 
   """
   
   for title in randomizedTitles:
   
   while True:
   
   rank = raw_input(title + " ")
   
   if not rank.isdigit():

   continue
   elif ( int(rank) > 10 ):
   continue

I'd have made the while test do the checking:

rank = ''
while (not rank.isdigit() ) or ( int(rank) > 10 ):
  rank = raw_input()

And I'd have put the next line outside the while
  
   dictOfTitles[title].append(rank)


And you then don't need the break
   break

Just an opinion though,


--
Alan Gauld
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] Python Variables Changing in Other Functions

2011-05-25 Thread Wayne Werner
On Wed, May 25, 2011 at 3:59 PM, Rachel-Mikel ArceJaeger <
arcejae...@gmail.com> wrote:

> Thank you so much for taking the time to comment this all out. It was very
> very helpful and showed me improvements to some coding styles I have been
> doing for years. I have a couple of questions, though:
>
> 1. I tried the following line:  titles = [title in myFile if title not in
> ["\n",""]]
> as you suggested, but I'm getting a syntax error pointing to the last ].
> Later on I ended up changed titles from a list to a dict, so I'm not sure if
> this is even applicable anymore, but since I use this sort of structure a
> lot, I'm curious as to why it is not working.
>

You'll have to copy/paste the traceback, and the code snippet - otherwise
it's just a guess!


> 2. I am curious as to how the amended for-loop (for titles in myFile) knows
> to assign title to a line of text. I can see that it does, but I'm not sure
> why it acts that way.
>

It's magic! Well, not really. In C-style languages, your for loop usually
takes the form of

for(int x = 0; x < sizeOfSomething; x++){
somehow_use(something[x]);
}

But x is usually unused - what you really want to say is "for each item in
this collection, do something with that item". So Guido Van Rossum, in his
Dutch-y wisdom, blessed us with this type called an iterable. Which is
basically anything that you can think of in separate parts. Letters in a
string, lines in a file, items in a list, and so on and so forth. Rather
than wasting the extra "int x = 0; x < size; x++", you simply have to tell
the loop what variable you want to use, and what iteratble you want to
iterate over, and Python takes care of the details.

Iterables really allow for some super neat programming.


> 3. I've never used zip before and I'm a little confused about why your
> amended for-loop works the way it does. As far as I can tell,
>
> a = [1,2,3]
> b = ['a','b','c']
> d = zip(a,b)
>
> means d is [(1, 'a'), (2, 'b'), (3, 'c')]
>
> So how is it that if I say
>
> for c,d in zip(a,b):
> ... print [c,d]
>
> I get:
>
> [1, 'a']
> [2, 'b']
> [3, 'c']
>
> It seems to me we should have to unzip the zipped list or something to get
> the tuple first, but it immediately gets the elements of the tuple. Why?
>

This looks like magic, but it really isn't. Consider the following:
>>> a = (1,2)
>>> x, y = a
>>> x
1
>>> y
2
>>> b = [(4,5), (6,7)]
>>> x, y = b[0]
>>> x
4
>>> y
5

Python has this nifty little feature called unpacking, that allows you to
use a collection of data on the right side and a collection of variables on
the left side, and if the numbers of arguments match, then assignment
happens. As for what happens when the numbers don't match up, I'll leave
that experiment to you ;)


>
> 4. Regarding my previous question about passing in arguments, is the
> following surmise correct?: When python takes in arguments to a function, it
> passes in the entire object, so any modifications made to that object will
> be retained after the function terminates without you having to explicity
> return the object. You only have to return an object if it wasn't passed in
> as an argument to the function and you need to use in in another function.
>

No. It might appear that way at times, but that surmise is based on an
incorrect premise. If you read this paper:
http://effbot.org/zone/python-objects.htm it explains what Python objects
really are. Then read http://effbot.org/zone/call-by-object.htm and it
explains how Python passes arguments.

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


Re: [Tutor] Python Variables Changing in Other Functions

2011-05-25 Thread Rachel-Mikel ArceJaeger
You asked for the traceback. All I get is this:
-

python a2.py
  File "a2.py", line 20
titles = [title in myFile if title not in ["\n",""]]
   ^
SyntaxError: invalid syntax

--
(In case the spaces don't come through in this email, the carrot ^ is pointing 
to the last ])
The function was this:
--

def getTitleList():
""" Makes a list of all the lines in a file """

filename = raw_input("Name and Extension of File: ")

myFile = open( filename )

titles = [title in myFile if title not in ["\n",""]]

return titles

--
Rachel





On May 25, 2011, at 6:29 PM, Wayne Werner wrote:

> On Wed, May 25, 2011 at 3:59 PM, Rachel-Mikel ArceJaeger 
>  wrote:
> Thank you so much for taking the time to comment this all out. It was very 
> very helpful and showed me improvements to some coding styles I have been 
> doing for years. I have a couple of questions, though:
> 
> 1. I tried the following line:  titles = [title in myFile if title not in 
> ["\n",""]]
> as you suggested, but I'm getting a syntax error pointing to the last ]. 
> Later on I ended up changed titles from a list to a dict, so I'm not sure if 
> this is even applicable anymore, but since I use this sort of structure a 
> lot, I'm curious as to why it is not working.
> 
> You'll have to copy/paste the traceback, and the code snippet - otherwise 
> it's just a guess!
>  
> 2. I am curious as to how the amended for-loop (for titles in myFile) knows 
> to assign title to a line of text. I can see that it does, but I'm not sure 
> why it acts that way.
>  
> It's magic! Well, not really. In C-style languages, your for loop usually 
> takes the form of 
> 
> for(int x = 0; x < sizeOfSomething; x++){
> somehow_use(something[x]);
> }
> 
> But x is usually unused - what you really want to say is "for each item in 
> this collection, do something with that item". So Guido Van Rossum, in his 
> Dutch-y wisdom, blessed us with this type called an iterable. Which is 
> basically anything that you can think of in separate parts. Letters in a 
> string, lines in a file, items in a list, and so on and so forth. Rather than 
> wasting the extra "int x = 0; x < size; x++", you simply have to tell the 
> loop what variable you want to use, and what iteratble you want to iterate 
> over, and Python takes care of the details. 
> 
> Iterables really allow for some super neat programming.
>  
> 3. I've never used zip before and I'm a little confused about why your 
> amended for-loop works the way it does. As far as I can tell, 
> 
> a = [1,2,3]
> b = ['a','b','c']
> d = zip(a,b)
> 
> means d is [(1, 'a'), (2, 'b'), (3, 'c')]
> 
> So how is it that if I say
> 
> for c,d in zip(a,b):
> ... print [c,d]
> 
> I get:
> 
> [1, 'a']
> [2, 'b']
> [3, 'c']
> 
> It seems to me we should have to unzip the zipped list or something to get 
> the tuple first, but it immediately gets the elements of the tuple. Why?
> 
> This looks like magic, but it really isn't. Consider the following:
> >>> a = (1,2)
> >>> x, y = a
> >>> x
> 1
> >>> y
> 2
> >>> b = [(4,5), (6,7)]
> >>> x, y = b[0]
> >>> x
> 4
> >>> y
> 5
> 
> Python has this nifty little feature called unpacking, that allows you to use 
> a collection of data on the right side and a collection of variables on the 
> left side, and if the numbers of arguments match, then assignment happens. As 
> for what happens when the numbers don't match up, I'll leave that experiment 
> to you ;)
>  
> 
> 4. Regarding my previous question about passing in arguments, is the 
> following surmise correct?: When python takes in arguments to a function, it 
> passes in the entire object, so any modifications made to that object will be 
> retained after the function terminates without you having to explicity return 
> the object. You only have to return an object if it wasn't passed in as an 
> argument to the function and you need to use in in another function. 
> 
> No. It might appear that way at times, but that surmise is based on an 
> incorrect premise. If you read this paper: 
> http://effbot.org/zone/python-objects.htm it explains what Python objects 
> really are. Then read http://effbot.org/zone/call-by-object.htm and it 
> explains how Python passes arguments.
>  
> HTH,
> Wayne

R.M. ArceJaeger
Author/Publisher, Platypus Press

Contact: arcejae...@gmail.com
Website: http://rmarcejaeger.com

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


Re: [Tutor] Python Variables Changing in Other Functions

2011-05-25 Thread Wayne Werner
On Wed, May 25, 2011 at 10:17 PM, Rachel-Mikel ArceJaeger <
arcejae...@gmail.com> wrote:

> You asked for the traceback. All I get is this:
> -
>
> python a2.py
>   File "a2.py", line 20
> titles = [title in myFile if title not in ["\n",""]]
>
> ^
> SyntaxError: invalid syntax
>

Ahah. You're missing the important part:

titles = [title for title in myFile if title not in ["\n",""]]

you're missing the "title for" part. That should fix it.

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


[Tutor] PI

2011-05-25 Thread David Merrick
How do I can access to the math module to use PI?

area = math.pi * pow(3,2)
Traceback (most recent call last):
  File "", line 1, in 
area = math.i * pow(3,2)
NameError: name 'math' is not defined

-- 
Dave Merrick

merrick...@gmail.com

Ph   03 3423 121
Cell 027 3089 169
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] PI

2011-05-25 Thread memilanuk

On 05/25/2011 09:21 PM, David Merrick wrote:

How do I can access to the math module to use PI?

area = math.pi * pow(3,2)
Traceback (most recent call last):
   File "", line 1, in 
 area = math.i * pow(3,2)
NameError: name 'math' is not defined



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


Re: [Tutor] Clunky Password maker

2011-05-25 Thread naheed arafat
On Wed, May 25, 2011 at 11:25 PM, Wolf Halton  wrote:

> Is there a less clunky way to do this?
> [code]
> def new_pass():
> series = ['`', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-',
> '=', \
>   '~', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_',
> '+', \
>   'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']',
> '\\', \
>   'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}',
> '|', \
>   'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', "'", \
>   'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', \
>   'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', \
>   'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?']
>
>
> well. i would have made the series list as follows:
 >>> a=[chr(i) for i in range(33,127)]
>>> a
['!', '"', '#', '$', '%', '&', "'", '(', ')', '*', '+', ',', '-', '.', '/',
 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>',
'?',
 '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
'O',
 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^',
'_'
, '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o'
, 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~']
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor