Is there any equivalent to range or xrange in Cobra?
If not, how would you write this in Cobra (or any other .NET language)?
mylist = range(10, 50)
(Sorry, I'm not expert in .Net...)
neuruss
Forums
Equivalent to Python's range
18 posts
• Page 1 of 2 • 1, 2
Re: Equivalent to Python's range
I can't say this is the proper .Net way of doing it, but it'll get the job done.
- Code: Select all
class Range
inherits List<of int>
def init(beginning as int, ending as int)
for i = beginning .. ending
.add(i)
def init(beginning as int, ending as int, stepBy as int)
if beginning < ending and stepBy > 0
for i = beginning .. ending ++stepBy
.add(i)
else if ending < beginning and stepBy < 0
for i = beginning .. ending --(-stepBy)
.add(i)
class Program
def main is shared
myList = Range(10, 50)
- khjklujn
- Posts: 29
Re: Equivalent to Python's range
It looks pretty good.
That would be a handy addition to the language. Or at least to my "useful"stuff library...
Thanks again!
neuruss
That would be a handy addition to the language. Or at least to my "useful"stuff library...
Thanks again!
neuruss
- neuruss
- Posts: 23
Re: Equivalent to Python's range
Some more robust examples of range and xrange.
class Range
inherits List<of int>
"""
Range emulates the behavior of Python's builtin range function. The behavior
differs in the case where the end value is less than the begin value or the
step value is in a nonsensical direction. In Python these cases return an
empty list. Here they will raise an exception.
"""
def init(beginning as int, ending as int, stepBy as int)
require
(beginning <= ending and stepBy > 0) or (ending <= beginning and stepBy < 0)
test
assert Range(0, 0, 1) == []
assert Range(0, 0, -1) == []
assert Range(0, 10, 2) == [0, 2, 4, 6, 8]
assert Range(10, 0, -2) == [10, 8, 6, 4, 2]
try
for i in Range(10, 0, 2)
assert false
catch Cobra.Lang.RequireException
assert true
try
for i in Range(0, 10, -2)
assert false
catch Cobra.Lang.RequireException
assert true
try
for i in Range(0, 10, 0)
assert false
catch Cobra.Lang.RequireException
assert true
body
if stepBy > 0
for i = beginning .. ending ++ stepBy
.add(i)
else
for i = beginning .. ending -- -stepBy
.add(i)
def init(beginning as int, ending as int)
.init(beginning, ending, 1)
class XRange
implements IEnumerable
"""
XRange emulates the behavior of Python's builtin xrange function. The behavior
differs in the case where the end value is less than the begin value or the
step value is in a nonsensical direction. In Python these cases return an
empty generator. Here they will raise an exception.
"""
var _beginning as int
var _ending as int
var _stepBy as int
def init(beginning as int, ending as int, stepBy as int)
require
(beginning <= ending and stepBy > 0) or (ending <= beginning and stepBy < 0)
test
for i in XRange(0, 0, 1)
assert false
for i in XRange(0, 0, -1)
assert false
c = 0
for i in XRange(0, 10, 2)
assert i == c
c += 2
c = 10
for i in XRange(10, 0, -2)
assert i == c
c -= 2
try
for i in XRange(10, 0, 2)
assert false
catch Cobra.Lang.RequireException
assert true
try
for i in XRange(0, 10, -2)
assert false
catch Cobra.Lang.RequireException
assert true
try
for i in XRange(0, 10, 0)
assert false
catch Cobra.Lang.RequireException
assert true
body
_beginning = beginning
_ending = ending
_stepBy = stepBy
def init(beginning as int, ending as int)
.init(beginning, ending, 1)
def getEnumerator as IEnumerator
if _stepBy > 0
for i = _beginning .. _ending ++ _stepBy
yield i
else
for i = _beginning .. _ending -- -_stepBy
yield i
- khjklujn
- Posts: 29
Re: Equivalent to Python's range
Addendum: the exception testing in the above example was incomplete--forgot to test the test. A better pattern would be something like:
# raise the exception
try
for i in Range(10, 0, 2)
assert false
# test the exception
catch Cobra.Lang.RequireException
assert true
# guarantee the exception was raised
# because the test may be flawed
success
assert false
- khjklujn
- Posts: 29
Re: Equivalent to Python's range
There is an explicit statement for testing that an expected exception gets thrown:
This will raise an ExpectException if the code does not raise precisely the exception expected. It also comes with a nice message telling you what exception was expected and whether there was no exception or the different type of exception that was raised instead.
You can have more than one statement in the block if you desire, although just having one is pretty common.
You can use "expect" in both "test" sections and regular code.
expect RequireException
obj.foo
This will raise an ExpectException if the code does not raise precisely the exception expected. It also comes with a nice message telling you what exception was expected and whether there was no exception or the different type of exception that was raised instead.
You can have more than one statement in the block if you desire, although just having one is pretty common.
You can use "expect" in both "test" sections and regular code.
- Charles
- Posts: 2515
- Location: Los Angeles, CA
Re: Equivalent to Python's range
Btw I think I read that Python's range() was going to change to the xrange() behavior at some point. I recommend renaming your XRange class and giving it a .toList method:
Most of the time people won't care if Range is IEnumerable, but then if they really need that list they can tack on ".toList".
def toList as List<of int>
return List<of int>(this)
Most of the time people won't care if Range is IEnumerable, but then if they really need that list they can tack on ".toList".
- Charles
- Posts: 2515
- Location: Los Angeles, CA
Re: Equivalent to Python's range
Chuck wrote:There is an explicit statement for testing that an expected exception gets thrown
Way cool.
Chuck wrote:I recommend renaming your XRange class and giving it a .toList method
Yeah, that would be more concise.
- khjklujn
- Posts: 29
Re: Equivalent to Python's range
Why do you do:
isn't incrementing by a negative the same as decrementing by a negated negative? Why couldn't it simply be:
without the if/else and duplicated for?
So I wrote a little program to test it and exits without executing the contents of the loop. works as expected, but I insist I don't have to like it.
if stepBy > 0
for i = beginning .. ending ++ stepBy
.add(i)
else
for i = beginning .. ending -- -stepBy
.add(i)
isn't incrementing by a negative the same as decrementing by a negated negative? Why couldn't it simply be:
for i = beginning .. ending ++ stepBy
.add(i)
without the if/else and duplicated for?
So I wrote a little program to test it and
for i = big .. small ++ neg
for i = big .. small -- -neg
- dennis
- Posts: 21
Re: Equivalent to Python's range
The compiler is using the ++ and -- to indicate which way the comparison is made in the exit condition of the loop.
No problem if you use them in a manner that makes sense to people who are used to working with C style languages (where ++i unequivocally means the loop index is gonna go up, --i always means down).
for i = 0 .. 10 ++ 2 ==> for(int i = 0; i < 10; i += 2) ==> works as expected
for i = 10 .. 0 -- 2 ==> for(int i = 10; i > 0; i -= 2) ==> works as expected
Syntactically, this one also makes sense, but...
for i = 10 .. 0 ++ -2 ==> for(int i = 10; i < 0; i += (-2)) ==> exits immediately
The problem is that in order to use the C# for loop, the direction of the comparison has to be determined at compile time, so you have to provide something to indicate which direction you think the index is supposed to go. The compiler can't use the values of the end points because they usually won't be known until runtime.
I suppose it might be possible to use something like that XRange class (renamed to Range, of course) to have the compiler generate:
for i = 10 .. 0 step -2 ==> foreach(int i in Range(10, 0, -2))
But that's Chuck's domain. There might be nontrivial performance differences between C#'s for and foreach that justify a syntax that doesn't appear to always make sense mathematically.
The syntax of C style for loops has always struck me as a little quirky. If you thought "exits immediately" was fun, give this one a try:
for i = 10 .. 0 ---2
I've had to hit Ctrl-C often enough to know that I don't always see the problem with that construct the first time I look at it.
No problem if you use them in a manner that makes sense to people who are used to working with C style languages (where ++i unequivocally means the loop index is gonna go up, --i always means down).
for i = 0 .. 10 ++ 2 ==> for(int i = 0; i < 10; i += 2) ==> works as expected
for i = 10 .. 0 -- 2 ==> for(int i = 10; i > 0; i -= 2) ==> works as expected
Syntactically, this one also makes sense, but...
for i = 10 .. 0 ++ -2 ==> for(int i = 10; i < 0; i += (-2)) ==> exits immediately
The problem is that in order to use the C# for loop, the direction of the comparison has to be determined at compile time, so you have to provide something to indicate which direction you think the index is supposed to go. The compiler can't use the values of the end points because they usually won't be known until runtime.
I suppose it might be possible to use something like that XRange class (renamed to Range, of course) to have the compiler generate:
for i = 10 .. 0 step -2 ==> foreach(int i in Range(10, 0, -2))
But that's Chuck's domain. There might be nontrivial performance differences between C#'s for and foreach that justify a syntax that doesn't appear to always make sense mathematically.
The syntax of C style for loops has always struck me as a little quirky. If you thought "exits immediately" was fun, give this one a try:
for i = 10 .. 0 ---2
I've had to hit Ctrl-C often enough to know that I don't always see the problem with that construct the first time I look at it.
- khjklujn
- Posts: 29
18 posts
• Page 1 of 2 • 1, 2
Who is online
Users browsing this forum: No registered users and 4 guests