Quick Tip: Counting up to a limit

joestrout

JoeStrout

Posted on December 6, 2023

Quick Tip: Counting up to a limit

A very common need is to iterate over all indexes into a list, or more generally, iterate from 0 up to (but not including) some limit or count. It's tempting to use range(0, count-1) for this, but therein lies a gotcha: if count is zero, then this will be range(0, -1), which in MiniScript returns [0, -1] rather than an empty list.

Fortunately, MiniScript has two easy solutions.

Use .indexes

If your need is actually to iterate over the indexes of some list — let's call it seq — then don't use range(0, seq.len-1); instead just use seq.indexes.

seq = [1,2,3,5,7,11]
for i in seq.indexes
    print "Elem " + i + " is " + seq[i]
end for
Enter fullscreen mode Exit fullscreen mode

This is less to type, quick to read, and more clearly expresses your intention. It's also very MiniScript-idiomatic!

Use range(0, count-1, 1)

The third parameter to range is the step value. If you don't supply a value for this parameter, then it will default to 1 if the end value is greater than the start value, and -1 if it's lesser. This is how you can count down from 10 to 1 just by doing range(10, 1). But it's also why range(0, -1) returns [0, -1].

However, if you simply specify a step value of 1, then any time the end value is less than the start value, you'll get an empty list!

count = input("Count how many? ").val
for i in range(0, count-1, 1)
    print i
end for
Enter fullscreen mode Exit fullscreen mode

This is a safe way to express "I definitely want a range of numbers that increase as I go, never decrease, no matter what my start and end values are." And it's perfect when the end point of your range depends on some variable, like count - 1.

Bonus tip: iterating over very large ranges

Doing the Advent of Code contest this year, there have been a couple times where my attempt to use range in a for loop failed with a "list too large" error. For example:

for i in range(1, 1E9)
    if sqrt(i) % 7 == 0 then result += 1
end for
Enter fullscreen mode Exit fullscreen mode

...produces:

Runtime Error: list too large [line 1]
Enter fullscreen mode Exit fullscreen mode

In such a case, simply switch from a for loop to a while loop. Just remember to increment your loop variable, or you'll create an infinite loop!

i = 1
while i < 1E9
    if sqrt(i) % 7 == 0 then result += 1
    i += 1
end while
Enter fullscreen mode Exit fullscreen mode

Got any other tips for iterating over some range of numbers? Let us know in the comments below!

💖 💪 🙅 🚩
joestrout
JoeStrout

Posted on December 6, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

if locals == globals
miniscript if locals == globals

July 24, 2024

Quick Tip: Counting up to a limit
miniscript Quick Tip: Counting up to a limit

December 6, 2023