Slip documentation bug ??? [ RAKU ] - list

In raku documentation for class Slip (https://docs.raku.org/type/Slip) and also in "Lists, sequences, and arrays" documentation (slips section: https://docs.raku.org/language/list), it is stated that "slip", "Slip (method)" and "| (prefix)" can be used to create slips but they behave slightly "different".
The thing is that I've tried to confirm the above statement but with disappointing results.
I run the following tests to find out the differences:
my $l = (1, 2, 3);
say (0, slip($l, 4)).perl;
say (0, ($l, 4).Slip).perl;
say (0, |($l, 4)).perl;
say '------------------------------';
say (slip($l, 4)).perl;
say (($l, 4).Slip).perl;
say (|($l, 4)).perl;
say '------------------------------';
say (0, slip($l)).perl;
say (0, ($l).Slip).perl;
say (0, |($l)).perl;
say '------------------------------';
say (0, slip $l).perl;
say (0, $l.Slip).perl;
say (0, |$l).perl;
say '------------------------------';
say (slip $l).perl;
say ($l.Slip).perl;
say (|$l).perl;
and the results are the same for all three of them:
(0, $(1, 2, 3), 4)
(0, $(1, 2, 3), 4)
(0, $(1, 2, 3), 4)
------------------------------
slip($(1, 2, 3), 4)
slip($(1, 2, 3), 4)
slip($(1, 2, 3), 4)
------------------------------
(0, 1, 2, 3)
(0, 1, 2, 3)
(0, 1, 2, 3)
------------------------------
(0, 1, 2, 3)
(0, 1, 2, 3)
(0, 1, 2, 3)
------------------------------
slip(1, 2, 3)
slip(1, 2, 3)
slip(1, 2, 3)
Is there a catch or is it a documentation bug?

Just a little further down the docs you find an example of the ( a? ) difference:
Please note that prefix:<|> will also apply parameters in a slippy
manner to a routine call. It does not forward a Slip to the called
routine, that includes return and take.
my \l = gather for 1..10 -> $a, $b { take |($a, $b) }; say l.perl;
# OUTPUT: «((1, 2), (3, 4), (5, 6), (7, 8), (9, 10)).Seq
my \m= gather for 1..10 -> $a, $b { take ($a, $b).Slip }; say m.perl;
# OUTPUT: «(1, 2, 3, 4, 5, 6, 7, 8, 9, 10).Seq

Related

how to save every LIST in parallel as a fields and records to the txt file in a clear formatted way in python

SS1=[(1, 2, 3, 4, 5), (1, 2, 3, 4, 6), (1, 2, 3, 5, 6), (1, 2, 4, 5, 6), (1, 3, 4, 5, 6), (2, 3, 4, 5, 6)]
SS2=[(1, 2, 3, 4), (1, 2, 3, 4), (1, 2, 3, 5), (1, 2, 4, 5), (1, 3, 4, 5), (2, 3, 4, 5)]
SS3=[(1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 4), (1, 3, 4), (2, 3, 4)]
I'm Writing my list into a file using the below codes...But when i write again it's adding to the last line of the file.
but what i want is....it should append horizontally not vertically. I mean must go like table and fields and records.
so, for the above ss1 the line of records is going to be 6 and for every save should add the values in parallel as table fields and records manner
ss1 ss2 ss3
1, 2, 3, 4, 5 1, 2, 3, 4 1, 2, 3
def write_to_txt(a, file_name, delimiter=','):
with open(file_name, 'a') as f:
for k in SS1:
fmt = '%s' % delimiter
f.write(fmt.join(map(str, k)) + '\n')
not only writing and help me to read it back to same number of lists based on it's number columns.
def read_from_txt(file_name):
with open(file_name, 'r') as f:
data = [tuple(map(int, k.split(','))) for k in f.read().splitlines()]
return data
#write_to_txt(SS1, 'ABC.txt')
#data = read_from_txt('ABC.txt')
This is a good first aproach:
SS1=[(1, 2, 3, 4, 5), (1, 2, 3, 4, 6), (1, 2, 3, 5, 6), (1, 2, 4, 5, 6), (1, 3, 4, 5, 6), (2, 3, 4, 5, 6)]
SS2=[(1, 2, 3, 4), (1, 2, 3, 4), (1, 2, 3, 5), (1, 2, 4, 5), (1, 3, 4, 5), (2, 3, 4, 5)]
SS3=[(1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 4), (1, 3, 4), (2, 3, 4)]
ALL = [SS1,SS2,SS3]
def write_to_txt(a, file_name, delimiter=','):
with open(file_name, 'a') as f:
for i, ss in enumerate(SS1):
if i != 0:
f.write("\n")
for ss in ALL:
fmt = '%s' % delimiter
f.write(fmt.join(map(str, ss[i])) + ",")
write_to_txt("a","lines.txt")
Unfortunately, that's not how text files work. If you wish to append "horizontally", what you really need to do is
Read each line of the file
Append your new value to each line (by concatenating the old string with a new one)
Write each new line of the file (now in write mode, not append). Note that this needs to be to a new file, or you should read your whole file first and overwrite it here.
Hope that helps.

Replacing the values of `edgelist` with those of a `labels` dictionary

I am new to both Python and NetworkX. I have a square, regular graph G with NxN nodes (a lattice). Such nodes are labelled by means of a dict (see code below). Now I want the edgelist to return the start and endpoint of each edge not by referring to the node coordinates but to the label the node has been given.
Example:
N = 3
G=nx.grid_2d_graph(N,N)
labels = dict( ((i, j), i + (N-1-j) * N ) for i, j in G.nodes() )
#This gives nodes an attribute ID that is identical to their labels
for (i,j) in labels:
G.node[(i,j)] ['ID']= labels[(i,j)]
edgelist=G.edges() #This gives the list of all edges in the format (Start XY, End XY)
If I run it with N=3 I get:
In [14]: labels
Out[14]: {(0, 0): 6, (0, 1): 3, (0, 2): 0, (1, 0): 7, (1, 1): 4, (1, 2): 1, (2, 0): 8, (2, 1): 5, (2, 2): 2}
This scheme labels the upper left node as 0, with node (N-1)th being placed in the lower right corner. And this is what I want. Now the problem with edgelist:
In [15]: edgelist
Out [15]: [((0, 1), (0, 0)), ((0, 1), (1, 1)), ((0, 1), (0, 2)), ((1, 2), (1, 1)), ((1, 2), (0, 2)), ((1, 2), (2, 2)), ((0, 0), (1, 0)), ((2, 1), (2, 0)), ((2, 1), (1, 1)), ((2, 1), (2, 2)), ((1, 1), (1, 0)), ((2, 0), (1, 0))]
I tried to solve the problem with these lines (inspiration from here: Replace items in a list using a dictionary):
allKeys = {}
for subdict in (labels):
allKeys.update(subdict)
new_edgelist = [allKeys[edge] for edge in edgelist]
but I get this wonderful thing which enlightens my monday:
TypeError: cannot convert dictionary update sequence element #0 to a sequence
To sum up, I want to be able to replace the elements of the edgelist list with the values of the labels dictionary so that, say, the edge from ((2,0),(1,0)) (which correspond to nodes 8 and 7) is returned (8,7). Endless thanks!
I believe what you are looking for is simply nx.relabel_nodes(G,labels,False) here is the documentation
Here is the output when I printed the nodes of G before and after calling the relabel nodes function.
# Before relabel_nodes
[(0, 1), (1, 0), (0, 0), (1, 1)]
# After relabel_nodes
[0, 1, 2, 3]
After doing this, the edge labels automatically becomes what you expect.
# Edges before relabelling nodes
[((0, 1), (0, 0)), ((0, 1), (1, 1)), ((1, 0), (0, 0)), ((1, 0), (1, 1))]
# Edges after relabelling nodes
[(0, 1), (0, 2), (1, 3), (2, 3)]
Also, I have replied to this question in the chat that you created but it seems you were not notified.

Scala, prepend a list of variables to the beginning of each list in a list

I am new to scala and want to get the following thing done using map, flatMap, and/or for comprehension.
I have a list of lists l = List[List[T]]. For example, l = [[1,2,3],[2,4,6,4],[3,4,6,2,3]]. Note that each list inside l can have varying length.
Now I have val x: List[Int] = [1,2,3] and I want to do some operation on x and l that returns [[1,1,2,3], [1,2,4,6,4], [1,3,4,6,2,3], [2,1,2,3], [2,2,4,6,4], [2,3,4,6,2,3], [3,1,2,3], [3,2,4,6,4], [3,3,4,6,2,3]] (the order of sublists doesn't matter).
I feel like I should use map or flatMap or for-loop to do this but after a long time of trial I can't even get the type correct. Can anyone help me on it?
scala> val ls = List(List(1,2,3),List(2,4,6,4),List(3,4,6,2,3))
ls: List[List[Int]] = List(List(1, 2, 3), List(2, 4, 6, 4), List(3, 4, 6, 2, 3))
scala> val xs: List[Int] = List(1,2,3)
xs: List[Int] = List(1, 2, 3)
scala> for(x <- xs; l <- ls) yield x +: l
res22: List[List[Int]] = List(List(1, 1, 2, 3), List(1, 2, 4, 6, 4), List(1, 3, 4, 6, 2, 3), List(2, 1, 2, 3), List(2, 2, 4, 6, 4), List(2, 3, 4, 6, 2, 3), List(3, 1, 2, 3), List(3, 2, 4, 6, 4), List(3, 3, 4, 6, 2, 3))
x.flatMap(i => l.map(i::_))

Flattening a complex list of tuples

I have a list of tuples, with nested tuples and lists, that looks like the list bellow:
a= [('Maria', [1, [2, {'teste': (2, 1.0)}]]),
('Lisa ', [2, [4, {'field': (4, 0.75), 'bola': (4, 0.25)}]]),
('John ', [4, [5, {'engine': (5, 0.2), 'wheel': (5, 0.4), 'wheels': (5, 0.2)}]]),
('Tracy ', [4, [6, {'pizza': (6, 0.16), 'fish': (6, 0.1), 'animals': (6, 0.1)}]])]
I want to flat out this list to look like:
a.modified = ('Maria', 1, 2, {'teste': (2, 1.0)}]]),
('Lisa ', 2, 4, {'field': (4, 0.75), 'bola': (4, 0.25)}]]),
('John ', 4, 5, {'engine': (5, 0.2), 'wheel': (5, 0.4), 'wheels': (5, 0.2)}]]),
('Tracy ', 4, 6, {'pizza': (6, 0.16), 'fish': (6, 0.1), 'animals': (6, 0.1}]])])
I have tried doing it step by step, using:
a2=[item for sublist in a for item in sublist]
and
a2 = list(itertools.chain.from_iterable(a))
and also:
a2 = list(item for sublist in a for item in sublist)
Nothing seems to work. I know this is too basic, but any tips on how to solve this would be really helpful. Thanks!
So it appears you have a list of tuples and linked-list-like structures. Whenever operating on linked-lists, you should think, recursion.
def flatten(items):
from itertools import chain
def flatten_link(link):
if isinstance(link, list):
yield link[0]
for item in flatten_link(link[1]):
yield item
elif link is not None:
yield link
return list(tuple(chain(item[:1], flatten_link(item[1]))) for item in items)
a = [
('Maria', [1, [2, {'teste': (2, 1.0)}]]),
('Lisa ', [2, [4, {'field': (4, 0.75), 'bola': (4, 0.25)}]]),
('John ', [4, [5, {'engine': (5, 0.2), 'wheel': (5, 0.4), 'wheels': (5, 0.2)}]]),
('Tracy', [4, [6, {'pizza': (6, 0.16), 'fish': (6, 0.1), 'animals': (6, 0.1)}]]),
]
print(flatten(a))
Which yields:
[
('Maria', 1, 2, {'teste': (2, 1.0)}),
('Lisa ', 2, 4, {'bola': (4, 0.25), 'field': (4, 0.75)}),
('John ', 4, 5, {'engine': (5, 0.2), 'wheel': (5, 0.4), 'wheels': (5, 0.2)}),
('Tracy', 4, 6, {'fish': (6, 0.1), 'animals': (6, 0.1), 'pizza': (6, 0.16)})
]

What's the most Pythonic way to identify consecutive duplicates in a list?

I've got a list of integers and I want to be able to identify contiguous blocks of duplicates: that is, I want to produce an order-preserving list of duples where each duples contains (int_in_question, number of occurrences).
For example, if I have a list like:
[0, 0, 0, 3, 3, 2, 5, 2, 6, 6]
I want the result to be:
[(0, 3), (3, 2), (2, 1), (5, 1), (2, 1), (6, 2)]
I have a fairly simple way of doing this with a for-loop, a temp, and a counter:
result_list = []
current = source_list[0]
count = 0
for value in source_list:
if value == current:
count += 1
else:
result_list.append((current, count))
current = value
count = 1
result_list.append((current, count))
But I really like python's functional programming idioms, and I'd like to be able to do this with a simple generator expression. However I find it difficult to keep sub-counts when working with generators. I have a feeling a two-step process might get me there, but for now I'm stumped.
Is there a particularly elegant/pythonic way to do this, especially with generators?
>>> from itertools import groupby
>>> L = [0, 0, 0, 3, 3, 2, 5, 2, 6, 6]
>>> grouped_L = [(k, sum(1 for i in g)) for k,g in groupby(L)]
>>> # Or (k, len(list(g))), but that creates an intermediate list
>>> grouped_L
[(0, 3), (3, 2), (2, 1), (5, 1), (2, 1), (6, 2)]
Batteries included, as they say.
Suggestion for using sum and generator expression from JBernardo; see comment.