473,320 Members | 1,953 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.

[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 3266
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
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
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...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
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)...
1
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...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
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.