Appending to a sequence in Ceylon - ceylon

How do I append a single element to a list in Ceylon? I tried the append method like this, but it only accepts another list:
value list = [1,2].append(3); // Integer is not assignable to 'Nothing[]'
Obviously, I can work around by wrapping the element:
value list = [1,2].append([3]);
But I feel there should be a better way...

You must be a Python programmer. The method you are looking for is called withTrailing:
value list = [1,2].withTrailing(3);

Related

Convert List<dynamic> to List<String>

I am getting data from server. The run runtimeType shows that they have type List.
Currently I am using cast<String>() to get List<String>.
But is it's only\right way?
var value = await http.get('http://127.0.0.1:5001/regions');
if(value.statusCode == 200) {
return jsonDecode(value.body)['data'].cast<String>();
}
There are multiple ways, depending on how soon you want an error if the list contains a non-string, and how you're going to use the list.
list.cast<String>() creates a lazy wrapper around the original list. It checks on each read that the value is actually a String. If you plan to read often, all that type checking might be expensive, and if you want an early error if the last element of the list is not a string, it won't do that for you.
List<String>.from(list) creates a new list of String and copies each element from list into the new list, checking along the way that it's actually a String. This approach errs early if a value isn't actually a string. After creation, there are no further type checks. On the other hand, creating a new list costs extra memory.
[for (var s in list) s as String],
[... list.cast<String>()],
<String>[for (var s in list) s],
<String>[... list] are all other ways to create a new list of strings. The last two relies on implicit downcast from dynamic, the first two uses explicit casts.
I recommend using list literals where possible. Here, I'd probably go for the smallest version <String>[...list], if you want a new list. Otherwise .cast<String>() is fine.

Responding checkbox with withItemResponse

My problem is:
const answers = sheet.getSheetValues(2, 2, sheet.getLastRow()-1, sheet.getLastColumn()-1); // Get the information from the sheet
formResponse[i].withItemResponse(items[19].asCheckboxItem().createResponse( answers[i][17])); // add a response to formResponse ,it is a checkbox item
answers[i][17] is an object actually. It has the value "FALSE". I get this error:
Cannot find method createResponse(string).
Even if i write false/true or "false"/"true" or something else , createResponse rejects it with error. When i use boolean i take the same error with the boolean version.
How should i add the checkbox as a response ? Thanks in advance.
I solved the problem with a weird way. Code:
if(answers[i][17] == true)
formResponse[i].withItemResponse(items[19].asCheckboxItem().createResponse( new Array(items[19].asCheckboxItem().getChoices()[0].getValue() )));
The reason behind this:
You need to give the string array, not string itself. And string must be the checkbox title, not true or false. Because we could add more than one checkbox and when it comes to checkboxes responses, how could we choose which one is true or false? So i took the choices and since i have one choice, instead of making it string array in a loop i decide to use only the first item. Since i have one item, array has one element. But it is choice array, so i took the first string and i put it in a new array. Here it is, you have a string array. For multiple checking, you can create a loop that iterates the choice array and add their value(which is string) to a new array. Like:
var strArray = new Array(choiceArray.length);
for(var i=0; i < choiceArray.length; ++i)
strArray[i] = choiceArray[i];
And you can disable some of the for letting it unchecked. It is just a way, you can do more efficient versions.
PS: I think that google apps script has things that enforce the developers to write non-efficient and too many lines of codes. But at the end, the fundamental system is working great and actually if some of us decide to use another language or framework, it could be much slower.

Filling eltType with nil values

So I have a chapel issue i can't seem to figure out. I have a queue that one can set size. The only thing is is that it's setting size and filling the queue with a bunch of 0s (which make's sense). I'm trying to fill the queue with null rather than numerical values so later on when I work on the add method I can check if queue is null. I have attached an image of how everything is set up. Let me know if you guys have any guidance or ideas.
The error that i'm getting is:
error: type mismatch in assignment from string to int(64)
I must be doing it the wrong way here.
The error you are seeing is about the line:
elements[i] = 'nil';
'nil' is a string, not the nil value, which is written as just nil without any quotes. Assigning a string to a slot in an array of int(64) doesn't work, so the compiler issues an error.
In Chapel only classes can have a nil value though, so you'll need to use a different way to keep track of which positions in the elements array are filled.
One way to do that would be to add two new integers to your class that keep track of the first and last positions containing valid values. As you add values to the queue the last position increases, and as you remove values the first position increases. When either of those values passes the end of the array, it wraps around back to the front. If last ever catches first, then the array is full. If first ever catches last then the array is empty.
A few other things I think should be corrected in your code are:
use semaphore.chpl; Use statements work with module names, not filenames, so this should probably be use semaphore;.
If I'm understanding your intent here, this code is trying to set the size of the elements array to 5.
var elementsDomain: domain(1);
var elements: [elementsDomain] eltType = 5;
The array's domain controls the size of the array, so the way to set the array size is through the domain:
var elementsDomain: domain(1) = {0..#5};
var elements: [elementsDomain] eltType;
elementsDomain = (0..capacity - 1); is setting elementsDomain to a range literal value. This works since the domain is 1-dimensional, but to make it more clear, you can set it to a domain literal value instead: {0..capacity - 1}.

AS3: calling a property by name or by reference

I am kinda new to AS and stumbled upon a "funny looking" feature in the documentation:
You can use the Object class to create associative arrays. At its core, an associative array is an instance of the Object class, and each key-value pair is represented by a property and its value. Another reason to declare an associative array using the Object data type is that you can then use an object literal to populate your associative array (but only at the time you declare it). The following example creates an associative array using an object literal, accesses items using both the dot operator and the array access operator, and then adds a new key-value pair by creating a new property:
Copy var myAssocArray:Object = {fname:"John", lname:"Public"};
trace(myAssocArray.fname); // John
trace(myAssocArray["lname"]); // Public
myAssocArray.initial = "Q";
trace(myAssocArray.initial); // Q
from here.
I understand that there are cases where this can be helpful, like this one but with a backround in mostly typesafe languages like Java and C# I am a little bit confused about which access-operator is common practice and why.
Normally I would go with the dot oporator, as it allows me and the compiler to keep track of all given properties and you are save regarding typos.
The code I am looking at right now uses both, with no recognizable pattern, which is even more confusing.
Any input on this? Is one better than the other? Why? When to use which one?
Normally I would go with the dot oporator, as it allows me and the
compiler to keep track of all given properties and you are save
regarding typos.
You are not safe against typos. When you create an Object, any property that you haven't defined/assigned to will just return undefined.
var awd:Object = {}
awd.aaa++ //NaN
awd ['aaa']++ //NaN
The compiler will not catch any attempt to reference a property that hasn't been defined.
I use the [] method almost exclusively because it does everything I would need the . method to do plus more. The biggest advantage for me is that I can access properties via variables.
var awd:Object = {}
var key:String = 'some_key';
awd [key] = 1;
awd.key = 5; //This will literally assign to the 'key' property, not what I want

X++ container to CSV string

I was wondering whether a container with values such as ["abc", 50, myDate, myRealNumber] can be converted to "abc","50","1/1/1900","-50.34" using a single function.
The con2Str global function fails if the input type is anything other than str.
I tried creating my own version of con2str function to use an "anyType" instead of str, but it fails because anyType cannot be assigned a different type after the first assignment.
If such a function exists (it does not), it would have to deal with strings containing quotes etc.
This is all handled in class CommaIo method writeExp.
But it writes to a file of cause.
Regarding your problem with anytype you could use the class SysAnyType which wraps your value in another object so that multiple assignments are possible.