AutoHotkey Community

It is currently May 27th, 2012, 1:18 pm

All times are UTC [ DST ]




Post new topic Reply to topic  [ 8 posts ] 
Author Message
PostPosted: July 23rd, 2008, 11:57 am 
Offline

Joined: March 11th, 2008, 11:36 pm
Posts: 291
it's equivalent to Python's built-in function Range() except :

1) Python starts from 0 but it starts from 1 so Range(10) results differently
Python : 0.1,2,3,4,5,6,7,8,9
AutoHotkey : 1,2,3,4,5,6,7,8,9,10

2) Python does not support char but it does
Python : Range("a", "z") doesn't works
AutoHotkey : Range("a", "z") results a,b,c,d,e.....v,w,x,y,z



as you can see below, Titan greatly optimized this function to have less lines but faster with additional features.
so i would like to recommend to use Titan's 2nd version.
my very first version will be kept just as a reference to give better readability.
Much appreciated to Titan and [VxE], Ian as well.

the output is Matchlist friendly (comma seperated, you can change the delimiter in Titan's version)
so you can apply it like IF Var in % Range(10)
be aware that it supports integers only which is same in Python

Code:
MsgBox % Range(1,10)        ;1,2,3,4,5,6,7,8,9,10
MsgBox % Range(10)          ;1,2,3,4,5,6,7,8,9,10 (same as above)
MsgBox % Range(5,10)        ;5,6,7,8,9,10
MsgBox % Range(1,10,2)      ;1,3,5,7,9 (step by 2)
MsgBox % Range("a", "j")    ;a,b,c,d,e,f,g,h,i,j (alphabets)
MsgBox % Range("a", "m", 2) ;a,c,e,g,i,k,m (step on alphabets as well)
MsgBox % Range("A", "J")    ;A,B,C,D,E,F,G,H,I,J (upper cases)

;added features in Titan's version
MsgBox % Range(-10,10)      ;supports negative numbers as well
MsgBox % Range("J")         ;A,B,C,D,E,F,G,H,I,J (same as "A","J")
MsgBox % Range(1,10,1,"`n") ;Using custom delimiter



Code:
;Prototype   
Range(Start, Stop="", Step=1){
    if RegExMatch(Start,"i)[a-z]") && RegExMatch(Stop,"i)[a-z]")
        Start := asc(Start) , Stop := asc(Stop) , alpha := 1
    if !alpha {
        if !Stop {
            Stop := Start
            Loop, %Stop%
                Output .= A_Index ","
        } else {
            Loop, %Stop%
                Output .= (!Mod(A_Index-1, Step) && A_Index >= Start) ? A_Index "," :
        }
    } else {
        Loop, %Stop%
            Output .= (!Mod(A_Index-1, Step) && A_Index >= Start) ? chr(A_Index) "," :
    }
    StringTrimRight, Output, Output, 1
    Return Output   
}

_________________
Easy WinAPI - Dive into Windows API World
Benchmark your AutoHotkey skills at PlayAHK.com


Last edited by heresy on July 24th, 2008, 12:53 am, edited 3 times in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 23rd, 2008, 3:19 pm 
Offline
User avatar

Joined: August 11th, 2004, 1:47 am
Posts: 5347
Location: UK
You asked on IRC so here's an optimized version:

Code:
range(x, y, c = 1, d = ",") {
   If (!a := x | 0)
      x := Asc(x), y := Asc(y)
   Loop, % (y - x) // c + 1
      r .= d . (a ? x : Chr(x)), x += c
   Return, SubStr(r, 1 + StrLen(d))
}


Haven't coded ahk in a while so my skillz are rusty. This won't work if you don't pass a stop value but that can easily be changed. It'll be interesting to see if Skan can write something shorter :P

Edit: here's a version that does range(10); range("j") etc.
Edit 2: typo fix

Code:
range(x, y = "", c = 1, d = ",") {
   If (!a := x | 1)
      x := Asc(x), y := Asc(y)
   Loop, % (y == (a ? "" : 0) ? (y := x) - x := x > 96 ? 97 : x > 64 ? 65 : 1 : y - x) // c + 1
      r .= d . (a ? x : Chr(x)), x += c
   Return, SubStr(r, 1 + StrLen(d))
}

_________________
GitHubScriptsIronAHK Contact by email not private message.


Last edited by polyethene on July 24th, 2008, 1:03 am, edited 2 times in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 23rd, 2008, 8:54 pm 
Offline
User avatar

Joined: October 7th, 2006, 8:45 am
Posts: 3330
Location: Simi Valley, CA
Code:
range(x, y=0, c=1, d=",", i=0)
{
   If (x*0="")
      x := Asc(x), y := Asc(y), i := 1
   r := x + (u := c * Round((y-x+0.1)/Abs(y-x+0.1)))
   return % ((x=y || (x-2*u>=y)!=(r>=y))) ? (i ? Chr(x) : x) : ((i ? Chr(x) : x) d range(r, y, c, d, i))
}

msgbox % range("g","3", 3)
I think I've got it. I've tested chars and numbers where X>Y and Y>X. Tested C>1 a little bit. Not gonna bother with testing D. i is used internally... it could just be a static but that might be confusing.

_________________
Ternary (a ? b : c) guide     TSV Table Manipulation Library
Post code inside [code][/code] tags!


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 23rd, 2008, 10:47 pm 
Offline

Joined: July 15th, 2007, 1:43 am
Posts: 1320
mod on Titan's code.

Code:
MsgBox % range("-32") "`n" range("-32~2") "`n" range("A~J")
range(x, c = 1, d = ",") {
   StringSplit, x, x, ~
   a := x1+1,x1 := (a ? x1 : Asc(x1)),z := !x2 ? (x1>=97 ? 97 : x1>=65 ? 65 : 1) : (a ? x2 : Asc(x2))
   Loop, % Abs(z-x1)//c+1
      r .= d . (a ? (!x2 ? z : x1) : Chr((!x2 ? z : x1))),z += c,x1 += !x2 ? -c : c
   Return, SubStr(r, 1 + StrLen(d))
}


Support for one term rather than two, and negative numbers. Custom separator (~) to show two characters.

Edit:

Bugfix: LETTER~LETTER was outputting backwards.

I made another version using RegExMatch, but it does not yet support integers.

Code:
range(x, y="") {
   RegExReplace("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,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,"
   , (!y ? x >= a ? "a" : "A" : x) . "(.*)" . (!y ? x : y), SubPat)
   Return (!y ? x >= a ? "a" : "A" : x) . SubPat1 . (!y ? x : y)
}

_________________
Religion is false. >_>


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 26th, 2008, 9:41 pm 
Offline

Joined: October 1st, 2005, 9:55 pm
Posts: 775
Location: Texas, USA
Excellent function idea. I always figured I would get around to writing something like this but now I don't have to! Thanks to everyone who contributed. :)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 27th, 2008, 7:22 pm 
Offline

Joined: February 14th, 2005, 4:05 pm
Posts: 4710
Location: Boulder, CO
Having one function for characters and integers can work in AHK, but it is counterintuitive in typed languages, like C. I would use two different functions instead.

It is hard to tell, what is the “right” behavior when start > end (with step > 0). In many cases you want the empty list, what Titan’s function returns, but sometimes you want to list the elements backwards: range(4,1) --> 4,3,2,1.

What would you do with step = 0? It could be an error, so return the empty list, maybe except when start=stop, in which case range can be {start}.

Here is a single line function for (not necessarily integer, signed) numbers, which returns the empty string if start > end and step > 0, or start < end and step < 0, or step = 0:
Code:
NRange(a,b,d=1,s=",") { ; {a, a+d, ..., ~b}, numbers separated by s
   Return (a-b)*d > 0 or !d ? "" : ("" = c:=NRange(a+d,b,d,s)) ? a : a . s . c
}
You can make it even shorter, but less clear. A similar oneliner can be written for characters by replacing number x with Chr(x), and character y with Asc(y), appropriately:
Code:
CRange(a,b,d=1,s=",") { ; {a, Chr(Asc(a)+d), ..., ~b}, chars separated by s
   Return (Asc(a)-Asc(b))*d > 0 or !floor(d) ? "" : ("" = c:=CRange(Chr(Asc(a)+d),b,d,s)) ? a : a . s . c
}


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 28th, 2008, 9:53 am 
Offline

Joined: March 11th, 2008, 11:36 pm
Posts: 291
Thank Laszlo for introducing another way. seems [VxE] and You're pretty familiar with recursive function. i really need a lesson on Recursive functions. :( i might post FRange() later for floats when i completely got your recursive functions. Thanks!

_________________
Easy WinAPI - Dive into Windows API World
Benchmark your AutoHotkey skills at PlayAHK.com


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 28th, 2008, 4:14 pm 
Offline

Joined: February 14th, 2005, 4:05 pm
Posts: 4710
Location: Boulder, CO
NRange works for any numbers, including floats.


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 8 posts ] 

All times are UTC [ DST ]


Who is online

Users browsing this forum: Bon and 15 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group