When I try to modify matrix in raku.
I got the error :
my #matrix = ^100 .rotor(10);
#matrix[1;*] = 1 xx 10
Cannot modify an immutable Int (10)
in block <unit> at <unknown file> line 1
#matrix[1;1] = 3
Cannot modify an immutable List ((10 11 12 13 14 15 1...)
in block <unit> at <unknown file> line 1
Why all of those values are immutable value?
Well, lists are always immutable. You can modify their container, but not themselves. rotor creates lists, so once they have been created, you can't modify them.
Don't know exactly what you want to do here, but looking at the errors here, I would say you need to turn those immutable lists into mutable Arrays:
my #matrix = ^100 .rotor(10).map: *.Array;
#matrix[1;*] = 1 xx 10;
#matrix[1;1] = 3;
Related
Python beginner here.
I already have the solution to the question but I'm not understanding why the "add" variable in the solution plays a role of creating exceptions to remove numbers between 6 and 9. I already tried Python Tutor but still not understanding. Many thanks in advance!
QUESTION: Return the sum of the numbers in the array, except ignore sections of numbers starting with a 6 and extending to the next 9 (every 6 will be followed by at least one 9). Return 0 for no numbers.
Sample Solution code
def summer_69(arr):
total = 0
add = True
for num in arr:
while add:
if num != 6:
total += num
break
else:
add = False
while not add:
if num != 9:
break
else:
add = True
break
return total
Sample answers:
summer_69([1, 3, 5]) --> 9
summer_69([4, 5, 6, 7, 8, 9]) --> 9
summer_69([2, 1, 6, 9, 11]) --> 14
You can think of the variable "add" as a flag. I think that might be a better name for this variable in this instance.
It is only being used to tell if you have run into a 6 within the sequence of numbers in the array, then once it has been set it goes through an arbitrary amount of numbers in the array until it gets a 9 and then it resets the flag.
It may help to rename the variable "add" as "flag". Have your new variable "flag" default to False and then if you run into a 6 set "flag" to true. Once the flag is on do not add any trailing numbers in the sequence until you run into the number 9 then reset to false.
Perhaps that will help the readability. Naming variables is the hardest part of programming.
Suppose I define a lazy, infinite array using a triangular reduction at the REPL, with a single element pasted onto the front:
> my #s = 0, |[\+] (1, 2 ... *)
[...]
I can print out the first few elements:
> #s[^10]
(0 1 3 6 10 15 21 28 36 45)
I'd like to move the zero element inside the reduction like so:
> my #s = [\+] (0, |(1, 2 ... *))
However, in response to this, the REPL hangs, presumably by trying to evaluate the infinite list.
If I do it in separate steps, it works:
> my #s = 0, |(1, 2 ... *)
[...]
> ([\+] #s)[^10]
(0 1 3 6 10 15 21 28 36 45)
Why doesn't the way that doesn't work...work?
Short answer:
It is probably a bug.
Long answer:
(1, 2 ... *) produces a lazy sequence because it is obviously infinite, but somehow that is not making the resulting sequence from being marked as lazy.
Putting a sequence into an array #s causes it to be eagerly evaluated unless it is marked as being lazy.
Quick fix:
Append lazy to the front.
> my #s = [\+] lazy 0, |(1, 2 ... *)
[...]
> #s[^10]
(0 1 3 6 10 15 21 28 36 45)
Let me start by saying that I understand that what I'm asking about in the title is dubious practice (as explained here), but my lack of understanding concerns the syntax involved.
When I first tried to bind a scalar to a sigilless symbol, I did this:
my \a = $(3);
thinking that $(...) would package the Int 3 in a Scalar (as seemingly suggested in the documentation), which would then be bound to symbol a. This doesn't seem to work though: the Scalar is nowhere to be found (a.VAR.WHAT returns (Int), not (Scalar)).
In the above-referenced post, raiph mentions that the desired binding can be performed using a different syntax:
my \a = $ = 3;
which works. Given the result, I suspect that the statement can be phrased equivalently, though less concisely, as: my \a = (my $ = 3), which I could then understand.
That leaves the question: why does the attempt with $(...) not work, and what does it do instead?
What $(…) does is turn a value into an item.
(A value in a scalar variable ($a) also gets marked as being an item)
say flat (1,2, (3,4) );
# (1 2 3 4)
say flat (1,2, $((3,4)) );
# (1 2 (3 4))
say flat (1,2, item((3,4)) );
# (1 2 (3 4))
Basically it is there to prevent a value from flattening. The reason for its existence is that Perl 6 does not flatten lists as much as most other languages, and sometimes you need a little more control over flattening.
The following only sort-of does what you want it to do
my \a = $ = 3;
A bare $ is an anonymous state variable.
my \a = (state $) = 3;
The problem shows up when you run that same bit of code more than once.
sub foo ( $init ) {
my \a = $ = $init; # my \a = (state $) = $init;
(^10).map: {
sleep 0.1;
++a
}
}
.say for await (start foo(0)), (start foo(42));
# (43 44 45 46 47 48 49 50 51 52)
# (53 54 55 56 57 58 59 60 61 62)
# If foo(42) beat out foo(0) instead it would result in:
# (1 2 3 4 5 6 7 8 9 10)
# (11 12 13 14 15 16 17 18 19 20)
Note that variable is shared between calls.
The first Promise halts at the sleep call, and then the second sets the state variable before the first runs ++a.
If you use my $ instead, it now works properly.
sub foo ( $init ) {
my \a = my $ = $init;
(^10).map: {
sleep 0.1;
++a
}
}
.say for await (start foo(0)), (start foo(42));
# (1 2 3 4 5 6 7 8 9 10)
# (43 44 45 46 47 48 49 50 51 52)
The thing is that sigiless “variables” aren't really variables (they don't vary), they are more akin to lexically scoped (non)constants.
constant \foo = (1..10).pick; # only pick one value and never change it
say foo;
for ^5 {
my \foo = (1..10).pick; # pick a new one each time through
say foo;
}
Basically the whole point of them is to be as close as possible to referring to the value you assign to it. (Static Single Assignment)
# these work basically the same
-> \a {…}
-> \a is raw {…}
-> $a is raw {…}
# as do these
my \a = $i;
my \a := $i;
my $a := $i;
Note that above I wrote the following:
my \a = (state $) = 3;
Normally in the declaration of a state var, the assignment only happens the first time the code gets run. Bare $ doesn't have a declaration as such, so I had to prevent that behaviour by putting the declaration in parens.
# bare $
for (5 ... 1) {
my \a = $ = $_; # set each time through the loop
say a *= 2; # 15 12 9 6 3
}
# state in parens
for (5 ... 1) {
my \a = (state $) = $_; # set each time through the loop
say a *= 2; # 15 12 9 6 3
}
# normal state declaration
for (5 ... 1) {
my \a = state $ = $_; # set it only on the first time through the loop
say a *= 2; # 15 45 135 405 1215
}
Sigilless variables are not actually variables, they are more of an alias, that is, they are not containers but bind to the values they get on the right hand side.
my \a = $(3);
say a.WHAT; # OUTPUT: «(Int)»
say a.VAR.WHAT; # OUTPUT: «(Int)»
Here, by doing $(3) you are actually putting in scalar context what is already in scalar context:
my \a = 3; say a.WHAT; say a.VAR.WHAT; # OUTPUT: «(Int)(Int)»
However, the second form in your question does something different. You're binding to an anonymous variable, which is a container:
my \a = $ = 3;
say a.WHAT; # OUTPUT: «(Int)»
say a.VAR.WHAT;# OUTPUT: «(Scalar)»
In the first case, a was an alias for 3 (or $(3), which is the same); in the second, a is an alias for $, which is a container, whose value is 3. This last case is equivalent to:
my $anon = 3; say $anon.WHAT; say $anon.VAR.WHAT; # OUTPUT: «(Int)(Scalar)»
(If you have some suggestion on how to improve the documentation, I'd be happy to follow up on it)
my #numbers = <4 8 15 16 23 42>;
this works:
.say for #numbers[0..2]
# 4
# 8
# 15
but this doesn't:
my $range = 0..2;
.say for #numbers[$range];
# 16
the subscript seems to be interpreting $range as the number of elements in the range (3). what gives?
Working as intended. Flatten the range object into a list with #numbers[|$range] or use binding on Range objects to hand them around. https://docs.perl6.org will be updated shortly.
On Fri Jul 22 15:34:02 2016, gfldex wrote:
> my #numbers = <4 8 15 16 23 42>; my $range = 0..2; .say for
> #numbers[$range];
> # OUTPUT«16»
> # expected:
> # OUTPUT«4815»
>
This is correct, and part of the "Scalar container implies item" rule.
Changing it would break things like the second evaluation here:
> my #x = 1..10; my #y := 1..3; #x[#y]
(2 3 4)
> #x[item #y]
4
Noting that since a range can bind to #y in a signature, then Range being a
special case would make an expression like #x[$(#arr-param)]
unpredictable in its semantics.
> # also binding to $range provides the expected result
> my #numbers = <4 8 15 16 23 42>; my $range := 0..2; .say for
> #numbers[$range];
> # OUTPUT«4815»
> y
This is also expected, since with binding there is no Scalar container to
enforce treatment as an item.
So, all here is working as designed.
A symbol bound to a Scalar container yields one thing
Options for getting what you want include:
Prefix with # to get a plural view of the single thing: numbers[#$range]; OR
declare the range variable differently so it works directly
For the latter option, consider the following:
# Bind the symbol `numbers` to the value 1..10:
my \numbers = [0,1,2,3,4,5,6,7,8,9,10];
# Bind the symbol `rangeA` to the value 1..10:
my \rangeA := 1..10;
# Bind the symbol `rangeB` to the value 1..10:
my \rangeB = 1..10;
# Bind the symbol `$rangeC` to the value 1..10:
my $rangeC := 1..10;
# Bind the symbol `$rangeD` to a Scalar container
# and then store the value 1..10 in it:`
my $rangeD = 1..10;
# Bind the symbol `#rangeE` to the value 1..10:
my #rangeE := 1..10;
# Bind the symbol `#rangeF` to an Array container and then
# store 1 thru 10 in the Scalar containers 1 thru 10 inside the Array
my #rangeF = 1..10;
say numbers[rangeA]; # (1 2 3 4 5 6 7 8 9 10)
say numbers[rangeB]; # (1 2 3 4 5 6 7 8 9 10)
say numbers[$rangeC]; # (1 2 3 4 5 6 7 8 9 10)
say numbers[$rangeD]; # 10
say numbers[#rangeE]; # (1 2 3 4 5 6 7 8 9 10)
say numbers[#rangeF]; # (1 2 3 4 5 6 7 8 9 10)
A symbol that's bound to a Scalar container ($rangeD) always yields a single value. In a [...] subscript that single value must be a number. And a range, treated as a single number, yields the length of that range.
I have a test PsychoPy Builder script that I am using to investigate some counter-intuitive behaviour. The structure is four routines:
"Init", not in a loop, the following code in "Begin Experiment":
x = 0
y = 0
z = 0
foo = [0, 0, 0]
"One", in a loop, the following code in "End Routine":
x = x + 1
foo[0] = foo[0] + 1
thisExp.addData("x", x)
thisExp.addData("y", y)
thisExp.addData("z", z)
thisExp.addData("foo", foo)
"Two", in a loop, the following code in "End Routine":
y = y + 2
foo[1] = foo[1] + 2
thisExp.addData("x", x)
thisExp.addData("y", y)
thisExp.addData("z", z)
thisExp.addData("fooY", foo[1])
thisExp.addData("foo", foo)
"Three", in a loop, the following code in "End Routine":
z = z + 3
foo[2] = foo[2] + 3
thisExp.addData("x", x)
thisExp.addData("y", y)
thisExp.addData("z", z)
thisExp.addData("foo", foo)
There is no other code, no other components. The routines "One", "Two", and "Three" form a loop in that order executed five times. The relevant columns of the CSV output file are as follows:
trials.thisRepN trials.thisTrialN trials.thisN trials.thisIndex x y z foo fooY
0 0 0 0 1 2 3 [5, 10, 15] 2
1 0 1 0 2 4 6 [5, 10, 15] 4
2 0 2 0 3 6 9 [5, 10, 15] 6
3 0 3 0 4 8 12 [5, 10, 15] 8
4 0 4 0 5 10 15 [5, 10, 15] 10
Is this the expected output? If so, why? Note that the individual variables, x, y, and z, are displaying updated values each time through the loop (at the end of the loop), while the list foo shows only the final value after the loop iterates all five times, but it shows this in every line. But calling out individual elements of the list displays as individual variables do.
What is the logic and rationale behind this?
Is there a way to make the list output perform as the others do?
Is there a way to force the output to capture/display any of these variables as they are when the addData() is invoked rather than waiting until the end of the loop?
I think I know what is going wrong here. It's probably because python assigns by reference rather than copy. This is explained in detail elsewhere but briefly,
original = [1, 2]
new = original # new is simply a reference to original! It is not a copy.
new[0] = 'Oops' # original is now ['Oops', 2] as is new (which is just a reference or pointer
In your case, the TrialHandler receives the reference, which simply points to the "foo" variable which is updated throughout the experiment. Since the log is only saved in the end of the experiment, all the rows in "foo" now points to the "foo variable" which now holds the value [5, 10, 15].
This assignment-by-reference can be extremely beautiful and handy, but sometimes cause headache like in your example. It applies to all python mutables: lists, dicts, functions, and classes. But not for immutables, like numbers, tuples and strings! That's why your script works for digits but not for the list.
There are different solutions. The simplest is probably to replace the addData calls with thisExp.addData("foo", tuple(foo)) which converts the mutable list to an immutable tuple. One can also do thisExp.addData("foo", [x for x in foo]). A more all-round solution for all kinds of objects is to run import copy in the beginning of the experiment and then add data like thisExp.addData("foo", copy.copy(foo)) in the other codeblocks (if you have a complicated object, use copy.deepcopy instead).