Search the web
Sign In
New User? Sign Up
perl-python
? Already a member? Sign in to Yahoo!

Yahoo! Groups Tips

Did you know...
Want to share photos of your group with the world? Add a group photo to Flickr.

Best of Y! Groups

   Check them out and nominate your group.
Having problems with message search? Fill out this form to ensure your group is one of the first to be migrated to the new message search system.

Messages

  Messages Help
Advanced
one-line loop functional style   Message List  
Reply | Forward Message #117 of 127 |
One-Liner Loop in Functional Style

Xah Lee, 200510

Today we show a example of a loop done as a one-liner of Functional
Programing style.

Suppose you have a list of file full paths of images:

/Users/t/t4/oh/DSCN2059m-s.jpg
/Users/t/t4/oh/DSCN2062m-s.jpg
/Users/t/t4/oh/DSCN2097m-s.jpg
/Users/t/t4/oh/DSCN2099m-s.jpg
/Users/t/Icons_dir/icon_sum.gif

For those ending with -s (indicate a smaller version), you want to
change it to the full version without the -s, if it exists. Here's the
code:

# -*- coding: utf-8 -*-
# python

import re, os.path

imgPaths=[u'/Users/t/web/Periodic_dosage_dir/lanci/t4/oh/DSCN2059m-
s.jpg',
u'/Users/t/web/Periodic_dosage_dir/lanci/t4/oh/DSCN2062m-s.jpg',
u'/Users/t/web/Periodic_dosage_dir/lanci/t4/oh/DSCN2097m-s.jpg',
u'/Users/t/web/Periodic_dosage_dir/lanci/t4/oh/DSCN2099m-s.jpg',
u'/Users/t/web/Icons_dir/icon_sum.gif']


# change the image path to the full sized image, if it exists
# that is, if image ends in -s.jpg, find one without the '-s'.
imgPaths2=[]
for myPath in imgPaths:
p=myPath
(dirName, fileName) = os.path.split(myPath)
(fileBaseName, fileExtension)=os.path.splitext(fileName)
if(fileBaseName[-2:] == '-s'):
p2=os.path.join(dirName,fileBaseName[0:-2]) + fileExtension
if os.path.exists(p2): p=p2
imgPaths2.append(p)

print imgPaths2

But how do you do it in a functional programing style? Namely,
something of the from imgPath2=f(imgPath), where the f is some
function. Normally, the f would be a pure function construct made up on
the spot, that is, lambda. But Python's lambda is limited to only a
expression as its body. Nevertheless, one can achieve a functional
style with some workaround, using map twice. Here's the code:

imgPaths3 = map( lambda x: os.path.exists(x[1]) and x[1] or x[0], \
map(lambda x: (x, re.sub( r"^(.+?)-s(\.[^.]+)$",r"\1\2", x)), imgPaths))

The first map:

newList = map(lambda x: (x, re.sub( r"^(.+?)-s(\.[^.]+)$",r"\1\2", x)),
imgPaths)

generate a list of pairs (x, y), where x is the same element in
imgPaths, and y is one without the -s. Then, a second map:

map( lambda x: os.path.exists(x[1]) and x[1] or x[0], newList,
imgPaths))

checks if the path y exists, if so, use that, else, use the x part. The
function body is essentially of a conditional EXPRESSION, of the from
(test, if true return result1, else return result2). This form of a
test that returns a expression is very important in functional
programing. Because, in functional programing a common pattern is to
sequence functions and passing values. One cannot stop in the middle
and use a block structure. Here's how this form's syntax in several
languages:

test? trueExpression: falseExpression (C, Perl)
If[test, trueExpression, falseExpression] (Mathematica)
(test trueExpression falseExpression) (LISP)

In Python, there's no such form for this, but a semantically equivalent
workaround is to sequence boolean expressions as used in our example.
Namely:

test and trueExpression or falseExpression (Python)

This works because it exploits a particular behavior of how Python
treats boolean sequences. In Python, “x and y” returns y if x is true.
And, “x or y” returns x if x is true. This behavior is compatible with
the mathematical sense of booleans. For example, mathematically “x and
y” should be true if both are true, yet in Python if x is true then y
is returned, and if y is true then this is compatible with the math
sense, but if y is false then the whole result is also false, so it
also satisfies the math sense. Similar is the case of “x or y”. The
point here is that one of the element is returned, instead of a real
True or False value. Therefore, in a twisted way this can be used for
the If[test, trueExpression, falseExpression] form. Example.

result1= True and 4 or 5 # returns 4
result2= False and 4 or 5 # returns 5

print result1
print result2

Such language behavior is a result of the laziness of the compiler
implementation, particular seen in unix shells (&& and ||). The problem
with this design is that codes relying on the the returned element of a
boolean sequence does not clearly indicate the programer's intention.
It works by language pecularities, instead of expressed program logic.

For the official doc on evaluating booleans, see:
http://python.org/doc/2.4.2/lib/boolean.html

Here's the Perl code of the same loop block:

# perl
use File::Basename;

@imgPaths=(
'/Users/t/web/Periodic_dosage_dir/lanci/t4/oh/DSCN2059m-s.jpg',
'/Users/t/web/Periodic_dosage_dir/lanci/t4/oh/DSCN2062m-s.jpg',
'/Users/t/web/Periodic_dosage_dir/lanci/t4/oh/DSCN2097m-s.jpg',
'/Users/t/web/Periodic_dosage_dir/lanci/t4/oh/DSCN2099m-s.jpg',
'/Users/t/web/Icons_dir/icon_sum.gif');

# change the image path to the full sized image, if it exists
# that is, if image ends in -s.jpg, find one without the '-s'.
$imgPaths2=();
for $myPath (@imgPaths){
$p=$myPath;
($fileBaseName, $dirName, $fileExtension) = fileparse($myPath,
('\.[^.]+$') );
if (substr($fileBaseName,-2,2) eq '-s') {
$p2= $dirName . '/' .
substr($fileBaseName,0,length($fileBaseName)-2) . $fileExtension;
print $p2, "\n";
if (-e $p2) { $p=$p2}
}
push(@imgPaths2,$p);
}

use Data::Dumper;
print Dumper(\@imgPaths2)

In Perl, this can be written in a functional style one-liner:

@imgPaths3= map{
$y = $_;
$y =~ s/^(.+?)-s(\.[^.]+)$/$1$2/;
-e $y ? $y : $_;
} @imgPaths;

For the official doc of Perl's map, type in command line: “perldoc -f
map”
------
this article is archived at:
http://xahlee.org/perl-python/one-liner_loop.html

Xah
xah@...
http://xahlee.org/





Thu Oct 20, 2005 10:57 am

p0lyglut
Online Now Online Now
Send Email Send Email

Forward
Message #117 of 127 |
Expand Messages Author Sort by Date

One-Liner Loop in Functional Style Xah Lee, 200510 Today we show a example of a loop done as a one-liner of Functional Programing style. Suppose you have a...
xah lee
p0lyglut
Online Now Send Email
Oct 20, 2005
11:11 am
Advanced

Copyright 2009 Yahoo! Inc. All rights reserved.
Privacy Policy - Terms of Service - Guidelines - Help