473,385 Members | 1,764 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,385 software developers and data experts.

[perl-python] Range function

Today we'll be writing a function called Range. The Perl documentation
is as follows.

Perl & Python & Java Solutions will be posted in 48 hours.

This is Perl-Python a-day. See
http://xahlee.org/web/perl-python/python.html

Xah
xa*@xahlee.org
∑ http://xahlee.org/

--------------------------

Range

Range($iMax) generates the list [1, 2, ... , $iMax].

Range($iMin, $iMax) generates the list [$iMin, ... , $iMax].

Range($iMin, $iMax, $iStep) uses increment $iStep, with the last
element
in the result being less or equal to $iMax. $iStep cannot be 0. If
$iStep is negative, then the role of $iMin and $iMax are reversed.

If Range fails, 0 is returned.

Example:

Range(5); # returns [1,2,3,4,5]

Range(5,10); # returns [5,6,7,8,9,10]

Range( 5, 7, 0.3); # returns [5, 5.3, 5.6, 5.9, 6.2, 6.5, 6.8]

Range( 5, -4, -2); # returns [5,3,1,-1,-3]

Jul 19 '05 #1
7 3282
Xah Lee wrote:
Today we'll be writing a function called Range.
I don't think so. Unless you meant to write "Today WE'll be writing ...."
The Perl documentation is as follows.


Bullshit. The Perl documentation is part of any Perl installation but you
didn't link to it anywhere left alone quote it.
Actually I'm glad you didn't, it's quite large after all.

jue

Jul 19 '05 #2
Here's the Perl code.

----------

#! perl

# http://xahlee.org/tree/tree.html
# Xah Lee, 2005-05

#_____ Range _____ _____ _____ _____

=pod

B<Range>

Range($iMax) generates the list [1, 2, ... , $iMax].

Range($iMin, $iMax) generates the list [$iMin, ... , $iMax].

Range($iMin, $iMax, $iStep) uses increment $iStep, with the last
element in the result being less or equal to $iMax. $iStep cannot be 0.
If $iStep is negative, then the role of $iMin and $iMax are reversed.

If Range fails, 0 is returned.

Example:

Range(5); # returns [1,2,3,4,5]

Range(5,10); # returns [5,6,7,8,9,10]

Range( 5, 7, 0.3); # returns [5, 5.3, 5.6, 5.9, 6.2, 6.5, 6.8]

Range( 5, -4, -2); # returns [5,3,1,-1,-3]

=cut

sub Range ($;$$) {
if (scalar @_ == 1) {return _rangeFullArgsWithErrorCheck(1,$_[0],1);};
if (scalar @_ == 2) {return
_rangeFullArgsWithErrorCheck($_[0],$_[1],1);};
if (scalar @_ == 3) {return
_rangeFullArgsWithErrorCheck($_[0],$_[1],$_[2]);};
};

sub _rangeFullArgsWithErrorCheck ($$$) {
my ($a1, $b1, $dx) = @_;

if ($dx == 0) {print "Range: increment cannot be zero."; return 0}
elsif ($a1 == $b1) {return [$a1];}
elsif ( ((($b1 - $a1) > 0) && ($dx < 0)) || ((($b1 - $a1) < 0) && ($dx
0)) ) {print "Range: bad arguments. You have [$a1,$b1,$dx]"; return

0;}
elsif ((($a1 < $b1) && ($b1 < ($a1 + $dx))) || (($a1 > $b1) && ($b1 >
($a1 + $dx)))) {return [$a1];}
else { return _rangeWithGoodArgs ($a1,$b1,$dx);};
};

sub _rangeWithGoodArgs ($$$) {
my ($a1, $b1, $dx) = @_;
my @result;

if ($a1 < $b1) {for (my $i = $a1; $i <= $b1; $i += $dx) { push
(@result, $i);}; }
else {for (my $i = $a1; $i >= $b1; $i += $dx) { push (@result, $i);};
};
return \@result;
};

#end Range

##########
# test

use Data::Dumper;
print Dumper(Range(5,7,0.3));

Jul 19 '05 #3
Here's the Python solution.

----------
# -*- coding: utf-8 -*-
# Python

# http://xahlee.org/tree/tree.html
# Xah Lee, 2005-05

# implementation note: When iStep is a decimal, rounding error
# accumulates. For example, the last item returned from
# Range(0,18,0.3) is 17.7 not 18. A remedy is to turn iStep into a
# fraction and do exact arithmetics, and possibly convert the result
# back to decimal. A lesser workaround is to split the interval as to
# do multiple smaller range and join them together.

def Range(iMin, iMax=None, iStep=None):
if (iMax==None and iStep==None):
return Range(1,iMin)
if iStep==None:
return Range(iMin,iMax,1)
if iMin <= iMax and iStep > 0:
if (isinstance(iStep,int) or isinstance(iStep,long)):
return range( iMix, iMax, iStep)
else:
result=[];temp=iStep
while iMin <= iMax:
result.append(iMin)
iMin += iStep
return result

# test
print Range(0, 18, 0.3)

Jul 19 '05 #4
Xah Lee wrote:
Here's the Python solution.
# implementation note: When iStep is a decimal, rounding error
# accumulates. For example, the last item returned from
# Range(0,18,0.3) is 17.7 not 18. A remedy is to turn iStep into a
# fraction and do exact arithmetics, and possibly convert the result
# back to decimal. A lesser workaround is to split the interval as to
# do multiple smaller range and join them together.
Good lord no! The correct way is to use an integer count and simply
multiply it each time by the step, and add that to the range. No
accumulation of errors then. Where did you learn to program?
(Rhetorical question of course, as you haven't, yet.)
def Range(iMin, iMax=None, iStep=None):
if (iMax==None and iStep==None):
return Range(1,iMin)
if iStep==None:
return Range(iMin,iMax,1)
if iMin <= iMax and iStep > 0:
if (isinstance(iStep,int) or isinstance(iStep,long)):
return range( iMix, iMax, iStep)
else:
result=[];temp=iStep
while iMin <= iMax:
result.append(iMin)
iMin += iStep
return result


That's some of the worst Python code I've seen recently. Please, no one
take this as representative of how decent Python programmers write code.

-Peter
Jul 19 '05 #5
the previous posted solutions are badly botched.

Here's a better solution. Any further correction will appear on the
website instead. (http://xahlee.org/tree/tree.html)

Similar change needs to be made for the Perl code... Java code will
come tomorror.

By the way, the code from me are not expected to be exemplary. These
are exercises for all, also as a intro to functional programing to
industry programers. Also, later on there will be non-trivial problems.

# -*- coding: utf-8 -*-
# Python

# http://xahlee.org/tree/tree.html
# Xah Lee, 2005-05

import math;

def Range(iMin, iMax=None, iStep=None):
if (iMax==None and iStep==None):
return Range(1,iMin)
if iStep==None:
return Range(iMin,iMax,1)
if iMin <= iMax and iStep > 0:
if (isinstance(iStep,int) or isinstance(iStep,long)):
return range( iMin, iMax+1, iStep)
else:
result=[]
for i in range(int(math.floor((iMax-iMin)/iStep))+1):
result.append( iMin+i*iStep)
return result
if iMin >= iMax and iStep < 0:
if (isinstance(iStep,int) or isinstance(iStep,long)):
return range( iMin, iMax-1, iStep)
else:
result=[]
for i in range(int(math.floor((iMin-iMax)/-iStep))+1):
result.append( iMin+i*iStep)
return result
# raise error about bad argument. To be added later.

# test
print Range(5,-4,-2)

# Thanks to Peter Hansen for a correction.

Xah
xa*@xahlee.org
∑ http://xahlee.org/

Jul 19 '05 #6
Xah Lee wrote:
the previous posted solutions are badly botched. def Range(iMin, iMax=None, iStep=None): [snip hideous code]
# Thanks to Peter Hansen for a correction.


Ohmigod, he's only made it worse and he's blaming me for it. Shows what
I get for replying to a cross-posted troll message.

Xah, don't use my name in reference to anything you do, ever, even if
it's only to try to give me credit.

-Peter
Jul 19 '05 #7
On 15 May 2005 02:50:38 -0700, Xah Lee <xa*@xahlee.org> wrote:
Here's the Perl code.
Where did you learn to program? Its highly unlikely that a Perl
programer would ever write a range function as there is a built in
Perl function that does the same thing. If your intent is purely
accedemic then the first thing you should do is learn Perl to a much
higher grade.
#! perl

# http://xahlee.org/tree/tree.html
# Xah Lee, 2005-05

#_____ Range _____ _____ _____ _____

=pod

B<Range>
Its considered poor style to have function names with capital
letters. The normal convention is to use all lower case.
Range($iMax) generates the list [1, 2, ... , $iMax].

Range($iMin, $iMax) generates the list [$iMin, ... , $iMax].

Range($iMin, $iMax, $iStep) uses increment $iStep, with the last
element in the result being less or equal to $iMax. $iStep cannot be 0.
If $iStep is negative, then the role of $iMin and $iMax are reversed.

If Range fails, 0 is returned.

Example:

Range(5); # returns [1,2,3,4,5]

Range(5,10); # returns [5,6,7,8,9,10]

Range( 5, 7, 0.3); # returns [5, 5.3, 5.6, 5.9, 6.2, 6.5, 6.8]

Range( 5, -4, -2); # returns [5,3,1,-1,-3]

=cut
sub range {

return [1..$_[0]] if (@_==1);

return [$_[0]..$_[1]] if (@_==2);

my $lowest = shift;
my $greatest = shift;
my $increment = shift;

my $steps = ($greatest - $lowest)/$increment;
my @return = map { $_ * $increment + $lowest } (0..$steps);

return \@return;
}

This does as you wish but it far shorter and I would argue easyer for
the typical perl programer to read.
sub Range ($;$$) {
if (scalar @_ == 1) {return _rangeFullArgsWithErrorCheck(1,$_[0],1);};
if (scalar @_ == 2) {return
_rangeFullArgsWithErrorCheck($_[0],$_[1],1);};
if (scalar @_ == 3) {return
_rangeFullArgsWithErrorCheck($_[0],$_[1],$_[2]);};
};
I would suggest that If you have the case where your doing a one line
if stament then you should make use of the line modifing verent of
if. Also since if produces a scalar context its not needed.

sub Range ($;$$) {
return _rangeFullArgsWithErrorCheck(1,$_[0],1) if (@_ == 1);
return _rangeFullArgsWithErrorCheck($_[0],$_[1],1) if (@_ == 2);
return _rangeFullArgsWithErrorCheck($_[0],$_[1],$_[2]) if (@_ == 3);
}

See how much neater and more readable the code is after doing that.
sub _rangeFullArgsWithErrorCheck ($$$) {
my ($a1, $b1, $dx) = @_;

if ($dx == 0) {print "Range: increment cannot be zero."; return 0}
elsif ($a1 == $b1) {return [$a1];}
elsif ( ((($b1 - $a1) > 0) && ($dx < 0)) || ((($b1 - $a1) < 0) && ($dx
0)) ) {print "Range: bad arguments. You have [$a1,$b1,$dx]"; return 0;}
elsif ((($a1 < $b1) && ($b1 < ($a1 + $dx))) || (($a1 > $b1) && ($b1 >
($a1 + $dx)))) {return [$a1];}
else { return _rangeWithGoodArgs ($a1,$b1,$dx);};
};


This would be a great place to make use of die. Throwing an exection for an
error.

sub _rangeFullArgsWithErrorCheck ($$$) {
my ($a1, $b1, $dx) = @_;

die "Range: increment cannot be zero." unless $dx;

return [$a1] if ($a1 == $b1);

if ( ((($b1 - $a1) > 0) && ($dx < 0))
||
((($b1 - $a1) < 0) && ($dx0))) {
die "Range: bad arguments. You have [$a1,$b1,$dx]";
}
}

sub _rangeWithGoodArgs ($$$) {
my ($a1, $b1, $dx) = @_;
my @result;

if ($a1 < $b1) {for (my $i = $a1; $i <= $b1; $i += $dx) { push
(@result, $i);}; }
else {for (my $i = $a1; $i >= $b1; $i += $dx) { push (@result, $i);};
};
return \@result;
};


Personally I don't like the c style while loop. I didn't like it in C
and I don't like it in perl.

--
Please excuse my spelling as I suffer from agraphia. See
http://dformosa.zeta.org.au/~dformosa/Spelling.html to find out more.
Free the Memes.
Jul 19 '05 #8

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

Similar topics

4
by: Mark Wilson CPU | last post by:
This must be easy, but I'm missing something... I want to execute a Perl script, and capture ALL its output into a PHP variable. Here are my 2 files: -------------------------------------...
6
by: John Smith | last post by:
Hello, I have a rather odd question. My company is an all java/oracle shop. We do everything is Java... no matter what it is... parsing of text files, messaging, gui you name it. My question...
3
by: David F. Skoll | last post by:
Hi, I'm tearing my hair out on this one. I'm trying to embed a Perl interpreter into a C program. I need to be able to create and destroy the interpreter periodically, but will never actually...
1
by: Julia Bell | last post by:
I would like to run the same script on two different platforms. The directory in which the script(s) will be stored is common to the two platforms. (I see the same directory contents regardless...
1
by: smsabu2002 | last post by:
Hi, I am facing the build problem while installing the DBD-MySql perl module (ver 2.9008) using both GCC and CC compilers in HP-UX machine. For the Build using GCC, the compiler error is...
13
by: Otto J. Makela | last post by:
I'm trying to install to php the Perl-1.0.0.tgz package (from http://pecl.php.net/package/perl, enabling one to call perl libraries) to a pre-existing Solaris system. Unfortunately, the attempt...
6
by: surfivor | last post by:
I may be involved in a data migration project involving databases and creating XML feeds. Our site is PHP based, so I imagine the team might suggest PHP, but I had a look at the PHP documentation...
223
by: Pilcrow | last post by:
Given that UNIX, including networking, is almost entirely coded in C, how come so many things are almost impossible in ordinary C? Examples: Network and internet access, access to UNIX...
4
by: vijayarl | last post by:
Hi All, i have the following software installed in my system : 1.OS: Win2k 2.Eclipse Version used :3.4.0 & even the perl too... 1. I have imported the my own perl project in Eclipse, when i...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

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.