range(範囲)を生成する課題

範囲の幅から計算した範囲の数ではなく最大値で制限した範囲の処理をする課題が目的、
範囲の数を指定できる場合と比べていく。

Java の場合、

範囲幅=100 で、5個の範囲の処理、この 5個と指定できる場合は次のように簡単に書ける。
すなわち、IntStream.rangeClosed を使える場合、

IntStream.rangeClosed(1, 5).boxed()
.map(i->new int[]{ (i - 1) * 100 + 1, i * 100 })
.forEach(n->{
    System.out.println(n[0] + " - "+ n[1]);
    // TODO 範囲 n[0] から n[1] の処理
});
1 - 100
101 - 200
201 - 300
301 - 400
401 - 500

このように範囲の生成を予め指定できないケースではどうするか?
無限イテレータに対して、最大値で限定する方法
最大値=500 を指定したい時、、

Java9 以降では Stream takeWhile がある。

IntStream.iterate(1, i->i+1)
.mapToObj(i->new int[]{ (i - 1) * 100 + 1, i * 100 })
.takeWhile(n->n[1] <= 500)
.forEach(n->{
    System.out.println(n[0] + " - "+ n[1]);
    // TODO 範囲 n[0] から n[1] の処理
});

Java8 ではこの takeWhile が使えないので、
https://oboe2uran.hatenablog.com/entry/2020/04/18/192429
で作成した whilestream メソッドを用意して
以下のようにする。

whilestream(IntStream.iterate(1, i->i+1)
               .mapToObj(i->new int[]{ (i - 1) * 100 + 1, i * 100 })
            , n->n[1] <= 500
).forEach(n->{
     System.out.println(n[0] + " - "+ n[1]);
     // TODO 範囲 n[0] から n[1] の処理
});

Python の場合、

範囲の数を指定できる range を使う場合は簡単で、リスト内包表記で
範囲のタプルのリスト生成で処理できる。

for t in ((i*100+1, (i+1)*100) for i in range(5)):
    print(t)
(1, 100)
(101, 200)
(201, 300)
(301, 400)
(401, 500)

最大値で限定する方法
以下のメソッド、0から始まる数の無限ジェネレータ count() から
範囲を生成するジェネレータ用意して、最大値でループを抜ける

def count():
    c = 0
    while True:
        yield c
        c += 1
def makerange(len:int):
    counter = count()
    while True:
        i = counter.__next__()
        yield (i * len + 1, (i + 1) * len)

for t in makerange(100):
    print(t)
    # TODO tuple [0] [1] を使用する
    if t[1] >= 500:
        break

この count() は、itertools.count() で置き換えられるので、

import itertools

for i in itertools.count():
    t = (i * 100 + 1, (i + 1) * 100)
    print(t)
    # TODO tuple [0] [1] を使用する
    if t[1] >= 500:
        break

と簡潔にすることが可能

範囲の幅と最大値を指定できるようにif文を含むメソッドにすれば

もっと簡潔になる。

import itertools

def makerange(len:int, max:int):
    for i in itertools.count():
        t = (i * len + 1, (i + 1) * len)
        yield t
        if t[1] >= max:
            break

for t in makerange(100, 500):
    print(t)
    # TODO tuple [0] [1] を使用する