Python Translator

Please put small code samples here from other languages, and we will try to translate it into PythonLanguage. The goal is to ease the learning curve for Python.


In AplLanguage: +/M where M is any numeric matrix of rank 2 thru X (integer), result is another matrix of rank (x-1), where the projection is summed up. Example of APL operation on a matrix (rank 2) results in a vector (rank 1):

| 1 2 3 |
M = | 4 5 6 |
| 7 8 9 |

'+/ (reads Plus reduce) means the operator "+" is applied to the data. For a 1 dimensional vector, it just adds everything (to a scalar of rank 0). But it works on higher dimensions, too. The above would sum to:

| 12 15 18 |

If the input were a 3d matrix, the output would be a 2d matrix resulting from summing along the third dimension. The APL standard supports matrices up to at least 63 dimensions. So although it would be easy to implement sum for a 1-vector or a 2-matrix in any language, it is more complicated to handle X dimensions, yet the APL code is still just +/M -- so this problem was obviously posed by a SmugAplWeenie. :-)

Python bites back :)

How's this (generalised OO version):

class Matrix(list):
def _reduce(self, f):
try:
return Matrix([f(x) for x in zip(*self)])
except TypeError:
try:
return Matrix([Matrix(x)._reduce(f) for x in zip(*self)])
except TypeError:
return f(self)
def r_sum(self):
return self._reduce(sum)
def r_mul(self):
mul = lambda x: reduce(operator.mul, x)
return self._reduce(mul)
a = Matrix([1,2,3])
b = Matrix([[1,2,3]])
c = Matrix([[1,2,3], [4,5,6], [7,8,9]])
d = Matrix([[[1,2,3], [4,5,6], [7,8,9]],
[[10,11,12], [13,14,15], [16,17,18]],
[[19,20,21],[22,23,24], [25,26,27]]])
>>> print a.r_sum()
6
>>> print b.r_sum()
[1, 2, 3]
>>> print c.r_sum()
[12, 15, 18]
>>> print d.r_sum()
[[30, 33, 36], [39, 42, 45], [48, 51, 54]]

It'll hit an upper limit when it runs out of stack, but should be able to handle a 64d matrix

Not that I'm aware of - Python tends to use the SamuraiPrinciple - though you can probably estimate by analysing the algorithm. That said, you're probably better off NOT using pure python for heavy number crunching (for a low number of dimensions Python should be fine - for a large number, you'll probably run out of memory - if not experience heat death of the universe). The Numeric or NumPy package may be suitable, however. if you do run out of stack, you could always use StacklessPython

-- TaroOgawa


In PerlLanguage: Taken from (http://www.perlmonks.net/index.pl?node_id=6940). The expected output is the primes between 2 and 99, each on a new line:

perl -e 'while($l++<99){$_.=x;print $l,$/if! /^x$|^(xx+)\1+$/}'

In Python:

import re
for i in range(1,100):
if not re.match(r"^x$|^(xx+)\1+$", "x"*i):
print i

Or if you want to be a little bit more Pythonic (and faster too):

def primes(low, high):
m = re.compile(r"^x$|^(xx+)\1+$")
primes = [str(i) for i in range(low, high+1) if not m.match("x"*i)]
print "\n".join(primes)

In PerlLanguage:

#!/usr/local/bin/perl -w
use strict;
use Tie::File;
my $file = shift;
my @array;
tie @array, 'Tie::File', $file or die "$file can't be opened:$!\n";
$array[1] = 'blah'; # line 2 of the file is now 'blah'
print "[" . $array[2] . "]\n"; # display line 3 of the file
push( @array, "new line" ); # add a line to the file
Here's what this example does.
$ cat junk
  1. SimpleType.pm
  2. badshebang.pl
  3. bitshift.pl
  4. cat
$ ./tie_array.pl junk
[3 bitshift.pl]
$ cat junk
  1. SimpleType.pm
blah
  1. bitshift.pl
  2. cat
new line
Basically I am asking what is the Python equiv. of Tie::File

Python:

#! /usr/local/bin/python
class Tie(list):
def __init__(self, filename):
self.f = open(filename, 'r+')
list.__init__(self, [line[:-1] for line in self.f])
self.f.seek(0)
def close(self):
if self.f:
for line in self:
print >> self.f, line
self.f.close()
self.f = None
def __del__(self):
self.close()
if __name__ == '__main__':
import sys
fn = sys.argv[1]
array = Tie(fn)
array[1] = 'blah'
print "[%s]" % array[2]
array.append("newline")

In PerlLanguage:

print __FILE__ . "[" . __LINE__ . "] here is some debug on line foo of file bar\n";

You'll want to define a HelperFunction for that. Something like this:

import traceback
def log(*args):
caller = traceback.extract_stack()[-2]
print "%s:%d: %s" % (caller[0], caller[1], .join(str(a) for a in args))

And using caller[2] would give you the function name.


How does one do constructor overloading in Python? In JavaLanguage:

class MyObject {
public MyObject() {
System.out.println("uno");
}
}
class MyClass {
private int a;
private MyObject my;
public MyClass(int a) {
this.a = a;
}
public MyClass(MyObject my) {
this.my = my;
}
}
class MyTest {
public static void main(String args[]) {
MyClass mc1 = new MyClass(42);
MyClass mc2 = new MyClass(new MyObject());
}
}

You don't. Python uses DynamicTypes and thus doesn't offer any kind of "overloading" based on argument type. The way this is typically done in Python:

class MyObject:

def __init__(self): print "UNO"

class MyClass: pass

def MyClassWithInt(a):

new_instance = MyClass()
new_instance.a = a
return new_instance

def MyClassWithObject(my):

new_instance = MyClass()
new_instance.my = my
return new_instance

if __name__ == '__main__':

mc1 = MyClassWithInt(42)
mc2 = MyClassWithObject(MyObject())

You could also use class methods as factories instead of the module-level functions used here, but there's no practical difference for this contrived example.


Printing a hello message to someone, asking for their name:

In CeeLanguage:

#include
int main(void) {
char name[30];
printf("What's your name?");
scanf("%s", name);
printf("Hello, %s\n", name);
return 0;
}

In Python:

name = raw_input("What's your name? ")
print "Hello, %s" % name

(Note that the Python version does not suffer from the BufferOverflow bug that the C version has.)


In CeePlusPlus:

/*pretty sure this code would compile*/
#include
main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10};
cout << "This is my array, watch as I output it";
for(int i =0;i < 10; i ++)
{
cout << arr[i];
}
cout << "\nThis is my c++ example code to output an array, I wonder what it would be in python?";
}

-- camthompson@shaw.ca

arr = range(1,11) # alternatively: arr = [ 1,2,3,4,5,6,7,8,9,10 ]
print "This is my array, which I will output."
for i in arr:
print i,
print "\nNot so different, just a bit simpler, isn't it?"

If you don't mind Python's list output style, you can avoid the loop:

arr = range(1,11)
print 'This is my array, which I will output.'
print arr
print "Even simpler, isn't it?"

If you do mind Python's list output style, you can convert and trim the edges:

arr = range(1,11)
print 'This is my array, which I will output.'
print str(arr)[1:-1]
print "This is a bit of a cheat."

Or more obscurely:

arr = range(1,11)
print 'This is my array, which I will output.'
print ' '.join([str(i) for i in arr])
print "Rather different, isn't it?"

Or even more obscurely:

arr = range(1,11)
print 'This is my array, which I will output.'
print 10*"%s "%tuple(arr)
print "TMTOWTDI but not all are equally good."

In PerlLanguage: taken from http://www.perlmonks.net/index.pl?node_id=358667

#
# draw the pegs on the board based on the information
# contained in the board object
#
# dx, dy, radius, units are global vars
#
# $can is a Tk::Canvas object
sub placePegs {
my $can = shift;
my $board = shift;
my $hole = 0;
my $tag;
my $radius = 10;
$tag = "HOLE_$hole";
$can->create(oval => $dx*($units/2)-$radius, $dy-$radius, $dx*($units/2)+$radius, $dy+$radius,
-fill => $board->{'holes'}[$hole]->{'peg'},
-tag => [$tag] );
$can->bind( $tag, '