I am having difficulty in what should be a trivial task of creating an interface array. Here is my code,
var result float64
for i := 0; i < len(diff); i++ {
result += diff[i]
}
result = 1 / (1 + math.Sqrt(result))
id1 := user1.UserId
id2 := user2.UserId
user1.Similar[id2] = [2]interface{id2, result}
user2.Similar[id1] = [2]interface{id1, result}
result is a float and user*.UserId is an int.
My error message is
syntax error: name list not allowed in interface type
For example,
package main
import (
"fmt"
)
func main() {
x, y := 1, "#"
a := [2]interface{}{x, y}
fmt.Println(a)
b := [2]interface{}{0, "x"}
fmt.Println(b)
}
Output:
[1 #]
[0 x]
Related
I have this script:
strategy("My strategy")
var float start_price = na
var float end_price = na
var float[] start_prices = array.new_float(0)
var float[] end_prices = array.new_float(0)
var float p = na
f(x) => math.round(x / 500) * 500
lo = (high + close) / 2
var i = 0
if bar_index == 1
start_price := f(lo)
end_price := f(start_price * 1.015)
else
if close <= start_price
strategy.entry(str.format("Long {0}",i), strategy.long)
array.push(end_prices, end_price)
array.push(start_prices, end_price)
i := i + 1
start_price := start_price - 500
end_price := f(start_price * 1.015)
for j = 0 to (array.size(end_prices) == 0 ? na : array.size(end_prices) - 1)
p := array.get(end_prices, j)
if close >= p
strategy.exit(str.format("Long {0}",j), limit=end_price)
I want to console/debug/display the values in start_prices array
But I can't figure out for the life of me how to do that, there's no console.log or anything like that. I'm a somewhat competent python programmer, but I always use the print()... Anyway, how do people debug in this language?
You can use the tostring() function (str.tostring() in v5) to generate a string of your array. You can then output it into a label or table.
eg.
start_prices_string = str.tostring(start_prices)
debug = label.new(x = bar_index, y = close, style = label.style_label_left, text = start_prices_string)
label.delete(debug[1])
The following code is to concatenate two strings. It is getting compiled but shows errors after elaboration.
Code:
package problems
import chisel3._
import chisel3.util._
class Compare1 extends Module {
val io = IO(new Bundle {
val in1 = Input(Vec(5, UInt(3.W)))
val in2 = Input(Vec(5, UInt(3.W)))
val out = Output(Vec(6, UInt(3.W)))
})
val L = 5
io.out := io.in2
val ml = 4
for (l <- 0 until ml) {
when (io.in2(l) === io.in1(L - ml + l)) {
io.out(l) := io.in1(l)
}
}
val m = (2*L) - ml
for (i <- ml until m) {
io.out(i) := io.in2(i - (L - ml))
}
}
Testbench:
I am poking 19333 and 23599 and expecting 154671
Error:
To sum it up, this is what I get
Errors: 1: in the following tutorials
Tutorial Compare1: exception Connection between sink (Vec(chisel3.core.UInt#80, chisel3.core.UInt#82, chisel3.core.UInt#84, chisel3.core.UInt#86, chisel3.core.UInt#88, chisel3.core.UInt#8a)) and source (Vec(chisel3.core.UInt#6a, chisel3.core.UInt#6c, chisel3.core.UInt#6e, chisel3.core.UInt#70, chisel3.core.UInt#72)) failed #: Sink and Source are different length Vecs.
The error is with the line: io.out := io.in2, io.out is a Vec of length 6 while io.in2 is a Vec of length 5. As the error says, you cannot connect Vecs of different lengths together.
If you wish to connect indices 0 to 4 of io.in2 to io.out, try
for (i <- 0 until io.in2.size) { io.out(i) := io.in2(i) }
I am trying to define a function in scala ( ^ ), which takes 2 values and prints them like
2
x
Here is what I have so far...
class $ (val text2D: Array[Array[Char]])
{
def ^(that: $) =
{
" " ++ s"${this.text2D(0)(0)}" ++
"\n" ++ s"${that.text2D(0)(0)}"
}
def +(that: $) = this.text2D + "+" + that.text2D
override def toString = s"${this.text2D(0)(0)}"
}
object $ {
val array = Array.ofDim[Char](1,1)
def apply(x: String): $ = {
array (0)(0) = x.charAt(0)
new $ (array)
}
}
val x = $("x")
println(x)
val x2 = $("x") ^ $("2")
println(x2)
When I run this, I do not get the output I am expecting, instead I get
2
2
Why is it only taking the second element? Any help would be appreciated.
object creates a singleton, so the (mutable) array that you use is shared between calls to apply. You need to allocate that array inside the apply call.
def apply(x: String): $ = {
val array = Array.ofDim[Char](1,1)
array (0)(0) = x.charAt(0)
new $ (array)
}
Also, slightly unrelated, but I believe you have your arguments backward. To get the output you want, you need
" " ++ s"${that.text2D(0)(0)}" ++
"\n" ++ s"${this.text2D(0)(0)}"
I think what you need is something like this:
class $(val text2D: Array[String]) {
def ^(that: $): $ = {
if (this.text2D.length == 0)
that
else if (that.text2D.length == 0)
this
else {
val thisW = this.text2D(0).length
val thatW = that.text2D(0).length
// cross-pad arrays to have the same width
val padThisRight = " " * thatW
val padThatLeft = " " * thisW
val thisPaddedW = this.text2D.map(_ + padThisRight)
val thatPaddedW = that.text2D.map(padThatLeft + _)
// first lines comes from that!
new $(thatPaddedW ++ thisPaddedW)
}
}
def +(that: $): $ = {
if (this.text2D.length == 0)
that
else if (that.text2D.length == 0)
this
else {
val thisH = this.text2D.length
val thatH = that.text2D.length
val thisW = this.text2D(0).length
val thatW = that.text2D(0).length
// pad arrays to have the same height
val emptyThis = " " * thisW
val emptyThat = " " * thatW
val thisPaddedH = if (thisH >= thatH) this.text2D else Array.fill(thatH - thisH)(emptyThis) ++ this.text2D
val thatPaddedH = if (thisH <= thatH) that.text2D else Array.fill(thisH - thatH)(emptyThat) ++ that.text2D
new $(thisPaddedH.zip(thatPaddedH).map(p => p._1 + p._2))
}
}
override def toString = text2D.mkString("\n")
}
object $ {
def apply(x: String): $ = {
new $(Array[String](x))
}
}
and then
val x2 = $("x") ^ $("2")
println(s"x2:\n$x2")
println("----------------------------")
val z = x2 + $(" + ") + y2
println(s"z:\n$z")
println("----------------------------")
val zz = x2 + $(" + ") + (y2 ^ $("3"))
println(s"zz:\n$zz")
println("----------------------------")
produces following output
x2:
2
x
----------------------------
z:
2 2
x + y
----------------------------
zz:
3
2 2
x + y
----------------------------
The main idea here is that operations on $ produce another instance of $ rather than String (I use String instead of Array[Char] as it seems much easier and has no obvious drawbacks). In such way you don't have to re-parse String splitting it by new lines and have to wonder how to handle cases when the string is not well-aligned. So now operators ^ and + is just an exercise in aligning two 2d-arrays to have either the same width or the same height and then joining them.
With help from many sources, I have a working generic thing for a ring-buffer, with push and read of single elements:
q.ads:
generic
Q_SIZE : POSITIVE;
type T is private;
package Q is
subtype SIZE_TYPE is NATURAL range 0 .. Q_SIZE;
subtype Q_INDEX_TYPE is SIZE_TYPE range 1 .. SIZE_TYPE'last;
type Q_ARRAY_TYPE is array (Q_INDEX_TYPE) of T;
procedure INITIALIZE;
procedure PUSH(element : T);
function READ return T;
end Q;
q.adb:
package body Q is
Q_ARRAY : Q_ARRAY_TYPE;
TAIL : Q_INDEX_TYPE;
HEAD : Q_INDEX_TYPE;
...
end Q;
My test program instantiates the above for bytes and exercises the ring. It is basically as follows:
package body main is
package RING is new Q (15, UNSIGNED.BYTE);
procedure TEST is
byteval : UNSIGNED.BYTE;
begin
byteval := 16;
RING.PUSH(byteval);
...
I would now like to add the ability to pass an array of T in. I've add this to the ADS and ADB files:
procedure PUSH_ARRAY(DATA_ARRAY : Q_ARRAY_TYPE; COUNT : SIZE_TYPE);
My problem is in the test program. I've changed it to this:
BYTE_ARRAY : array (1 .. 10) of UNSIGNED.BYTE;
procedure TEST is begin
-- initialize the first 5 elements of BYTE_ARRAY, then
RING.PUSH_ARRAY(BYTE_ARRAY, 5);
this last line gives me an error message: expected type Q_ARRAY_TYPE defined at Q.ADS:xx. How do I pass a BYTE ARRAY to my method which expects an instance of the generic array?
Question: What is the purpose of SIZE_TYPE?
In Ada, the 'Length attribute will return the size of the array in Natural (the nonnegative Integer subtype). With that in mind, it doesn't seem to make sense to declare an extra subtype with an extra value for the index.
Ring_Buffer.ads
Generic
Type T is private;
Default : T;
Size : Positive;
Package Ring_Buffer is
SubType Index is Positive range 1..Size;
Type Ring is private;
Function Length( Obj : Ring ) return Natural;
Function Pop( Obj : in out Ring ) return T
with Pre => Length(Obj) in Positive,
Post => Length(Obj'Old)-1 = Length(Obj); --' --Highlight fix
Procedure Push( Obj : in out Ring; Item : in T )
with Pre => Length(Obj) < Size,
Post => Length(Obj'Old)+1 = Length(Obj); --'
Private
Type Internal_Data is Array(Index) of T;
Type Ring is record
Start : Positive:= Internal_Data'First; --'
Size : Natural:= 0;
Data : Internal_Data:= (Others => Default);
end record
with Type_Invariant => Ring.Size <= Size;
Function Length( Obj : Ring ) return Natural is
( Obj.Size );
End Ring_Buffer;
Ring_Buffer.adb
Package Body Ring_Buffer is
Function Pop( Obj : in out Ring ) return T is
Begin
return Result : constant T := Obj.Data(Obj.Start) do
Obj.Size:= Natural'Pred( Obj.Size ); --'
Obj.Start:= (if Obj.Start = Size then 1 else Obj.Start + 1);
end return;
End Pop;
Procedure Push( Obj : in out Ring; Item : in T ) is
Begin
Obj.Data( Natural'Succ((Obj.Start-1) + Obj.Size mod Size) ):= Item; --'
Obj.Size:= Obj.Size + 1;
End Push;
End Ring_Buffer;
I'm doing a rather easy example to learn how to use ocaml as an imperative language.
My guess is I messed up with the semicolons but I can't find any mistakes in the code
let sort array =
for index = 0 to (Array.length array -1) do
let boole = ref false;
let pos = ref index;
let max = ref array.(index);
let p = ref !pos;
let m = ref !max;
while !pos <> (Array.lenght array -1 ) do
if array.(!pos) > !max then begin
max := array(!pos);
boole := true;
p := !pos
end
pos := !pos + 1
done;
if (!boole = true) then begin
array.(index) <- max;
array.(pos) <- m
end
done ;;
Thank you.
Edit 1 :
In case someone comes across this question, I'm posting the correct code cause the above didn't sort the array correctly even with the correct syntax:
let sort array =
for index = 0 to (Array.length array -1) do
let boole = ref false in
let pos = ref index in
let max = ref array.(index) in
let p = ref !pos in
let m = ref !max in
for i = !pos to (Array.length array -1) do
if (array.(i) > !max) then begin
pos :=i;
max := array.(!pos);
boole := true;
end;
done;
if (!boole = true) then begin
array.(!pos) <- !m;
array.(!p) <- !max;
end;
done ;;
First off all, there is no let x = y; expression in OCaml, a correct syntax is let x = y in, also you shouldn't forget to dereference your references.
let sort array =
for index = 0 to (Array.length array -1) do
let boole = ref false in
let pos = ref index in
let max = ref array.(index) in
let p = ref !pos in
let m = ref !max in
while !pos <> (Array.length array -1 ) do
if array.(!pos) > !max then begin
max := array.(!pos);
boole := true;
p := !pos
end;
pos := !pos + 1;
done;
if (!boole = true) then begin
array.(index) <- !max;
array.(!pos) <- !m;
end;
done ;;
The following fix in the code may help - at least to get the code compiled - :
let sort toto =
for index = 0 to (Array.length toto - 1) do
let boole = ref false in
let pos = ref index in
let max = ref toto.(index) in
let p = ref !pos in
let m = ref !max in
begin
while !pos <> (Array.length toto - 1 ) do
begin
if (toto.(!pos) > !max) then
begin
max := toto.(!pos);
boole := true;
p := !pos;
end;
pos := !pos + 1;
end
done;
if (!boole = true) then begin
toto.(index) <- !max;
toto.(!pos) <- !m
end
end
done;;
Notably : the declaration of local variable, and also some missing semicolons.
I change the name of the argument (array to toto) - as array is a keyword, but I do not think it is necessary.