coffee-script loop efficiency - coffeescript

super simple coffeescript question
circles = []
for coordinate, i in coordinates
circles[i] = new MakeCircle(cnBlue, coordinate.x, coordinate.y, 16, 8, 0, theCanvas.ctx)
This works. But I know that with the syntax candy there is probably and even more coffeescriptish way to write this. Is there a way to write this without using the i?

The canonical CoffeeScript way is to use a for comprehension, which will return an array:
circles = for coordinate in coordinates
new MakeCircle(cnBlue, coordinate.x, coordinate.y, 16, 8, 0, theCanvas.ctx)
Or, on one line:
circles = (new MakeCircle(cnBlue, coordinate.x, coordinate.y, 16, 8, 0, theCanvas.ctx) for coordinate in coordinates)
See Loops and Comprehensions:
Note how because we are assigning the value of the comprehensions to a variable in the example above, CoffeeScript is collecting the result of each iteration into an array.

circles.push(new MakeCircle(cnBlue, coordinate.x, coordinate.y, 16, 8, 0, theCanvas.ctx))
;)

More "coffeescriptish" is writing it on one line :
circles = []
circles[i] = new MakeCircle(cnBlue, coor.x, coor.y, 16, 8, 0, theCanvas.ctx) for coor, i in coordinates
you could remove i when using push
circles = []
mc = (x,y) -> new MakeCircle cnBlue,x,y,16,8,0,theCanvas.ctx
circles.push mc(coor.x,coor.y) for coor in coordinates

You can always use jQuery map:
circles = jQuery.map(coordinates,
(coordinate) -> new MakeCircle(cnBlue, coordinate.x, coordinate.y, 16, 8, 0, theCanvas.ctx)
)
I've never actually written CoffeeScript before, so apologies if that doesn't compile as is. This is definately a more "functional" style way of doing what you want, which I identify with modern javascript.

Related

Very Basic Misunderstanding of for loops in Swift

I'm new to swift. can someone please explain what I'm doing wrong here.
1.
var numbers = [1, 5, 7, 6, 6, 6, 6, 6, 2]
for i in numbers{
print(numbers[i],terminator: "")
}
why doesn't this just print the numbers in the array?
2.
Here I want to set the elements in the array to a random number from 0 to 2, and then print them.
for j in numbers{
numbers[j] = Int.random(in: 0...2)
print(numbers[j],terminator: "")
}
this seems to work, but then if, outside of the for loop, I print them again:
for k in numbers{
print(numbers[k],terminator: "")
}
It outputs different numbers, from 0 to 2
3.
OK so I try a different syntax:
for m in numbers{
print(m,terminator: "")
}
now I get the same numbers every time and they are not from 0 to 2... I'm sure my mistakes are trivial but an explanation would help me out. Thanks.
to achieve what you expect, you need to loop over the indices of the array, like this:
var numbers = [1, 5, 7, 6, 6, 6, 6, 6, 2]
for i in numbers.indices { // <-- here
print(numbers[i])
}
And as mentioned, read the basics of Swift.

Trying to access some elements in an IndexSet

I'm using IndexSet and I'm trying to access some indexes which at times are consecutive and at other times are not.
For example, my set may contain [1, 2, 3, 5, 6, 7, 13, 31]
I want to pull out of the set a range of 3...13, but am having difficulty with the syntax. I've learned how to use the function commands from Apple documentation, by using myIndexSet.sorted(). However, the Apple Documentation does not give an example of how to access a range of elements in the set. The Apple Documentation for accessing elements in the index set are the following:
subscript(Range<IndexSet.Index>)
I've tried a number of ways to write this but can't figure out how to do it right. Can someone show me how to access a range of elements in the set to create a new set? I've tried things such as:
let subset = subscript(Range: myLargerSet.3...13)
but it doesn't seem to work.
Thanks
What you're looking for is the intersection of your IndexSet ([1, 2, 3, 5, 6, 7, 13, 31]) with another IndexSet ([3, 4, ..., 12, 13]):
let yourIndexSet: IndexSet = [1, 2, 3, 5, 6, 7, 13, 31]
let desiredIndexRange = IndexSet(3...13)
let indicesOfInterest = yourIndexSet.intersection(desiredIndexRange)
print(indicesOfInterest.sorted()) // => [3, 5, 6, 7, 13]
One possible solution is to use a filter to create a new IndexSet.
let set = IndexSet(arrayLiteral: 1,2,3,5,6,7,13,31)
let subset = set.filteredIndexSet { (index) -> Bool in
index >= 3 && index <= 13
}
You can access a slice of your original set as follows:
let slice = indexSet[indexSet.indexRange(in: 3...13)]
slice accesses the existing elements in place, so creation of the slice is O(1)

How to generate different random number by scala? and the number should be as short as possible

How to generate different random number by scala? and the number should be as short as possible.I want to generate unique id to label data, in the same time the id should be short enough to save the cost?
Since your requirement is
random number
unique
as short as possible
Then I think you should consider to use scala.util.Random.shuffle, eg,
scala.util.Random.shuffle(1 to 30)
Above code will generate a Vector that contains unique random number (in terms of position) from 1 to 30, eg, Vector(26, 10, 7, 29, 11, 14, 16, 1, 12, 9, 28, 6, 19, 4, 27, 8, 13, 18, 30, 20, 23, 5, 21, 24, 17, 25, 2, 15, 22, 3).
Basically it just fulfill everything you need.
If you prefer to get the result in Set or List, simply call toSet or toList method will do.
nextInt can achieve the same thing but you might need a lot of logic and retry mechanism for it.
Try this:
import util.Random.nextInt
Stream.continually(nextInt(100)).take(10)
or you can check in console the numbers generated:
import util.Random.nextInt
val res = Stream.continually(nextInt(100)).take(10)
res.foreach(println)
So basically you can use "Set" to generate unique random numbers.
val r = scala.util.Random
var temp:Int = 0
var s:Set[Int] = Set()
var i:Int = 0
while(i<n){
temp = r.nextInt(range) //random number will be checked whether it is already in the set or not
if(!s.contains(temp)){ //if the random number is not in the set
s=s+temp; //random number is added in the set
i+=1
}
}
s.toArray //converts the set into array

Using Swift tuples as an alternative to multiple assignment

Is there any performance impact or best practice conflict regarding readablity if I do this in Swift:
var (a, b, c, d) = (0, 0, 0, 0)
Instead of this:
var a = 0, b = 0, c = 0, d = 0
The best practice is to be as clear (to other programmers) as possible with your code.
To be concerned about optimization at the level is just crazy. Donald Knuth: "Premature optimization is the root of all evil (or at least most of it) in programming.".

FPDF print MultiCell() adjacently

I've googled around and found this question very common but I can't seem to find a proper and direct answer. I'm using FPDF and I want to generate tables using MultiCell() since I need the line break property of it. Tried Cell() but it can't read the line break.
$col1="PILOT REMARKS\n\n";
$pdf->MultiCell(189, 10, $col1, 1, 1);
$col2="Pilot's Name and Signature\n".$name;
$pdf->MultiCell(63, 10, $col2, 1);
$pdf->Ln(0);
$col3="Date Prepared\n".$date;
$pdf->MultiCell(63, 10, $col3, 1);
But I can't generate it properly 'cause MultiCell() stacks the result. How can I achieve having MultiCell() printed adjacently with each other in a most simple and easy way?
Found this similar question but it doesn't provide a clear answer. Any help will be appreciated. Thanks in advance.
Try storing the X and Y co-ordinates and then setting them after the write
$x = $pdf->GetX();
$y = $pdf->GetY();
$col1="PILOT REMARKS\n\n";
$pdf->MultiCell(189, 10, $col1, 1, 1);
$pdf->SetXY($x + 189, $y);
$col2="Pilot's Name and Signature\n".$name;
$pdf->MultiCell(63, 10, $col2, 1);
$pdf->Ln(0);
$col3="Date Prepared\n".$date;
$pdf->MultiCell(63, 10, $col3, 1);
Just to add to Danny's answer. I like keeping the Width of each column stored and then use that when executing the SetXY method.
Example:
$x = $this->x;
$y = $this->y;
$push_right = 0;
$this->MultiCell($w = 100,3,"Column\r\nNumber 1",1,'C',1);
$push_right += $w;
$this->SetXY($x + $push_right, $y);
$this->MultiCell($w = 60,3,"Column\r\nNumber 2",1,'C',1);
$push_right += $w;
$this->SetXY($x + $push_right, $y);
$this->MultiCell(0,3,"Column 3\r\nFilling in the Rest",1,'C',1);
You can use SetXY(x,y) function to set cursor in pdf .
$pdf->SetXY(x,y);
Set cursor to print data in pdf
Where x is x-axis value and y is y-axis value
None of these worked for me. I had to SetXY before each element (for some reason it's reseting to the start of the multicell after write of any element). So before each and every element, manually SetXY.
use $pdf->Ln(10);
with $pdf->cell();
Example:
$pdf->cell(100,10,"your content");
$pdf->Ln(10);