ES6 multiple assignments/updates in one line [duplicate] - node.js

Can anyone explain, why the following happens with ES6 array destructuring?
let a, b, c
[a, b] = ['A', 'B']
[b, c] = ['BB', 'C']
console.log(`a=${a} b=${b} c=${c}`)
// expected: a=A b=BB c=C
// actual: a=BB b=C c=undefined
http://codepen.io/ronkot/pen/WxRqXg?editors=0011

As others have said, you're missing semicolons. But…
Can anyone explain?
There are no semicolons automatically inserted between your lines to separate the "two" statements, because it is valid as a single statement. It is parsed (and evaluated) as
let a = undefined, b = undefined, c = undefined;
[a, b] = (['A', 'B']
[(b, c)] = ['BB', 'C']);
console.log(`a=${a} b=${b} c=${c}`);
wherein
[a, b] = …; is a destructuring assignment as expected
(… = ['BB', 'C']) is an assignment expression assigning the array to the left hand side, and evaluating to the array
['A', 'B'][…] is a property reference on an array literal
(b, c) is using the comma operator, evaluating to c (which is undefined)
If you want to omit semicolons and let them be automatically inserted where ever possible needed, you will need to put one at the start of every line that begins with (, [, /, +, - or `.

You've fallen into a trap of line wrapping and automatic semicolon insertion rules in JavaScript.
Take this example:
let x = [1, 2]
[2, 1]
It's the interpreted as:
let x = [1, 2][2, 1] // === [1, 2][(2, 1)] === [1, 2][1] === 2
That weird [(2, 1)] thing above is related to how Comma Operator works.
Thus, your example:
let a, b, c
[a, b] = ['A', 'B']
[b, c] = ['BB', 'C']
console.log(`a=${a} b=${b} c=${c}`)
Is interpreted as:
let a, b, c
[a, b] = ['A', 'B'][b, c] = ['BB', 'C']
console.log(`a=${a} b=${b} c=${c}`)
Now, if you insert a semicolon, it will work as you intended:
let a, b, c
[a, b] = ['A', 'B']; // note a semicolon here
[b, c] = ['BB', 'C']
console.log(`a=${a} b=${b} c=${c}`)
Also, it's a good idea to check your code by pasting it into Babel repl to see the generated output:
'use strict';
var a = void 0,
b = void 0,
c = void 0;
var _ref = ['A', 'B'][(b, c)] = ['BB', 'C'];
a = _ref[0];
b = _ref[1];
console.log('a=' + a + ' b=' + b + ' c=' + c);

I believe you have forgotten the line breaks ';'. Below is the corrected code. Please try:
let a,b,c
[a, b] = ['A', 'B'];
[b, c] = ['BB', 'C'];
console.log(`a=${a} b=${b} c=${c}`)

let a, b, c
[a, b] = ['A', 'B']***;***
[b, c] = ['BB', 'C']
console.log(`a=${a} b=${b} c=${c}`)
console: a=A b=BB c=C

Related

Python 3 - type hints for sequences of str

Have a function:
def f(a: Sequence[str], b: Sequence[str]) -> List[str]:
return list(set(a) - set(b))
a = ['a', 'b', 'c']
b = ['b', 'c']
f(a, b)
But this function can be applicable not only for str type but for other types that can be comparable (int, float etc). In this case how to set up type hints for a and b parameters
You should use the Any Type if you are not sure
from typing import Any
def f(a: Sequence[Any], b: Sequence[Any]) -> List[Any]:
return list(set(a) - set(b))
a = ['a', 'b', 'c']
b = ['b', 'c']
f(a, b)
If you want to make it applicable only to those three types (int, float, str), you should use Union:
from typing import Union
def f(a: Sequence[Union[str, int, float]], b: Sequence[Union[str, int, float]]) -> List[Union[str, int, float]]:
return list(set(a) - set(b))
a = ['a', 'b', 'c']
b = ['b', 'c']
f(a, b)
As of python 3.10 the union type can be omitted and you can write it directly like so:
a: Sequence[str|int|float]

how to plott several curves after while loop in function

def a(t, A, B, C, At, Bt):
while:
calculations
return t, A, B, C, At, Bt
print(def(t, A, B, C, At, Bt))
I return several numpy.arrays. and wanna plot them in the form
B, = plt.plot(t, B)
C, = plt.plot(t, C)
plt.legend(handles=[ B, C, A],
labels=[ 'B', 'C', 'A'])
Use the object-oriented interface to matplotlib:
from matplotlib import pyplot
t, A, B, C, At, Bt = a(t, A, B, C, At, Bt)
fig, ax = pyplot.subplots()
for array, label in zip([A, B, C], ['A', 'B', 'C']):
ax.plot(t, array, label=label)
ax.legend()

Python - list concatenation with shallow referencing?

I'm working on such project, and got question for code compression.
There are many ways for list concatenation a+b, a.extend(b), and so on.
but my question is, there are any way for shallow concatenation of the lists; for example,
a = [1,2,3]
b = [4,5]
c = a+b
c
>> [1,2,3,4,5]
b[0] = 10
c
>> [1,2,3,4,5]
but, my desired result is [1,2,3,10,5], then how to define c for this?
If you create a nested list from a and b you can kinda achieve what you are looking for:
>>> a = [1, 2, 3]
>>> b = [4, 5]
>>> c = [a, b]
>>> b[0] = 10
>>> c
[[1, 2, 3], [10, 5]]
>>> c = [val for sub_list in c for val in sub_list]
>>> c
[1, 2, 3, 10, 5]
a = [1,2,3]
b = [4,5]
b[0] = 10
c = a+b
print(c)
or
import copy
a = [1,2,3]
b = [4,5]
c=[a,b]
bb = copy.copy(c)
c[1][0]=10
print([val for l in c for val in l])
# refer this link for shallow-deep-copy reference
# https://www.programiz.com/python-programming/shallow-deep-copy

f string and extended unpacking

I am trying to do extended unpacking of tuple with * syntax. I'm trying to format string with f'' string syntax. None of those work in visual-studio-code python3.7.3 linuxmint64 system.
l = [1, 2, 3, 4, 5, 6]
a, *b = l
print(a, b)
Here is the error :
line 3
a, *b = l
^
SyntaxError: invalid syntax
Your Code:
l = [1, 2, 3, 4, 5, 6]
a, *b = l
print(a, b)
The above code won't as the correct syntax is b=[*l]. The * is used to unpack a list.
So if you want to have some values in both a and b so the code below...
l = [1, 2, 3, 4, 5, 6]
d = [3,2,1]
a , b = [*l] , [*d] # Here [*l] unpacks l in a list and assign it to a and
# and [*d] unpacks d in a list and assign it to b
print(a , b)
Hope this helps...

Calculate the number of times a combination is used in a log

I have a log of events in the bellow form:
A B C D
A B C D
A B C D
A B C D
D E F G
D E F G
D E F G
D E F G
D E F G
D E F G
D E F G
A D E F G
D E F G
A D E G
I am trying to calculate the frequency of for example how many times A -> B.
With the bellow code I calculate the frequency of each trace.
from collections import Counter
flog = []
input_file ="test.txt"
with open(input_file, "r") as f:
for line in f.readlines():
line = line.split()
flog.append(line)
trace_frequency= map(tuple,flog)
flog=list(Counter(trace_frequency).items())
That gives me :
(('A', 'B', 'C', 'D'), 4)
(('D', 'E', 'F', 'G'), 8)
(('A', 'D', 'E', 'F', 'G'), 1)
(('A', 'D', 'E', 'G'), 1)
So my question is how can I go from the above to a format where I calculate all instances of the log to the bellow format:
A B 4
B C 4
C D 4
A D 2
D E 10...etc
Thanks to all for your time.
Instead of counting each line as a whole, split each line to pairs then count the appearance of each pair.
For example, instead of counting ('A', 'B', 'C', 'D'), count ('A', 'B'), ('B', 'C'), ('C', 'D') individually.
from collections import Counter
flog = []
input_file = "test.txt"
with open(input_file, "r") as f:
for line in f.readlines():
line = line.split()
flog.extend(line[i: i + 2] for i in range(len(line) - 1))
# ^ note extend instead of append
trace_frequency = map(tuple, flog)
flog = list(Counter(trace_frequency).items())
flog is now
[(('A', 'B'), 4), (('B', 'C'), 4), (('C', 'D'), 4), (('D', 'E'), 10),
(('E', 'F'), 9), (('F', 'G'), 9), (('A', 'D'), 2), (('E', 'G'), 1)]
To get your desired format (with the bonus of order) you can use:
flog = Counter(trace_frequency)
for entry, count in flog.most_common():
print(' '.join(entry), count)
Outputs
D E 10
E F 9
F G 9
A B 4
B C 4
C D 4
A D 2
E G 1
Not sure if it's the best, but one possibility is to use Pandas. Given a file log.txt that looks like this:
0 1 2 3 4
A B C D
A B C D
A B C D
A B C D
D E F G
D E F G
D E F G
D E F G
D E F G
D E F G
D E F G
A D E F G
D E F G
A D E G
This code will work:
import pandas as pd
import numpy as np
df = pd.read_csv('log.txt', sep='\s+')
combos = [[(y[1][x], y[1][x + 1]) for x in range(len(df.loc[0]) - 1)] for y in df.iterrows()]
combos = [item for sublist in combos for item in sublist if np.nan not in item]
from collections import Counter
print(Counter(combos))
Giving you:
('A', 'B') 4
('B', 'C') 4
('C', 'D') 4
('D', 'E') 10
('E', 'F') 9
('F', 'G') 9
('A', 'D') 2
('E', 'G') 1

Resources