Unable to compare byte slices - unit-testing

I am trying to write a unit test case, where I'm using reflect.DeepEqual to compare computed and expected results. One of the entries in the struct is a byte slice and DeepEqual keeps on failing it.
Sample Code https://goplay.space/#OcAPkK-EqDX
package main
import (
"fmt"
"reflect"
)
func main() {
var a = []byte("qwedsa")
var b [6]byte
copy(b[:], a)
fmt.Println(reflect.DeepEqual(a, b), len(a), len(b), cap(a), cap(b))
}

reflect.DeepEqual(a, b) returns false because you are comparing two types.
var a = []byte("qwedsa") //here a is a slice with length 6
var b [6]byte //here b is a array with length 6
You can use different options to Do this as mentioned in below.
reflect.DeepEqual(a, b[:]) //by getting a slice from b array
use this instead of reflect package because reflect is not good for performance as Adrian mentioned in his comment
bytes.Equal(a, b[:])
create b directly as a slice with length of a if there is no need to use it as an array.
var b = make([]byte, len(a))
bytes.Equal(a, b)

This does it:
package main
import "bytes"
func main() {
var (
a = []byte("qwedsa")
b [6]byte
)
copy(b[:], a)
println(bytes.Equal(a, b[:]))
}
https://golang.org/pkg/bytes#Equal

Based on the suggestions you have to convert your byte array to byte slice and use bytes.Equal .Here is the implementation of the same:
package main
import (
"bytes"
"fmt"
)
func main() {
var a = []byte("qwedsa")
var b [6]byte
sliceb := b[:]
copy(sliceb, a)
fmt.Println(bytes.Equal(a, sliceb))
}
Output:
true

Related

Construct a List<Map> object out of multiple List<Any> objects in Kotlin

I have multiple different data classes in kotlin and they are saved in extra lists with the exact same length. Now I want to combine them into a result list which contains them as a map with the same length (1000 entries). I tried it with a for loop and a prefilled list of maps, but that looks a bit messy to me, so I asked myself if there is a cleaner way of doing this, especially with kotlin.
data class One(
val a: Double,
val b: Double,
var c: Double
)
data class Two(
val d: Double,
val e: Double,
)
fun main() {
val oneList: List<One> = listOf(One(1.0, 0.0, 2.0), One(3.0, 5.0, 10.0))
val twoList: List<Two> = listOf(Two(5.0, 2.0), Two(7.0, 1.0))
val results: List<MutableMap<String,Double>> = (0..1).map{ mutableMapOf() }
for(i in 0 .. 1){
results[i]["a"] = oneList[i].a
results[i]["b"] = oneList[i].b
results[i]["c"] = oneList[i].c
results[i]["d"] = twoList[i].d
results[i]["e"] = twoList[i].e
}
}
The problem is, that I have about 10 classes with around 2-3 members in each object, whereby the code would be about 30+ lines... The result should look like this:
[
{
a: 1.0,
b: 0.0,
c: 2.0,
d: 5.0,
e: 2.0
},
{
a: 3.0,
b: 5.0,
c: 10.0,
d: 7.0,
e: 1.0
}
]
You could use .zip in order to link the 2 lists and then directly create the list using .map and a simple mapOf() to create the map.
val results = oneList.zip(twoList).map { (one, two) ->
mapOf("a" to one.a, "b" to one.b, "c" to one.c, "d" to two.d, "e" to two.e)
}
As for actually doing this for a lot of classes ... not 100% sure. You could use reflexion maybe, but that is not something you use in an actual program usually. Another way would be to create a function in each of the classes that would give a map and then just add those maps together in the .map from above. That way, the code would look a bit cleaner. Something along the lines of:
data class One(
val a: Double,
val b: Double,
var c: Double
){
fun toMap(): Map<String, Double> {
return mapOf("a" to a, "b" to b, "c" to c)
}
}
//.....
val results = oneList.zip(twoList).map { (one, two) -> one.toMap() + two.toMap() }
But you'll soon notice that zip doesn't work with more than 2 lists. I would suggest implementing something like this: Zip multiple lists SO. But that as well won't work, since your classes are of a different type. What I would do is create a abstract class with a toMap() fun, and then all the classes that you need there can inherit it. It would look something like this:
abstract class MotherClass(){
abstract fun toMap(): Map<String, Double>
}
data class One(
val a: Double,
val b: Double,
var c: Double
):MotherClass() {
override fun toMap(): Map<String, Double> {
return mapOf("a" to a, "b" to b, "c" to c)
}
}
// ...
val results = zip(oneList, twoList /*, threeList, etc */).map { list -> list.map { it.toMap() } }
So at the end of the day, you want a String representation of a property name, mapped to its value? I think you have two choices there:
use reflection to fetch all the member names, filter on the types you want (e.g. only the Doubles), so your Strings are derived directly from the class at runtime
define a String somewhere that acts as a label for each property, and try to tie it as closely to the class as you can, so it's easy to maintain. Because it's not derived from the property itself, you'll have to keep the property name and its label in sync - there's no inherent connection between the two things that could automate it
You're already doing the latter in your code - you're using hardcoded arbitrary labels like "a" and "b" when building your results map, and that's where you're connecting a label with a property (e.g. results[i]["a"] = oneList[i].a). So here's another way you could approach that!
Kotlin playground
interface Mappable {
// allows us to declare classes as having the property map we're using
abstract val propertyMap: Map<String, Double>
}
data class One(
val a: Double,
val b: Double,
var c: Double
) : Mappable {
// you have to do this association somewhere - may as well be in the class itself
// you could also use reflection to build this map automatically
override val propertyMap = mapOf("a" to a, "b" to b, "c" to c)
}
data class Two(
val d: Double,
val e: Double,
) : Mappable {
override val propertyMap = mapOf("d" to d, "e" to e)
}
fun main() {
val oneList = listOf(One(1.0, 0.0, 2.0), One(3.0, 5.0, 10.0))
val twoList = listOf(Two(5.0, 2.0), Two(7.0, 1.0))
combine(oneList, twoList).forEach(::println)
}
fun combine(vararg lists: List<Mappable>): List<Map<String, Double>> {
// lists could be different lengths, so we go until one of them runs out
val length = lists.minOf { it.size }
return (0 until length).map { index ->
// create a combined map for each index
mutableMapOf<String, Double>().apply {
// visit each list at this index, grabbing the property map from each object
// and adding its contents to the combined map we're building
lists.map { it.elementAt(index).propertyMap }.forEach(this::putAll)
}
}
}
>> {a=1.0, b=0.0, c=2.0, d=5.0, e=2.0}
{a=3.0, b=5.0, c=10.0, d=7.0, e=1.0}
The problem really is that artificial connection you're introducing between a property, and a label you explicitly define for it - which you have to ensure you maintain, and if you don't, you got bugs. I think that's unavoidable unless you use reflection.
Also if by any chance this data is originally coming from something arbitrary like JSON (where the problem of validation and labelling a property is earlier in the chain) you could take a look at Kotlin's map delegate and see if that's a better fit for this approach
import kotlin.reflect.full.declaredMemberProperties
data class One(val a: Double, val b: Double, var c: Double)
data class Two(val d: Double, val e: Double)
val oneList: List<One> = listOf(One(1.0, 0.0, 2.0), One(3.0, 5.0, 10.0))
val twoList: List<Two> = listOf(Two(5.0, 2.0), Two(7.0, 1.0))
fun compounded(vararg lists: List<Any>): List<Map<String, Double>> {
return lists
.mapIndexed { index, _ ->
lists
.flatMap {
it[index]::class.declaredMemberProperties.map { prop ->
mapOf(prop.name to prop.call(it[index]) as Double)
}
}
.fold(mapOf()) { acc, map ->
mutableMapOf<String, Double>().apply { putAll(acc + map) }
}
}
}
val result = compounded(oneList, twoList)

Can one create an object to store multiple domains?

I have some code which I think should look like:
on Locales[0] {
var slice: domain(1) = {0..#widthOfLocaleMatrix};
on Locales[1] {
slice(0) = A.localSubdomain();
}
var localSlice: [slice(0)] int = A[slice(0)];
}
Basically, I am trying to fetch multiple slices of data from the other numLocales - 1 locales. Can I create an object to store the localSubdomain's from all other locales? I think I can work around this, but I was curious.
To store multiple domains, you'll want to create an array of domains (or some other collection of domains). Specifically, the main problem with the code above is that it is seemingly trying to index into a domain ( slice(0) ) -- keep in mind that domains are merely index sets, not arrays/maps from indices to values.
The following sample program creates a distributed array ( A ) whose distribution we want to interrogate and an array of domains ( slicePerLocale ) that we'll use to keep track of who owns what. It populates slicePerLocale via the localSubdomain() query to determine the subdomain that each locale owns and stores that in the respective element of slicePerLocale. Finally, it prints out what it has learned:
use BlockDist;
config const n = 10;
var D = {1..n, 1..n} dmapped Block({1..n, 1..n});
var A: [D] real;
var slicePerLocale: [LocaleSpace] domain(2);
coforall loc in Locales do
on loc do
slicePerLocale[loc.id] = A.localSubdomain();
for (loc, slice) in zip(LocaleSpace, slicePerLocale) do
writeln("locale ", loc, " owns: ", slice);
Running this on four locales with the default problem size of 10 results in:
locale 0 owns: {1..5, 1..5}
locale 1 owns: {1..5, 6..10}
locale 2 owns: {6..10, 1..5}
locale 3 owns: {6..10, 6..10}

Grouping the output of a CouchDB View

I have a map reduce view:
.....
emit( diffYears, doc.xyz );
reduced with _sum.
xyz is then a number which is summed per integer(diffYears).
The output looks roughly like this:
4 1204.9
5 796.19
6 1124.8
7 1112.6
8 1993.62
9 159.26
10 395.41
11 456.05
12 457.97
13 39.80
14 483.68
15 269.469
etc..
What I would like to do is group the results as follows:
Grouping Total per group
0-4 1959.2 i.e add up the xyz's for years 0,1,2,3,4
5-9 3998.5 same for 5,6,7,8,9 ...etc.
10-14 3566.3
I saw a suggestion where a list was used on a view output here: Using a CouchDB view, can I count groups and filter by key range at the same time?
but have been unable to adapt it to get any kind of result.
The code given is:
{
_id: "_design/authors",
views: {
authors_by_date: {
map: function(doc) {
emit(doc.date, doc.author);
}
}
},
lists: {
count_occurrences: function(head, req) {
start({ headers: { "Content-Type": "application/json" }});
var result = {};
var row;
while(row = getRow()) {
var val = row.value;
if(result[val]) result[val]++;
else result[val] = 1;
}
return result;
}
}
}
I substituted var val = row.key in this section:
while(row = getRow()) {
var val = row.value;
if(result[val]) result[val]++;
else result[val] = 1;
}
(although in this case the result is a count.)
This seems to be the way to do it.
(It is like having a startkey and endkey for each grouping which I can do manually, naturally, but not inside a process. Or is there a way of entering multiple start- and endkeys into one GET command???? )
This must be a fairly normal thing to do especially for researchers using statistical analysis.
I assume therefore that it does get done but I cannot locate examples
as far as CouchDB is concerned.
I would appreciate some help with this please or a pointer in the right direction.
Many thanks.
EDIT:
Perhaps the answer lies in a process in 'reduce' to group the output??
You can accomplish what you want using a complex key. The limitation is that the group size is static and needs to be defined in the view.
You'll need a simple step function to create your groups within map like:
var size = 5;
var group = ( doc.diffYears - (doc.diffYears % size)) / size;
emit( [group, doc.diffYears], doc.xyz);
The reduce function can remain _sum.
Now when you query the view use group_level to control the grouping. At group_level=0, everything will be summed and one value will be returned. At group_level=1 you'll receive your desired sums of 0-4, 5-9 etc. At group_level=2 you'll get your original output.

How to transform a Seq[State[S,A]] into State[S, A]

Is there an existing combinator to perform that.
Here is my existing code
private def traverse(states: Seq[State[Set[Tip], Unit]]) : State[Set[Tip], Unit] = {
states.reduce((a,b) => for { _ <- a
bb <- b } yield bb)
}
First, there is a simpler syntax for monadic bind that ignores the value from the first monad—>>:
import scalaz.State
import scalaz.syntax.monad._
val states: List[State[Set[Tip], Unit]] = ???
states.reduce((a, b) => a >> b)
But there is also a special method to do what you want, namely Foldable.sequenceS_:
import scalaz.State
import scalaz.std.iterable._
import scalaz.syntax.foldable._
val states: List[State[Set[Tip], Unit]] = ???
states.sequenceS_[Set[Tip], Unit]

Does Go have "if x in" construct similar to Python?

How can I check if x is in an array without iterating over the entire array, using Go? Does the language have a construct for this?
Like in Python:
if "x" in array:
# do something
There is no built-in operator to do it in Go. You need to iterate over the array. You can write your own function to do it, like this:
func stringInSlice(a string, list []string) bool {
for _, b := range list {
if b == a {
return true
}
}
return false
}
Or in Go 1.18 or newer, you can use slices.Contains (from golang.org/x/exp/slices).
If you want to be able to check for membership without iterating over the whole list, you need to use a map instead of an array or slice, like this:
visitedURL := map[string]bool {
"http://www.google.com": true,
"https://paypal.com": true,
}
if visitedURL[thisSite] {
fmt.Println("Already been here.")
}
Another solution if the list contains static values.
eg: checking for a valid value from a list of valid values:
func IsValidCategory(category string) bool {
switch category {
case
"auto",
"news",
"sport",
"music":
return true
}
return false
}
This is quote from the book "Programming in Go: Creating Applications for the 21st Century":
Using a simple linear search like this is the only option for unsorted
data and is fine for small slices (up to hundreds of items). But for
larger slices—especially if we are performing searches repeatedly—the
linear search is very inefficient, on average requiring half the items
to be compared each time.
Go provides a sort.Search() method which uses the binary search
algorithm: This requires the comparison of only log2(n) items (where n
is the number of items) each time. To put this in perspective, a
linear search of 1000000 items requires 500000 comparisons on average,
with a worst case of 1000000 comparisons; a binary search needs at
most 20 comparisons, even in the worst case.
files := []string{"Test.conf", "util.go", "Makefile", "misc.go", "main.go"}
target := "Makefile"
sort.Strings(files)
i := sort.Search(len(files),
func(i int) bool { return files[i] >= target })
if i < len(files) && files[i] == target {
fmt.Printf("found \"%s\" at files[%d]\n", files[i], i)
}
https://play.golang.org/p/UIndYQ8FeW
Just had a similar question and decided to try out some of the suggestions in this thread.
I've benchmarked best and worst-case scenarios of 3 types of lookup:
using a map
using a list
using a switch statement
Here's the function code:
func belongsToMap(lookup string) bool {
list := map[string]bool{
"900898296857": true,
"900898302052": true,
"900898296492": true,
"900898296850": true,
"900898296703": true,
"900898296633": true,
"900898296613": true,
"900898296615": true,
"900898296620": true,
"900898296636": true,
}
if _, ok := list[lookup]; ok {
return true
} else {
return false
}
}
func belongsToList(lookup string) bool {
list := []string{
"900898296857",
"900898302052",
"900898296492",
"900898296850",
"900898296703",
"900898296633",
"900898296613",
"900898296615",
"900898296620",
"900898296636",
}
for _, val := range list {
if val == lookup {
return true
}
}
return false
}
func belongsToSwitch(lookup string) bool {
switch lookup {
case
"900898296857",
"900898302052",
"900898296492",
"900898296850",
"900898296703",
"900898296633",
"900898296613",
"900898296615",
"900898296620",
"900898296636":
return true
}
return false
}
Best-case scenarios pick the first item in lists, worst-case ones use nonexistent value.
Here are the results:
BenchmarkBelongsToMapWorstCase-4 2000000 787 ns/op
BenchmarkBelongsToSwitchWorstCase-4 2000000000 0.35 ns/op
BenchmarkBelongsToListWorstCase-4 100000000 14.7 ns/op
BenchmarkBelongsToMapBestCase-4 2000000 683 ns/op
BenchmarkBelongsToSwitchBestCase-4 100000000 10.6 ns/op
BenchmarkBelongsToListBestCase-4 100000000 10.4 ns/op
Switch wins all the way, worst case is surpassingly quicker than best case.
Maps are the worst and list is closer to switch.
So the moral is:
If you have a static, reasonably small list, switch statement is the way to go.
The above example using sort is close, but in the case of strings simply use SearchString:
files := []string{"Test.conf", "util.go", "Makefile", "misc.go", "main.go"}
target := "Makefile"
sort.Strings(files)
i := sort.SearchStrings(files, target)
if i < len(files) && files[i] == target {
fmt.Printf("found \"%s\" at files[%d]\n", files[i], i)
}
https://golang.org/pkg/sort/#SearchStrings
This is as close as I can get to the natural feel of Python's "in" operator. You have to define your own type. Then you can extend the functionality of that type by adding a method like "has" which behaves like you'd hope.
package main
import "fmt"
type StrSlice []string
func (list StrSlice) Has(a string) bool {
for _, b := range list {
if b == a {
return true
}
}
return false
}
func main() {
var testList = StrSlice{"The", "big", "dog", "has", "fleas"}
if testList.Has("dog") {
fmt.Println("Yay!")
}
}
I have a utility library where I define a few common things like this for several types of slices, like those containing integers or my own other structs.
Yes, it runs in linear time, but that's not the point. The point is to ask and learn what common language constructs Go has and doesn't have. It's a good exercise. Whether this answer is silly or useful is up to the reader.
Another option is using a map as a set. You use just the keys and having the value be something like a boolean that's always true. Then you can easily check if the map contains the key or not. This is useful if you need the behavior of a set, where if you add a value multiple times it's only in the set once.
Here's a simple example where I add random numbers as keys to a map. If the same number is generated more than once it doesn't matter, it will only appear in the final map once. Then I use a simple if check to see if a key is in the map or not.
package main
import (
"fmt"
"math/rand"
)
func main() {
var MAX int = 10
m := make(map[int]bool)
for i := 0; i <= MAX; i++ {
m[rand.Intn(MAX)] = true
}
for i := 0; i <= MAX; i++ {
if _, ok := m[i]; ok {
fmt.Printf("%v is in map\n", i)
} else {
fmt.Printf("%v is not in map\n", i)
}
}
}
Here it is on the go playground
In Go 1.18+, you can now declare generic Contains function which is also implemented in the experimental slice function. It works for any comparable type
func Contains[T comparable](arr []T, x T) bool {
for _, v := range arr {
if v == x {
return true
}
}
return false
}
and use it like this:
if Contains(arr, "x") {
// do something
}
// or
if slices.Contains(arr, "x") {
// do something
}
which I found here
try lo: https://github.com/samber/lo#contains
present := lo.Contains[int]([]int{0, 1, 2, 3, 4, 5}, 5)