hello let me do a demonstration in python about what I want to achieve in kotlin:
np.linspace(start = 0, stop = 100, num = 5)
This results:
-------------------------
|0 | 25 | 50 | 75 | 100 |
-------------------------
Now in Kotlin how can I get the same result? Is there a similar library?
This should work exactly like linspace (not handling cases when num is 0 or 1):
fun linspace(start: Int, stop: Int, num: Int) = (start..stop step (stop - start) / (num - 1)).toList()
It makes use of the rangestart..stop (a range in kotlin is inclusive) and the function step lets us define how far the steps in this ranges should be.
EDIT
As #forpas suggested in the comments the step should be calculated using (stop - start) and not only stop. Using stop alone would only work if the start was 0.
#Alexey Romanov correctly said that unless you explicitly need a List as return type you should return the IntProgression (it does not hold all the elements in memory like a list does) since its also Iterable.
Thank you both for your input!
Not exactly the same, but it generates an array with 5 integers, multiples of 25 starting from 0:
val array = Array(5) { it * 25 }
the result is:
[0, 25, 50, 75, 100]
You can create a function simulating what you need:
fun linspace(start: Int, stop: Int, num: Int) = Array(num) { start + it * ((stop - start) / (num - 1)) }
DoubleProgression used to exist but was removed, because it raises rounding issues; you can copy the sources from that commit as a starting point if you really need it. Or consider converting it to a BigDecimalProgression instead. Of course, you need division to get the step from your arguments, which isn't exact even for BigDecimal.
You can also use sequences:
fun linspaceD(start: Double, stop: Double, num: Double): Sequence<Double> {
val step = (stop - start) / (num - 1)
return sequence {
for i in 0 until num yield(start + step*i)
}
}
Note that this resolves rounding in a specific way, by always yielding num values even if the last one is slightly greater than stop.
Related
Isn't order of execution generally from left to right in Raku?
my #a = my #b = [9 , 3];
say (#a[1] - #a[0]) == (#b[1] R- #b[0]); # False {as expected}
say (#a.pop() - #a.pop()) == (#b.pop() R- #b.pop()); # True {Huh?!?}
This is what I get in Rakudo(tm) v2020.12 and 2021.07.
The first 2 lines make sense, but the third I can not fathom.
It is.
But you should realize that the minus infix operator is just a subroutine under the hood, taking 2 parameters that are evaluated left to right. So when you're saying:
$a - $b
you are in fact calling the infix:<-> sub:
infix:<->($a,$b);
The R meta-operator basically creates a wrap around the infix:<-> sub that reverses the arguments:
my &infix:<R->($a,$b) = &infix:<->.wrap: -> $a, $b { nextwith $b, $a }
So, if you do a:
$a R- $b
you are in fact doing a:
infix:<R->($a,$b)
which is then basically a:
infix:<->($b,$a)
Note that in the call to infix:<R-> in your example, $a become 3, and $b becomes 9 because the order of the arguments is processed left to right. This then calls infix:<->(3,9), producing the -6 value that you would also get without the R.
It may be a little counter-intuitive, but I consider this behaviour as correct. Although the documentation could probably use some additional explanation on this behaviour.
Let me emulate what I assumed was happening in line 3 of my code prefaced with #a is the same as #b is 9, 3 (big number then little number)
(#a.pop() - #a.pop()) == (#b.pop() R- #b.pop())
(3 - 9) == (3 R- 9)
( -6 ) == ( 6 )
False
...That was my expectation. But what raku seems to be doing is
(#a.pop() - #a.pop()) == (#b.pop() R- #b.pop())
#R meta-op swaps 1st `#b.pop()` with 2nd `#b.pop()`
(#a.pop() - #a.pop()) == (#b.pop() - #b.pop())
(3 - 9) == (3 - 9)
( -6 ) == ( -6 )
True
The R in R- swaps functions first, then calls the for values. Since they are the same function, the R in R- has no practical effect.
Side Note: In fuctional programming a 'pure' function will return the same value every time you call it with the same parameters. But pop is not 'pure'. Every call can produce different results. It needs to be used with care.
The R meta op not only reverses the operator, it will also reverse the order in which the operands will be evaluated.
sub term:<a> { say 'a'; '3' }
sub term:<b> { say 'b'; '9' }
say a ~ b;
a
b
ab
Note that a happened first.
If we use R, then b happens first instead.
say a R~ b;
b
a
ba
The problem is that in your code all of the pop calls are getting their data from the same source.
my #data = < a b a b >;
sub term:<l> { my $v = #data.shift; say "l=$v"; return $v }
sub term:<r> { my $v = #data.shift; say "r=$v"; return $v }
say l ~ r;
l=a
r=b
ab
say l R~ r;
r=a
l=b
ab
A way to get around that is to use the reduce meta operator with a list
[-](#a.pop, #a.pop) == [R-](#a.pop, #a.pop)
Or in some other way make sure the pop operations happen in the order you expect.
You could also just use the values directly from the array without using pop.
[-]( #a[0,1] ) == [R-]( #a[2,3] )
Let me emulate what happens by writing the logic one way for #a then manually reversing the operands for #b instead of using R:
my #a = my #b = [9 , 3];
sub apop { #a.pop }
sub bpop { #b.pop }
say apop - apop; # -6
say bpop - bpop; # -6 (operands *manually* reversed)
This not only appeals to my sense of intuition about what's going on, I'm thus far confused why you were confused and why Liz has said "It may be a little counter-intuitive" and you've said it is plain unintuitive!
today I've encountered a strange behaviour in Kotlin that I cannot explain. Given the following code:
data class Data(
val v1: Int,
val v2: Int,
val v3: Int)
fun main() {
val d = Data(1,1,1)
val sum1 = d.v1 + d.v2 + d.v3
println("Oneliner: $sum1") // prints: Oneliner: 3
val sum2 = d.v1
+ d.v2
+ d.v3
println("OperatorFirst: $sum2") // prints: OperatorFirst: 1
val sum3 = d.v1 +
d.v2 +
d.v3
println("OperatorLast: $sum3") // prints: OperatorLast: 3
}
(Testable at: https://pl.kotl.in/gMjif_6FO)
Now it seems to depend on where you place the + operator to get the correct result of 3. However, the IDE doesn't show that anything might be wrong with the second version and i couldn't find any information of why this case would behave differently.
A question on the software engineering space also says that several coding guidelines suggest to put the operator at the beginning of the line: https://softwareengineering.stackexchange.com/questions/93670/line-break-before-after-operator
Also, the only explanation I could find for this behaviour is that the + at the line beginnings is interpreted as a unary plus operator. https://www.programiz.com/kotlin-programming/operators#unary
However, even this makes no sense to me on a val
That's the price you pay for optional semicolons. Andrey Breslav said in one of his lectures that it is intended behavior. Binary operators like + or * should be placed on the top line, not the bottom line. If you want to place them on bottom line, use parentheses:
val sum = (1
+ 1
+ 1)
println(sum) // prints: 3
I have recently sat a computing exam in university in which we were never taught beforehand about the modulus function or any other check for odd/even function and we have no access to external documentation except our previous lecture notes. Is it possible to do this without these and how?
Bitwise AND (&)
Extract the last bit of the number using the bitwise AND operator. If the last bit is 1, then it's odd, else it's even. This is the simplest and most efficient way of testing it. Examples in some languages:
C / C++ / C#
bool is_even(int value) {
return (value & 1) == 0;
}
Java
public static boolean is_even(int value) {
return (value & 1) == 0;
}
Python
def is_even(value):
return (value & 1) == 0
I assume this is only for integer numbers as the concept of odd/even eludes me for floating point values.
For these integer numbers, the check of the Least Significant Bit (LSB) as proposed by Rotem is the most straightforward method, but there are many other ways to accomplish that.
For example, you could use the integer division operation as a test. This is one of the most basic operation which is implemented in virtually every platform. The result of an integer division is always another integer. For example:
>> x = int64( 13 ) ;
>> x / 2
ans =
7
Here I cast the value 13 as a int64 to make sure MATLAB treats the number as an integer instead of double data type.
Also here the result is actually rounded towards infinity to the next integral value. This is MATLAB specific implementation, other platform might round down but it does not matter for us as the only behavior we look for is the rounding, whichever way it goes. The rounding allow us to define the following behavior:
If a number is even: Dividing it by 2 will produce an exact result, such that if we multiply this result by 2, we obtain the original number.
If a number is odd: Dividing it by 2 will result in a rounded result, such that multiplying it by 2 will yield a different number than the original input.
Now you have the logic worked out, the code is pretty straightforward:
%% sample input
x = int64(42) ;
y = int64(43) ;
%% define the checking function
% uses only multiplication and division operator, no high level function
is_even = #(x) int64(x) == (int64(x)/2)*2 ;
And obvisouly, this will yield:
>> is_even(x)
ans =
1
>> is_even(y)
ans =
0
I found out from a fellow student how to solve this simplistically with maths instead of functions.
Using (-1)^n :
If n is odd then the outcome is -1
If n is even then the outcome is 1
This is some pretty out-of-the-box thinking, but it would be the only way to solve this without previous knowledge of complex functions including mod.
The following method determines how many numbers can be added up starting from the beginning of the list without adding up to 4:
number_before_Reaching_sum (4, [1,2,3,4,6]);
should return : val it = 2 : int
fun number_before_reaching_sum (sum : int * int list) =
let val len_orig_list = length (#2 sum)
in fun num_bef_reach_sum (sum) =
if #1 sum <= 0
then len_orig_list - (length (#2 sum)) - 1
else num_bef_reach_sum (#1 sum - hd (#2 sum), tl (#2 sum))
end
syntax error: inserting LOCAL
syntax error found at EOF
I can't seem to find the errors in this code. I have some experience with Python, but just starting to learn sml. I'm loving it, but I don't understand all the error messages. I have really spent hours on this, but I think I don't know enough to solve my problem. I tried exchanging let with local, but i still got a syntax error (equalop). I think that the function between in and end is an expression and not a declaration. But I would appreciate any comments on this. If you come up with alternative code, it would be great if you did it without using more advanced features, since I'm just trying to get the basics down :-)
You probably meant this:
fun number_before_reaching_sum (sum : int * int list) =
let
val len_orig_list = length (#2 sum)
fun num_bef_reach_sum (sum) =
if #1 sum <= 0
then len_orig_list - (length (#2 sum)) - 1
else num_bef_reach_sum (#1 sum - hd (#2 sum), tl (#2 sum))
in
num_bef_reach_sum (sum)
end
With let … in … end, the part between let and in is for the local definitions; the part between in and end is for the expression which will be the evaluation of the let … in … end expression (this construct is indeed an expression).
Think of let … in … end as a possibly complex expression. You hoist parts of the expression as definitions, then rewrite the complex expression using references to these definitions. This help write shorter expressions by folding some of its sub‑expressions. This construct is also required when recursion is needed (a recursion requires a defining name).
Another way to understand it, is as the application of an anonymous function whose arguments bindings are these definitions.
Ex.
let
val x = 1
val y = 2
in
x + y
end
is the same as writing
(fn (x, y) => x + y) (1, 2)
which is the same as writing
1 + 2
You erroneously put a definition at the place of the expression the whole evaluates to.
(note I did not check the function's logic, as the question was about syntax)
I am trying randomly generate a positive or negative number and rather then worry about the bigger range I am hoping to randomly generate either 1 or -1 to just multiply by my other random number.
I know this can be done with a longer rule of generating 0 or 1 and then checking return and using that to either multiply by 1 or -1.
Hoping someone knows of an easier way to just randomly set the sign on a number. Trying to keep my code as clean as possible.
I like to use arc4random() because it doesn't require you to seed the random number generator. It also conveniently returns a uint_32_t, so you don't have to worry about the result being between 0 and 1, etc. It'll just give you a random integer.
int myRandom() {
return (arc4random() % 2 ? 1 : -1);
}
If I understand the question correctly, you want a pseudorandom sequence of 1 and -1:
int f(void)
{
return random() & 1 ? 1 : -1;
// or...
// return 2 * (random() & 1) - 1;
// or...
// return ((random() & 1) << 1) - 1;
// or...
// return (random() & 2) - 1; // This one from Chris Lutz
}
Update: Ok, something has been bothering me since I wrote this. One of the frequent weaknesses of common RNGs is that the low order bits can go through short cycles. It's probably best to test a higher-order bit: random() & 0x80000 ? 1 : -1
To generate either 1 or -1 directly, you could do:
int PlusOrMinusOne() {
return (rand() % 2) * 2 - 1
}
But why are you worried about the broader range?
return ( ((arc4random() & 2) * 2) - 1 );
This extra step won't give you any additional "randomness". Just generate your number straight away in the range that you need (e.g. -10..10).
Standard rand() will return a value from this range: 0..1
You can multiply it by a constant to increase the span of the range or you can add a constant to push it left/right on the X-Axis.
E.g. to generate random values from from (-5..10) range you will have:
rand()*15-5
rand will give you a number from 0 to RAND_MAX which will cover every bit in an int except for the sign. By shifting that result left 1 bit you turn the signed MSB into the sign, but have zeroed-out the 0th bit, which you can repopulate with a random bit from another call to rand. The code will look something like:
int my_rand()
{
return (rand() << 1) + (rand() & 1);
}