How to parse string effectively in a structured manner using Go? - go

I have two maps with a key & value like the below.
Value is a string here, how can I effectively compare the content(value) of each of these gateways and identify that both are not same? Any structured way to achieve this?
Key: Gateway1
Value:
| Attribute | Value |
| ----------------------------- | --------------------|
| ADDRESS | ipv4:10.1.1.1 |
| CERT_EXPIRY_LEAD_TIME | 8 |
| CLIENT_CERT_REQ | TRUE |
| PORT | 5000 |
| SUPPORT_TLS | FALSE |
| TLS_DTLS_VERSION | 1.1 |
| TRANSPORT | TCP |
Key: Gateway2
Value:
| Attribute |Value |
| ----------------------------- |-------------------------|
| ADDRESS | ipv4:10.1.1.2 |
| CERT_EXPIRY_LEAD_TIME | 8 |
| CLIENT_CERT_REQ | TRUE |
| PORT | 4000 |
| SUPPORT_TLS | FALSE |
| TLS_DTLS_VERSION | 1.2 |
| TRANSPORT | TCP |

For comparing maps you could use DeepEqual.
Here is a sample code (basically taken from here)
/* equal */
func main() {
map_1 := map[int]string{
1: "One",
2: "Two",
}
map_2 := map[int]string {
1: "One",
2: "Two",
}
res1 := reflect.DeepEqual(map_1, map_2)
fmt.Println("equal ", res1)
}
/* NOT equal */
func main() {
map_1 := map[int]string{
3: "Three",
4: "Four",
}
map_2 := map[int]string {
1: "One",
2: "Two",
}
res1 := reflect.DeepEqual(map_1, map_2)
fmt.Println("Not equal: ", res1)
}

Related

Print data in form of table

I have a code, that prints values to 3 columns, but i can't print them in straight columns
fmt.Printf("%d | %.1f | %.5f | \n", int(i), x, val)
I'm getting this:
0 | 0.0 | error |
1 | 90.0 | error |
2 | 180.0 | -0.00000 |
3 | 270.0 | 3.94795 |
4 | 360.0 | error |
5 | 450.0 | error |
6 | 540.0 | -0.00000 |
7 | 630.0 | 3.94795 |
8 | 720.0 | error |
I couldn't find a way to do this in go.
You can look at tabwriter
Package tabwriter implements a write filter (tabwriter.Writer) that translates tabbed columns in input into properly aligned text.
package main
import (
"fmt"
"os"
"text/tabwriter"
)
func main() {
w := tabwriter.NewWriter(os.Stdout, 10, 1, 1, ' ', tabwriter.Debug)
fmt.Fprintf(w, "%d\t%v\t%v\t\n", 0, 0.0, "error")
fmt.Fprintf(w, "%d\t%v\t%v\t\n", 0, 90.0, "error")
fmt.Fprintf(w, "%d\t%v\t%v\t\n", 7, 630.0, 3.94795)
w.Flush()
}
https://go.dev/play/p/_u5W46AZ5sq

Ruby adding empty strings to hash for CSV spacing

I have:
hash = {"1"=>["A", "B", "C", ... "Z"], "2"=>["B", "C"], "3"=>["A", "C"]
My goal is to use hash as a source for creating a CSV with columns whose names are a letter of the alphabet and with rows hash(key) = 1,2,3 etc.
I created an array of all hash.values.unshift("")values that serve as row 1 (columns labels).
desired output:
| A | B | C | ... | Z |
1| A | B | C | ... | Z |
2| | B | C | ....... |
3| A | | C | ....... |
Creating CSV:
CSV.open("groups.csv", 'w') do |csv|
csv << row1
hash.each do |v|
csv << v.flatten
end
end
This makes the CSV look almost what I want but There is no spacing to get columns to align.
Any advice on how to make a method for modifying my hash that compares my all [A-Z] against each subsequent hash key (rows) to insert empty strings to provide spacing?
Can Class CSV do it better?
Something like this?
require 'csv'
ALPHA = ('A'..'Z').to_a.freeze
hash={"1"=>ALPHA, "2"=>["B", "C"], "3"=>["A", "C"]}
csv = CSV.generate("", col_sep: "|") do |csv|
csv << [" "] + ALPHA # header
hash.each do |k, v|
alphabet = ALPHA.map { |el| [el, 0] }.to_h
v.each { |el| alphabet[el] += 1 }
csv << [k, *alphabet.map { |k, val| val == 1 ? k : " " }]
end
end
csv.split("\n").each { |row| puts row }
output:
|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z
1|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z
2| |B|C| | | | | | | | | | | | | | | | | | | | | | |
3|A| |C| | | | | | | | | | | | | | | | | | | | | | |
If your values are truly single characters and don't need the CSV escaping, then I recommend bypassing CSV altogether and building the string in plain Ruby.
Assuming you want to align your lines correctly regardless of the number of digits in the row number (e.g. 1, 10, and 100), you can use printf style formatting to guarantee horizontal aligment (assuming your row number width never exceeds the value of ROWNUM_WIDTH).
By the way, I changed the hash's keys to integers, hope that's ok.
#!/usr/bin/env ruby
FIELDS = ('A'..'Z').to_a
DATA = { 1 => FIELDS, 2 => %w(B C), 3 => %w(A C) }
ROWNUM_WIDTH = 3
output = ' ' * ROWNUM_WIDTH + " | #{FIELDS.join(' | ')} |\n"
DATA.each do |rownum, values|
line = "%*d | " % [ROWNUM_WIDTH, rownum]
FIELDS.each do |field|
char = values.include?(field) ? field : ' '
line << "#{char} | "
end
output << line << "\n"
end
puts output
=begin
Outputs:
| A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z |
1 | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z |
2 | | B | C | | | | | | | | | | | | | | | | | | | | | | | |
3 | A | | C | | | | | | | | | | | | | | | | | | | | | | | |
=end
all = [*?A..?Z]
hash = {"1"=>[*?A..?Z], "2"=>["B", "C"], "3"=>["A", "C"]}
hash.map do |k, v|
[k, *all.map { |k| v.include?(k) ? k : ' ' }]
end.unshift([' ', *all]).
map { |row| row.join('|') }
#⇒ [
# [0] " |A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z",
# [1] "1|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z",
# [2] "2| |B|C| | | | | | | | | | | | | | | | | | | | | | | ",
# [3] "3|A| |C| | | | | | | | | | | | | | | | | | | | | | | "
# ]

strings.Split acting weird

I am doing a simple strings.Split on a date.
The format is 2015-10-04
month := strings.Split(date, "-")
output is [2015 10 03].
If I do month[0] it returns 2015 but when I do month[1], it returns
panic: runtime error: index out of range
Though it clearly isn't. Am I using it wrong? Any idea what is going on?
Here's a complete working example:
package main
import "strings"
func main() {
date := "2015-01-02"
month := strings.Split(date, "-")
println(month[0])
println(month[1])
println(month[2])
}
Output:
2015
01
02
Playground
Perhaps you're not using the correct "dash" character? There are lots:
+-------+--------+----------+
| glyph | codes |
+-------+--------+----------+
| - | U+002D | - |
| ֊ | U+058A | ֊ |
| ־ | U+05BE | ־ |
| ᠆ | U+1806 | ᠆ |
| ‐ | U+2010 | ‐ |
| ‑ | U+2011 | ‑ |
| ‒ | U+2012 | ‒ |
| – | U+2013 | – |
| — | U+2014 | — |
| ― | U+2015 | ― |
| ⁻ | U+207B | ⁻ |
| ₋ | U+208B | ₋ |
| − | U+2212 | − |
| ﹘ | U+FE58 | ﹘ |
| ﹣ | U+FE63 | ﹣ |
| - | U+FF0D | - |
+-------+--------+----------+
Here is the code with a different input string, which also throws an index out of bounds exception:
package main
import "strings"
func main() {
date := "2015‐01‐02" // U+2010 dashes
month := strings.Split(date, "-")
println(month[0])
println(month[1])
println(month[2])
}
Playground.

Ruby: trouble with batch variable assignment

Yesterday, I started making a chess program and, trying to save 60-odd lines, decided to try my hand at batch variable assignment. That is, assigning variables through loops. I can't seem to join spot_def_letters[i] with o_s in the correct fashion, though. ($board is scoped for later use)
My code:
spot_def_letters = ["a", "b", "c", "d", "e", "f", "g", "h"]
8.times do
i = 0
o = 1
8.times do
o_s = o.to_s
spot_def_letters[i] + o_s = " "
o += 1
end
end
$board = """
| | | | | | |
#{a8}|#{b8}|#{c8}|#{d8}|#{e8}|#{f8}|#{g8}|#{h8}
| | | | | | |
#{a7}|#{b7}|#{c7}|#{d7}|#{e7}|#{f7}|#{g7}|#{h7}
| | | | | | |
#{a6}|#{b6}|#{c6}|#{d6}|#{e6}|#{f6}|#{g6}|#{h6}
| | | | | | |
#{a5}|#{b5}|#{c5}|#{d5}|#{e5}|#{f5}|#{g5}|#{h5}
| | | | | | |
#{a4}|#{b4}|#{c4}|#{d4}|#{e4}|#{f4}|#{g4}|#{h4}
| | | | | | |
#{a3}|#{b3}|#{c3}|#{d3}|#{e3}|#{f3}|#{g3}|#{h3}
| | | | | | |
#{a2}|#{b2}|#{c2}|#{d2}|#{e2}|#{f2}|#{g2}|#{h2}
| | | | | | |
#{a1}|#{b1}|#{c1}|#{d1}|#{e1}|#{f1}|#{g1}|#{h1}
"""
instead of indexing into string arrays and using a bunch of sneaky, bad-looking code, I decided to use a 64-value array (spots = Array.new(64, " ")) and puts those values.

Format text in sphinx table cells

I have a table I am generating in sphinx for comparing constructs in different languages. I would like to have the cells contain code blocks in each language and have it come out looking like code (at least in a monospaced font). What I have so far is:
+-----------------------------+------------------------+
| Haskell | Scala |
+=============================+========================+
| | do var1<- expn1 | | for {var1 <- expn1; |
| | var2 <- expn2 | | var2 <- expn2; |
| | expn3 | | result <- expn3 |
| | | } yield result |
+-----------------------------+------------------------+
| | do var1 <- expn1 | | for {var1 <- expn1; |
| | var2 <- expn2 | | var2 <- expn2; |
| | return expn3 | | } yield expn3 |
+-----------------------------+------------------------+
| | do var1 <- expn1 >> expn2 | | for {_ <- expn1; |
| | return expn3 | | var1 <- expn2 |
| | | } yield expn3 |
+-----------------------------+------------------------+
This, at least preserves line breaks but it comes out in the same font as the rest of the document which is a little annoying.
Is there any way to convert the cells to some better format?
Did you try using the .. code-block:: directive?
This works fine on my PC using Sphinx 1.4.1:
+----------------------------------+----------------------------------+
| Tweedledee | Tweedledum |
+----------------------------------+----------------------------------+
| .. code-block:: c | .. code-block:: c |
| :caption: foo.c | :caption: bar.c |
| | |
| extern int bar(int y); | extern int foo(int x); |
| int foo(int x) | int bar(int y) |
| { | { |
| return x > 0 ? bar(x-1)+1 | return y > 0 ? foo(x-1)*2 |
| : 0; | : 0; |
| } | } |
+----------------------------------+----------------------------------+

Resources