Unexpected Hash flattening - hashmap

I'm looking for explanation why those two data structures are not equal:
$ perl6 -e 'use Test; is-deeply [ { a => "b" } ], [ { a => "b" }, ];'
not ok 1 -
# Failed test at -e line 1
# expected: $[{:a("b")},]
# got: $[:a("b")]
Trailing comma in Hashes and Arrays is meaningless just like in P5:
$ perl6 -e '[ 1 ].elems.say; [ 1, ].elems.say'
1
1
But without it Hash is somehow lost and it gets flattened to array of Pairs:
$ perl6 -e '[ { a => "b", c => "d" } ].elems.say;'
2
I suspect some Great List Refactor laws apply here but I'd like to get more detailed explanation to understand logic behind this flattening.

Trailing comma in Hashes and Arrays is meaningless just like in P5
No, it's not meaningless:
(1 ).WHAT.say ; # (Int)
(1,).WHAT.say ; # (List)
The big simplification in the Great List Refactor was switching to the single argument rule for iterating features1. That is to say, features like a for or the array and hash composers (and subscripts) always get a single argument. That is indeed what's going on with your original example.
The single argument may be -- often will be -- a list of values, possibly even a list of lists etc., but the top level list would still then be a single argument to the iterating feature.
If the single argument to an iterating feature does the Iterable role (for example lists, arrays, and hashes), then it's iterated. (This is an imprecise formulation; see my answer to "When does for call the iterator method?" for a more precise one.)
So the key thing to note here about that extra comma is that if the single argument does not do the Iterable role, such as 1, then the end result is exactly the same as if the argument were instead a list containing just that one value (i.e. 1,):
.perl.say for {:a("b")} ; # :a("b") Iterable Hash was iterated
.perl.say for {:a("b")} , ; # {:a("b")} Iterable List was iterated
.perl.say for 1 ; # 1 Non Iterable 1 left as is
.perl.say for 1 , ; # 1 Iterable List was iterated
The typical way "to preserve structure [other than] using trailing comma when single element list is declared" (see comment below), i.e. to
stop a single Iterable value being iterated as it normally would, is by item-izing it with a $:
my #t = [ $[ $[ "a" ] ] ];
#t.push: "b";
#t.perl.say; # [[["a"],], "b"]
1 The iteration is used to get values to be passed to some code in the case of a for; to get values to become elements of the array/hash being constructed in the case of a composer; to get an indexing slice in the case of a subscript; and so on for other iterating features.

Related

list of one string element getting converted to list of characters

I have a program which receives input from another program and use it for further operations. The input can be a list, set, tuple but for further operations a list is needed. So I am converting input to list.
The problem arises when input my program receives is a list/set/tuple with just one element like below. The
import itertools
def not_mine(c):
d = {'John':['mid', 'forward'],
'Lana':['mid'],
'Jacob':['defence', 'mid'],
'Ian':['goal', 'mid']}
n = itemgetter(*c)(d)
n = list(set(itertools.chain.from_iterable(n)))
return n
def mine(c):
name = not_mine(c)
name_1 = list(name)
print(name_1)
mine(['Jacob', 'Ian'])
['defence', 'goal', 'mid']
mine(['Lana'])
['i', 'm', 'd']
Is there any way to prevent the second case? It should be a list of one element ['mid'].
Iterators
The function set uses the first argument as an iterator to create a sequence of items. str is natively an iterator. In other words, you can loop over a str and you'll assign to the for variable each character in the string per iteration.
for whatami in "hi!":
print(whatami)
h
i
!
If you want to treat a single string input as a single item, explicitly pass an iterator argument to set (list works the same way, BTW) with a single item in it. Tuple is, also, an iterator. Let's try to use it to prove our theory
t1 = ('ourstring', )
print(f"t1 is of type {type(t1)}")
s1 = set(t1)
print(s1)
t1 is of type <class 'tuple'>
{'ourstring'}
It works!
What we've done with ('ourstring', ) is explicitly define a tuple with one item. There's a familiar delimiter, ,, used to say "this tuple is instantiated with only one item".
Input
To separate situations between ingesting a list of items and one string item, you can consider two approaches.
The most straight-forward way is to agree on a delimiter in the input such as comma separated values. firstvalue,secondvalue,etc. The down side of this is that you'll quickly run into limitations of what kind of data you can receive.
To ease your development, argparse is strongly recommended command line arguments. It is a built-in, battle-hardened package made for this type of task. The docs's first example even shows a multi-value field.

What does this syntax mean in Python 3?

I've been seeing this syntax, but I'm not quite sure what it means. It's when two square brackets are next to the name of one list. I'm assuming this does some type of list slicing?
mylist[x][y]
mylist[][]
These are just some examples of what I've seen. (I've used variables x&y to represent an arbitrary number)
This notation can be used when the list contains some other lists as elements, which is helpful to represent the matrices. For example:
a=[[1,2,3],[4,5,6],[7,8,9]]
a[0][0] #This gives the number 1.
In this case, a[0] (the first index) chooses the 1st element, which is [1,2,3]. Then the second index (a[0][0]) chooses the first element of the list defined by a[0], thus giving the answer 1.
The top line just indexes into a list within a list. So for example, you could have
mylist = [
[1,2,3],
[4,5,6],
[7,8,9],
]
value = mylist[1][2]
which will get the value 6.
The bottom line doesn't look like valid Python to me.
EXPLANATION:
Consider that mylist[1] just extracts the second element from mylist (second because of 0-based indexing), which is [4,5,6]. Then adding [2] looks up the third item in that list, which is 6. You could also write
inner_list = mylist[1]
value = inner_list[2]
or
value = (mylist[1]) [2]
which both do the same thing.

How does Perl 6's multi dispatch decide which routine to use?

Consider this program where I construct an Array in the argument list. Although there's a signature that accepts an Array, this calls the one that accepts a List:
foo( [ 1, 2, 3 ] );
multi foo ( Array #array ) { put "Called Array # version" }
multi foo ( Array $array ) { put "Called Array \$ version" }
multi foo ( List $list ) { put "Called List version" }
multi foo ( Range $range ) { put "Called Range version" }
I get the output from an unexpected routine:
Called Array $ version
If I uncomment that other signature, that one is called:
Called List version
Why doesn't it call the ( Array #array ) version? How is the dispatcher making its decision (and where is it documented)?
Why doesn't it call the ( Array #array ) version?
Your test foo call has just an Array ([1,2,3]) as its argument, not an Array of Arrays (eg [[1,2,3],[4,5,6]]).
(The # in #array indicates a value that does Positional, eg an array or a list. Array #array indicates the same thing but with the additional constraint that each element of the array, list or whatever is an Array.)
How is the dispatcher making its decision?
Simplifying, it's picking the narrowest matching type:
multi foo ( Array ) {} # Narrowest
multi foo ( List ) {} # Broader
multi foo ( Positional ) {} # Broader still
multi foo ( #array ) {} # Same as `Positional`
(Diagram of subtype relationships of Array, List and Positional.)
For lots of details see jnthn's authoritative answer to a related SO question.
(and where is it documented)?
I'm not sure about the doc. Multi-dispatch looks pretty minimal.
I made a really dumb mistake, and that's why I wasn't seeing what I expected. You can't constrain a variable that starts with #. Any constraint applies to its elements. The Array #array denotes that I have a positional sort of thing in which each element is an Array. This is the same thing that raiph said. The odd thing is that the grammar looks the same but it does different things. It's something I've tripped over before.
Since it's doing something different, it's not going to work out even if the data structure matches:
foo( [ [1], [2], [3] ] );
foo( [ 1, 2, 3 ] );
multi foo ( Array #array ) { put "Called Array # version" }
multi foo ( Array $array ) { put "Called Array \$ version" }
multi foo ( List $list ) { put "Called List version" }
multi foo ( Range $range ) { put "Called Range version" }
I still get the version I wouldn't expect based on the constraint and the data structure:
Called Array $ version
Called Array $ version
I think this is just going to be one of Perl 6's warts that normal users will have to learn.
There seems to be a trade off between the design documents (more complete but more outdated) and the documentation (known to be incomplete, as docs.perl6.org acknowledges, but hopefully more up-to-date). The former explains multisub resolution in Synopsis 12. Excerpt:
When you call a routine with a particular short name, if there are multiple visible long names, they are all considered candidates. They are sorted into an order according to how close the run-time types of the arguments match up with the declared types of the parameters of each candidate. The best candidate is called, unless there's a tie, in which case the tied candidates are redispatched using any additional tiebreaker strategies (see below). [...]
There are three tiebreaking modes, in increasing order of desperation:
A) inner or derived scope
B) run-time constraint processing
C) use of a candidate marked with "is default"
Tiebreaker A simply prefers candidates in an inner or more derived scope over candidates in an outer or less derived scope. For candidates in the same scope, we proceed to tiebreaker B.
In the absence of any constraints, ties in tiebreaker A immediately failover to tiebreaker C; if not resolved by C, they warn at compile time about an ambiguous dispatch. [...]
I don’t know enough about Perl 6 to testify as to its accuracy, but it seems to be in agreement with raith’s answer, and covers additional ground as well.

string 'w32' == 0 evaluates to true in php. huh?

So I was getting a notice in my php while creating a google product feed.
The notice was
"The following php notice has occurred 4989 times on the _ site today:
PHP Notice: Undefined index: 0 in /xxx/Status.php on line 583"
This was the code in that class
public function inStockLocally($productcode)
{
if($this->_status[$productcode]['status'] == self::IN_STOCK) {
return $this->_status[$productcode]['in_stock_local'];
}
return false;
}
The function was getting a $productcode = 0, but the productcode was infact 'w32', so the key didn't exist.
up the stack where the function was being called I put this in, in order to break on the troublesome product.
if ($productcode == 0) {
$test = 'breakhere';
}
Using netbeans and firebug, it broke on the line when $productcode = 'w32'
So my question is why does 'w32' == 0 evaluate to true?
It is also evaluating to true with other similar structure codes like 'h94'.
Any help would be appreciated as no one in the department can figure out why this is happening.
I guess I didn't put enough info in the q. Two things going on.
1. 'w32' converted to a number = 0 for some reason. 2. [0] is being inserted as my key in the array when the productcode has the structure 'x##';
I'm a little new here, so pardon if this isn't the answer you were expecting, but PHP does a lot of automatic type conversion. So any string that doesn't start with a numeric character (0..9, +, -, etc) will evaluate to zero.
"If you compare a number with a string or the comparison involves numerical strings, then each string is converted to a number and the comparison performed numerically. "
http://php.net/manual/en/language.operators.comparison.php
Additionally, I suppose you have an indexed array, although you expect it to be an associative array:
The array() function is used to create an array.
In PHP, there are three types of arrays:
Indexed arrays - Arrays with numeric index
Associative arrays - Arrays with named keys
Multidimensional arrays - Arrays containing one or more arrays
Syntax
Syntax for indexed arrays:
array(value1,value2,value3,etc.);
Syntax for associative arrays:
array(key=>value,key=>value,key=>value,etc.);

replace within boxed structure

I have the following (for example) data
'a';'b';'c';'a';'b';'a'
┌─┬─┬─┬─┬─┬─┐
│a│b│c│a│b│a│
└─┴─┴─┴─┴─┴─┘
and I'd like to replace all 'a' with a number, 3, and 'b' with another number 4, and get back
┌─┬─┬─┬─┬─┬─┐
│3│4│c│3│4│3│
└─┴─┴─┴─┴─┴─┘
how can I do that?
Thanks for help.
rplc
If that was a string (like 'abcaba') there would be the easy solution of rplc:
'abcaba' rplc 'a';'3';'b';'4'
34c343
amend }
If you need to have it like boxed data (if, for example, 'a' represents something more complex than a character or atom), then maybe you can use amend }:
L =: 'a';'b';'c';'a';'b';'a'
p =: I. (<'a') = L NB. positions of 'a' in L
0 3 5
(<'3') p } L NB. 'amend' "3" on those positions
putting the above into a dyad:
f =: 4 :'({.x) (I.({:x) = y) } y' NB. amend '{.x' in positions where '{:x' = y
('3';'a') f L
┌─┬─┬─┬─┬─┬─┐
│3│b│c│3│b│3│
└─┴─┴─┴─┴─┴─┘
which you can use in more complex settings:
]L =: (i.5);'abc';(i.3);'hello world';(<1;2)
┌─────────┬───┬─────┬───────────┬─────┐
│0 1 2 3 4│abc│0 1 2│hello world│┌─┬─┐│
│ │ │ │ ││1│2││
│ │ │ │ │└─┴─┘│
└─────────┴───┴─────┴───────────┴─────┘
((1;2);(i.3)) f L
┌─────────┬───┬─────┬───────────┬─────┐
│0 1 2 3 4│abc│┌─┬─┐│hello world│┌─┬─┐│
│ │ ││1│2││ ││1│2││
│ │ │└─┴─┘│ │└─┴─┘│
└─────────┴───┴─────┴───────────┴─────┘
btw, {.y is the first item of y; {:y is the last item of y
bottom line
Here's a little utility you can put in your toolbox:
tr =: dyad def '(y i.~ ({." 1 x),y) { ({:" 1 x) , y'
] MAP =: _2 ]\ 'a';3; 'b';4
+-+-+
|a|3|
+-+-+
|b|4|
+-+-+
MAP tr 'a';'b';'c';'a';'b';'a'
+-+-+-+-+-+-+
|3|4|c|3|4|3|
+-+-+-+-+-+-+
just above the bottom line
The utility tr is a verb which takes two arguments (a dyad): the right argument is the target, and the left argument is the mapping table. The table must have two columns, and each row represents a single mapping. To make just a single replacement, a vector of two items is acceptable (i.e. 1D list instead of 2D table, so long as the list is two items long).
Note that the table must have the same datatype as the target (so, if you're replacing boxes, it must be a table of boxes; if characters, then a table of characters; numbers for numbers, etc).
And, since we're doing like-for-like mapping, the cells of the mapping table must have the same shape as the items of the target, so it's not suitable for tasks like string substitution, which may require shape-shifting. For example, ('pony';'horse') tr 'I want a pony for christmas' won't work (though, amusingly, 'pony horse' tr&.;: 'I want a pony for christmas' would, for reasons I won't get into).
way above the bottom line
There's no one, standard answer to your question. That said, there is a very common idiom to do translation (in the tr, or mapping 1:1, sense):
FROM =: ;: 'cat dog bird'
TO =: ;: 'tiger wolf pterodactyl'
input=: ;: 'cat bird dog bird bird cat'
(FROM i. input) { TO
+-----+-----------+----+-----------+-----------+-----+
|tiger|pterodactyl|wolf|pterodactyl|pterodactyl|tiger|
+-----+-----------+----+-----------+-----------+-----+
To break this down, the primitive i. is the lookup function and the primitive { is the selection function (mnemonic: i. gives you the *i*ndex of the elements you're looking for).
But the simplistic formulation above only applies when you want to replace literally everything in the input, and FROM is guaranteed to be total (i.e. the items of the input are constrained to whatever is in FROM).
These contraints make the simple formulation appropriate for tasks like case conversion of strings, where you want to replace all the letters, and we know the total universe of letters in advance (i.e. the alphabet is finite).
But what happens if we don't have a finite universe? What should we do with unrecognized items? Well, anything we want. This need for flexibility is the reason that there is no one, single translation function in J: instead, the language gives you the tools to craft a solution specific to your needs.
For example, one very common extension to the pattern above is the concept of substitution-with-default (for unrecognized items). And, because i. is defined to return 1+#input for items not found in the lookup, the extension is surprisingly simple: we just extend the replacement list by one item, i.e. just append the default!
DEFAULT =: <'yeti'
input=: ;: 'cat bird dog horse bird monkey cat iguana'
(FROM i. input) { TO,DEFAULT
+-----+-----------+----+----+-----------+----+-----+----+
|tiger|pterodactyl|wolf|yeti|pterodactyl|yeti|tiger|yeti|
+-----+-----------+----+----+-----------+----+-----+----+
Of course, this is destructive in the sense it's not invertible: it leaves no information about the input. Sometimes, as in your question, if you don't know how to replace something, it's best to leave it alone.
Again, this kind of extension is surprisingly simple, and, once you see it, obvious: you extend the lookup table by appending the input. That way, you're guaranteed to find all the items of the input. And replacement is similarly simple: you extend the replacement list by appending the input. So you end up replacing all unknown items with themselves.
( (FROM,input) i. input) { TO,input
+-----+-----------+----+-----+-----------+------+-----+------+
|tiger|pterodactyl|wolf|horse|pterodactyl|monkey|tiger|iguana|
+-----+-----------+----+-----+-----------+------+-----+------+
This is the strategy embodied in tr.
above the top line: an extension
BTW, when writing utilities like tr, J programmers will often consider the N-dimensional case, because that's the spirit of the language. As it stands, tr requires a 2-dimensional mapping table (and, by accident, will accept a 1-dimensional list of two items, which can be convenient). But there may come a day when we want to replace a plane inside a cube, or a cube inside a hypercube, etc (common in in business intelligence applications). We may wish to extend the utility to cover these cases, should they ever arise.
But how? Well, we know the mapping table must have at least two dimensions: one to hold multiple simultaneous substitutions, and another to hold the rules for replacement (i.e. one "row" per substition and two "columns" to identify an item and its replacement). The key here is that's all we need. To generalize tr, we merely need to say we don't care about what's beneath those dimensions. It could be a Nx2 table of single characters, or an Nx2 table of fixed-length strings, or an Nx2 table of matrices for some linear algebra purpose, or ... who cares? Not our problem. We only care about the frame, not the contents.
So let's say that, in tr:
NB. Original
tr =: dyad def '(y i.~ ({." 1 x),y) { ({:" 1 x) , y'
NB. New, laissez-faire definition
tr =: dyad def '(y i.~ ({."_1 x),y) { ({:"_1 x) , y'
A taxing change, as you can see ;). Less glibly: the rank operator " can take positive or negative arguments. A positive argument lets the verb address the content of its input, whereas a negative argument lets the verb address the frame of its input. Here, "1 (positive) applies {. to the rows of the x, whereas "_1 (negative) applies it to the the "rows" of x, where "rows" in scare-quotes simply means the items along the first dimension, even if they happen to be 37-dimensional hyperrectangles. Who cares?
Well, one guy cares. The original definition of tr let the laziest programmer write ('dog';'cat') tr ;: 'a dog makes the best pet' instead of (,:'dog';'cat') tr ;: 'a dog makes the best pet'. That is, the original tr (completely accidentally) allowed a simple list as a mapping table, which of course isn't a Nx2 table, even in an abstract, virtual sense (because it doesn't have at least two dimensions). Maybe we'd like to retain this convenience. If so, we'd have to promote degenerate arguments on the user's behalf:
tr =: dyad define
x=.,:^:(1=##$) x
(y i.~ ({."_1 x),y) { ({:"_1 x) , y
)
After all, laziness is a prime virtue of a programmer.
Here's the simplest way I can think of to accomplish what you have asked for:
(3;3;3;4;4) 0 3 5 1 4} 'a';'b';'c';'a';'b';'a'
┌─┬─┬─┬─┬─┬─┐
│3│4│c│3│4│3│
└─┴─┴─┴─┴─┴─┘
here's another approach
(<3) 0 3 5} (<4) 1 4} 'a';'b';'c';'a';'b';'a'
┌─┬─┬─┬─┬─┬─┐
│3│4│c│3│4│3│
└─┴─┴─┴─┴─┴─┘
Hypothetically speaking, you might want to be generalizing this kind of expression, or you might want an alternative. I think the other posters here have pointed out ways of doing that. . But sometimes just seeing the simplest form can be interesting?
By the way, here's how I got my above indices (with some but not all of the irrelevancies removed):
I. (<'a') = 'a';'b';'c';'a';'b';'a'
0 3 5
('a') =S:0 'a';'b';'c';'a';'b';'a'
1 0 0 1 0 1
('a') -:S:0 'a';'b';'c';'a';'b';'a'
1 0 0 1 0 1
I.('a') -:S:0 'a';'b';'c';'a';'b';'a'
0 3 5
I.('b') -:S:0 'a';'b';'c';'a';'b';'a'
1 4

Resources