diff --git a/answers.tex b/answers.tex index cb5a7ef..5493921 100644 --- a/answers.tex +++ b/answers.tex @@ -11,49 +11,14 @@ \section*{Chapter 2: Quick Start} \textbf{Solution:} -\begin{lstlisting}[numbers=none] -package main - -import "fmt" - -func StartsCapital(s string) bool { - for _, v := range "ABCDEFGHIJKLMNOPQRSTUVWXYZ" { - if string(s[0]) == string(v) { - return true - } - } - return false -} - -func main() { - h := StartsCapital("Hello") - fmt.Println(h) - w := StartsCapital("world") - fmt.Println(w) -} -\end{lstlisting} +\lstinputlisting[numbers=none]{code/answers/quick-start/capital.go} \textbf{Problem 2:} Write a function to generate Fibonacci numbers below a given value. \textbf{Solution:} -\begin{lstlisting}[numbers=none] -package main - -import "fmt" - -func Fib(n int) { - for i, j := 0, 1; i < n; i, j = i+j, i { - fmt.Println(i) - } - -} - -func main() { - Fib(200) -} -\end{lstlisting} +\lstinputlisting[numbers=none]{code/answers/quick-start/fibonacci.go} \section*{Chapter 3: Control Structures} @@ -62,26 +27,7 @@ \section*{Chapter 3: Control Structures} \textbf{Solution:} -\begin{lstlisting}[numbers=none] -package main - -import ( - "fmt" - "time" -) - -func main() { - t := time.Now() - switch { - case t.Hour() < 12: - fmt.Println("Good morning!") - case t.Hour() < 17: - fmt.Println("Good afternoon.") - default: - fmt.Println("Good evening.") - } -} -\end{lstlisting} +\lstinputlisting[numbers=none]{code/answers/control-structures/greetings.go} \textbf{Problem 2:} Write a program to check if a given number is a multiple of 2, 3, or 5. @@ -112,25 +58,7 @@ \section*{Chapter 5: Functions \& Methods} \textbf{Solution:} -\begin{lstlisting}[numbers=none] -package main - -import "fmt" - -type Circle struct { - Radius float64 -} - -// Area return the area of a circle for the given radius -func (c Circle) Area() float64 { - return 3.14 * c.Radius * c.Radius -} - -func main() { - c := Circle{5.0} - fmt.Println(c.Area()) -} -\end{lstlisting} +\lstinputlisting[numbers=none]{code/answers/functions/circle.go} \section*{Chapter 6: Interfaces} @@ -144,30 +72,7 @@ \section*{Chapter 6: Interfaces} \textbf{Solution:} -\begin{lstlisting}[numbers=none] -package main - -import "fmt" - -type UnauthorizedError struct { - UserID string -} - -func (e UnauthorizedError) Error() string { - return "User not authorised: " + e.UserID -} - -func SomeAction() error { - return UnauthorizedError{"jack"} -} - -func main() { - err := SomeAction() - if err != nil { - fmt.Println(err) - } -} -\end{lstlisting} +\lstinputlisting[numbers=none]{code/answers/interfaces/error.go} \section*{Chapter 7: Concurrency} @@ -176,60 +81,7 @@ \section*{Chapter 7: Concurrency} \textbf{Solution:} -\begin{lstlisting}[numbers=none] -package main - -import ( - "bufio" - "fmt" - "os" - "os/signal" - "strings" - "time" -) - -func watch(word, fp string) error { - - f, err := os.Open(fp) - if err != nil { - return err - } - r := bufio.NewReader(f) - defer f.Close() - for { - line, err := r.ReadBytes('\n') - if err != nil { - if err.Error() == "EOF" { - time.Sleep(2 * time.Second) - continue - } - fmt.Printf("Error: %s\n%v\n", line, err) - } - if strings.Contains(string(line), word) { - fmt.Printf("%s: Matched: %s\n", fp, line) - } - time.Sleep(2 * time.Second) - } -} - -func main() { - word := os.Args[1] - files := []string{} - for _, f := range os.Args[2:len(os.Args)] { - files = append(files, f) - go watch(word, f) - } - sig := make(chan os.Signal, 1) - done := make(chan bool) - signal.Notify(sig, os.Interrupt) - go func() { - for _ = range sig { - done <- true - } - }() - <-done -} -\end{lstlisting} +\lstinputlisting[numbers=none]{code/answers/concurrency/watchlog.go} \section*{Chapter 8: Packages} @@ -241,60 +93,19 @@ \section*{Chapter 8: Packages} circle.go: -\begin{lstlisting}[numbers=none] -package shape - -// Circle represents a circle shape -type Circle struct { - Radius float64 -} - -// Area return the area of a circle -func (c Circle) Area() float64 { - return 3.14 * c.Radius * c.Radius -} -\end{lstlisting} +\lstinputlisting[numbers=none]{code/answers/packages/docs/circle.go} rectangle.go: -\begin{lstlisting}[numbers=none] -package shape - -// Rectangle represents a rectangle shape -type Rectangle struct { - Length float64 - Width float64 -} - -// Area return the area of a rectangle -func (r Rectangle) Area() float64 { - return r.Length * r.Width -} -\end{lstlisting} +\lstinputlisting[numbers=none]{code/answers/packages/docs/rectangle.go} triangle.go: -\begin{lstlisting}[numbers=none] -package shape - -// Triangle represents a rectangle shape -type Triangle struct { - Breadth float64 - Height float64 -} - -// Area return the area of a triangle -func (t Triangle) Area() float64 { - return (t.Breadth * t.Height)/2 -} -\end{lstlisting} +\lstinputlisting[numbers=none]{code/answers/packages/docs/triangle.go} doc.go: -\begin{lstlisting}[numbers=none] -// Package shape provides areas for different shapes -// This includes circle, rectangle, and triangle. -\end{lstlisting} +\lstinputlisting[numbers=none]{code/answers/packages/docs/doc.go} \section*{Chapter 9: Input/Output} @@ -331,20 +142,7 @@ \section*{Chapter 11: Tooling} Here is the package definition for a circle object: -\begin{lstlisting}[numbers=none] -// Package defines a circle object -package circle - -// Circle represents a circle shape -type Circle struct { - Radius float64 -} - -// Area return the area of a circle -func (c Circle) Area() float64 { - return 3.14 * c.Radius * c.Radius -} -\end{lstlisting} +\lstinputlisting[numbers=none]{code/answers/tooling/circle.go} The docs can be accessed like this: diff --git a/code/answers/concurrency/watchlog.go b/code/answers/concurrency/watchlog.go new file mode 100644 index 0000000..7da1296 --- /dev/null +++ b/code/answers/concurrency/watchlog.go @@ -0,0 +1,52 @@ +package main + +import ( + "bufio" + "fmt" + "os" + "os/signal" + "strings" + "time" +) + +func watch(word, fp string) error { + + f, err := os.Open(fp) + if err != nil { + return err + } + r := bufio.NewReader(f) + defer f.Close() + for { + line, err := r.ReadBytes('\n') + if err != nil { + if err.Error() == "EOF" { + time.Sleep(2 * time.Second) + continue + } + fmt.Printf("Error: %s\n%v\n", line, err) + } + if strings.Contains(string(line), word) { + fmt.Printf("%s: Matched: %s\n", fp, line) + } + time.Sleep(2 * time.Second) + } +} + +func main() { + word := os.Args[1] + files := []string{} + for _, f := range os.Args[2:len(os.Args)] { + files = append(files, f) + go watch(word, f) + } + sig := make(chan os.Signal, 1) + done := make(chan bool) + signal.Notify(sig, os.Interrupt) + go func() { + for _ = range sig { + done <- true + } + }() + <-done +} diff --git a/code/answers/control-structures/greetings.go b/code/answers/control-structures/greetings.go new file mode 100644 index 0000000..f3bbcd8 --- /dev/null +++ b/code/answers/control-structures/greetings.go @@ -0,0 +1,18 @@ +package main + +import ( + "fmt" + "time" +) + +func main() { + t := time.Now() + switch { + case t.Hour() < 12: + fmt.Println("Good morning!") + case t.Hour() < 17: + fmt.Println("Good afternoon.") + default: + fmt.Println("Good evening.") + } +} diff --git a/code/answers/functions/circle.go b/code/answers/functions/circle.go new file mode 100644 index 0000000..0a388d0 --- /dev/null +++ b/code/answers/functions/circle.go @@ -0,0 +1,17 @@ +package main + +import "fmt" + +type Circle struct { + Radius float64 +} + +// Area return the area of a circle for the given radius +func (c Circle) Area() float64 { + return 3.14 * c.Radius * c.Radius +} + +func main() { + c := Circle{5.0} + fmt.Println(c.Area()) +} diff --git a/code/answers/interfaces/error.go b/code/answers/interfaces/error.go new file mode 100644 index 0000000..4e53c0a --- /dev/null +++ b/code/answers/interfaces/error.go @@ -0,0 +1,22 @@ +package main + +import "fmt" + +type UnauthorizedError struct { + UserID string +} + +func (e UnauthorizedError) Error() string { + return "User not authorised: " + e.UserID +} + +func SomeAction() error { + return UnauthorizedError{"jack"} +} + +func main() { + err := SomeAction() + if err != nil { + fmt.Println(err) + } +} diff --git a/code/answers/packages/docs/circle.go b/code/answers/packages/docs/circle.go new file mode 100644 index 0000000..28b48a3 --- /dev/null +++ b/code/answers/packages/docs/circle.go @@ -0,0 +1,11 @@ +package shape + +// Circle represents a circle shape +type Circle struct { + Radius float64 +} + +// Area return the area of a circle +func (c Circle) Area() float64 { + return 3.14 * c.Radius * c.Radius +} diff --git a/code/answers/packages/docs/doc.go b/code/answers/packages/docs/doc.go new file mode 100644 index 0000000..30eaa3a --- /dev/null +++ b/code/answers/packages/docs/doc.go @@ -0,0 +1,2 @@ +// Package shape provides areas for different shapes +// This includes circle, rectangle, and triangle. diff --git a/code/answers/packages/docs/rectangle.go b/code/answers/packages/docs/rectangle.go new file mode 100644 index 0000000..1ca32ef --- /dev/null +++ b/code/answers/packages/docs/rectangle.go @@ -0,0 +1,12 @@ +package shape + +// Rectangle represents a rectangle shape +type Rectangle struct { + Length float64 + Width float64 +} + +// Area return the area of a rectangle +func (r Rectangle) Area() float64 { + return r.Length * r.Width +} diff --git a/code/answers/packages/docs/triangle.go b/code/answers/packages/docs/triangle.go new file mode 100644 index 0000000..8f344b6 --- /dev/null +++ b/code/answers/packages/docs/triangle.go @@ -0,0 +1,12 @@ +package shape + +// Triangle represents a rectangle shape +type Triangle struct { + Breadth float64 + Height float64 +} + +// Area return the area of a triangle +func (t Triangle) Area() float64 { + return (t.Breadth * t.Height)/2 +} diff --git a/code/answers/quick-start/capital.go b/code/answers/quick-start/capital.go new file mode 100644 index 0000000..b692f4f --- /dev/null +++ b/code/answers/quick-start/capital.go @@ -0,0 +1,19 @@ +package main + +import "fmt" + +func StartsCapital(s string) bool { + for _, v := range "ABCDEFGHIJKLMNOPQRSTUVWXYZ" { + if string(s[0]) == string(v) { + return true + } + } + return false +} + +func main() { + h := StartsCapital("Hello") + fmt.Println(h) + w := StartsCapital("world") + fmt.Println(w) +} diff --git a/code/answers/quick-start/fibonacci.go b/code/answers/quick-start/fibonacci.go new file mode 100644 index 0000000..1b35eee --- /dev/null +++ b/code/answers/quick-start/fibonacci.go @@ -0,0 +1,14 @@ +package main + +import "fmt" + +func Fib(n int) { + for i, j := 0, 1; i < n; i, j = i+j, i { + fmt.Println(i) + } + +} + +func main() { + Fib(200) +} diff --git a/code/answers/tooling/circle.go b/code/answers/tooling/circle.go new file mode 100644 index 0000000..4a44f93 --- /dev/null +++ b/code/answers/tooling/circle.go @@ -0,0 +1,12 @@ +// Package defines a circle object +package circle + +// Circle represents a circle shape +type Circle struct { + Radius float64 +} + +// Area return the area of a circle +func (c Circle) Area() float64 { + return 3.14 * c.Radius * c.Radius +} diff --git a/code/io/commandline.go b/code/io/commandline.go new file mode 100644 index 0000000..efb8f70 --- /dev/null +++ b/code/io/commandline.go @@ -0,0 +1,13 @@ +package main + +import ( + "fmt" + "os" +) + +func main() { + fmt.Println(os.Args) + fmt.Println(os.Args[0]) + fmt.Println(os.Args[1]) + fmt.Println(os.Args[2]) +} diff --git a/io.tex b/io.tex index 2007939..524d85c 100644 --- a/io.tex +++ b/io.tex @@ -33,21 +33,7 @@ \section{Command Line Arguments} the command line arguments using the \texttt{Args} array/slice attribute available in \texttt{os} package. Here is an example: -\begin{lstlisting}[numbers=none] -package main - -import ( - "fmt" - "os" -) - -func main() { - fmt.Println(os.Args) - fmt.Println(os.Args[0]) - fmt.Println(os.Args[1]) - fmt.Println(os.Args[2]) -} -\end{lstlisting} +\lstinputlisting[numbers=none]{code/io/commandline.go} You can run this program with minimum two additional arguments: diff --git a/quickstart.tex b/quickstart.tex index 64b58e6..d542830 100644 --- a/quickstart.tex +++ b/quickstart.tex @@ -7,13 +7,12 @@ \chapter{Quick Start} and other programmers.} -- Russ Cox \end{quote} -This chapter walks through few basic topics in Go. You should be able -to write simple programs using Go after reading and practicing the -examples given in this chapter. The next 3 sections revisit the hello -world program introduced in the last chapter. Later we will move on -to few basic topics in Go. We will learn about data types, variables, -comments, For loop, range clause, If, functions, operators, slices and -maps. +This chapter walks through a few basic topics in Go. You should be able to write +simple programs using Go after reading and practicing the examples given in this +chapter. The next 3 sections revisit the hello world program introduced in the +last chapter. Later we will move on to a few basic topics in Go. We will learn +about data types, variables, comments, For loops, range clauses, If, functions, +operators, slices, and maps. \section{Hello World!} @@ -169,7 +168,7 @@ \section{Organizing Code} packages that are released together. To understand the code organization, you also need to understand about Go -module. A file named go.mod there declares the module path: the import path +module. A file named \textit{go.mod} declares the module path: the import path prefix for all packages within the module. The module contains the packages in the directory containing its go.mod file as well as subdirectories of that directory, up to the next subdirectory containing another go.mod file (if any). diff --git a/scripts/code_block.py b/scripts/code_block.py index af978ef..f19fd77 100644 --- a/scripts/code_block.py +++ b/scripts/code_block.py @@ -37,7 +37,8 @@ def update_code_block(): if line.startswith(".. code:: go"): new_line = line.replace(".. code:: go", ".. code-block:: go") new_rst_lines.append(new_line) - new_rst_lines.append(" :linenos:\n") + if rst_file != "sphinx/answers.rst": + new_rst_lines.append(" :linenos:\n") continue found_figure = False if rst_file in images_map: diff --git a/sphinx/answers.rst b/sphinx/answers.rst index 38f4331..663bd4e 100644 --- a/sphinx/answers.rst +++ b/sphinx/answers.rst @@ -9,26 +9,26 @@ given string is capital letters in English (A,B,C,D etc). **Solution:** -:: +.. code-block:: go package main import "fmt" func StartsCapital(s string) bool { - for _, v := range "ABCDEFGHIJKLMNOPQRSTUVWXYZ" { - if string(s[0]) == string(v) { - return true - } - } - return false + for _, v := range "ABCDEFGHIJKLMNOPQRSTUVWXYZ" { + if string(s[0]) == string(v) { + return true + } + } + return false } func main() { - h := StartsCapital("Hello") - fmt.Println(h) - w := StartsCapital("world") - fmt.Println(w) + h := StartsCapital("Hello") + fmt.Println(h) + w := StartsCapital("world") + fmt.Println(w) } **Problem 2:** Write a function to generate Fibonacci numbers below a @@ -36,21 +36,21 @@ given value. **Solution:** -:: +.. code-block:: go package main import "fmt" func Fib(n int) { - for i, j := 0, 1; i < n; i, j = i+j, i { - fmt.Println(i) - } + for i, j := 0, 1; i < n; i, j = i+j, i { + fmt.Println(i) + } } func main() { - Fib(200) + Fib(200) } Chapter 3: Control Structures @@ -61,25 +61,25 @@ Possible greetings are Good morning, Good afternoon and Good evening. **Solution:** -:: +.. code-block:: go package main import ( - "fmt" - "time" + "fmt" + "time" ) func main() { - t := time.Now() - switch { - case t.Hour() < 12: - fmt.Println("Good morning!") - case t.Hour() < 17: - fmt.Println("Good afternoon.") - default: - fmt.Println("Good evening.") - } + t := time.Now() + switch { + case t.Hour() < 12: + fmt.Println("Good morning!") + case t.Hour() < 17: + fmt.Println("Good afternoon.") + default: + fmt.Println("Good evening.") + } } **Problem 2:** Write a program to check if a given number is a multiple @@ -88,7 +88,6 @@ of 2, 3, or 5. **Solution:** .. code-block:: go - :linenos: package main @@ -119,7 +118,6 @@ locations and functionality to check whether its freezing or not. **Solution:** .. code-block:: go - :linenos: package main @@ -158,7 +156,6 @@ capital, currency, and population. **Solution:** .. code-block:: go - :linenos: package main @@ -185,24 +182,24 @@ a circle. **Solution:** -:: +.. code-block:: go package main import "fmt" type Circle struct { - Radius float64 + Radius float64 } // Area return the area of a circle for the given radius func (c Circle) Area() float64 { - return 3.14 * c.Radius * c.Radius + return 3.14 * c.Radius * c.Radius } func main() { - c := Circle{5.0} - fmt.Println(c.Area()) + c := Circle{5.0} + fmt.Println(c.Area()) } Chapter 6: Interfaces @@ -219,29 +216,29 @@ data type. This is how the ``error`` interface is defined: **Solution:** -:: +.. code-block:: go package main import "fmt" type UnauthorizedError struct { - UserID string + UserID string } func (e UnauthorizedError) Error() string { - return "User not authorised: " + e.UserID + return "User not authorised: " + e.UserID } func SomeAction() error { - return UnauthorizedError{"jack"} + return UnauthorizedError{"jack"} } func main() { - err := SomeAction() - if err != nil { - fmt.Println(err) - } + err := SomeAction() + if err != nil { + fmt.Println(err) + } } Chapter 7: Concurrency @@ -252,7 +249,7 @@ with a particular word. **Solution:** -:: +.. code-block:: go package main @@ -318,57 +315,57 @@ areas for circle, rectangle, and triangle. circle.go: -:: +.. code-block:: go package shape // Circle represents a circle shape type Circle struct { - Radius float64 + Radius float64 } // Area return the area of a circle func (c Circle) Area() float64 { - return 3.14 * c.Radius * c.Radius + return 3.14 * c.Radius * c.Radius } rectangle.go: -:: +.. code-block:: go package shape // Rectangle represents a rectangle shape type Rectangle struct { - Length float64 - Width float64 + Length float64 + Width float64 } // Area return the area of a rectangle func (r Rectangle) Area() float64 { - return r.Length * r.Width + return r.Length * r.Width } triangle.go: -:: +.. code-block:: go package shape // Triangle represents a rectangle shape type Triangle struct { - Breadth float64 - Height float64 + Breadth float64 + Height float64 } // Area return the area of a triangle func (t Triangle) Area() float64 { - return (t.Breadth * t.Height)/2 + return (t.Breadth * t.Height)/2 } doc.go: -:: +.. code-block:: go // Package shape provides areas for different shapes // This includes circle, rectangle, and triangle. @@ -391,7 +388,6 @@ Use a struct like this to define the complex number: **Solution:** .. code-block:: go - :linenos: package main @@ -420,7 +416,6 @@ remaining tests. **Solution:** .. code-block:: go - :linenos: package main @@ -443,19 +438,19 @@ command. Here is the package definition for a circle object: -:: +.. code-block:: go // Package defines a circle object package circle // Circle represents a circle shape type Circle struct { - Radius float64 + Radius float64 } // Area return the area of a circle func (c Circle) Area() float64 { - return 3.14 * c.Radius * c.Radius + return 3.14 * c.Radius * c.Radius } The docs can be accessed like this: diff --git a/sphinx/io.rst b/sphinx/io.rst index fe8e14b..0118eac 100644 --- a/sphinx/io.rst +++ b/sphinx/io.rst @@ -33,20 +33,21 @@ files and devices. You can access all the command line arguments using the ``Args`` array/slice attribute available in ``os`` package. Here is an example: -:: +.. code-block:: go + :linenos: package main import ( - "fmt" - "os" + "fmt" + "os" ) func main() { - fmt.Println(os.Args) - fmt.Println(os.Args[0]) - fmt.Println(os.Args[1]) - fmt.Println(os.Args[2]) + fmt.Println(os.Args) + fmt.Println(os.Args[0]) + fmt.Println(os.Args[1]) + fmt.Println(os.Args[2]) } You can run this program with minimum two additional arguments: diff --git a/sphinx/quickstart.rst b/sphinx/quickstart.rst index 8fd3623..f027a35 100644 --- a/sphinx/quickstart.rst +++ b/sphinx/quickstart.rst @@ -4,12 +4,13 @@ Quick Start *Software engineering is what happens to programming when you add time, and other programmers.* – Russ Cox -This chapter walks through few basic topics in Go. You should be able to -write simple programs using Go after reading and practicing the examples -given in this chapter. The next 3 sections revisit the hello world -program introduced in the last chapter. Later we will move on to few -basic topics in Go. We will learn about data types, variables, comments, -For loop, range clause, If, functions, operators, slices and maps. +This chapter walks through a few basic topics in Go. You should be able +to write simple programs using Go after reading and practicing the +examples given in this chapter. The next 3 sections revisit the hello +world program introduced in the last chapter. Later we will move on to a +few basic topics in Go. We will learn about data types, variables, +comments, For loops, range clauses, If, functions, operators, slices, +and maps. Hello World! ------------ @@ -178,11 +179,11 @@ however it is possible to add more than one, if necessary. A Go module is a collection of Go packages that are released together. To understand the code organization, you also need to understand about -Go module. A file named go.mod there declares the module path: the -import path prefix for all packages within the module. The module -contains the packages in the directory containing its go.mod file as -well as subdirectories of that directory, up to the next subdirectory -containing another go.mod file (if any). +Go module. A file named *go.mod* declares the module path: the import +path prefix for all packages within the module. The module contains the +packages in the directory containing its go.mod file as well as +subdirectories of that directory, up to the next subdirectory containing +another go.mod file (if any). Note that you don’t need to publish your code to a remote repository before you can build it. A module can be defined locally without