I have a text field and this text field gives me a String and I want to convert this String to a Function. for example >>>
"{
print("a")
}"
this is the String and I want this String to be a function like this>>>
{
print("a")
}
There is a way in my mind.
using textField with text controller to get data after user type
to use that string to make sure that string which user typed will meet two different regex patterns which shown on the pictures.
and then using if..else to invoke print().
RegExp regExp1 = new RegExp("your algorium"); <- to find print
RegExp regExp2 = new RegExp("your algorium"); <- to find "xxxx"
var a = regExp1.hasMatch("{print("a")}")
var b = regExp2.hasMatch("{print("a")}")
if ( a && b)
{
String test = regExp2.stringMatch("{print("a")}").toString()
print(test);
}
For some reason when I input a string with double spaces such as " ", the function does not remove them from the string, nor does it remove them when they are generated by two WUB's in a row
For example:
songDecoder("WUBCATWUBWUBBALLWUB") outputs "CAT_ _BALL" (underscores represent spaces)
I could fix this by other means, but since I have no idea why my current code isn't working I figured I should ask to patch my understanding.
def songDecoder(song:String):String = {
val l = song.indexOf("WUB")
if (song.contains(" ")) {
val e = song.indexOf(" ")
songDecoder(song.patch(e,Nil,1))
}
if (l==0) {
val c = song.patch(l,Nil,3)
songDecoder(c)
}
if (l== -1)
song.trim
else {
val c = song.patch(l,Nil,2)
val b = c.patch(l," ",1)
songDecoder(b)
}
}
The reason it doesn't work is because when you call a recursive method it eventually returns with its result. The code that clears out the double-whitespace doesn't save that result.
if (song.contains(" ")) {
val e = song.indexOf(" ")
songDecoder(song.patch(e,Nil,1)) //send patched song to decoder
} //don't save returned string
//continue with unpatched song
The 2nd if block also recurses without saving the result.
if (l==0) {
val c = song.patch(l,Nil,3)
songDecoder(c) //send patched song to decoder
} //don't save returned string
//continue with unpatched song
You can remove both of those if blocks and you'll get the same results from your method. The only code that effects the output is the final if/else and that's because it is at the end of the method's code block. So whatever the if/else produces that's what the method returns.
if (l== -1)
song.trim //return the final result string
else {
val c = song.patch(l,Nil,2) //remove one WUB
val b = c.patch(l," ",1) //replace with space
songDecoder(b) //return whatever the next recursion returns
}
Just as an FYI, here's a different approach.
def songDecoder(song:String):String =
"(WUB)+".r.replaceAllIn(song, " ").trim
How about something like:
song.split(“(WUB)+”).mkString(“ “).trim
In Chapel, we can set the default value of function formal arguments easily, for example,
proc test( a = 1, b = 2.0, c = "hi" ) {
...
}
and call the function by using keywords also:
test( 10 ); // a = 10, b = 2.0, c = "hi"
test( b = 3.14 ); // a = 1, b = 3.14, c = "hi"
test( c = "yo" ); // a = 1, b = 2.0, c = "yo"
Here, I am wondering if it is possible to define a keyword argument that does not require a predefined default value. More specifically, I would like to write a function that can optionally receive an array depending on cases (e.g., to save intermediate data). Here, the only requirement is that I can check whether the actual argument is passed or not, and there is no need to give the default array value. I imagined something like
proc test( ..., optional d: [] real ) {
if present( d ) then ...;
}
or
proc test( ..., d: [] real = None ) {
if present( d ) then ...;
}
but was not able to find similar things. At the moment, my workaround is to give some dummy default value and check their properties to determine whether an actual argument is passed.
proc test( arr = empty2Dreal ) { ... } // where "empty2Dreal" is a pre-defined global array
or
proc test( arr = reshape( [0.0], {1..1,1..1} ) ) { ... } // some dummy array
}
However, I am wondering whether there might be a more elegant(?) or idiomatic(?) approach...
Edit
As suggested in the comment, it is also convenient to overload several functions to get different interfaces, but at some point I guess I need to pass some "dummy" object to the final (full-fledged) routine and ask the latter to see if the passed object is "dummy" or not... MWE is something like this:
const empty1Dint: [1..0] int;
proc test( x: real, arr: [] int )
{
writeln("test() with 2 args");
writeln(( x, arr ));
// here, I need to check whether the passed object is
// an actual array or not by some predefined rule
if arr.size > 0 then writeln("got a non-empty array");
}
proc test( x: real )
{
writeln("test() with 1 arg");
test( x = x, arr = empty1Dint );
}
var work = [1,2,3,4,5];
test( x = 1.0 );
writeln();
test( x = 1.0, arr = work );
which gives
test() with 1 arg
test() with 2 args
(1.0, )
test() with 2 args
(1.0, 1 2 3 4 5)
got a non-empty array
The corresponding default-value version is
const empty1Dint: [1..0] int;
proc test( x: real, arr: [] int = empty1Dint )
{
writeln("test() with 2 args");
writeln(( x, arr ));
if arr.size > 0 then writeln("got a non-empty array");
}
var work = [1,2,3,4,5];
test( x = 1.0 );
writeln();
test( x = 1.0, arr = work );
which gives
test() with 2 args
(1.0, )
test() with 2 args
(1.0, 1 2 3 4 5)
got a non-empty array
Although the above approach works for arrays, the rule needs to change depending on the type of objects used. So, I was wondering if there is some systematic way, e.g., to pass a "null pointer" or some unique global object to tell the final routine about the presence of the actual data. (But, as noted above, the above approach works for arrays).
Edit 2
Another approach may be simply to pass an additional flag for using the passed array (then there is no need to think much about the nature of the default object, so may be overall simpler...)
const empty1Dint: [1..0] int;
proc test( x: real, arr: [] int = empty1Dint, use_arr = false )
{
writeln( "x= ", x );
if use_arr {
writeln("working with the passed array...");
for i in 1..arr.size do arr[ i ] = i * 10;
}
}
test( x = 1.0 );
writeln();
var work: [1..5] int;
test( x = 2.0, arr = work, use_arr = true );
writeln( "work = ", work );
Edit 3
Following Option 3 in the answer, here is a modified version of my code using _void and void:
proc test( x: real, arr: ?T = _void )
{
writeln( "\ntest():" );
writeln( "x = ", x );
writeln( "arr = ", arr );
writeln( "arr.type = ", arr.type:string );
writeln( "T = ", T:string );
if arr.type != void {
writeln( "doing some checks" );
assert( isArray( arr ) );
}
if arr.type != void {
writeln( "writing arr" );
for i in 1..arr.size do arr[ i ] = i * 10;
}
}
// no optional arg
test( x = 1.0 );
// use an optional arg
var work: [1..5] int;
test( x = 2.0, arr = work );
writeln( "\nmain> work = ", work );
Result:
test():
x = 1.0
arr =
arr.type = void
T = void
test():
x = 2.0
arr = 0 0 0 0 0
arr.type = [domain(1,int(64),false)] int(64)
T = [domain(1,int(64),false)] int(64)
doing some checks
writing arr
main> work = 10 20 30 40 50
This answer discusses 3 answers:
The strategy discussed in the edit of the question.
A strategy using a Box type
A strategy using a generic function with a void default value
My favorite of these options is Option 3.
Option 1
proc test( x: real, arr: [] int = empty1Dint, use_arr = false ) strategy described in the question is reasonable, if a little verbose. The main drawback here is that you'd need more overloads of test if you didn't want the call sites to have to pass use_arr=true or use_arr=false. Here is a simple program that does that:
proc test(optional, hasOptional:bool) {
writeln("in test");
writeln(" optional is ", optional);
if hasOptional == false then
writeln(" note: default was used for optional");
}
proc test(optional) {
test(optional, hasOptional=true);
}
proc test() {
var emptyArray:[1..0] int;
test(emptyArray, hasOptional=false);
}
test();
test([1, 2, 3]);
Option 2
Another alternative is to create a class to store the optional argument data, and pass nil by default.
class Box {
var contents;
}
proc makeArray() {
var A:[1..2] int;
return A;
}
proc emptyBox() {
var A:[1..0] int;
var ret: owned Box(A.type) = nil;
return ret;
}
proc test( optional=emptyBox() ) {
writeln("in test with optional=", optional);
}
test();
test(new owned Box(makeArray()));
Here the main tricky part is that the array type returned by makeArray() and emptyBox() have to match. It'd be possible to use a type alias to have them refer to the same array type, but how exactly that would fit in depends on your application. Another problem with this approach is that it causes the array to be copied in the process of passing such an argument. And, one has to think about where the Box will be destroyed. Is test to hang on to the array value (e.g. storing it in a data structure) or just going to use it temporarily? This is set by the type returned by emptyBox in my example.
It's probably reasonable for the standard library to gain such a Box type but it doesn't have one now.
Option 3
My favorite solution to this problem is a third strategy altogether.
Chapel includes a value of void type called _void. The key is the declaration proc test( optional:?t=_void ). Here test is a generic function - the syntax argument:?t indicates that the argument can have a varied type (which will be available as t within the function). This is necessary to get a generic argument that also has a default value (otherwise the argument will have only the type inferred from the default value).
If no optional argument is provided, it will instantiate with optional having type void. Which makes sense as a way to not pass something. Technically it's not the same as checking if the default value was provided, but I think a call site like test(optional=_void) is reasonably clear at communicating that the value of optional should be ignored (since it's void).
Anyway here is the code:
proc test( optional:?t=_void ) {
writeln("in test");
writeln(" optional is ", optional);
if optional.type == void then
writeln(" note: default was used for optional");
}
test();
test([1, 2, 3]);
I'm trying to get a number from a user. That number is then used to
call another function randomList(n) which takes the given number and
uses it. I keep getting the error exception option. I've read that
adding SOME to the variable declaration or valOf can fix this issue,
but it is not working for me. What do I need to change?
fun getNumber() =
print "Please enter the number of integers: ";
let
val str = valOf (TextIO.inputLine TextIO.stdIn)
val i : int = valOf (Int.fromString str)
in
randomList(i)
end;
getNumber();
The issue here is that fun getNumber() only encompasses the print statement on the following line. You need to enclose the print and the let within parenthesis if you want them to both be a part of getNumber().
For example, the following code compiles and echos the input integer that is passed in via stdin:
fun getNumber() = (
print "Please enter the number of integers: ";
let
val str = valOf (TextIO.inputLine TextIO.stdIn)
val i : int = valOf (Int.fromString str)
in
print(Int.toString(i))
end
);
getNumber();
import Foundation
for i in 1 ... n {
let entry = readLine()!.characters.split(" ").map(String.init)
let name = entry[0]
let phone = Int(entry[1])!
phoneBook[name] = phone``
}
//can someone explain this piece of code`
I assume you know everything else in the code except this line:
let entry = readLine()!.characters.split(" ").map(String.init)
readLine() reads user input and returns it. Let's say the user input is
Sweeper 12345678
using .characters.split(" "), we split the input using a separator. What is this separator? A space (" ")! Now the input has been split into two - "Sweeper" and "12345678".
We want the two split parts to be strings, right? Strings are much more easier to manipulate. Currently the split parts are stored in an array of String.CharacterView.SubSequence. We want to turn each String.CharacterView.SubSequence into a string. That is why we use map. map applies a certain function to everything in a collection. So
.map(String.init)
is like
// this is for demonstration purposes only, not real code
for x in readLine()!.characters.split(" ") {
String.init(x)
}
We have now transformed the whole collection into strings!
There is error in your code replace it like below:
let entry = readLine()!.characters.split(separator: " ").map(String.init)
Alternative to the above code is:
let entry = readLine()!.components(separatedBy: " ")
Example:
var str = "Hello, playground"
let entry = str.characters.split(separator: " ").map(String.init)
print(entry)
Now characters.split with split the characters with the separator you give in above case " "(space). So it will generate an array of characters. And you need to use it as string so you are mapping characters into String type by map().