Re: [Tutor] improve the code

2011-11-04 Thread Peter Otten
lina wrote:

> On Wed, Nov 2, 2011 at 12:14 AM, Peter Otten <__pete...@web.de> wrote:
>> lina wrote:
>>
 sorted(new_dictionary.items())
>>>
>>> Thanks, it works, but there is still a minor question,
>>>
>>> can I sort based on the general numerical value?
>>>
>>> namely not:
>>> :
>>> :
>>> 83ILE 1
>>> 84ALA 2
>>> 8SER 0
>>> 9GLY 0
>>> :
>>> :
>>>
>>> rather 8 9 ...83 84,
>>>
>>> Thanks,
>>
>> You need a custom key function for that one:
>>
> import re
> def gnv(s):
>> ... parts = re.split(r"(\d+)", s)
>> ... parts[1::2] = map(int, parts[1::2])
>> ... return parts
>> ...
> items = [("83ILE", 1), ("84ALA", 2), ("8SER", 0), ("9GLY", 0)]
> sorted(items, key=lambda pair: (gnv(pair[0]), pair[1]))
>> [('8SER', 0), ('9GLY', 0), ('83ILE', 1), ('84ALA', 2)]
> 
> 
> Thanks, I can follow the procedure and get the exact results, but
> still don't understand this part
> 
> parts = re.split(r'"(\d+)",s)
> 
> r"(\d+)", sorry,
> 
 items
> [('83ILE', 1), ('84ALA', 2), ('8SER', 0), ('9GLY', 0)]
> 
> 
 parts = re.split(r"(\d+)",items)
> Traceback (most recent call last):
>   File "", line 1, in 
> parts = re.split(r"(\d+)",items)
>   File "/usr/lib/python3.2/re.py", line 183, in split
> return _compile(pattern, flags).split(string, maxsplit)
> TypeError: expected string or buffer

I was a bit lazy and hoped you would accept the gnv() function as a black 
box...

Here's a step-through:
re.split() takes a pattern where to split the string and a string. In the 
following example the pattern is the character "_":

>>> re.split("_", "alpha_beta___gamma")
['alpha', 'beta', '', '', 'gamma']

You can see that this simple form works just like 
"alpha_beta___gamma".split("_"), and finds an empty string between two 
adjacent "_". If you want both "_" and "___" to work as a single separator 
you can change the pattern to "_+", where the "+" means one or more of the 
previous:

>>> re.split("_+", "alpha_beta___gamma")
['alpha', 'beta', 'gamma']

If we want to keep the separators, we can wrap the whole expression in 
parens:

>>> re.split("(_+)", "alpha_beta___gamma")
['alpha', '_', 'beta', '___', 'gamma']

Now for the step that is a bit unobvious: we can change the separator to 
include all digits. Regular expressions have two ways to spell "any digit": 
[0-9] or \d:

>>> re.split("([0-9]+)", "alpha1beta123gamma")
['alpha', '1', 'beta', '123', 'gamma']

I chose the other (which will also accept non-ascii digits)

>>> re.split(r"(\d+)", "alpha1beta123gamma")
['alpha', '1', 'beta', '123', 'gamma']

At this point we are sure that the list contains a sequence of non-integer-
str, integer-str, ..., non-integer-str, the first and the last always being 
a non-integer str.

>>> parts = re.split(r"(\d+)", "alpha1beta123gamma")

So

>>> parts[1::2]
['1', '123']

will always give us the parts that can be converted to an integer

>>> parts
['alpha', '1', 'beta', '123', 'gamma']
>>> parts[1::2] = map(int, parts[1::2])
>>> parts
['alpha', 1, 'beta', 123, 'gamma']

We need to do the conversion because strings won't sort the way we like:

>>> sorted(["2", "20", "10"])
['10', '2', '20']
>>> sorted(["2", "20", "10"], key=int)
['2', '10', '20']

We now have the complete gnv() function

>>> def gnv(s):
... parts = re.split(r"(\d+)", s)
... parts[1::2] = map(int, parts[1::2])
... return parts
...

and can successfully sort a simple list of strings like

>>> values = ["83ILE", "84ALA", "8SER", "9GLY"]
>>> sorted(values, key=gnv)
['8SER', '9GLY', '83ILE', '84ALA']

The sorted() function calls gnv() internally for every item in the list and 
uses the results to determine the order of the items. When 
sorted()/list.sort() did not feature the key argument you could do this 
manually with "decorate sort undecorate":

>>> decorated = [(gnv(item), item) for item in values]
>>> decorated
[(['', 83, 'ILE'], '83ILE'), (['', 84, 'ALA'], '84ALA'), (['', 8, 'SER'], 
'8SER'), (['', 9, 'GLY'], '9GLY')]
>>> decorated.sort()
>>> decorated
[(['', 8, 'SER'], '8SER'), (['', 9, 'GLY'], '9GLY'), (['', 83, 'ILE'], 
'83ILE'), (['', 84, 'ALA'], '84ALA')]
>>> undecorated
['8SER', '9GLY', '83ILE', '84ALA']

For your actual data 

>>> items
[('83ILE', 1), ('84ALA', 2), ('8SER', 0), ('9GLY', 0)]

you need to extract the first from an (x, y) pair

>>> def first_gnv(item):
... return gnv(item[0])
...
>>> first_gnv(("83ILE", 1))
['', 83, 'ILE']

but what if there are items with the same x? In that case the order is 
undefined:

>>> sorted([("83ILE", 1), ("83ILE", 2)], key=first_gnv)
[('83ILE', 1), ('83ILE', 2)]
>>> sorted([("83ILE", 2), ("83ILE", 1)], key=first_gnv)
[('83ILE', 2), ('83ILE', 1)]

Let's take y into account, too:

>>> def first_gnv(item):
... return gnv(item[0]), item[1]
...
>>> sorted([("83ILE", 1), ("83ILE", 2)], key=first_gnv)
[('83ILE', 1), ('83ILE', 2)]
>>> sorted([("83ILE", 2), ("83ILE", 1)], key=first_gnv)
[('83ILE', 1), ('83ILE', 2)]

We're done!

>>> sorted(items, key=first_gnv)
[('8SER', 0), ('9GLY',

Re: [Tutor] assign all parameters of __init__ to class variables?

2011-11-04 Thread Alex Hall
No, I mean what you said. My class has one or two class-level:
class myClass:
  x=5

and a lot of instance-level:
  def __init__(self, p1, p2...):
self.__dict__.update(locals())

On 11/4/11, Steven D'Aprano  wrote:
> Alex Hall wrote:
>> I'm sorry, I misspoke (well, mistyped anyway). I have a couple
>> class-level variables, but most of them are set in the __init__ so
>> that every instance gets a fresh copy of them. Thatnks for the
>> responses.
>
>
> Ah I see, or at least I think I see. Possibly we're talking at
> cross-purposes.
>
> When you talk about "class-level variables", to me that means class
> attributes: attributes of a class, like this:
>
> class Spam:
>  x = "this is at the class level"
>
> as opposed to "instance-level variables", which I would interpret as
> instance attributes:
>
>
> class Ham:
>  def __init__(self):
>  self.x = "this is on the instance"
>
>
> If you mean something different from this, then we're talking past each
> other.
>
>
>
> --
> Steven
> ___
> Tutor maillist  -  Tutor@python.org
> To unsubscribe or change subscription options:
> http://mail.python.org/mailman/listinfo/tutor
>


-- 
Have a great day,
Alex (msg sent from GMail website)
mehg...@gmail.com; http://www.facebook.com/mehgcap
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


[Tutor] Help with re in Python 3

2011-11-04 Thread Joe Batt

Hi all,Still trying with Python and programming in general…. 
I am trying to get a grip with re. I am writing a program to open a text file 
and scan it for exactly 3 uppercase letters in a row followed by a lowercase 
followed by exactly 3 uppercase letters. ( i.e.  oooXXXoXXXooo )If possible 
could you explain why I am getting "EOL while scanning string literal" when I 
try running the following program in Python 3.
My program:
import 
reregexp=re.compile(r"[a-z]"r"[A-Z]"r"[A-Z]"r"[A-Z]"r"[a-z]"r"[A-Z]"r"[A-Z]"r"[A-Z]"r"[a-z])
  file=('///Users/joebatt/Desktop/python3.txt','r')for line in 
file.readlines():if regexp.search(line):print("Found value 3 caps 
followed by lower case followed by 3 caps")file.close()
If possible could you explain why I am getting "EOL while scanning string 
literal" when I try running my program in Python 3.
Thanks for your help
Joe

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


Re: [Tutor] Help with re in Python 3

2011-11-04 Thread Joel Goldstick
On Fri, Nov 4, 2011 at 3:42 PM, Joe Batt  wrote:

>  Hi all,
> Still trying with Python and programming in general….
>
> I am trying to get a grip with re. I am writing a program to open a text
> file and scan it for exactly 3 uppercase letters in a row followed by a
> lowercase followed by exactly 3 uppercase letters. ( i.e.  oooXXXoXXXooo )
> If possible could you explain why I am getting "EOL while scanning string
> literal" when I try running the following program in Python 3.
>
> My program:
>
> import re
>
> regexp=re.compile(r"[a-z]"r"[A-Z]"r"[A-Z]"r"[A-Z]"r"[a-z]"r"[A-Z]"r"[A-Z]"r"[A-Z]"r"[a-z])
>
> file=('///Users/joebatt/Desktop/python3.txt','r')
> for line in file.readlines():
> if regexp.search(line):
> print("Found value 3 caps followed by lower case followed by 3
> caps")
> file.close()
>
> If possible could you explain why I am getting "EOL while scanning string
> literal" when I try running my program in Python 3.
>
> Thanks for your help
>
> Joe
>
>
>
> ___
> Tutor maillist  -  Tutor@python.org
> To unsubscribe or change subscription options:
> http://mail.python.org/mailman/listinfo/tutor
>
>
You should read a little more about regular expressions to simplify yours,
but I believe your problem is that you have no closing "
after this: r"[a-z])

change it to r"[a-z]")


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


Re: [Tutor] Help with re in Python 3

2011-11-04 Thread Albert-Jan Roskam
It seems that you are not opening the file properly. You could do
f = file('///Users/joebatt/Desktop/python3.txt','r')
or:
withfile('///Users/joebatt/Desktop/python3.txt','r') as f:
  for line in f:
    m = re.search("[A-Z]{3}[a-z][A-Z]{3}", line)
    if m:
  print("Pattern found")
  print(m.group(0))
 
Cheers!!
Albert-Jan


~~
All right, but apart from the sanitation, the medicine, education, wine, public 
order, irrigation, roads, a fresh water system, and public health, what have 
the Romans ever done for us?
~~


>
>From: Joe Batt 
>To: tutor@python.org
>Sent: Friday, November 4, 2011 8:42 PM
>Subject: [Tutor] Help with re in Python 3
>
>
> 
>Hi all,
>Still trying with Python and programming in general…. 
>
>
>I am trying to get a grip with re. I am writing a program to open a text file 
>and scan it for exactly 3 uppercase letters in a row followed by a lowercase 
>followed by exactly 3 uppercase letters. ( i.e.  oooXXXoXXXooo )
>If possible could you explain why I am getting "EOL while scanning string 
>literal" when I try running the following program in Python 3.
>
>
>My program:
>
>
>import re
>regexp=re.compile(r"[a-z]"r"[A-Z]"r"[A-Z]"r"[A-Z]"r"[a-z]"r"[A-Z]"r"[A-Z]"r"[A-Z]"r"[a-z])
>                  
>file=('///Users/joebatt/Desktop/python3.txt','r')
>for line in file.readlines():
>    if regexp.search(line):
>        print("Found value 3 caps followed by lower case followed by 3 caps")
>file.close()
>
>
>If possible could you explain why I am getting "EOL while scanning string 
>literal" when I try running my program in Python 3.
>
>
>Thanks for your help
>
>
>Joe
>
>
>
>
>___
>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


[Tutor] Assigning variables with names set by other variables

2011-11-04 Thread Max S.
Is it possible to create a variable with a string held by another variable
in Python?  For example,

>>> var_name = input("Variable name: ")
(input: 'var')
>>> var_name = 4
>>> print(var)
(output: 4)

(Yeah, I know that if this gets typed into Python, it won't work.  It just
pseudocode.)

I'm on a Windows Vista with Python 3.2.2.  Thanks.
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Help with re in Python 3

2011-11-04 Thread Prasad, Ramit
>m = re.search("[A-Z]{3}[a-z][A-Z]{3}", line)

That is the expression I would suggest, except it is still more efficient to 
use a compiled regular expression like the original version.

Ramit


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



This email is confidential and subject to important disclaimers and
conditions including on offers for the purchase or sale of
securities, accuracy and completeness of information, viruses,
confidentiality, legal privilege, and legal entity disclaimers,
available at http://www.jpmorgan.com/pages/disclosures/email.  
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Assigning variables with names set by other variables

2011-11-04 Thread Wayne Werner
On Fri, Nov 4, 2011 at 4:21 PM, Max S.  wrote:

> Is it possible to create a variable with a string held by another variable
> in Python?  For example,
>
> >>> var_name = input("Variable name: ")
> (input: 'var')
> >>> var_name = 4
> >>> print(var)
> (output: 4)
>
> (Yeah, I know that if this gets typed into Python, it won't work.  It just
> pseudocode.)
>

There are a few ways to do what you want. The most dangerous (you should
never use this unless you are 100% absolutely, totally for certain that the
input will be safe. Which means you should probably not use it) method is
by using exec(), which does what it sounds like: it executes whatever is
passed to it in a string:

>>> statement = input("Variable name: ")
Variable name: var
>>> exec(statement + "=4")
>>> var
4

The (hopefully) obvious danger here is that someone could type anything
into this statement:

>>> statement = input("Variable name: ")
Variable name: import sys; sys.exit(1); x
>>> exec(statement + " =4")

and now you're at your prompt. If the user wanted to do something more
malicious there are commands like shutil.rmtree that could do *much* more
damage.

A much safer way is to use a dictionary:

>>> safety = {}
>>> safety[input("Variable Name: ")] = 4
Variable Name: my_var
>>> safety["my_var"]
4

It requires a little more typing, but it also has the advantage of
accepting perfectly arbitrary strings.

There may be some other ways to do what you want, but hopefully that should
get you started.
HTH,
Wayne
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Assigning variables with names set by other variables

2011-11-04 Thread Peter Otten
Max S. wrote:

> Is it possible to create a variable with a string held by another variable
> in Python?  For example,
> 
 var_name = input("Variable name: ")
> (input: 'var')
 var_name = 4
 print(var)
> (output: 4)
> 
> (Yeah, I know that if this gets typed into Python, it won't work.  It just
> pseudocode.)
> 
> I'm on a Windows Vista with Python 3.2.2.  Thanks.

The direct translation into python uses exec()

>>> name = input("variable name: ")
variable name: var
>>> exec(name + " = 4")
>>> var
4

However, exec() can execute arbitrary code, and if a malicious user enters

import shutil; shutil.rmtree("/path/to/your/data"); x

as the "variable name" you may be in trouble. Therefore experienced users 
normally use a dictionary instead:

>>> namespace = {}
>>> name = input("variable name: ")
variable name: var
>>> namespace[name] = 4
>>> namespace[name]
4

It may look less convenient at first sight, but can save you a lot of 
trouble later on.

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


Re: [Tutor] Assigning variables with names set by other variables

2011-11-04 Thread Terry Carroll

On Fri, 4 Nov 2011, Max S. wrote:


Is it possible to create a variable with a string held by another variable
in Python?  For example,


It's possible, but in almost all cases where this comes up, the better 
approach is to use a dictionary.___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


[Tutor] regexp

2011-11-04 Thread Dinara Vakhitova
Hello,

I need to find the words in a corpus, which letters are in the alphabetical
order ("almost", "my" etc.)
I started with matching two consecutive letters in a word, which are in
the alphabetical order, and tried to use this expression: ([a-z])[\1-z],
but it won't work, it's matching any sequence of two letters. I can't
figure out why... Evidently I can't refer to a group like this, can I? But
how in this case can I achieve what I need?

Thank you.

-- 
*Yours faithfully,
Dinara Vakhitova*
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Assigning variables with names set by other variables

2011-11-04 Thread Steven D'Aprano

Max S. wrote:

Is it possible to create a variable with a string held by another variable
in Python?  For example,


Yes, but you shouldn't do it. Seriously. Don't do this, you will regret it.

var_name = input("Variable name? ")  # use raw_input in Python 2
exec("%s = 4" % var_name)


Instead, you should use a dictionary, like this:

var_name = input("Variable name? ")
table = {var_name: 4}

and then later when you need to retrieve the value:

print(table[var_name])



Why shouldn't you use exec?

Three main reasons:

(1) This code contains a MAJOR vulnerability to a code injection attack. 
  There are enough code injection vulnerabilities in the world without 
you adding to it, please don't add another.


(2) It makes for hard to read, difficult to follow code.

(3) It's slow.


If you don't know what code injection attacks means, consider this 
simple example where I create a variable spam=4 while executing any code 
I like:


>>> var_name = input('Enter the variable name: ')
Enter the variable name: print(123*456); spam
>>> exec("%s = 4" % var_name)
56088
>>> spam
4


In this case, executing "print(123*456)" is harmless, but annoying, but 
it could do *anything* that Python can do (which is pretty much 
*anything at all*: delete files, send email, take over your computer, 
anything). Code injection attacks are among the two or three most common 
methods that viruses and malware operate.


Sanitising user input so it is safe to pass to exec is a hard job. But 
suppose you do it (somehow!):


var_name = sanitise(input('Enter the variable name: '))
exec("%s = 4" % var_name)
# ...
# ... later on
# ...
print(spam+1)  # do something useful with the new variable

But wait, that can't work! How do you know that the variable is called 
"spam"? You don't. It could be called anything. So now you have to do this:


exec("print(%s+1)" % var_name)

which is a nuisance, it is harder to read and harder to follow, and 
defeats any of the useful features in your editor or IDE. It gets worse 
if you need to use this var_name repeatedly:


exec("print(%s+1)" % var_name)
exec("my_list = [1, 2, 3, %s, 5]" % var_name)
print(my_list)
exec("y = func(23, %s, 42) + %s" % (var_name, var_name))
print(y)

How tedious and painful and hard to follow. And it is potentially buggy: 
what if the user typed "func" as the variable name, by accident? Or 
over-wrote one of your other variables?


And it's slow. Every time you call exec(), Python has to run a 
mini-interpreter over the string, analyzing it, splitting it into 
tokens, compiling it into code that can be executed, and then finally 
execute it. In general, this is slow: in my experience, running 
exec("command") is about 10 times slower than just running command directly.


So just avoid using exec. Anytime you think you need exec, you almost 
certainly do not. And you definitely don't need it for indirect 
variables! Just use a dictionary instead:


var_name = input("Variable name? ")
table = {var_name: 4}
# ...
# ... later on
# ...
print(table[var_name]+1)
my_list = [1, 2, 3, table[var_name], 5]
print(my_list)
y = func(23, table[var_name], 42) + table[var_name]
print(y)




--
Steven

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


Re: [Tutor] regexp

2011-11-04 Thread Steven D'Aprano

Dinara Vakhitova wrote:

Hello,

I need to find the words in a corpus, which letters are in the alphabetical
order ("almost", "my" etc.)


Quoting Jamie Zawinski:

Some people, when confronted with a problem, think "I know, I'll
use regular expressions." Now they have two problems.

Now you have two problems: find words in the corpus which are in 
alphabetical order, and get the damn regular expression to work correctly.


Don't use a regex for this. It is much simpler to write a Python 
function to solve it:


def letters_in_order(astring):
"""Return True if letters in astring are in alphabetical order.

>>> letters_in_order("almost")
True
>>> letters_in_order("zoology")
False

"""
if len(astring) <= 1:
return True
for i in range(1, len(astring)):
if astring[i] < astring[i-1]:
   # Pair of characters are out of order.
return False
# If none of the pairs are out of order, they whole string
# must be in order.
return True

words = filter(letters_in_order, corpus)
for word in words:
print(word)



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


Re: [Tutor] regexp

2011-11-04 Thread Dinara Vakhitova
Thank you for your answer, Steven.

Of course it would have been easier to write this function,
but unfortunately my task is to do it with a regular expression :(

D.

2011/11/5 Steven D'Aprano 

> Dinara Vakhitova wrote:
>
>> Hello,
>>
>> I need to find the words in a corpus, which letters are in the
>> alphabetical
>> order ("almost", "my" etc.)
>>
>
> Quoting Jamie Zawinski:
>
>Some people, when confronted with a problem, think "I know, I'll
>use regular expressions." Now they have two problems.
>
> Now you have two problems: find words in the corpus which are in
> alphabetical order, and get the damn regular expression to work correctly.
>
> Don't use a regex for this. It is much simpler to write a Python function
> to solve it:
>
> def letters_in_order(astring):
>"""Return True if letters in astring are in alphabetical order.
>
>>>> letters_in_order("almost")
>True
>>>> letters_in_order("zoology")
>False
>
>"""
>if len(astring) <= 1:
>return True
>for i in range(1, len(astring)):
>if astring[i] < astring[i-1]:
>   # Pair of characters are out of order.
>return False
># If none of the pairs are out of order, they whole string
># must be in order.
>return True
>
> words = filter(letters_in_order, corpus)
> for word in words:
>print(word)
>
>
>
> --
> Steven
> __**_
> Tutor maillist  -  Tutor@python.org
> To unsubscribe or change subscription options:
> http://mail.python.org/**mailman/listinfo/tutor
>



-- 
*Yours faithfully,
Dinara Vakhitova*
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] regexp

2011-11-04 Thread Steven D'Aprano

Dinara Vakhitova wrote:

Thank you for your answer, Steven.

Of course it would have been easier to write this function,
but unfortunately my task is to do it with a regular expression :(


Is this homework? You should have said so.

I don't understand questions like this. Do carpenters ask their 
apprentices to cut a piece of wood with a hammer? Do apprentice chefs 
get told to dice carrots using only a spoon? Computer programming is the 
only skill I know of where teachers routinely insist that students use 
inappropriate tools to solve a problem, just to prove they can do it.


In any case, if this is even possible using regular expressions -- and I 
don't think it is -- I have no idea how to do it. Good luck. Maybe 
somebody else might have a clue.


I don't think it's possible because you don't know how many characters 
the string will have. Even if [\1-z] works (which it doesn't), you still 
have the same problem that you don't know where to stop:


[a-z][\1-z][\2-z][\3-z][\4-z]...[\99-z]

This is related to the reason you can't parse indefinitely nested 
parentheses using a regular expression.




--
Steven

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


Re: [Tutor] regexp

2011-11-04 Thread Dinara Vakhitova
Sorry, I didn´t know that I couldn´t ask questions about the homework...
I wanted to do it recursively, like this:

def check_abc(string):
string = string.lower()
check_pair = re.compile("([a-z])[\1-z]")
if check_pair.match(string):
if check_abc(string[1:]):
return True
else:
return False
else:
return False

the only problem is that this regex doesn´t work and this case is not
specified in the Python documentation...

Excuse me for disturbing you.

2011/11/5 Steven D'Aprano 

> Dinara Vakhitova wrote:
>
>> Thank you for your answer, Steven.
>>
>> Of course it would have been easier to write this function,
>> but unfortunately my task is to do it with a regular expression :(
>>
>
> Is this homework? You should have said so.
>
> I don't understand questions like this. Do carpenters ask their
> apprentices to cut a piece of wood with a hammer? Do apprentice chefs get
> told to dice carrots using only a spoon? Computer programming is the only
> skill I know of where teachers routinely insist that students use
> inappropriate tools to solve a problem, just to prove they can do it.
>
> In any case, if this is even possible using regular expressions -- and I
> don't think it is -- I have no idea how to do it. Good luck. Maybe somebody
> else might have a clue.
>
> I don't think it's possible because you don't know how many characters the
> string will have. Even if [\1-z] works (which it doesn't), you still have
> the same problem that you don't know where to stop:
>
> [a-z][\1-z][\2-z][\3-z][\4-z].**..[\99-z]
>
> This is related to the reason you can't parse indefinitely nested
> parentheses using a regular expression.
>
>
>
>
> --
> Steven
>
> __**_
> Tutor maillist  -  Tutor@python.org
> To unsubscribe or change subscription options:
> http://mail.python.org/**mailman/listinfo/tutor
>



-- 
*Yours faithfully,
Dinara Vakhitova*
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] regexp

2011-11-04 Thread Sander Sweers
On 5 November 2011 00:38, Dinara Vakhitova  wrote:
> Sorry, I didn´t know that I couldn´t ask questions about the homework...

This list is meant to help with learning python and not  to do
homework assignments. So if you get stuck with something yes you can
post it but be open about it and show what you have tried (code). I
suspect then people on this list will provide guidance and drop hints
but leave the *writing* of the code to you.

> I wanted to do it recursively, like this:
> def check_abc(string):
>     string = string.lower()
>     check_pair = re.compile("([a-z])[\1-z]")
>     if check_pair.match(string):
>         if check_abc(string[1:]):
>             return True
>         else:
>             return False
>     else:
>         return False

Is using regular expressions a requirement? As Steve already pointed
out this is a hard problem to solve (if it can be solved at all) with
regex. So unless the home work requires regex just drop it.

> the only problem is that this regex doesn´t work and this case is not
> specified in the Python documentation...

There is a separate howto on http://docs.python.org/howto/regex.html
does a decent job.

> Excuse me for disturbing you.

Well, people on this list are volunteers and do not get paid for
answering questions. He actually gave you good and well reasoned
advice and if I was you I'd take it.

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


Re: [Tutor] regexp

2011-11-04 Thread Steven D'Aprano

Dinara Vakhitova wrote:

Sorry, I didn´t know that I couldn´t ask questions about the homework...



You're welcome to ask questions about homework or school projects, but 
most of the people here believe that ethically the student should do the 
homework, not the tutor :)


So if something looks like a homework question, we will usually point 
the student in the right direction and ask them to actually write the 
code, rather than write the code ourselves.


Good luck with the question! If you do solve it, please come back and 
tell us how you did it. I for one am curious now whether or not it can 
be done using Python regexes. Perhaps someone else might have a 
solution. You could try the python-l...@python.org mailing list, also 
available on comp.lang.python on Usenet.


(You could also try it with Perl regexes, which I understand are more 
powerful.)




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


Re: [Tutor] Help with re in Python 3

2011-11-04 Thread Steven D'Aprano

Prasad, Ramit wrote:

m = re.search("[A-Z]{3}[a-z][A-Z]{3}", line)


That is the expression I would suggest, except it is still more
efficient to use a compiled regular expression like the original
version.


Not necessarily. The Python regex module caches recently used regex 
strings, avoiding re-compiling them when possible.


However there is no guarantee on how many regexes are kept in the cache, 
so if you care, it is safer to keep your own compiled version.




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


Re: [Tutor] regexp

2011-11-04 Thread Walter Prins
Dinara, Steven,

On 4 November 2011 23:29, Steven D'Aprano  wrote:

> Is this homework? You should have said so.
>

Inded he should've...


> I don't understand questions like this. Do carpenters ask their
> apprentices to cut a piece of wood with a hammer? Do apprentice chefs get
> told to dice carrots using only a spoon? Computer programming is the only
> skill I know of where teachers routinely insist that students use
> inappropriate tools to solve a problem, just to prove they can do it.
>

Calm down dear, it's only a reg-ex... ;)

Additionally, if I may say so, I find this part of your response rather
less than helpful, it's rant-ish IMHO, and as far as I'm concerned the
apprentice analogies are not akin to what programming teachers do and why
they do it.  Fact is, people need to learn the tools of their trade
somewhere.  Sometimes it's neccesary to focus on a particular tool and
therefore dream up some artificial problem for the sake of learning to use
the tool.  It's not that apprentices are being taught to cut wood with a
hammer or whatnot.  And yes, regular expression can be damn useful
sometimes.  Whether or not you like regular expressions, use them, or are
good at them have no bearing on whether Dinara should be able learn how to
use them, nor is it relevant what you think of the question or if the
context of the learning is a contrived question/excercise.


> In any case, if this is even possible using regular expressions -- and I
> don't think it is -- I have no idea how to do it. Good luck. Maybe somebody
> else might have a clue.
>

@Dinara:

It is actually.  Let's describe the requirement a bit differently, first in
words, then see if we can write a regular expression that will match that
description:  A word that matches our requirement will start with 0 or more
occurences of a, and be followed by 0 or more occurrences of b, and so on,
until z, after which we must have reached the end of the word.  So the
requirements for the regex is:
1.) The regex must start at the beginning of the string
2.) 0 or more a's may be matched, followed by 0 or more b's, followed by 0
or more c's and son on, up to z,
3.) The regex must end at the end of the string (so 1 and 3 together imply
that all the text in the string must be matched/consumed by the regex for a
match to have been found.

If we write an equivalent regex, to the above requirement, and it matches
all the text in a string (e.g. a match is found), then by definition it
will have found a word containing letters in alphabetized order.  The only
special case to handle would be the empty string -- this would be matched
by the above regex but may not be considered correct per the intent of the
problem. (On the other hand, an empty string is not a word either, so one
might consider this invalid input in the first place and should properly
probably reject the input and refuse to process it.)

I'll give you some further hints.

1.) To specify/match the beginning of a string, you use the ^ character in
a regex.
2.) To specify 0 or more of something you append an asterisk, e.g. *
3.) To specify a letter to be matched, you can write it directly.  To
therefore match 0 or more a's for example, you'd write a*
4.) To specify a sequence of things you simply write them out.  So for
example the regular expression a*b* will match strings like 'ab', 'aab',
'abb', 'b', 'a', but not 'baa'...
5.) To specify the end of a string, you use the $ character in a regex.

By the way, it's possible to write an alternatve version of the function
that Steven provied in a single line (of body code) with a regex.

HTH,

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


Re: [Tutor] regexp

2011-11-04 Thread Dave Angel

On 11/04/2011 07:00 PM, Steven D'Aprano wrote:

Dinara Vakhitova wrote:

Hello,

I need to find the words in a corpus, which letters are in the 
alphabetical

order ("almost", "my" etc.)


Quoting Jamie Zawinski:

Some people, when confronted with a problem, think "I know, I'll
use regular expressions." Now they have two problems.

Now you have two problems: find words in the corpus which are in 
alphabetical order, and get the damn regular expression to work 
correctly.


Don't use a regex for this. It is much simpler to write a Python 
function to solve it:


def letters_in_order(astring):
"""Return True if letters in astring are in alphabetical order.

>>> letters_in_order("almost")
True
>>> letters_in_order("zoology")
False

"""
if len(astring) <= 1:
return True
for i in range(1, len(astring)):
if astring[i] < astring[i-1]:
   # Pair of characters are out of order.
return False
# If none of the pairs are out of order, they whole string
# must be in order.
return True

words = filter(letters_in_order, corpus)
for word in words:
print(word)




Seems to me it'd much simpler to do something like:
return "".join(sorted(astring)) == astring

with suitable adjustment if both lower and uppercase are desirable.

--

DaveA

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


Re: [Tutor] Assigning variables with names set by other variables

2011-11-04 Thread Max gmail
Thanks Steven.
On Nov 4, 2011, at 6:45 PM, Steven D'Aprano wrote:

> Max S. wrote:
>> Is it possible to create a variable with a string held by another variable
>> in Python?  For example,
> 
> Yes, but you shouldn't do it. Seriously. Don't do this, you will regret it.
> 
>var_name = input("Variable name? ")  # use raw_input in Python 2
>exec("%s = 4" % var_name)
> 
> 
> Instead, you should use a dictionary, like this:
> 
>var_name = input("Variable name? ")
>table = {var_name: 4}
> 
> and then later when you need to retrieve the value:
> 
>print(table[var_name])
> 
> 
> 
> Why shouldn't you use exec?
> 
> Three main reasons:
> 
> (1) This code contains a MAJOR vulnerability to a code injection attack.   
> There are enough code injection vulnerabilities in the world without you 
> adding to it, please don't add another.
> 
> (2) It makes for hard to read, difficult to follow code.
> 
> (3) It's slow.
> 
> 
> If you don't know what code injection attacks means, consider this simple 
> example where I create a variable spam=4 while executing any code I like:
> 
> >>> var_name = input('Enter the variable name: ')
> Enter the variable name: print(123*456); spam
> >>> exec("%s = 4" % var_name)
> 56088
> >>> spam
> 4
> 
> 
> In this case, executing "print(123*456)" is harmless, but annoying, but it 
> could do *anything* that Python can do (which is pretty much *anything at 
> all*: delete files, send email, take over your computer, anything). Code 
> injection attacks are among the two or three most common methods that viruses 
> and malware operate.
> 
> Sanitising user input so it is safe to pass to exec is a hard job. But 
> suppose you do it (somehow!):
> 
>var_name = sanitise(input('Enter the variable name: '))
>exec("%s = 4" % var_name)
># ...
># ... later on
># ...
>print(spam+1)  # do something useful with the new variable
> 
> But wait, that can't work! How do you know that the variable is called 
> "spam"? You don't. It could be called anything. So now you have to do this:
> 
>exec("print(%s+1)" % var_name)
> 
> which is a nuisance, it is harder to read and harder to follow, and defeats 
> any of the useful features in your editor or IDE. It gets worse if you need 
> to use this var_name repeatedly:
> 
>exec("print(%s+1)" % var_name)
>exec("my_list = [1, 2, 3, %s, 5]" % var_name)
>print(my_list)
>exec("y = func(23, %s, 42) + %s" % (var_name, var_name))
>print(y)
> 
> How tedious and painful and hard to follow. And it is potentially buggy: what 
> if the user typed "func" as the variable name, by accident? Or over-wrote one 
> of your other variables?
> 
> And it's slow. Every time you call exec(), Python has to run a 
> mini-interpreter over the string, analyzing it, splitting it into tokens, 
> compiling it into code that can be executed, and then finally execute it. In 
> general, this is slow: in my experience, running exec("command") is about 10 
> times slower than just running command directly.
> 
> So just avoid using exec. Anytime you think you need exec, you almost 
> certainly do not. And you definitely don't need it for indirect variables! 
> Just use a dictionary instead:
> 
>var_name = input("Variable name? ")
>table = {var_name: 4}
># ...
># ... later on
># ...
>print(table[var_name]+1)
>my_list = [1, 2, 3, table[var_name], 5]
>print(my_list)
>y = func(23, table[var_name], 42) + table[var_name]
>print(y)
> 
> 
> 
> 
> -- 
> Steven
> 
> ___
> 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] Assigning variables with names set by other variables

2011-11-04 Thread Max gmail
Thank you, Wayne!  This helps a lot.
On Nov 4, 2011, at 5:38 PM, Wayne Werner wrote:

> On Fri, Nov 4, 2011 at 4:21 PM, Max S.  wrote:
> Is it possible to create a variable with a string held by another variable in 
> Python?  For example,
> 
> >>> var_name = input("Variable name: ")
> (input: 'var')
> >>> var_name = 4
> >>> print(var)
> (output: 4)
> 
> (Yeah, I know that if this gets typed into Python, it won't work.  It just 
> pseudocode.)
> 
> There are a few ways to do what you want. The most dangerous (you should 
> never use this unless you are 100% absolutely, totally for certain that the 
> input will be safe. Which means you should probably not use it) method is by 
> using exec(), which does what it sounds like: it executes whatever is passed 
> to it in a string:
> 
> >>> statement = input("Variable name: ")
> Variable name: var
> >>> exec(statement + "=4")
> >>> var
> 4
> 
> The (hopefully) obvious danger here is that someone could type anything into 
> this statement:
> 
> >>> statement = input("Variable name: ")
> Variable name: import sys; sys.exit(1); x
> >>> exec(statement + " =4")
> 
> and now you're at your prompt. If the user wanted to do something more 
> malicious there are commands like shutil.rmtree that could do *much* more 
> damage.
> 
> A much safer way is to use a dictionary:
> 
> >>> safety = {}
> >>> safety[input("Variable Name: ")] = 4
> Variable Name: my_var
> >>> safety["my_var"]
> 4
> 
> It requires a little more typing, but it also has the advantage of accepting 
> perfectly arbitrary strings.
> 
> There may be some other ways to do what you want, but hopefully that should 
> get you started.
> HTH,
> Wayne

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