Print data in form of table - go

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

Related

How to parse string effectively in a structured manner using 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)
}

how to delete few rows of data from a text file using shell scripting based on some conditions

I have a text file with more than 100k rows. Below mentioned data is a sample for the text file I have. I want to use some conditions on this data and delete some rows. The text file does not have headers (ID,NAME,Code-1,code,2-code-3). I mentioned for reference. How can I achieve this with shell scripting?
Input test file:
| ID | NAME | Code-1 | code-2 | code-3 |
| $$ | 5HF | 1E | N | Y |
| $$ | 2MU | 3C | N | Y |
| $$ | 32E | 3C | N | N |
| AB | 3CH | 3C | N | N |
| MK | A1M | AS | P | N |
| $$ | Y01 | 01 | F | Y |
| $$ | BG0 | 0G | F | N |
Conditions:
if code-2 = 'N' and code-1 not equal to ( '3C' , '3B' , '32' , '31' , '3D' ) then ID='$$'
if code-2 ='N' and code-1 equal to ( '3C' , '3B' , '32' , '31' , '3D') then accept any ID and (accept ID='$$' only if code-3='Y')'
if code-2 != 'N' then accept (ID='$$' only if code-3='Y') and all other IDs
Output:
| ID | NAME | Code-1 | code-2 | code-3 |
| $$ | 5HF | 1E | N | Y |
| $$ | 2MU | 3C | N | Y |
| AB | 3CH | 3C | N | N |
| MK | A1M | AS | P | N |
| $$ | Y01 | 01 | F | Y |
It's encouraged you demonstrate own efforts when ask questions. But I do understand this question could be complicated if you are new to Bash. Here is my solution using awk. Spent 0.545s processed 137k lines on my computer (with moderate specs).
awk '{
ID=$2; NAME=$4; CODE1=$6; CODE2=$8; CODE3=$10;
if (CODE2 == "N") {
if (CODE1 ~ /(3C|3B|32|31|3D)/) {
if (ID == "$$") {
if (CODE3 == "Y") {
print;
}
}
else {
print;
}
}
else {
if (ID == "$$") {
print;
}
}
}
else {
if (ID == "$$") {
if (CODE3 == "Y") {
print;
}
}
else {
print;
}
}}' file
Note it has certain restrictions:
a) It delimits values by spaces not |. It will work with your exact input format, but won't work with input rows without additional spaces, e.g.
|$$|32E|3C|N|N|
|AB|3CH|3C|N|N|
b) For the same reason, the command will generate incorrect result, if col value has extra spaces, e.g.
| $$ | 32E FOO | 3C | N | N |
| AB | 3CH BBT | 3C | N | N |

How to split a row where there's 2 data in each cells separated by a carriage return?

Someone gives me a file with, sometimes, inadequate data.
Data should be like this :
+---------+-----------+--------+
| Name | Initial | Age |
+---------+-----------+--------+
| Jack | J | 43 |
+---------+-----------+--------+
| Nicole | N | 12 |
+---------+-----------+--------+
| Mark | M | 22 |
+---------+-----------+--------+
| Karine | K | 25 |
+---------+-----------+--------+
Sometimes it comes like this tho :
+---------+-----------+--------+
| Name | Initial | Age |
+---------+-----------+--------+
| Jack | J | 43 |
+---------+-----------+--------+
| Nicole | N | 12 |
| Mark | M | 22 |
+---------+-----------+--------+
| Karine | K | 25 |
+---------+-----------+--------+
As you can see, Nicole and Mark are put in the same row, but the data are separated by a carriage return.
I can do split by row, but it demultiply the data :
+---------+-----------+--------+
| Nicole | N | 12 |
| | M | 22 |
+---------+-----------+--------+
| Mark | N | 12 |
| | M | 22 |
+---------+-----------+--------+
Which make me lose that Mark is associated with the "2nd row" of data.
(The data here is purely an example)
One way to do this is to transform each cell into a list by doing a Text.Split on the line feed / carriage return symbol.
TextSplit = Table.TransformColumns(Source,
{
{"Name", each Text.Split(_,"#(lf)"), type text},
{"Initial", each Text.Split(_,"#(lf)"), type text},
{"Age", each Text.Split(_,"#(lf)"), type text}
}
)
Now each column is a list of lists which you can combine into one long list using List.Combine and you can glue these columns together to make table with Table.FromColumns.
= Table.FromColumns(
{
List.Combine(TextSplit[Name]),
List.Combine(TextSplit[Initial]),
List.Combine(TextSplit[Age])
},
{"Name", "Initial", "Age"}
)
Putting this together, the whole query looks like this:
let
Source = <Your data source>
TextSplit = Table.TransformColumns(Source,{{"Name", each Text.Split(_,"#(lf)"), type text},{"Initial", each Text.Split(_,"#(lf)"), type text},{"Age", each Text.Split(_,"#(lf)"), type text}}),
FromColumns = Table.FromColumns({List.Combine(TextSplit[Name]),List.Combine(TextSplit[Initial]),List.Combine(TextSplit[Age])},{"Name","Initial","Age"})
in
FromColumns

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.

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