Ocaml - unexpected output - output

I have following code presented below:
let str = "AA";;
let i =ref 0;;
let tam_str = String.length str -1;;
let aux_char = 'A';;
let b_aux1 = ref false;;
exception Out_of_loop;;
try
while !i <= tam_str do
let c_r = str.[!i] in
if c_r = aux_char then(
b_aux1 := true;
i := !i +1;
)
else(
b_aux1 := false;
raise Out_of_loop
)
done;
with Out_of_loop ->();
if !b_aux1 then
print_endline "1"
else
print_endline "0";
;;
I expected the program to write the string "1" but it is returning "unit". But I don't understand why ... Can someone explain why?

Be careful of the precedence of the various constructs. You have written
try ...
with Out_of_loop ->
begin
();
if !b_aux1 then ...
end
while I suppose you wanted to write
begin
try ...
with Out_of_loop -> ()
end;
if !b_aux1 then ...

Related

Writing a JSON of different types in Go (int and string)

I'm new to Go and Json, so I might miss a lot of points here.
So what I'm basically trying to do is making a program which performs the simple Fizz-Buzz program and make a JSON out of it.
This program takes two integers (a and b), iterate from a to b (i) and outputs:
"Fizz" if the number is a factor of 3
"Buzz" if the number is a factor of 5
"FizzBuzz" if the number is a factor both and,
i if the number isn't a factor of both
Using this simple code snippet:
func fizzbuzz(a int, b int) string{
str := fmt.Sprint("{\"output\":[")
for i := a ; i <= b; i++ {
if i%5 == 0 && i%3 == 0 {str = fmt.Sprint(str, "\"FizzBuzz\"")
}else if i%3 == 0 {str = fmt.Sprint(str, "\"Fizz\"")
}else if i%5 == 0 {str = fmt.Sprint(str, "\"Buzz\"")
}else {str = fmt.Sprint(str, i)}
str = str + ","
}
str = str[:len(str) - 1]
str = str + "]}"
return str
}
I was able to construct the string that can later on be converted to JSON:
{"output":["FizzBuzz",1,2,"Fizz",4,"Buzz","Fizz",7,8,"Fizz","Buzz",11,"Fizz",13,14,"FizzBuzz"]}
This works fine so far. I'm just wondering, are there any other solutions to making a JSON array of mixed type (integer and strings) on Golang? I've tried struct and marshaling, but a struct seems to have fixed structure.
There are two good options that come to mind.
You can use an interface type.
package main
import (
"encoding/json"
"os"
)
type output struct {
Output []interface{} `json:"output"`
}
func main() {
out := output{
Output: []interface{}{"FizzBuzz", 1, 2, "Fizz"},
}
d, _ := json.Marshal(out)
os.Stdout.Write(d)
}
Output:
{"output":["FizzBuzz",1,2,"Fizz"]}
Or you can use a different JSON library, like gojay, which has a different API for serializing JSON.

How can I avoid passing a lot of parameters into a nested function?

I have read that there is no way how to pass all outer local parameters to a nested function, but maybe there are some hacks to do it anyway? How can I avoid passing a lot of parameters into this function, for example:
let var1 = 5;
let var2 = 12.2;
let var3 = bar();
let var4 = tar() * var1;
// etc ... a lot of variables ...
fn foo() {
// want to have var1, var2, var3, var4 ...
}
What you want is called a closure:
fn main() {
let var1 = 5;
let var2 = 12.2;
let foo = || {
var1 as f64 + var2
};
println!("foo(): {}", foo()); // prints "foo(): 17.2"
}

Guard statements for optionals are nil in swift

I'm parsing json data using SwiftyJson from a weather API. And i have a list of optional data that i added it to a single guard statement to make the code look simpler and more effective. But unfortunately in the list of optionals i sometimes have nil values from the parsed API data, so the statement goes to else and returns nothing. Do i have to put guard else statements to every optional or there is a way to continue and return the found non nil values in the else statement?
Here is my code:
dispatch_async(dispatch_get_main_queue(), {
let jsonContent = JSON(data: data!)
guard let cTemp = jsonContent["currently"]["temperature"].double,
let cFeelsLike = jsonContent["currently"]["apparentTemperature"].double,
let cHumidity = jsonContent["currently"]["humidity"].double,
let cDewPoint = jsonContent["currently"]["dewPoint"].double,
let cPressure = jsonContent["currently"]["pressure"].double,
let cVisibility = jsonContent["currently"]["visibility"].double,
let cWindSpeed = jsonContent["currently"]["windSpeed"].double,
let cWindDirection = jsonContent["currently"]["windBearing"].double,
let cRainChance = jsonContent["currently"]["precipProbability"].double,
let cIconString = jsonContent["currently"]["icon"].string,
let cSummary = jsonContent["currently"]["summary"].string,
let cDailySummary = jsonContent["daily"]["summary"].string
else{
self.messageFrame.removeFromSuperview()
return
}
Here is the code after parsing the data that changes the labels on the storyboard.
if self.segmentedControl.selectedSegmentIndex == 0 {
UIApplication.sharedApplication().applicationIconBadgeNumber = Int(round(cTemp))
self.tempLabel.text = String(Int(round(cTemp))) + "˚"
self.humidityLabel.text = String(Int(round(cHumidity*100))) + "%"
self.pressureLabel.text = String(Int(round(cPressure))) + NSLocalizedString(" mBar", comment: "milli Bar")
self.windSpeedLabel.text = String(Int(round(cWindSpeed))) + NSLocalizedString(" Km/h", comment: "Kilo fe El sa3a")
self.realFeelLabel.text = String(Int(round(cFeelsLike))) + "˚"
self.windDirectionLabel.text = self.windDirectionNotation(cWindDirection)
self.rainChanceLabel.text = String(Int(round(cRainChance * 100))) + "%"
// self.visibilityLabel.text = String(Int(round(cVisibility))) + NSLocalizedString(" Km", comment: "Km")
self.descriptionLabel.text = cSummary
self.descriptionMoreLabel.text = cDailySummary
self.bgImage.image = self.bgPicker(cIconString) //Change BG according to currently weather conditions.
} else {
self.tempLabel.text = String(Int(round(cTemp))) + "˚"
self.humidityLabel.text = String(Int(round(cHumidity*100))) + "%"
self.pressureLabel.text = String(Int(round(cPressure))) + NSLocalizedString(" mBar", comment: "milli Bar")
self.windSpeedLabel.text = String(Int(round(cWindSpeed))) + NSLocalizedString(" mph", comment: "meel fee el sa3a")
self.realFeelLabel.text = String(Int(round(cFeelsLike))) + "˚"
self.windDirectionLabel.text = self.windDirectionNotation(cWindDirection)
self.rainChanceLabel.text = String(Int(round(cRainChance * 100))) + "%"
// self.visibilityLabel.text = String(Int(round(cVisibility))) + NSLocalizedString(" mi", comment: "meel")
self.descriptionLabel.text = cSummary
self.descriptionMoreLabel.text = cDailySummary
self.bgImage.image = self.bgPicker(cIconString) //Change BG according to currently weather conditions.
}
It is legal to set a label's text to nil or an Optional string. So for each item, use Optional chaining to unwrap it and set the corresponding label's text.
Unfortunately I don't know SwiftyJSON, but here's how you would do it if this were simply a Dictionary:
// here is some test data
let content = ["currently":["temperature":"21"]]
let lab = UILabel()
// this is what you would do
lab.text = (content["currently"] as? NSDictionary)?["temperature"] as? String
The point is that last line. If we get nil, we set the label's text to nil and no harm done. If we get our string, we set the label's text to an Optional wrapping that string and no harm done.

Function override

I found something interesting in Go. Let's say I have my package name is mypkg, inside mypkg, I have two functions:
package mypkg
func MyFunc0(){
//...
}
var MyFunc1 = func(){
//...
}
Now in my main package, it is possible to override MyFunc1, like this:
mypkg.MyFunc1 = func(){
// new logic
}
However, it is not possible to override MyFunc0 the same way. So now a question is raised. What are the differences between the two ways of declaring a function? Is this behavior difference intended?
MyFunc0 is a function declaration (https://golang.org/ref/spec#Function_declarations)
MyFunc1 is not a function declaration. It is a variable (https://golang.org/ref/spec#Variable_declarations) of type func (see https://golang.org/ref/spec#Function_types, https://golang.org/ref/spec#Function_literals). It has an initial value, but can be changed to hold a different value/function (as long as function signatures match).
I learning go language (and English :P), and in the tour of go is a exersie: Fibonacci closure
(https://tour.golang.org/moretypes/22)
The result is:
0
1
1
2
3
5
8
13
21
34
The main function is:
func main() {
f := fibonacci()
for i := 0; i < 10; i++ {
fmt.Println(f())
}
}
And my first solution was:
func fibonacci() func() int {
antant := 0
ant := 1
i := 0
return func() int {
var result int
if i == 0 || i == 1 {
result = i
i++
return result
}
result = antant + ant
antant = ant
ant = result
return result
}
}
But I didn't want ask in heach call to f() if was the firsth or second call (if i == 0 || i == 1). The result was a function auto-override:
type doFibonacci func(*doFibonacci) int
func fibonacci() func() int {
antant := 0
ant := 1
i := 0
doFibo := doFibonacci(func(ptrDo *doFibonacci) int {
var result int
if i == 0 || i == 1 {
result = i
i++
return result
}
*ptrDo = func(ptrDo *doFibonacci) int {
var result int
result = antant + ant
antant = ant
ant = result
return result
}
return (*ptrDo)(ptrDo)
})
return func() int {
return doFibo(&doFibo)
}
}
I apologize for my English.

How to parse a JSON array in RAd Studio?

I am trying to parse the following Json document:
[
{"EventType":49,"Code":"234","EventDate":"20050202", "Result":1},
{"EventType":48,"Code":"0120","EventDate":"20130201", "Group":"g1"}
]
I use the following code:
TJSONObject* jsonread0 = (TJSONObject*) TJSONObject::ParseJSONValue(TEncoding::ASCII->GetBytes(Memo1->Lines->Text), 0);
for(int i=0;i<jsonread0->Size();i++)
{
TJSONPair* pair = jsonread0->Get(i);
At this point, pair.JsonValueis NULL. What do I need to do to read the values?
You are not casting the JSON String properly, you must cast as an TJSONArray and then iterate over the elements.
try these samples
Delphi
{$APPTYPE CONSOLE}
uses
DBXJSON,
System.SysUtils;
Const
StrJson =
'['+
'{"EventType":49,"Code":"234","EventDate":"20050202", "Result":1},'+
'{"EventType":48,"Code":"0120","EventDate":"20130201", "Group":"g1"}'+
']';
procedure ParseJson;
var
LJsonArr : TJSONArray;
LJsonValue : TJSONValue;
LItem : TJSONValue;
begin
LJsonArr := TJSONObject.ParseJSONValue(TEncoding.ASCII.GetBytes(StrJson),0) as TJSONArray;
for LJsonValue in LJsonArr do
begin
for LItem in TJSONArray(LJsonValue) do
Writeln(Format('%s : %s',[TJSONPair(LItem).JsonString.Value, TJSONPair(LItem).JsonValue.Value]));
Writeln;
end;
end;
begin
try
ParseJson;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
Readln;
end.
C++ Builder
#include <vcl.h>
#include <windows.h>
#pragma hdrstop
#pragma argsused
#include <tchar.h>
#include <stdio.h>
#include <DBXJSON.hpp>
#include <iostream>
int _tmain(int argc, _TCHAR* argv[])
{
TJSONArray* LJsonArr = (TJSONArray*)TJSONObject::ParseJSONValue(
BytesOf((UnicodeString)"[{\"EventType\":49,\"Code\":\"234\",\"EventDate\":\"20050202\", \"Result\":1}, {\"EventType\":48,\"Code\":\"0120\",\"EventDate\":\"20130201\", \"Group\":\"g1\"}]"),0);
int size = LJsonArr->Size();
for (int i = 0; i < size; ++i)
{
TJSONValue* LJsonValue = LJsonArr->Get(i);
TJSONArray* LJsonArr2 = (TJSONArray*)LJsonValue;
int size2 = LJsonArr2->Size();
for (int j = 0; j < size2; ++j)
{
TJSONValue* LItem = LJsonArr2->Get(j);
TJSONPair* LPair = (TJSONPair*)LItem;
printf("%s %s \n", (UTF8String )(LPair->JsonString->Value()).c_str(), (UTF8String )(LPair->JsonValue->Value()).c_str());
}
}
std::cin.get();
return 0;
}
This will return
EventType : 49
Code : 234
EventDate : 20050202
Result : 1
EventType : 48
Code : 0120
EventDate : 20130201
Group : g1
You have an invalid type cast, so what you're seeing is undefined behavior. A null result is just one of the many possible outcomes you could expect from this code. The ParseJSONValue function in this case should return a TJsonArray, not a TJsonObject. Although both classes have Get methods, they're not interchangeable.
The array's Get method returns a TJsonValue, not a TJsonPair. For this particular data, you can type-cast the value to TJsonObject because your data represents an array of two objects.
Use dynamic_cast or Delphi's as operator to cast from one class to another.
dbExpress JSON parser was told to be heavyweight and sometimes problematic.
Perhaps you can choose some of the number of 3rd-party parsers, for example this shows reading array: http://code.google.com/p/superobject/wiki/first_steps
you can get an array from a JSON string also using the JSonCBuilderBlog Library for C++Builder (free and open source):
UnicodeString JSONSource =
"[{\"EventType\":49,\"Code\":\"234\",\"EventDate\":\"20050202\", \"Result\":1},"
"{\"EventType\":48,\"Code\":\"0120\",\"EventDate\":\"20130201\",\"Group\":\"g1\"}]";
int Type;
UnicodeString Code;
UnicodeString Date;
int Result;
TMetaObject MyArray;
MyArray.Decode(JSONSource);
for(int i=0; i < MyArray.Count(); i++)
{
Type = MyArray[i]["EventType"];
Code = MyArray[i]["Code"];
Date = MyArray[i]["EventDate"];
}
The syntax is very simple, see the following link as reference: JSONCBuilderBlog library.