473,320 Members | 1,828 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

rot13 in a more Pythonic style?

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' )

Feb 14 '07 #1
16 2490
You could try "some_string".encode('rot_13')

Feb 14 '07 #2
On 2007-02-14, Andy Dingley <di*****@codesmiths.comwrote:
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
Feb 14 '07 #3
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

Feb 14 '07 #4
On 14 Feb, 16:23, Neil Cerutti <horp...@yahoo.comwrote:
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).

Feb 14 '07 #5
En Wed, 14 Feb 2007 14:04:17 -0300, Andy Dingley <di*****@codesmiths.com>
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

Feb 14 '07 #6
On Feb 14, 9:04 am, "Andy Dingley" <ding...@codesmiths.comwrote:
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

Feb 14 '07 #7
"Andy Dingley" <di*****@codesmiths.comwrites:
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
Feb 14 '07 #8
"Andy Dingley" <di*****@codesmiths.comwrites:
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.
Feb 14 '07 #9
Martin P. Hellwig
for me (personal) being Pythonic means that I should
separate the logic and variables, etc...
Well, for me me Pythonic means using built-in functionalities as much
as possible (like using encode("rot13") or translate), and to write
less code, (avoiding overgeneralizations from the start too). It means
other things too.

Bye,
bearophile

Feb 14 '07 #10
"Andy Dingley" <di*****@codesmiths.comwrites:
c_rot13 = lambdaf c : (((c, uc_rot13(c)) [c in
'ABCDEFGHIJKLMNOPQRSTUVWXYZ']), lc_rot13(c) )[c in
'abcdefghijklmnopqrstuvwxyz']
Oh, I see what you mean, you have separate upper and lower case maps
and you're asking how to select one in an expression. Pythonistas
seem to prefer using multiple statements:

def c_rot13(c):
if c in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ': return uc_rot13(c)
elif c in 'abcdefghijklmnopqrstuvwxyz': return lc_rot13(c)
return c

You could use the new ternary expression though:

c_rot13 = lambda c: \
uc_rot13(c) if c in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' else \
(lc_rot13(c) if c in 'abcdefghijklmnopqrstuvwxyz' else \
c)

if I have that right.
Feb 14 '07 #11
be************@lycos.com wrote:
Martin P. Hellwig
>for me (personal) being Pythonic means that I should
separate the logic and variables, etc...

Well, for me me Pythonic means using built-in functionalities as much
as possible (like using encode("rot13") or translate), and to write
less code, (avoiding overgeneralizations from the start too). It means
other things too.

Bye,
bearophile
Yup, but I have a sever case of "NIH" especially if the question asked
is something more general then the example given :-)
However you are very much right, I reimplemented rot13 and translate in
a dull way here :-)

--
mph
Feb 14 '07 #12
On 14 Feb, 21:59, Paul Rubin <http://phr...@NOSPAM.invalidwrote:
Why don't you describe the actual problem instead of the rot13 analogy.
I don't know what the actual problem is! I need to perform a complex
mapping between "old style" structured identifiers and "new style"
structured identifers. As the original specification was never thought
through or written down anywhere, I'm now having to try and reverse-
engineer from 5 years of collected inconsistent practice. So far I
have about four pages of BNF to describe things and I'm still not sure
what's accurate, what's inaccurate spec and what's merely an error in
practice. Hopefully there's a neat little structure underlying it all
and a few typos I can merely ignore, but probably it really is just an
inconsistent structure that needs a lot of explicit tests around the
corner-cases to make sense of.

rot13 isn't the issue here, and I already know how to use .translate()
What I'm after is a tutorial of my Python coding style for an example
that's quite similar to the rot13 case. Your previous posting was
very helpful here.

Feb 15 '07 #13
On Feb 14, 11:46 am, "Gabriel Genellina" <gagsl...@yahoo.com.ar>
wrote:
En Wed, 14 Feb 2007 14:04:17 -0300, Andy Dingley <ding...@codesmiths.com>
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
They are still useful for reduce(), which has no listcomp equivalent
that I know of.

Feb 15 '07 #14
On 15 Feb, 17:55, Dennis Lee Bieber <wlfr...@ix.netcom.comwrote:
Sounds more like a case for a parser/lexer wherein the emitted "code
tokens" are the "new style" identifiers...
8-( I'm trying not to think about that....

Fortunately I don't think it's _quite_ that bad.

Feb 15 '07 #15
On Fri, 16 Feb 2007 04:53:23 +0000, Dennis Lee Bieber wrote:
On 15 Feb 2007 11:10:53 -0800, "Andy Dingley" <di*****@codesmiths.com>
declaimed the following in comp.lang.python:
>>
Fortunately I don't think it's _quite_ that bad.

Possibly not, but that description of the problem would likely have
gotten more applicable help than a debate on the merits of
reimplementing translate().

The Original Poster did say in his first post that he knew about translate
and encode and he wasn't looking for those solutions:

[quote]
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.
[end quote]

Perhaps rot13 wasn't the best choice in the world, but how was Andy to
know people would answer his post without reading it in full?

Oh wait, this is Usenet...

*wink*
--
Steven.

Feb 16 '07 #16
On 14 Feb, 20:06, "Beej" <b...@beej.uswrote:
http://linuxgazette.net/109/pramode.html
Thanks, that's a _really_ interesting link (Oh, I need to learn
Scheme!)

My code now looks like this, which I'm starting to feel much happier
about in a functional sense.
c_rot = lambda c, chars : (chr((ord(c) - ord(chars[0]) +
(len(chars) // 2)) % len(chars) + ord(chars[0])))

c_rot13 = lambda c : (((c, \
c_rot(c, string.ascii_uppercase)) [c in string.ascii_uppercase]),
\
c_rot(c, string.ascii_lowercase)) [c in string.ascii_lowercase]

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

I also considered this, but don't trust it as it relies on the two
sets being mutually disjoint between their inputs and outputs.

qc_rot = lambda c, chars : (c, c_rot(c, chars)) [c in chars]
c_rot13 = lambda c : (qc_rot( qc_rot(c, string.ascii_lowercase),
string.ascii_uppercase))
Feb 16 '07 #17

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

12
by: Nickolay Kolev | last post by:
Hi all, I would like to find a more pythonic way of solving the following: Having a string consisting of letters only, find out the total sound score of the string. The sound score is...
15
by: Eirik | last post by:
This is a little function I wrote, inspired by the thread "Urgent HELP! required for Caesar Cipher PLEASE" $ cat /home/keisar/bin/c/ymse/rot13.h char rot13(char character) { int changed;...
5
by: yxq | last post by:
Hello, I want to encrypt and decrypt using ROT13, found a class to encrypt string, but where is the decrypter? http://authors.aspalliance.com/brettb/ROT13EncodingWithASPNet.asp#CodeSamples ...
3
by: andrew.fabbro | last post by:
I'm working on an app that will be deployed on several different servers. In each case, I'll want to change some config info (database name, paths, etc.) In perl, I would have done something...
4
by: Carl J. Van Arsdall | last post by:
It seems the more I come to learn about Python as a langauge and the way its used I've come across several discussions where people discuss how to do things using an OO model and then how to design...
20
by: krypto.wizard | last post by:
Is there any editor or IDE in Python (either Windows or Linux) which has very good debugging facilites like MS VisualStudio has or something like that. I like SPE but couldn't easily use winPDP....
14
by: Pythor | last post by:
I wrote the following code for a personal project. I need a function that will plot a filled circle in a two dimensional array. I found Bresenham's algorithm, and produced this code. Please tell...
0
by: robert | last post by:
As more and more python packages are starting to use the bloomy (Java-ish) 'logging' module in a mood of responsibility and as I am not overly happy with the current "thickener" style of usage, I...
11
by: Hussein B | last post by:
Hey, Well, as you all know by now, I'm learning Python :) One thing that is annoying my is the OOP in Python. Consider this code in Java: -- public class Car { private int speed; private...
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
0
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.