Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Ascii characters in a loop

Reply
Thread Tools

Ascii characters in a loop

 
 
Mark Hobley
Guest
Posts: n/a
 
      01-13-2007
The following loop works fine in Perl:

for ($l = 'a'; $l le 'y'; $l++) {
print "$l";
}

However, if I try to loop from a through to z, the loop does not work:

for ($l = 'a'; $l le 'z'; $l++) {
print "$l";
}

I know that a for each loop would work, but that is not what I want.

Regards,

Mark.

--
Mark Hobley
393 Quinton Road West
QUINTON
Birmingham
B32 1QE

Telephone: (0121) 247 1596
International: 0044 121 247 1596

Email: markhobley at hotpop dot donottypethisbit com

http://markhobley.yi.org/

 
Reply With Quote
 
 
 
 
RedGrittyBrick
Guest
Posts: n/a
 
      01-14-2007
Mark Hobley wrote:
> The following loop works fine in Perl:
>
> for ($l = 'a'; $l le 'y'; $l++) {
> print "$l";
> }
>
> However, if I try to loop from a through to z, the loop does not work:


It does but it produces results you might not have expected.

>
> for ($l = 'a'; $l le 'z'; $l++) {
> print "$l";
> }
>


Because of the way the post-increment operator works on strings.
See `perldoc perlop` under Auto-increment.

The value after 'z' is 'aa' and 'aa' is still stringwise less than 'z'.

Luckily 'zz' is greater than 'z'.
 
Reply With Quote
 
 
 
 
RedGrittyBrick
Guest
Posts: n/a
 
      01-14-2007
RedGrittyBrick wrote:
> Mark Hobley wrote:
>> The following loop works fine in Perl:
>>
>> for ($l = 'a'; $l le 'y'; $l++) {
>> print "$l";
>> }
>>
>> However, if I try to loop from a through to z, the loop does not work:

>
> It does but it produces results you might not have expected.
>
>>
>> for ($l = 'a'; $l le 'z'; $l++) {
>> print "$l";
>> }
>>

>
> Because of the way the post-increment operator works on strings.
> See `perldoc perlop` under Auto-increment.
>
> The value after 'z' is 'aa' and 'aa' is still stringwise less than 'z'.
>
> Luckily 'zz' is greater than 'z'.


Oh yes,

Why exactly don't you want a foreach loop?

C:\>perl -e "for $x ('a'..'z') { print \"$x,\";}"
a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y, z,

C:\>perl -e "$e='z'; for $x ('a'..$e) { print \"$x,\";}"
a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y, z,
 
Reply With Quote
 
Mark Donovan
Guest
Posts: n/a
 
      01-14-2007
On 1/13/07 16:04, in article rm4o74-, "Mark
Hobley" <> wrote:

> The following loop works fine in Perl:
>
> for ($l = 'a'; $l le 'y'; $l++) {
> print "$l";
> }
>
> However, if I try to loop from a through to z, the loop does not work:
>
> for ($l = 'a'; $l le 'z'; $l++) {
> print "$l";
> }
>
> I know that a for each loop would work, but that is not what I want.
>


I think you're expecting: abcdefghijklmnopqrstuvwxyz

And if that's what you want, you must use ne instead of le to end the loop.

for ($l = 'a'; $l ne 'z'; $l++) {
print "$l";
}

If you replace
print "$l";
with
print "$l ";
you can see what's happening. Change the comparison from le the ne, and the
loop stops at z, but with le, the loop does not stop until zz is less than
z.

Try this little experiment.

print join(' ', sort qw( a b c x y z aa bb cc xx yy zz )), "\n";

There are two things happening in your second loop. First, Auto-increment
for string data is smarter than you expect, maybe too smart. The next value
after z is aa. Second, operators like lt, le, eq, ne, ge, and gt are
stringwise comparisons. This means the result of a comparison reflects the
sorting order of the strings, and as you see from the experiment, aa is less
than z.

--
Regards,
Mark


 
Reply With Quote
 
John Bokma
Guest
Posts: n/a
 
      01-14-2007
Mark Donovan <> wrote:

> On 1/13/07 16:04, in article rm4o74-,
> "Mark Hobley" <> wrote:


[..]


>> for ($l = 'a'; $l le 'z'; $l++) {
>> print "$l";
>> }
>>
>> I know that a for each loop would work, but that is not what I want.
>>

>
> I think you're expecting: abcdefghijklmnopqrstuvwxyz
>
> And if that's what you want, you must use ne instead of le to end the
> loop.


No, 'aa' Which might confuse a lot of people.

> for ($l = 'a'; $l ne 'z'; $l++) {
> print "$l";
> }


abcdefghijklmnopqrstuvwxy

for ($l = 'a'; $l ne 'aa'; $l++) {
print "$l";
}

abcdefghijklmnopqrstuvwxyz


> If you replace
> print "$l";
> with
> print "$l ";
> you can see what's happening. Change the comparison from le the ne,
> and the loop stops at z,


but doesn't reach the print

--
John Experienced Perl programmer: http://castleamber.com/

Perl help, tutorials, and examples: http://johnbokma.com/perl/
 
Reply With Quote
 
John Bokma
Guest
Posts: n/a
 
      01-14-2007
RedGrittyBrick <> wrote:

> Oh yes,
>
> Why exactly don't you want a foreach loop?


My guess: because he wants to know why this one "doesn't work" instead of
reading: "use this instead".

To me it was educational (as in if someone has asked to write that loop
like that I am sure it would have bitten me as well), so thanks OP

--
John Experienced Perl programmer: http://castleamber.com/

Perl help, tutorials, and examples: http://johnbokma.com/perl/
 
Reply With Quote
 
Mark Hobley
Guest
Posts: n/a
 
      01-14-2007
John Bokma <> wrote:
>
> My guess: because he wants to know why this one "doesn't work" instead of
> reading: "use this instead".


I am writing Perl documentation. All these points seem to be missed in the
reference books that I am using, which incidently are extremely big and run
into several thousand pages each and cost me quite a few quid.

It seems strange that if I increment $l (which equals 'z') then I now have a
value that is comparitively less than 'z'.

This looks like a bug to me, at least in the context of an a to z loop.

Regards,

Mark.

--
Mark Hobley
393 Quinton Road West
QUINTON
Birmingham
B32 1QE

Telephone: (0121) 247 1596
International: 0044 121 247 1596

Email: markhobley at hotpop dot donottypethisbit com

http://markhobley.yi.org/

 
Reply With Quote
 
Dr.Ruud
Guest
Posts: n/a
 
      01-14-2007
Mark Hobley schreef:

> The following loop works fine in Perl:
>
> for ($l = 'a'; $l le 'y'; $l++) {
> print "$l";
> }
>
> However, if I try to loop from a through to z, the loop does not work:
>
> for ($l = 'a'; $l le 'z'; $l++) {
> print "$l";
> }


It does work, but not in the way that you suspect(ed).
See also perldoc -q quoting.


> I know that a for each loop would work, but that is not what I want.


Better mention what you do want.

--
Affijn, Ruud

"Gewoon is een tijger."

 
Reply With Quote
 
RedGrittyBrick
Guest
Posts: n/a
 
      01-14-2007
Mark Hobley wrote:
> John Bokma <> wrote:
>> My guess: because he wants to know why this one "doesn't work" instead of
>> reading: "use this instead".

>
> I am writing Perl documentation. All these points seem to be missed in the
> reference books that I am using, which incidently are extremely big and run
> into several thousand pages each and cost me quite a few quid.
>
> It seems strange that if I increment $l (which equals 'z') then I now have a
> value that is comparitively less than 'z'.
>
> This looks like a bug to me, at least in the context of an a to z loop.
>


Probably because you are thinking "for $x := 'a' to 'z'" but writing
something completely different.

In my view, you *don't* have an a to z loop. You have an initializer;
loop-test; counting-expression loop.

I've always disliked them, I find they're mostly used for shooting
yourself in the foot or doing something more clearly expressed as a
foreach or numeric-range loop.

http://en.wikipedia.org/wiki/For_loo...s_of_for_loops


Saying "in the context of" suggests that you'd like 'z' le 'aa' to
sometimes return true and sometimes return false depending in whether
the expression was being evaluated in the context of a for loop or not.

I think that would be a bad thing. In the code below the value returned
by my inorder subroutine would have to depend on whether it was called
from an expression that was part of a for loop. This would be horribly
hard to justify.

#!perl
use strict;
use warnings;

if (inorder('aa','z')) { print 'ordered OK'; }

for (my $x='x'; inorder($x, 'z'); $x++) {
print $x,' ';
}

sub inorder {
my ($p, $q) = @_;
$p le $q;
}

And of course, if you are using a three-part for loop to sort a
dictionary you'd want the current behaviour of the le operator even in
the context of a for loop.
 
Reply With Quote
 
Mark Hobley
Guest
Posts: n/a
 
      01-14-2007
John Bokma <> wrote:

> for ($l = 'a'; $l ne 'aa'; $l++) {
> print "$l";
> }


Yeah! I just think that 'a to z' looks far nicer late on a Friday night when I
am trying to debug code.

I need to test reverse loops, capitals, jumping by more than one letter at a
time now to see if there are any more nasty surprises.

I often loop through alphabetical sequences in code.

Regards,

Mark.

--
Mark Hobley
393 Quinton Road West
QUINTON
Birmingham
B32 1QE

Telephone: (0121) 247 1596
International: 0044 121 247 1596

Email: markhobley at hotpop dot donottypethisbit com

http://markhobley.yi.org/

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Triple nested loop python (While loop insde of for loop inside ofwhile loop) Isaac Won Python 9 03-04-2013 10:08 AM
Re: convert unicode characters to visibly similar ascii characters Laszlo Nagy Python 6 07-02-2008 04:42 PM
Re: convert unicode characters to visibly similar ascii characters M.-A. Lemburg Python 0 07-02-2008 08:39 AM
Re: convert unicode characters to visibly similar ascii characters Terry Reedy Python 0 07-01-2008 07:46 PM
[FR/EN] how to convert the characters ASCII(0-255) to ASCII(0-127) Alextophi Perl Misc 8 12-30-2005 10:43 AM



Advertisments