How to change separator in CoffeeScript generator? - coffeescript

Following code:
yearsOld = max: 10, ida: 9, tim: 11
ages = for child, age of yearsOld
"#{child} is #{age}"
will return:
max is 10, ida is 9, tim is 11
How to make it return a value without commas? Like that:
max is 10 ida is 9 tim is 11

There are no "commas" in ages.
ages is an array, and if you write an array to the console, the default behavior is to display it with commas. If you don't want commas, you can use Array#join produce a string separating the values with whatever separator you want:
yearsOld = max: 10, ida: 9, tim: 11
ages = for child, age of yearsOld
"#{child} is #{age}"
agesString = ages.join ' '
console.log agesString

c.coffee
yearsOld = max: 10, ida: 9, tim: 11
ages = (input)->
output=""
for k,v of input
output += k + " is " + v + " "
return output
console.log ages yearsOld
run
coffee c.coffee
max is 10 ida is 9 tim is 11

If you want a "one-liner":
c.coffee
yearsOld = max: 10, ida: 9, tim: 11
console.log (("#{k} is #{v}") for k, v of yearsOld).join(' ')
run
coffee c.coffee
max is 10 ida is 9 tim is 11
If you want to filter, for example not including ida:
console.log ((("#{k} is #{v}") if k != "ida") for k, v of yearsOld ).join(' ').replace(' ', ' ').replace(/^\s/, '')
or only above 10 years old:
console.log ((("#{k} is #{v}") if v > 10) for k, v of yearsOld ).join(' ').replace(' ', ' ').replace(/^\s/, '')

Related

Separator for five or more digits number in Tableau

I was working on a Tableau Project. We want to have a separator for five or more digits numbers.
For ex:-
1 as 1
12 as 12
123 as 123
1234 as 1234
12345 as 12,345
123456 as 1,23,456
Can you please assist me, how to achieve this?
I am nearly sure that this cannot be done as long as numbers are formatted as numbers. However, as a workaround, I have developed a method which however will convert numbers to string. Let's say you have a column col of desired numbers
copy your column say col2 (save original for future use) and convery type to string
Create a new calculated field say desired by using this calculation
If LEN([Col2]) <= 4 THEN
[Col2]
ELSEIF LEN([Col2]) < 6 THEN
REPLACE([Col2], RIGHT([Col2], 3), "") + "," +RIGHT([Col2], 3)
ELSEIF LEN([Col2]) <8 THEN
REPLACE([Col2], RIGHT([Col2], 5), "") + "," +
REPLACE(RIGHT([Col2],5), RIGHT([Col2], 3), "") + "," +RIGHT([Col2], 3)
ELSE
REPLACE([Col2], RIGHT([Col2], 7), "") + "," +
REPLACE(RIGHT([Col2],7), RIGHT([Col2], 5), "") + "," +
REPLACE(RIGHT([Col2],5), RIGHT([Col2], 3), "") + "," +RIGHT([Col2], 3)
END
this CF will work exactly as desired for upto 9 digits.
Alignment is not a big problem, if considered

Python: add zeroes in single digit numbers without using .zfill

Im currently using micropython and it does not have the .zfill method.
What Im trying to get is to get the YYMMDDhhmmss of the UTC.
The time that it gives me for example is
t = (2019, 10, 11, 3, 40, 8, 686538, None)
I'm able to access the ones that I need by using t[:6]. Now the problem is with the single digit numbers, the 3 and 8. I was able to get it to show 1910113408, but I need to get 19101034008 I would need to get the zeroes before those 2. I used
t = "".join(map(str,t))
t = t[2:]
So my idea was to iterate over t and then check if the number is less than 10. If it is. I will add zeroes in front of it, replacing the number . And this is what I came up with.
t = (2019, 1, 1, 2, 40, 0)
t = list(t)
for i in t:
if t[i] < 10:
t[i] = 0+t[i]
t[i] = t[i]
print(t)
However, this gives me IndexError: list index out of range
Please help, I'm pretty new to coding/python.
When you use
for i in t:
i is not index, each item.
>>> for i in t:
... print(i)
...
2019
10
11
3
40
8
686538
None
If you want to use index, do like following:
>>> for i, v in enumerate(t):
... print("{} is {}".format(i,v))
...
0 is 2019
1 is 10
2 is 11
3 is 3
4 is 40
5 is 8
6 is 686538
7 is None
another way to create '191011034008'
>>> t = (2019, 10, 11, 3, 40, 8, 686538, None)
>>> "".join(map(lambda x: "%02d" % x, t[:6]))
'20191011034008'
>>> "".join(map(lambda x: "%02d" % x, t[:6]))[2:]
'191011034008'
note that:
%02d add leading zero when argument is lower than 10 otherwise (greater or equal 10) use itself. So year is still 4digit string.
This lambda does not expect that argument is None.
I tested this code at https://micropython.org/unicorn/
edited :
str.format method version:
"".join(map(lambda x: "{:02d}".format(x), t[:6]))[2:]
or
"".join(map(lambda x: "{0:02d}".format(x), t[:6]))[2:]
second example's 0 is parameter index.
You can use parameter index if you want to specify it (ex: position mismatch between format-string and params, want to write same parameter multiple times...and so on) .
>>> print("arg 0: {0}, arg 2: {2}, arg 1: {1}, arg 0 again: {0}".format(1, 11, 111))
arg 0: 1, arg 2: 111, arg 1: 11, arg 0 again: 1
I'd recommend you to use Python's string formatting syntax.
>> t = (2019, 10, 11, 3, 40, 8, 686538, None)
>> r = ("%d%02d%02d%02d%02d%02d" % t[:-2])[2:]
>> print(r)
191011034008
Let's see what's going on here:
%d means "display a number"
%2d means "display a number, at least 2 digits"
%02d means "display a number, at least 2 digits, pad with zeroes"
so we're feeding all the relevant numbers, padding them as needed, and cut the "20" out of "2019".

How do you add spaces in front of 'y' integers in a nested loop?

for x in range(1, 4):
print(x)
for y in range(5, 10):
print(y)
I tried adding " " + in front of y within print. Essentially,
print(" " + y)
I tried creating a string w that equals " " to add in front of y. Essentially,
w = " "
print(w + y)
I'd like the output to look like:
1
5
6
2
5
6
3
5
6
I'm exploring .join() at the moment to see if this method can provide a solution.
Thank you.
for x in range(1, 4):
print(x)
for y in range(5, 10):
w = " "
print(w + str(y)) or print(" " + str(y))
output:
1
5
6
2
5
6
Python string formatting is easy and clean in this case. You can see https://pyformat.info/ for a quick introduction.
Example with the most recent format function:
for x in range(1, 4):
print("{:d}".format(x))
for y in range(5, 10):
print("{:>3d}".format(y))
Short explanation:
{:d}: format the argument as a digit
{:>3d}: align right, make the string 3 characters long and format the argument as a digit

Branch and bound using Perl

I have a problem, I cannot find an answer to. I am using Perl. My input is a symmetric cost-matrix, kind of like the TSP.
I want to know all solutions that lie beneath my boundary, which is 10.
This is my matrix:
- B E G I K L P S
B - 10 10 2 10 10 10 10
E 10 - 2 10 10 10 1 10
G 10 2 - 10 2 3 3 3
I 2 10 10 - 4 10 10 2
K 10 10 2 4 - 10 10 3
L 10 10 3 10 10 - 2 2
P 10 1 3 10 10 2 - 10
S 10 10 3 2 3 2 10 -
Does anybody know how to implement the branch and bound algorithm to solve this? For now, I did replace every 10 in the matrix with "-".
What I did so far:
#verwbez = ( ["-", B, E, G, I, K, L, P, S],
[B,"-", 10, 10, 2, 10, 10, 10, 10],
[E, 10, "-", 2, 10, 10, 10, 1, 10],
[G, 10, 2, "-", 10, 2, 3, 3, 3],
[I, 2, 10, 10, "-", 4, 10, 10, 2],
[K, 10, 10, 2, 4, "-", 10, 10, 3],
[L, 10, 10, 3, 10, 10, "-", 2, 2],
[P, 10, 1, 3, 10, 10, 2, "-", 10],
[S, 10, 10, 3, 2, 3, 2, 10, "-"]);
for ($i=0;$i<=$#verwbez;$i++) {
for ($j=0; $j<=$#{$verwbez[$i]};$j++) {
while ($verwbez[$i][$j] >=7) {
$verwbez[$i][$j] = "-";
}
}
}
Basically just altering the matrix, every 10 is replaced with a "-". Now I want to find all solutions that are beneath 10 and contain 4 districts where always two cities are linked together. But unfortunately, I do not know how to proceed/start...
You're unlikely to get someone to implement the Branch and Bound algorithm for you. However, the following stackoverflow post, TSP - branch and bound, has some links to some helpful resources:
Optimal Solution for TSP using Branch and Bound
B&B Implementations for the TSP -
Part 1: A solution with nodes containing partial tours with
constraints
B&B Implementations for the TSP - Part 2: Single threaded solution with many inexpensive nodes
Since you appear new to perl, we can give you some quick tips
Always include use strict; and use warnings at the top of each and every perl script
Use the range operator .. when creating an incrementing for loop.
Your while loop should actually be an if statement.
For increased style, consider using qw() when initializing a mixed word/number array, especially since it will allow you to easily align a multidimensional array's elements
Your first goal for a project like this should be to create a method to output your multidimensional array in a readable format, so you can observe and verify the changes that you're making.
All of that gives the following changes:
use strict;
use warnings;
my #verwbez = (
[qw(- B E G I K L P S )],
[qw(B - 10 10 2 10 10 10 10)],
[qw(E 10 - 2 10 10 10 1 10)],
[qw(G 10 2 - 10 2 3 3 3 )],
[qw(I 2 10 10 - 4 10 10 2 )],
[qw(K 10 10 2 4 - 10 10 3 )],
[qw(L 10 10 3 10 10 - 2 2 )],
[qw(P 10 1 3 10 10 2 - 10)],
[qw(S 10 10 3 2 3 2 10 - )],
);
for my $i (0 .. $#verwbez) {
for my $j (0 .. $#{$verwbez[$i]}) {
if ($verwbez[$i][$j] =~ /\d/ && $verwbez[$i][$j] >= 7) {
$verwbez[$i][$j] = ".";
}
}
}
for (#verwbez) {
for (#$_) {
printf "%2s ", $_;
}
print "\n";
}
Outputs:
- B E G I K L P S
B - . . 2 . . . .
E . - 2 . . . 1 .
G . 2 - . 2 3 3 3
I 2 . . - 4 . . 2
K . . 2 4 - . . 3
L . . 3 . . - 2 2
P . 1 3 . . 2 - .
S . . 3 2 3 2 . -
Note that B has only 1 city it's near to. So if the goal was solving the TSP, then there isn't a trivial solution. However, given there are only 8 cities and (n-1)! circular permutations. That gives us just 5,040 permutations, so using brute force would totally work for finding a lowest cost solution.
use strict;
use warnings;
use Algorithm::Combinatorics qw(circular_permutations);
my #verwbez = ( ... already defined ... );
# Create a cost between two cities hash:
my %cost;
for my $i (1..$#verwbez) {
for my $j (1..$#{$verwbez[$i]}) {
$cost{ $verwbez[$i][0] }{ $verwbez[0][$j] } = $verwbez[$i][$j] if $i != $j;
}
}
# Determine all Routes and their cost (sorted)
my #cities = keys %cost;
my #perms = circular_permutations(\#cities);
my #cost_with_perm = sort {$a->[0] <=> $b->[0]} map {
my $perm = $_;
my $prev = $perm->[-1];
my $cost = 0;
for (#$perm) {
$cost += $cost{$_}{$prev};
$prev = $_
}
[$cost, $perm]
} #perms;
# Print out lowest cost routes:
print "Lowest cost is: " . $cost_with_perm[0][0] . "\n";
for (#cost_with_perm) {
last if $_->[0] > $cost_with_perm[0][0];
print join(' ', #{$_->[1]}), "\n";
}
It ends up there are only 2 lowest cost solutions to this setup, and they're mirror images of each other, which makes sense since we didn't filter by direction in our circular permutations. Am intentionally not stating what they are here.

How can we assign letters to numbers

I have the following:
d=[1 2 3 4 5 6 7]
I want Matlab to assign a day name to every number by doing a loop or
any suitable method as follows:
1 =tuesday
2=wednesday
.
.
.
7=monday
the results I am aiming to get after running the program is :
the Matlab window asks the user to enter a number from 1 to 7
n=('enter a number from 1 to 7')
then,
if we enter ,for example, 4 , this means that the printed result is: Friday
or
if we entered , for example , 7, this means that the printed result is: Monday
and so on
Is there any way to do this
regards
You could use a cell array, which allows you to store an array of text strings. The curly bracket is the key:
>> weekdays = {'Mon', 'Tues', 'Weds', 'Thurs', 'Fri', 'Sat', 'Sun'};
>> weekdays{4}
ans =
Thurs
Edit: You can get the relevant number from the user by using MATLAB's input function:
n = input('Enter your number:');
disp(weekdays{n})
Using a map might be one approach:
weekDays = containers.Map({1, 2, 3, 4, 5, 6, 7} , ...
{'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'});
number = input('enter a number from 1 to 7');
disp(sprintf('You did choose %s\n', weekDays(number)));
EDIT:
Using the solution by Bill Cheatham you end up with
weekdays = {'Mon', 'Tues', 'Weds', 'Thurs', 'Fri', 'Sat', 'Sun'};
number = input('enter a number from 1 to 7');
disp(sprintf('You did choose %s\n', weekdays{number}));