Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > rot13 in a more Pythonic style?

Reply
Thread Tools

rot13 in a more Pythonic style?

 
 
Andy Dingley
Guest
Posts: n/a
 
      02-14-2007
I'm trying to write rot13, but to do it in a better and more Pythonic
style than I'm currrently using. What would you reckon to the
following pretty ugly thing? How would you improve it? In
particular, I don't like the way a three-way selection is done by
nesting two binary selections. Also I dislike stating the same
algorithm twice, but can't see how to parameterise them neatly.

Yes, I know of .encode() and .translate().
No, I don't actually need rot13 itself, it's just a convenient
substitute example for the real job-specific task.
No, I don't have to do it with lambdas, but it would be nice if the
final function was a lambda.


#!/bin/python
import string

lc_rot13 = lambda c : (chr((ord(c) - ord('a') + 13) % 26 + ord('a')))

uc_rot13 = lambda c : (chr((ord(c) - ord('A') + 13) % 26 + ord('A')))

c_rot13 = lambda c : (((c, uc_rot13(c)) [c in
'ABCDEFGHIJKLMNOPQRSTUVWXYZ']), lc_rot13(c) )[c in
'abcdefghijklmnopqrstuvwxyz']

rot13 = lambda s : string.join([ c_rot13(c) for c in s ],'')


print rot13( 'Sybevk Tenohaqnr, Fcyhaqvt ihe guevtt' )

 
Reply With Quote
 
 
 
 
Rune Strand
Guest
Posts: n/a
 
      02-14-2007
You could try "some_string".encode('rot_13')

 
Reply With Quote
 
 
 
 
Neil Cerutti
Guest
Posts: n/a
 
      02-14-2007
On 2007-02-14, Andy Dingley <(E-Mail Removed)> wrote:
> I'm trying to write rot13, but to do it in a better and more
> Pythonic style than I'm currrently using. What would you
> reckon to the following pretty ugly thing? How would you
> improve it? In particular, I don't like the way a three-way
> selection is done by nesting two binary selections. Also I
> dislike stating the same algorithm twice, but can't see how to
> parameterise them neatly.
>
> Yes, I know of .encode() and .translate().


str.translate is what I'd do.

import string
rot13table = string.maketrans(
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVW XYZ',
'nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJ KLM')

print 'Sybevk Tenohaqnr, Fcyhaqvt ihe guevtt'.translate(rot13table)

> No, I don't actually need rot13 itself, it's just a convenient
> substitute example for the real job-specific task. No, I don't
> have to do it with lambdas, but it would be nice if the final
> function was a lambda.


How would it being a lambda help you?

--
Neil Cerutti
 
Reply With Quote
 
Martin P. Hellwig
Guest
Posts: n/a
 
      02-14-2007
Andy Dingley wrote:
> I'm trying to write rot13, but to do it in a better and more Pythonic
> style than I'm currrently using. What would you reckon to the
> following pretty ugly thing? How would you improve it? In
> particular, I don't like the way a three-way selection is done by
> nesting two binary selections. Also I dislike stating the same
> algorithm twice, but can't see how to parameterise them neatly.
>
> Yes, I know of .encode() and .translate().
> No, I don't actually need rot13 itself, it's just a convenient
> substitute example for the real job-specific task.
> No, I don't have to do it with lambdas, but it would be nice if the
> final function was a lambda.
>
>
> #!/bin/python
> import string
>
> lc_rot13 = lambda c : (chr((ord(c) - ord('a') + 13) % 26 + ord('a')))
>
> uc_rot13 = lambda c : (chr((ord(c) - ord('A') + 13) % 26 + ord('A')))
>
> c_rot13 = lambda c : (((c, uc_rot13(c)) [c in
> 'ABCDEFGHIJKLMNOPQRSTUVWXYZ']), lc_rot13(c) )[c in
> 'abcdefghijklmnopqrstuvwxyz']
>
> rot13 = lambda s : string.join([ c_rot13(c) for c in s ],'')
>
>
> print rot13( 'Sybevk Tenohaqnr, Fcyhaqvt ihe guevtt' )
>


Well first of all, for me (personal) being Pythonic means that I should
separate the logic and variables, in this case there is the rotation
mechanism and the variable with the amount it should rotate.
Then of course the letters case is something I consider as a state of
the letter itself, the meaning of the letter doesn't change.
And being a sucker for dictionaries I use them a lot

So with that in mind I would write a class like this:
###
class Rot(object):
def __init__(self,amount = 13):
self.__alpha = 'abcdefghijklmnopqrstuvwxyz'
self.__amount = amount
self.__index_string = dict()
self.__crypt_index_string = dict()
self.__string_index = dict()
self.__crypt_string_index = dict()
self.__position = 0

self.__create_dicts()


def __cypher(self,number):
alpha_len = len(self.__alpha)
rotation_overflow = alpha_len - self.__amount
new_number = None

if number > rotation_overflow:
new_number = number - self.__amount

else:
new_number = self.__position + self.__amount

return(new_number)


def __create_dicts(self):
for letter in self.__alpha:
self.__position += 1

self.__index_string[self.__position] = letter
self.__crypt_index_string[self.__cypher(self.__position)] =
letter

self.__string_index[letter] = self.__position
self.__crypt_string_index[letter] =
self.__cypher(self.__position)


def encrypt(self,text):
text_list = list()
letter_capital = None

for letter in text:
letter_capital = letter.isupper()
letter = letter.lower()

if letter not in self.__alpha:
text_list.append(letter)

else:
position_plain = self.__string_index[letter]
letter_crypt = self.__crypt_index_string[position_plain]

if letter_capital:
letter_crypt = letter_crypt.upper()

text_list.append(letter_crypt)

return("".join(text_list))


def decrypt(self,text):
text_list = list()
letter_capital = None

for letter in text:
letter_capital = letter.isupper()
letter = letter.lower()

if letter not in self.__alpha:
text_list.append(letter)

else:
position_crypt = self.__crypt_string_index[letter]
letter_plain = self.__index_string[position_crypt]

if letter_capital:
letter_plain = letter_plain.upper()

text_list.append(letter_plain)

return("".join(text_list))
###

Testing if it works:
>>> rot13.decrypt(rot13.encrypt("This is a TEST"))

'This is a TEST'

--
mph

 
Reply With Quote
 
Andy Dingley
Guest
Posts: n/a
 
      02-14-2007
On 14 Feb, 16:23, Neil Cerutti <(E-Mail Removed)> wrote:

> str.translate is what I'd do.


That's what I hope to do too, but it might not be possible (for the
live, complex example). It looks as if I have to make a test, then
process the contents of the code differently depending. There might
well be a translation inside this, but I think I still have to have an
explicit 3-way switch in there.



> How would it being a lambda help you?


I'm going to use it in a context where that would make for cleaner
code. There's not much in it though.

I still don't understand what a lambda is _for_ in Python. I know what
they are, I know what the alternatives are, but I still haven't found
an instance where it permits something novel to be done that couldn't
be done otherwise (if maybe not so neatly).

 
Reply With Quote
 
Gabriel Genellina
Guest
Posts: n/a
 
      02-14-2007
En Wed, 14 Feb 2007 14:04:17 -0300, Andy Dingley <(E-Mail Removed)>
escribió:

> I still don't understand what a lambda is _for_ in Python. I know what
> they are, I know what the alternatives are, but I still haven't found
> an instance where it permits something novel to be done that couldn't
> be done otherwise (if maybe not so neatly).


A lambda is a shorthand for a simple anonymous function. Any lambda can be
written as a function:

lambda args: expression

is the same as:

def __anonymous(args): return expression

(but the inverse is not true; lambda only allows a single expression in
the function body).

Except for easy event binding in some GUIs, deferred argument evaluation,
and maybe some other case, the're not used much anyway. Prior common usage
with map and filter can be replaced by list comprehensions (a lot more
clear, and perhaps as fast - any benchmark?)

--
Gabriel Genellina

 
Reply With Quote
 
Dennis Lee Bieber
Guest
Posts: n/a
 
      02-14-2007
On 14 Feb 2007 09:04:17 -0800, "Andy Dingley" <(E-Mail Removed)>
declaimed the following in comp.lang.python:

>
> I still don't understand what a lambda is _for_ in Python. I know what
> they are, I know what the alternatives are, but I still haven't found
> an instance where it permits something novel to be done that couldn't
> be done otherwise (if maybe not so neatly).


The only useful spot I've seen for them has been in callbacks to
Tkinter widgets... Rather than defining (silly example, I know)

def do_stuff(i):
...

def Button_0(event):
do_stuff(0)

def Button_1(event):
do_stuff(1)
....
def Button_9(event):
do_stuff(9)


with each button widget having a callback of

... =Button_0

... =Button_1

... ...

... =Button_9

One can just have

def do_stuff(i):
...

... =(lambda x=0: do_stuff(x))

... =(lambda x=1: do_stuff(x))

... ...

... =(lambda x=9: do_stuff(x))



This latter arrangement can be easily generated programmatically:

for z in range(10):
... =(lambda x=z: do_stuff(x))

--
Wulfraed Dennis Lee Bieber KD6MOG
http://www.velocityreviews.com/forums/(E-Mail Removed) (E-Mail Removed)
HTTP://wlfraed.home.netcom.com/
(Bestiaria Support Staff: (E-Mail Removed))
HTTP://www.bestiaria.com/
 
Reply With Quote
 
Beej
Guest
Posts: n/a
 
      02-14-2007
On Feb 14, 9:04 am, "Andy Dingley" <(E-Mail Removed)> wrote:
> I still don't understand what a lambda is _for_ in Python.


Python supports functional programming to a certain extent, and
lambdas are part of this.

http://linuxgazette.net/109/pramode.html

> I know what
> they are, I know what the alternatives are, but I still haven't found
> an instance where it permits something novel to be done that couldn't
> be done otherwise (if maybe not so neatly).


Strictly speaking, you can live your whole life without using them.
There's always a procedural way of doing things, as well.

-Beej

 
Reply With Quote
 
Rob Wolfe
Guest
Posts: n/a
 
      02-14-2007
"Andy Dingley" <(E-Mail Removed)> writes:

> I'm trying to write rot13, but to do it in a better and more Pythonic
> style than I'm currrently using. What would you reckon to the
> following pretty ugly thing? How would you improve it? In
> particular, I don't like the way a three-way selection is done by
> nesting two binary selections. Also I dislike stating the same
> algorithm twice, but can't see how to parameterise them neatly.


It looks to me like a good place to use closure and dictionaries.
I would write it this way:

def rot(step):
import string
rot_char = lambda a,c,step=step: chr((((ord(c) - ord(a)) + step) % 26) + ord(a))
make_dict = lambda a,s: dict([(x, rot_char(a, x)) for x in s])
d = make_dict('a', string.ascii_lowercase)
d.update(make_dict('A', string.ascii_uppercase))
def f(s):
return "".join([d.get(c) or c for c in s])
return f

>>> rot13 = rot(13)
>>> rot13('Sybevk Tenohaqnr, Fcyhaqvt ihe guevtt')

'Florix Grabundae, Splundig vur thrigg'
>>> rot_13 = rot(-13)
>>> rot_13('Florix Grabundae, Splundig vur thrigg')

'Sybevk Tenohaqnr, Fcyhaqvt ihe guevtt'

--
HTH,
Rob
 
Reply With Quote
 
Paul Rubin
Guest
Posts: n/a
 
      02-14-2007
"Andy Dingley" <(E-Mail Removed)> writes:
> I'm trying to write rot13, but to do it in a better and more Pythonic
> style than I'm currrently using. What would you reckon to the
> following pretty ugly thing? How would you improve it? In
> particular, I don't like the way a three-way selection is done by
> nesting two binary selections. Also I dislike stating the same
> algorithm twice, but can't see how to parameterise them neatly.


I'm having a hard time understanding what you're getting at. Why
don't you describe the actual problem instead of the rot13 analogy.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
ROT13(g(2307534882734083072Y,1,0).pbz) thor Java 3 05-29-2008 04:39 PM
ROT13 meerkat Computer Support 16 09-29-2007 05:54 PM
Object Oriented vs Pythonic Code, and Pythonic standards Carl J. Van Arsdall Python 4 02-07-2006 10:15 PM
ROT13. Justin gregg Computer Support 64 04-25-2004 09:24 AM
Why does this work? (rot13 function) Eirik C Programming 15 12-18-2003 03:35 AM



Advertisments