├── GoCore ├── gotut-10.go ├── gotut-10ex.go ├── gotut-11.go ├── gotut-12.go ├── gotut-13.go ├── gotut-14.go ├── gotut-15.go ├── gotut-16.go ├── gotut-17.go ├── gotut-18.go ├── gotut-19.go ├── gotut-20.go ├── gotut-21.go ├── gotut-22.go ├── gotut-23.go ├── gotut-24.go ├── gotut1.go ├── gotut2.go ├── gotut3.go ├── gotut3ex.go ├── gotut4.go ├── gotut4ex.go ├── gotut5.go ├── gotut5ex.go ├── gotut6.go ├── gotut7.go ├── gotut8.go ├── gotut9.go ├── sudoku.go ├── sudoku2.go ├── sudoku3.go └── sudoku4.go ├── PostgreSQL and Go.zip ├── Postgres-Files ├── PostgreSQL 10 Similar Like and Regex.docx ├── PostgreSQL 11 Views.docx ├── PostgreSQL 12 SQL Functions.docx ├── PostgreSQL 13 SQL Functions 2.docx ├── PostgreSQL 14 pgSQL Functions.docx ├── PostgreSQL 15 pgSQL Functions 2.docx ├── PostgreSQL 16 pgSQL 3.docx ├── PostgreSQL 17 Stored Procedures.docx ├── PostgreSQL 18 Triggers.docx ├── PostgreSQL 19 Cursors.docx ├── PostgreSQL 2 Intro Code.txt ├── PostgreSQL 20.docx ├── PostgreSQL 3 Data Types.docx ├── PostgreSQL 4 INSERT ALTER CUSTOM TYPES.docx ├── PostgreSQL 5 Organizing Tables.docx ├── PostgreSQL 6 Altering Tables.docx ├── PostgreSQL 7 Inserting Data.docx ├── PostgreSQL 8 Getting Data from One Table.docx └── PostgreSQL 9 Getting Data From Multiple Tables.docx ├── README.md ├── web1 ├── go.mod └── main.go ├── web2 ├── go.mod ├── main.go └── templates │ ├── about.page.tmpl │ └── home.page.tmpl ├── web3 - 29.zip ├── web3 11-12.zip ├── web3 13.zip ├── web3 14.zip ├── web3 21 - 28.zip ├── web3-1-6.zip ├── web3-10.zip ├── web3-7.zip └── web3-8-9.zip /GoCore/gotut-10.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | var pl = fmt.Println 8 | 9 | // ----- FUNCTIONS ----- 10 | func sayHello() { 11 | pl("Hello") 12 | } 13 | 14 | // Returns sum of values 15 | func getSum(x int, y int) int { 16 | return x + y 17 | } 18 | 19 | // Return multiple values 20 | func getTwo(x int) (int, int) { 21 | return x + 1, x + 2 22 | } 23 | 24 | // Return potential error 25 | func getQuotient(x float64, y float64) (ans float64, err error) { 26 | if y == 0 { 27 | // Define error message returned with dummy value 28 | // for ans 29 | return 0, fmt.Errorf("You can't divide by zero") 30 | } else { 31 | // If no error return nil 32 | return x / y, nil 33 | } 34 | } 35 | 36 | // Variadic function 37 | func getSum2(nums ...int) int { 38 | sum := 0 39 | // nums gets converted into a slice which is 40 | // iterated by range (More on slices later) 41 | for _, num := range nums { 42 | sum += num 43 | } 44 | return sum 45 | } 46 | 47 | func getArraySum(arr []int) int { 48 | sum := 0 49 | for _, val := range arr { 50 | sum += val 51 | } 52 | return sum 53 | } 54 | 55 | func changeVal(f3 int) int { 56 | f3 += 1 57 | return f3 58 | } 59 | 60 | func main() { 61 | // ----- FUNCTIONS ----- 62 | // func funcName(parameters) returnType {BODY} 63 | // If you only need a function in the current package 64 | // start with lowercase letter 65 | // Letters and numbers in camelcase 66 | sayHello() 67 | pl(getSum(5, 4)) 68 | f1, f2 := getTwo(5) 69 | fmt.Printf("%d %d\n", f1, f2) 70 | 71 | // Function that can return an error 72 | ans, err := getQuotient(5, 0) 73 | if err == nil { 74 | pl("5/4 =", ans) 75 | } else { 76 | pl(err) 77 | // End program 78 | // log.Fatal(err) 79 | } 80 | 81 | // Function receives unknown number of parameters 82 | // Variadic Function 83 | pl("Unknown Sum :", getSum2(1, 2, 3, 4)) 84 | 85 | // Pass an array to a function by value 86 | vArr := []int{1, 2, 3, 4} 87 | pl("Array Sum :", getArraySum(vArr)) 88 | 89 | // Go passes the value to functions so it isn't changed 90 | // even if the same variable name is used 91 | f3 := 5 92 | pl("f3 before func :", f3) 93 | changeVal(f3) 94 | pl("f3 after func :", f3) 95 | } 96 | -------------------------------------------------------------------------------- /GoCore/gotut-10ex.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "log" 7 | "math/rand" 8 | "os" 9 | "regexp" 10 | "strings" 11 | "time" 12 | ) 13 | 14 | /* 15 | +---+ 16 | | 17 | | 18 | | 19 | === 20 | 21 | Secret Word : ______ 22 | Incorrect Guesses : 23 | 24 | Guess a Letter : a 25 | 26 | Sorry Your Dead! The word is ZOMBIE 27 | Yes the Secret Word is ZOMBIE 28 | 29 | Please Enter Only One Letter 30 | Please Enter a Letter 31 | Please Enter a Letter you Haven't Guessed 32 | */ 33 | 34 | var pl = fmt.Println 35 | 36 | var hmArr = [7]string{ 37 | " +---+\n" + 38 | " |\n" + 39 | " |\n" + 40 | " |\n" + 41 | " ===\n", 42 | " +---+\n" + 43 | " 0 |\n" + 44 | " |\n" + 45 | " |\n" + 46 | " ===\n", 47 | " +---+\n" + 48 | " 0 |\n" + 49 | " | |\n" + 50 | " |\n" + 51 | " ===\n", 52 | " +---+\n" + 53 | " 0 |\n" + 54 | "/| |\n" + 55 | " |\n" + 56 | " ===\n", 57 | " +---+\n" + 58 | " 0 |\n" + 59 | "/|\\ |\n" + 60 | " |\n" + 61 | " ===\n", 62 | " +---+\n" + 63 | " 0 |\n" + 64 | "/|\\ |\n" + 65 | "/ |\n" + 66 | " ===\n", 67 | " +---+\n" + 68 | " 0 |\n" + 69 | "/|\\ |\n" + 70 | "/ \\ |\n" + 71 | " ===\n", 72 | } 73 | 74 | var wordArr = [7]string{ 75 | "JAZZ", "ZIGZAG", "ZILCH", "ZIPPER", 76 | "ZODIAC", "ZOMBIE", "FLUFF", 77 | } 78 | 79 | // Stores the random word to be guessed 80 | var randWord string 81 | 82 | // Stores all letters guessed 83 | var guessedLetters string 84 | 85 | // Stores correct guesses 86 | var correctLetters []string 87 | 88 | // Letters guessed that aren't in the randWord 89 | var wrongGuesses []string 90 | 91 | func getRandWord() string { 92 | // Returns seconds as int 93 | seedSecs := time.Now().Unix() 94 | rand.Seed(seedSecs) 95 | // Get random word from array 96 | randWord = wordArr[rand.Intn(7)] 97 | 98 | // Generate correctLetters array with correct size 99 | correctLetters = make([]string, len(randWord)) 100 | return randWord 101 | } 102 | 103 | func showBoard() { 104 | // Prints current hangman state 105 | pl(hmArr[len(wrongGuesses)]) 106 | 107 | fmt.Print("Secret Word : ") 108 | // Prints spaces for missing letter or the 109 | // letter 110 | // Cycle and if is a character print it 111 | // If not print an underscore 112 | for _, v := range correctLetters { 113 | if v == "" { 114 | fmt.Print("_") 115 | } else { 116 | fmt.Print(v) 117 | } 118 | } 119 | 120 | fmt.Print("\nIncorrect Guesses : ") 121 | if len(wrongGuesses) > 0 { 122 | for _, v := range wrongGuesses { 123 | fmt.Print(v + " ") 124 | } 125 | } 126 | pl() 127 | } 128 | 129 | func getUserLetter() string { 130 | // Setup buffered reader that gets text from the keyboard 131 | reader := bufio.NewReader(os.Stdin) 132 | // The guess the user makes 133 | var guess string 134 | 135 | for true { 136 | fmt.Print("\nGuess a Letter : ") 137 | guess, err := reader.ReadString('\n') 138 | if err != nil { 139 | log.Fatal(err) 140 | } 141 | 142 | // Convert to upper so it is easier to search 143 | guess = strings.ToUpper(guess) 144 | 145 | // Remove spaces 146 | guess = strings.TrimSpace(guess) 147 | 148 | // Create regular expression that verifies 149 | // if a single character is a letter 150 | var IsLetter = regexp.MustCompile(`^[a-zA-Z]$`).MatchString 151 | 152 | if len(guess) != 1 { 153 | fmt.Println("Please Enter Only One Letter") 154 | } else if !IsLetter(guess) { 155 | fmt.Println("Please Enter a Letter") 156 | } else if strings.Contains(guessedLetters, guess) { 157 | fmt.Println("Please Enter a Letter you Haven't Guessed") 158 | } else { 159 | return guess 160 | } 161 | } 162 | return guess 163 | } 164 | 165 | // Returns all indices matching the substring 166 | func getAllIndexes(theStr, subStr string) (indices []int) { 167 | if (len(subStr) == 0) || (len(theStr) == 0) { 168 | return indices 169 | } 170 | 171 | // Offset will find 1st matching index and then 172 | // move forward to find the rest 173 | offset := 0 174 | for { 175 | i := strings.Index(theStr[offset:], subStr) 176 | // If no matches or no more matches 177 | // since we cycled to the end 178 | // return indices 179 | if i == -1 { 180 | // fmt.Println(indices) 181 | return indices 182 | } 183 | offset += i 184 | // Add index 185 | indices = append(indices, offset) 186 | // Jump ahead the length of the substring 187 | offset += len(subStr) 188 | } 189 | } 190 | 191 | // Updates correctLetters string to display guessed 192 | // letters an _s 193 | func updateCorrectLetters(letter string) { 194 | indexMatches := getAllIndexes(randWord, letter) 195 | 196 | // Assign all matching indexes the 197 | // supplied letter 198 | for _, v := range indexMatches { 199 | correctLetters[v] = letter 200 | } 201 | } 202 | 203 | // Checks if array contains an empty value 204 | func sliceHasEmptys(theSlice []string) bool { 205 | for _, v := range theSlice { 206 | if len(v) == 0 { 207 | return true 208 | } 209 | } 210 | return false 211 | } 212 | 213 | func main() { 214 | pl(getRandWord()) 215 | 216 | for true { 217 | // Display opening board 218 | showBoard() 219 | 220 | // Get user guess 221 | guess := getUserLetter() 222 | 223 | if strings.Contains(randWord, guess) { 224 | updateCorrectLetters(guess) 225 | 226 | // Check if user guessed all 227 | // letters 228 | if sliceHasEmptys(correctLetters) { 229 | fmt.Println("More Letters to Guess") 230 | } else { 231 | fmt.Println("Yes the Secret Word is", randWord) 232 | break 233 | } 234 | 235 | } else { 236 | // They guessed a letter not in the secret 237 | // word 238 | // Append to string 239 | guessedLetters += guess 240 | // Append to slice 241 | wrongGuesses = append(wrongGuesses, guess) 242 | 243 | // Check if users ran out of guesses 244 | if len(wrongGuesses) >= 6 { 245 | fmt.Println("Sorry Your Dead! The word is", randWord) 246 | break 247 | } 248 | } 249 | } 250 | } 251 | -------------------------------------------------------------------------------- /GoCore/gotut-11.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | var pl = fmt.Println 8 | 9 | func changeVal2(myPtr *int) { 10 | *myPtr = 12 11 | } 12 | 13 | // Receives array by reference and doubles values 14 | func dblArrVals(arr *[4]int) { 15 | for x := 0; x < 4; x++ { 16 | arr[x] *= 2 17 | } 18 | } 19 | 20 | func getAverage(nums ...float64) float64 { 21 | var sum float64 = 0.0 22 | var numSize float64 = float64(len(nums)) 23 | 24 | for _, val := range nums { 25 | sum += val 26 | } 27 | return (sum / numSize) 28 | } 29 | 30 | func main() { 31 | // ----- POINTERS ----- 32 | 33 | // You can pass by reference with the & 34 | // (Address of Operator) 35 | // Print amount and address for amount in memory 36 | f4 := 10 37 | pl("f4 :", f4) 38 | pl("f4 Address :", &f4) 39 | 40 | // Store a pointer (Pointer to int) 41 | var f4Ptr *int = &f4 42 | pl("f4 Address :", f4Ptr) 43 | 44 | // Print value at pointer 45 | pl("f4 Value :", *f4Ptr) 46 | 47 | // Assign value using pointer 48 | *f4Ptr = 11 49 | pl("f4 Value :", *f4Ptr) 50 | 51 | // Change value in function 52 | pl("f4 before function :", f4) 53 | changeVal2(&f4) 54 | pl("f4 after function :", f4) 55 | 56 | // Pass an array by reference 57 | pArr := [4]int{1, 2, 3, 4} 58 | dblArrVals(&pArr) 59 | pl(pArr) 60 | 61 | // Passing a slice to a function works just 62 | // like when using variadic functions 63 | // Just add ... after the slice when passing 64 | iSlice := []float64{11, 13, 17} 65 | fmt.Printf("Average : %.3f\n", getAverage(iSlice...)) 66 | } 67 | -------------------------------------------------------------------------------- /GoCore/gotut-12.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "errors" 6 | "fmt" 7 | "log" 8 | "os" 9 | "strconv" 10 | ) 11 | 12 | var pl = fmt.Println 13 | 14 | func main() { 15 | // ----- FILE IO ----- 16 | // We can create, write and read from files 17 | 18 | // Create a file 19 | f, err := os.Create("data.txt") 20 | if err != nil { 21 | log.Fatal(err) 22 | } 23 | 24 | // Says to close the file after program ends or when 25 | // there is a closing curly bracket 26 | defer f.Close() 27 | 28 | // Create list of primes 29 | iPrimeArr := []int{2, 3, 5, 7, 11} 30 | // Create string array from int array 31 | var sPrimeArr []string 32 | for _, i := range iPrimeArr { 33 | sPrimeArr = append(sPrimeArr, strconv.Itoa(i)) 34 | } 35 | 36 | // Cycle through strings and write to file 37 | for _, num := range sPrimeArr { 38 | _, err := f.WriteString(num + "\n") 39 | 40 | if err != nil { 41 | log.Fatal(err) 42 | } 43 | } 44 | 45 | // Open the created file 46 | f, err = os.Open("data.txt") 47 | if err != nil { 48 | log.Fatal(err) 49 | } 50 | defer f.Close() 51 | 52 | // Read from file and print once per line 53 | scan1 := bufio.NewScanner(f) 54 | for scan1.Scan() { 55 | pl("Prime :", scan1.Text()) 56 | } 57 | if err := scan1.Err(); err != nil { 58 | log.Fatal(err) 59 | } 60 | 61 | // Append to file 62 | /* 63 | Exactly one of O_RDONLY, O_WRONLY, or O_RDWR must be specified 64 | O_RDONLY : open the file read-only 65 | O_WRONLY : open the file write-only 66 | O_RDWR : open the file read-write 67 | These can be or'ed 68 | O_APPEND : append data to the file when writing 69 | O_CREATE : create a new file if none exists 70 | O_EXCL : used with O_CREATE, file must not exist 71 | O_SYNC : open for synchronous I/O 72 | O_TRUNC : truncate regular writable file when opened 73 | */ 74 | 75 | // Check if file exists 76 | _, err = os.Stat("data.txt") 77 | if errors.Is(err, os.ErrNotExist) { 78 | pl("File Doesn't Exist") 79 | } else { 80 | f, err = os.OpenFile("data.txt", 81 | os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) 82 | if err != nil { 83 | log.Fatal(err) 84 | } 85 | defer f.Close() 86 | if _, err := f.WriteString("13\n"); err != nil { 87 | log.Fatal(err) 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /GoCore/gotut-13.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | var pl = fmt.Println 8 | 9 | func main() { 10 | // ----- COMMAND LINE ARGUMENTS ----- 11 | // You can pass values to your program 12 | // from the command line 13 | // Create gotut2.go 14 | // go build gotut2.go 15 | // .\gotut2 24 43 12 9 10 16 | // Returns an array with everything 17 | // passed with the name of the app 18 | // in the first index 19 | // Outputs the max number passed in 20 | } 21 | 22 | /* 23 | package main 24 | 25 | import ( 26 | "fmt" 27 | "os" 28 | "strconv" 29 | ) 30 | 31 | func main() { 32 | fmt.Println(os.Args) 33 | // Get all values after the first index 34 | args := os.Args[1:] 35 | 36 | // Create int array from string array 37 | var iArgs = []int{} 38 | for _, i := range args { 39 | val, err := strconv.Atoi(i) 40 | if err != nil { 41 | panic(err) 42 | } 43 | iArgs = append(iArgs, val) 44 | } 45 | 46 | max := 0 47 | for _, val := range iArgs { 48 | if val > max { 49 | max = val 50 | } 51 | } 52 | fmt.Println("Max Value :", max) 53 | } 54 | */ 55 | -------------------------------------------------------------------------------- /GoCore/gotut-14.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | _ stuff "example/project/mypackage" 6 | ) 7 | 8 | var pl = fmt.Println 9 | 10 | // ----- PACKAGES ----- 11 | // Packages allow you to keep related code together 12 | // Go looks for package code in a directory 13 | 14 | // If you are using VSC and have multiple 15 | // modules you get this error 16 | // gopls requires a module at the root of 17 | // your workspace 18 | // 1. Settings 19 | // 2. In search type gopls 20 | // 3. Paste "gopls": { "experimentalWorkspaceModule": true, } 21 | // 4. Restart VSC 22 | 23 | // cd /D D:\Tutorials\GoTutorial 24 | 25 | // Create a go directory : mkdir app (Create in VSC) 26 | // cd app (In terminal) 27 | // Choose a module path and create a go.mod file 28 | // go mod init example/project (In terminal) 29 | 30 | // Go modules allow you to manage libraries 31 | // They contain one project or library and a 32 | // collection of Go packages 33 | // go.mod : contains the name of the module and versions 34 | // of other modules your module depends on 35 | 36 | // Create a main.go file at the same level as go.mod 37 | 38 | // You can have many packages and sub packages 39 | // create a directory called mypackage in the project 40 | // directory mkdir mypackage (Create in VSC) 41 | // cd mypackage 42 | 43 | // Create file mypackage.go in it 44 | 45 | // Package names should be all lowercase 46 | 47 | func main() { 48 | fmt.Println("Hello", stuff.Name) 49 | intArr := []int{2,3,5,7,11} 50 | strArr := stuff.IntArrToStrArr(intArr) 51 | fmt.Println(strArr) 52 | fmt.Println(reflect.Typeof(strArr)) 53 | } 54 | 55 | /* mypackage.go 56 | package stuff 57 | 58 | import( 59 | "errors" 60 | "strconv" 61 | "time" 62 | ) 63 | 64 | var Name string = "Derek" 65 | func IntArrToStrArr(intArr []int) []string{ 66 | var strArr []string 67 | for _, i := range intArr{ 68 | strArr = append(strArr, strconv.Itoa(i)) 69 | } 70 | return strArr 71 | } 72 | 73 | */ 74 | -------------------------------------------------------------------------------- /GoCore/gotut-15.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | var pl = fmt.Println 8 | 9 | func main() { 10 | // ----- MAPS ----- 11 | // Maps are collections of key/value pairs 12 | // Keys can be any data type that can be compared 13 | // using == (They can be a different type than 14 | // the value) 15 | // var myMap map [keyType]valueType 16 | 17 | // Declare a map variable 18 | var heroes map[string]string 19 | // Create the map 20 | heroes = make(map[string]string) 21 | 22 | // You can do it in one step 23 | villians := make(map[string]string) 24 | 25 | // Add keys and values 26 | heroes["Batman"] = "Bruce Wayne" 27 | heroes["Superman"] = "Clark Kent" 28 | heroes["The Flash"] = "Barry Allen" 29 | villians["Lex Luther"] = "Lex Luther" 30 | 31 | // Define with map literal 32 | superPets := map[int]string{1: "Krypto", 33 | 2: "Bat Hound"} 34 | 35 | // Get value with key (Use %v with Printf) 36 | fmt.Printf("Batman is %v\n", heroes["Batman"]) 37 | 38 | // If you access a key that doesn't exist 39 | // you get nil 40 | pl("Chip :", superPets[3]) 41 | 42 | // You can check if there is a value or nil 43 | _, ok := superPets[3] 44 | pl("Is there a 3rd pet :", ok) 45 | 46 | // Cycle through map 47 | for k, v := range heroes { 48 | fmt.Printf("%s is %s\n", k, v) 49 | } 50 | 51 | // Delete a key value 52 | delete(heroes, "The Flash") 53 | } 54 | -------------------------------------------------------------------------------- /GoCore/gotut-16.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | var pl = fmt.Println 8 | 9 | // ----- FUNCTION THAT EXCEPTS GENERICS ----- 10 | // This generic type parameter is capital, between 11 | // square brackets and has a rule for what data 12 | // it will except called a constraint 13 | // any : anything 14 | // comparable : Anything that supports == 15 | // More Constraints : pkg.go.dev/golang.org/x/exp/constraints 16 | 17 | // You can also define what is excepted like this 18 | // Define that my generic must be an int or float64 19 | type MyConstraint interface { 20 | int | float64 21 | } 22 | 23 | func getSumGen[T MyConstraint](x T, y T) T { 24 | return x + y 25 | } 26 | 27 | func main() { 28 | // ----- GENERICS ----- 29 | // We can specify the data type to be used at a 30 | // later time with generics 31 | // It is mainly used when we want to create 32 | // functions that can work with 33 | // multiple data types 34 | pl("5 + 4 =", getSumGen(5, 4)) 35 | pl("5.6 + 4.7 =", getSumGen(5.6, 4.7)) 36 | 37 | // This causes an error 38 | // pl("5.6 + 4.7 =", getSumGen("5.6", "4.7")) 39 | } 40 | -------------------------------------------------------------------------------- /GoCore/gotut-17.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | var pl = fmt.Println 8 | 9 | // ----- STRUCTS ----- 10 | type customer struct { 11 | name string 12 | address string 13 | bal float64 14 | } 15 | 16 | // This struct has a function associated 17 | type rectangle struct { 18 | length, height float64 19 | } 20 | 21 | func (r rectangle) Area() float64 { 22 | return r.length * r.height 23 | } 24 | 25 | // Customer passed as values 26 | func getCustInfo(c customer) { 27 | fmt.Printf("%s owes us %.2f\n", c.name, c.bal) 28 | } 29 | 30 | func newCustAdd(c *customer, address string) { 31 | c.address = address 32 | } 33 | 34 | // Struct composition : Putting a struct in another 35 | type contact struct { 36 | fName string 37 | lName string 38 | phone string 39 | } 40 | 41 | type business struct { 42 | name string 43 | address string 44 | contact 45 | } 46 | 47 | func (b business) info() { 48 | fmt.Printf("Contact at %s is %s %s\n", b.name, b.contact.fName, b.contact.lName) 49 | } 50 | 51 | func main() { 52 | // ----- STRUCTS ----- 53 | // Structs allow you to store values with many 54 | // data types 55 | 56 | // Add values 57 | var tS customer 58 | tS.name = "Tom Smith" 59 | tS.address = "5 Main St" 60 | tS.bal = 234.56 61 | 62 | // Pass to function as values 63 | getCustInfo(tS) 64 | // or as reference 65 | newCustAdd(&tS, "123 South st") 66 | pl("Address :", tS.address) 67 | 68 | // Create a struct literal 69 | sS := customer{"Sally Smith", "123 Main", 0.0} 70 | pl("Name :", sS.name) 71 | 72 | // Structs with functions 73 | rect1 := rectangle{10.0, 15.0} 74 | pl("Rect Area :", rect1.Area()) 75 | 76 | // Go doesn't support inheritance, but it does 77 | // support composition by embedding a struct 78 | // in another 79 | con1 := contact{ 80 | "James", 81 | "Wang", 82 | "555-1212", 83 | } 84 | 85 | bus1 := business{ 86 | "ABC Plumbing", 87 | "234 North St", 88 | con1, 89 | } 90 | 91 | bus1.info() 92 | } 93 | -------------------------------------------------------------------------------- /GoCore/gotut-18.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | var pl = fmt.Println 8 | 9 | // ----- DEFINED TYPES ----- 10 | // I'll define different cooking measurement types 11 | // so we can do conversions 12 | type Tsp float64 13 | type TBs float64 14 | type ML float64 15 | 16 | // Convert with functions (Bad Way) 17 | func tspToML(tsp Tsp) ML { 18 | return ML(tsp * 4.92) 19 | } 20 | 21 | func TBToML(tbs TBs) ML { 22 | return ML(tbs * 14.79) 23 | } 24 | 25 | // Associate method with types 26 | func (tsp Tsp) ToMLs() ML { 27 | return ML(tsp * 4.92) 28 | } 29 | func (tbs TBs) ToMLs() ML { 30 | return ML(tbs * 14.79) 31 | } 32 | 33 | func main() { 34 | // ----- DEFINED TYPES ----- 35 | // We used a defined type previously with structs 36 | // You can use them also to enhance the quality 37 | // of other data types 38 | // We'll create them for different measurements 39 | 40 | // Convert from tsp to mL 41 | ml1 := ML(Tsp(3) * 4.92) 42 | fmt.Printf("3 tsps = %.2f mL\n", ml1) 43 | 44 | // Convert from TBs to mL 45 | ml2 := ML(TBs(3) * 14.79) 46 | fmt.Printf("3 TBs = %.2f mL\n", ml2) 47 | 48 | // You can use arithmetic and comparison 49 | // operators 50 | pl("2 tsp + 4 tsp =", Tsp(2) + Tsp(4)) 51 | pl("2 tsp > 4 tsp =", Tsp(2) > Tsp(4)) 52 | 53 | // We can convert with functions 54 | // Bad Way 55 | fmt.Printf("3 tsp = %.2f mL\n", tspToML(3)) 56 | fmt.Printf("3 TBs = %.2f mL\n", TBToML(3)) 57 | 58 | // We can solve this by using methods which 59 | // are functions associated with a type 60 | tsp1 := Tsp(3) 61 | fmt.Printf("%.2f tsp = %.2f mL\n", tsp1, tsp1.ToMLs()) 62 | } 63 | -------------------------------------------------------------------------------- /GoCore/gotut-19.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | var pl = fmt.Println 8 | 9 | // ----- INTERFACES ----- 10 | type Animal interface { 11 | AngrySound() 12 | HappySound() 13 | } 14 | 15 | // Define type with interface methods and its 16 | // own method 17 | type Cat string 18 | 19 | func (c Cat) Attack() { 20 | pl("Cat Attacks its Prey") 21 | } 22 | 23 | // Return the cats name with a type conversion 24 | func (c Cat) Name() string { 25 | return string(c) 26 | } 27 | 28 | func (c Cat) AngrySound() { 29 | pl("Cat says Hissssss") 30 | } 31 | func (c Cat) HappySound() { 32 | pl("Cat says Purrr") 33 | } 34 | 35 | func main() { 36 | // ----- INTERFACES ----- 37 | // Interfaces allow you to create contracts 38 | // that say if anything inherits it that 39 | // they will implement defined methods 40 | 41 | // If we had animals and wanted to define that 42 | // they all perform certain actions, but in their 43 | // specific way we could use an interface 44 | 45 | // With Go you don't have to say a type uses 46 | // an interface. When your type implements 47 | // the required methods it is automatic 48 | var kitty Animal 49 | kitty = Cat("Kitty") 50 | kitty.AngrySound() 51 | 52 | // We can only call methods defined in the 53 | // interface for Cats because of the contract 54 | // unless you convert Cat back into a concrete 55 | // Cat type using a type assertion 56 | var kitty2 Cat = kitty.(Cat) 57 | kitty2.Attack() 58 | pl("Cats Name :", kitty2.Name()) 59 | } 60 | -------------------------------------------------------------------------------- /GoCore/gotut-20.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | "time" 7 | ) 8 | 9 | var pl = fmt.Println 10 | 11 | // ----- CONCURRENCY ----- 12 | func printTo15() { 13 | for i := 1; i <= 15; i++ { 14 | pl("Func 1 :", i) 15 | } 16 | } 17 | func printTo10() { 18 | for i := 1; i <= 10; i++ { 19 | pl("Func 2 :", i) 20 | } 21 | } 22 | 23 | // These functions will print in order using 24 | // channels 25 | // Func receives a channel and then sends values 26 | // over channels once each time it is called 27 | func nums1(channel chan int) { 28 | channel <- 1 29 | channel <- 2 30 | channel <- 3 31 | } 32 | func nums2(channel chan int) { 33 | channel <- 4 34 | channel <- 5 35 | channel <- 6 36 | } 37 | 38 | // ----- BANK ACCOUNT EXAMPLE ----- 39 | // Here I'll simulate customers accessing a 40 | // bank account and lock out customers to 41 | // allow for individual access 42 | type Account struct { 43 | balance int 44 | lock sync.Mutex // Mutual exclusion 45 | } 46 | 47 | func (a *Account) GetBalance() int { 48 | a.lock.Lock() 49 | defer a.lock.Unlock() 50 | return a.balance 51 | } 52 | 53 | func (a *Account) Withdraw(v int) { 54 | a.lock.Lock() 55 | defer a.lock.Unlock() 56 | if v > a.balance { 57 | pl("Not enough money in account") 58 | } else { 59 | fmt.Printf("%d withdrawn : Balance : %d\n", 60 | v, a.balance) 61 | a.balance -= v 62 | } 63 | } 64 | 65 | func main() { 66 | // ----- CONCURRENCY ----- 67 | // Concurrency allows us to have multiple 68 | // blocks of code share execution time by 69 | // pausing their execution. We can also 70 | // run blocks of codes in parallel at the same 71 | // time. (Concurrent tasks in Go are called 72 | // goroutines) 73 | 74 | // To execute multiple functions in new 75 | // goroutines add the word go in front of 76 | // the function calls (Those functions can't 77 | // have return values) 78 | 79 | // We can't control when functions execute 80 | // so we may get different results 81 | go printTo15() 82 | go printTo10() 83 | 84 | // We have to pause the main function because 85 | // if main ends so will the goroutines 86 | time.Sleep(2 * time.Second) // Pause 2 seconds 87 | 88 | // You can have goroutines communicate by 89 | // using channels. The sending goroutine 90 | // also makes sure the receiving goroutine 91 | // receives the value before it attempts 92 | // to use it 93 | 94 | // Create a channel : Only carries values of 95 | // 1 type 96 | channel1 := make(chan int) 97 | channel2 := make(chan int) 98 | go nums1(channel1) 99 | go nums2(channel2) 100 | pl(<-channel1) 101 | pl(<-channel1) 102 | pl(<-channel1) 103 | pl(<-channel2) 104 | pl(<-channel2) 105 | pl(<-channel2) 106 | 107 | // Using locks to protect data from being 108 | // accessed by more than one user at a time 109 | // Locks are another option when you don't 110 | // have to pass data 111 | var acct Account 112 | acct.balance = 100 113 | pl("Balance :", acct.GetBalance()) 114 | 115 | for i := 0; i < 12; i++ { 116 | go acct.Withdraw(10) 117 | } 118 | time.Sleep(2 * time.Second) 119 | } 120 | -------------------------------------------------------------------------------- /GoCore/gotut-21.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | var pl = fmt.Println 8 | 9 | // ----- CLOSURES ----- 10 | // Pass a function to a function 11 | func useFunc(f func(int, int) int, x, y int) { 12 | pl("Answer :", (f(x, y))) 13 | } 14 | 15 | func sumVals(x, y int) int { 16 | return x + y 17 | } 18 | 19 | func main() { 20 | // ----- CLOSURES ----- 21 | // Closures are functions that don't have to be 22 | // associated with an identifier (Anonymous) 23 | 24 | // Create a closure that sums values 25 | intSum := func(x, y int) int { return x + y } 26 | pl("5 + 4 =", intSum(5, 4)) 27 | 28 | // Closures can change values outside the function 29 | samp1 := 1 30 | changeVar := func() { samp1 += 1 } 31 | changeVar() 32 | pl("samp1 =", samp1) 33 | 34 | // Pass a function to a function 35 | useFunc(sumVals, 5, 8) 36 | } 37 | -------------------------------------------------------------------------------- /GoCore/gotut-22.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | var pl = fmt.Println 8 | 9 | // ----- RECURSION ----- 10 | func factorial(num uint64) uint64 { 11 | // This condition ends calling functions 12 | if num == 0 { 13 | return 1 14 | } 15 | return num * factorial(num-1) 16 | } 17 | 18 | func main() { 19 | // ----- RECURSION ----- 20 | // Recursion occurs when a function calls itself 21 | // There must be a condition that ends this 22 | // Finding a factorial is commonly used 23 | pl("Factorial 4 =", factorial(4)) 24 | // 1st : result = 4 * factorial(3) = 4 * 6 = 24 25 | // 2nd : result = 3 * factorial(2) = 3 * 2 = 6 26 | // 3rd : result = 2 * factorial(1) = 2 * 1 = 2 27 | } 28 | -------------------------------------------------------------------------------- /GoCore/gotut-23.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "regexp" 6 | ) 7 | 8 | var pl = fmt.Println 9 | 10 | func main() { 11 | // ----- REGULAR EXPRESSIONS ----- 12 | // You can use regular expressions to test 13 | // if a string matches a pattern 14 | 15 | // Search for ape followed by not a space 16 | reStr := "The ape was at the apex" 17 | match, _ := regexp.MatchString("(ape[^ ]?)", reStr) 18 | pl(match) 19 | 20 | // You can compile them 21 | // Find multiple words ending with at 22 | reStr2 := "Cat rat mat fat pat" 23 | r, _ := regexp.Compile("([crmfp]at)") 24 | 25 | // Did you find any matches? 26 | pl("MatchString :", r.MatchString(reStr2)) 27 | 28 | // Return first match 29 | pl("FindString :", r.FindString(reStr2)) 30 | 31 | // Starting and ending index for 1st match 32 | pl("Index :", r.FindStringIndex(reStr2)) 33 | 34 | // Return all matches 35 | pl("All String :", r.FindAllString(reStr2, -1)) 36 | 37 | // Get 1st 2 matches 38 | pl("All String :", r.FindAllString(reStr2, 2)) 39 | 40 | // Get indexes for all matches 41 | pl("All Submatch Index :", r.FindAllStringSubmatchIndex(reStr2, -1)) 42 | 43 | // Replace all matches with Dog 44 | pl(r.ReplaceAllString(reStr2, "Dog")) 45 | } 46 | -------------------------------------------------------------------------------- /GoCore/gotut-24.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | var pl = fmt.Println 8 | 9 | func main() { 10 | // ----- AUTOMATED TESTING ----- 11 | // Automated tests make sure your program still 12 | // works while you change the code 13 | // Create app2 directory with testemail.go 14 | // cd app2 15 | // Create testemail_test.go 16 | // go mod init app2 17 | // Run Tests : go test -v 18 | } 19 | 20 | /* testemail.go 21 | package app2 22 | 23 | import ( 24 | "fmt" 25 | "regexp" 26 | ) 27 | 28 | func IsEmail(s string) (string, error) { 29 | // Used a raw string here so I didn't have 30 | // to double backslashes 31 | r, _ := regexp.Compile(`[\w._%+-]{1,20}@[\w.-]{2,20}.[A-Za-z]{2,3}`) 32 | 33 | if r.MatchString(s) { 34 | return "Valid Email", nil 35 | } else { 36 | return "", fmt.Errorf("not a valid email") 37 | } 38 | } 39 | */ 40 | 41 | /* testemail_test.go 42 | package app2 43 | 44 | import ( 45 | "testing" 46 | ) 47 | 48 | func TestIsEmail(t *testing.T) { 49 | _, err := IsEmail("hello") 50 | if err == nil { 51 | t.Error("hello is not an email") 52 | } 53 | 54 | _, err = IsEmail("derek@aol.com") 55 | if err != nil { 56 | t.Error("derek@aol.com is an email") 57 | } 58 | 59 | _, err = IsEmail("derek@aol") 60 | if err != nil { 61 | t.Error("derek@aol is not email") 62 | } 63 | } 64 | */ 65 | -------------------------------------------------------------------------------- /GoCore/gotut1.go: -------------------------------------------------------------------------------- 1 | // A package is a collection of code 2 | // We can define what package we want our code to belong to 3 | // We use main when we want our code to run in the terminal 4 | package main 5 | 6 | // Import multiple packages 7 | // You could use an alias like f "fmt" 8 | import ( 9 | "bufio" 10 | f "fmt" 11 | "log" 12 | "os" 13 | ) 14 | 15 | // Create alias to long function names 16 | var pl = f.Println 17 | 18 | /* 19 | I'm a block comment 20 | */ 21 | 22 | // When a Go program executes it executes a function named main 23 | // Go statements don't require semicolons 24 | func main() { 25 | // Prints text and a newline 26 | // List package name followed by a period and the function name 27 | pl("Hello Go") 28 | 29 | // Get user input (To run this in the terminal go run hellogo.go) 30 | pl("What is your name?") 31 | // Setup buffered reader that gets text from the keyboard 32 | reader := bufio.NewReader(os.Stdin) 33 | // Copy text up to the newline 34 | // The blank identifier _ will get err and ignore it (Bad Practice) 35 | // name, _ := reader.ReadString('\n') 36 | // It is better to handle it 37 | name, err := reader.ReadString('\n') 38 | if err == nil { 39 | pl("Hello", name) 40 | } else { 41 | // Log this error 42 | log.Fatal(err) 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /GoCore/gotut2.go: -------------------------------------------------------------------------------- 1 | // A package is a collection of code 2 | // We can define what package we want our code to belong to 3 | // We use main when we want our code to run in the terminal 4 | package main 5 | 6 | // Import multiple packages 7 | // You could use an alias like f "fmt" 8 | import ( 9 | "fmt" 10 | "reflect" 11 | "strconv" 12 | ) 13 | 14 | // Create alias to long function names 15 | var pl = fmt.Println 16 | 17 | func main() { 18 | 19 | // ----- VARIABLES ----- 20 | // var name type 21 | // Name must begin with letter and then letters or numbers 22 | // If a variable, function or type starts with a capital letter 23 | // it is considered exported and can be accessed outside the 24 | // package and otherwise is available only in the current package 25 | // Camal case is the default naming convention 26 | 27 | // var vName string = "Derek" 28 | // var v1, v2 = 1.2, 3.4 29 | 30 | // Short variable declaration (Type defined by data) 31 | // var v3 = "Hello" 32 | 33 | // Variables are mutable by default (Value can change as long 34 | // as the data type is the same) 35 | // v1 := 2.4 36 | 37 | // After declaring variables to assign values to them always use 38 | // = there after. If you use := you'll create a new variable 39 | 40 | // ----- DATA TYPES ----- 41 | // int, float64, bool, string, rune 42 | // Default type 0, 0.0, false, "" 43 | pl(reflect.TypeOf(25)) 44 | pl(reflect.TypeOf(3.14)) 45 | pl(reflect.TypeOf(true)) 46 | pl(reflect.TypeOf("Hello")) 47 | pl(reflect.TypeOf('🦍')) 48 | 49 | // ----- CASTING ----- 50 | // To cast type the type to convert to with the variable to 51 | // convert in parentheses 52 | // Doesn't work with bools or strings 53 | cV1 := 1.5 54 | cV2 := int(cV1) 55 | pl(cV2) 56 | 57 | // Convert string to int (ASCII to Integer) 58 | // Returns the result with an error if any 59 | cV3 := "50000000" 60 | cV4, err := strconv.Atoi(cV3) 61 | pl(cV4, err, reflect.TypeOf(cV4)) 62 | 63 | // Convert int to string (Integer to ASCII) 64 | cV5 := 50000000 65 | cV6 := strconv.Itoa(cV5) 66 | pl(cV6) 67 | 68 | // Convert string to float 69 | cV7 := "3.14" 70 | // Handling potential errors (Prints if err == nil) 71 | if cV8, err := strconv.ParseFloat(cV7, 64); err == nil { 72 | pl(cV8) 73 | } 74 | 75 | // Use Sprintf to convert from float to string 76 | cV9 := fmt.Sprintf("%f", 3.14) 77 | pl(cV9) 78 | } 79 | -------------------------------------------------------------------------------- /GoCore/gotut3.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | var pl = fmt.Println 6 | 7 | func main() { 8 | // ----- IF CONDITIONAL ----- 9 | // Conditional Operators : > < >= <= == != 10 | // Logical Operators : && || ! 11 | iAge := 8 12 | if (iAge >= 1) && (iAge <= 18) { 13 | pl("Important Birthday") 14 | } else if (iAge == 21) || (iAge == 50) { 15 | pl("Important Birthday") 16 | } else if iAge >= 65 { 17 | pl("Important Birthday") 18 | } else { 19 | pl("Not and Important Birthday") 20 | } 21 | 22 | // ! turns bools into their opposite value 23 | pl("!true =", !true) 24 | 25 | // ----- FORMATTED PRINT ----- 26 | // Go has its own version of C's printf 27 | // %d : Integer 28 | // %c : Character 29 | // %f : Float 30 | // %t : Boolean 31 | // %s : String 32 | // %o : Base 8 33 | // %x : Base 16 34 | // %v : Guesses based on data type 35 | // %T : Type of supplied value 36 | 37 | fmt.Printf("%s %d %c %f %t %o %x\n", "Stuff", 1, 'A', 38 | 3.14, true, 1, 1) 39 | 40 | // Float formatting 41 | fmt.Printf("%9f\n", 3.14) // Width 9 42 | fmt.Printf("%.2f\n", 3.141592) // Decimal precision 2 43 | fmt.Printf("%9.f\n", 3.141592) // Width 9 no precision 44 | 45 | // Sprintf returns a formatted string instead of printing 46 | sp1 := fmt.Sprintf("%9.f\n", 3.141592) 47 | pl(sp1) 48 | } 49 | -------------------------------------------------------------------------------- /GoCore/gotut3ex.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "log" 7 | "os" 8 | "strconv" 9 | "strings" 10 | ) 11 | 12 | var pl = fmt.Println 13 | 14 | func main() { 15 | // Setup buffered reader that gets text from the keyboard 16 | reader := bufio.NewReader(os.Stdin) 17 | 18 | fmt.Print("What is your age : ") 19 | age, err := reader.ReadString('\n') 20 | if err != nil { 21 | log.Fatal(err) 22 | } 23 | 24 | // Trims whitespace from age 25 | age = strings.TrimSpace(age) 26 | iAge, err := strconv.Atoi(age) 27 | if err != nil { 28 | log.Fatal(err) 29 | } 30 | 31 | if iAge < 5 { 32 | pl("Too young for school") 33 | } else if iAge == 5 { 34 | pl("Go to Kindergarten") 35 | } else if (iAge > 5) && (iAge <= 17) { 36 | grade := iAge - 5 37 | fmt.Printf("Go to grade %d\n", grade) 38 | } else { 39 | pl("Go to college") 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /GoCore/gotut4.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | "math/rand" 7 | "time" 8 | ) 9 | 10 | var pl = fmt.Println 11 | 12 | func main() { 13 | pl("5 + 4 =", 5+4) 14 | pl("5 - 4 =", 5-4) 15 | pl("5 * 4 =", 5*4) 16 | pl("5 / 4 =", 5/4) 17 | pl("5 % 4 =", 5%4) 18 | 19 | // Shorthand increment 20 | // Instead of mInt = mInt + 1 (mInt += 1) 21 | // -= *= /= 22 | mInt := 1 23 | mInt += 1 24 | // Also increment or decrement with ++ and -- 25 | mInt++ 26 | 27 | // Float precision increases with the size of your values 28 | pl("Float Precision =", 0.11111111111111111111+ 29 | 0.11111111111111111111) 30 | 31 | // Create a random value between 0 and 50 32 | // Get a seed value for our random number generator based on 33 | // seconds since 1/1/70 to make our random number more random 34 | seedSecs := time.Now().Unix() // Returns seconds as int 35 | rand.Seed(seedSecs) 36 | randNum := rand.Intn(50) + 1 37 | pl("Random :", randNum) 38 | 39 | // There are many math functions 40 | pl("Abs(-10) =", math.Abs(-10)) 41 | pl("Pow(4, 2) =", math.Pow(4, 2)) 42 | pl("Sqrt(16) =", math.Sqrt(16)) 43 | pl("Cbrt(8) =", math.Cbrt(8)) 44 | pl("Ceil(4.4) =", math.Ceil(4.4)) 45 | pl("Floor(4.4) =", math.Floor(4.4)) 46 | pl("Round(4.4) =", math.Round(4.4)) 47 | pl("Log2(8) =", math.Log2(8)) 48 | pl("Log10(100) =", math.Log10(100)) 49 | // Get the log of e to the power of 2 50 | pl("Log(7.389) =", math.Log(math.Exp(2))) 51 | pl("Max(5,4) =", math.Max(5, 4)) 52 | pl("Min(5,4) =", math.Min(5, 4)) 53 | 54 | // Convert 90 degrees to radians 55 | r90 := 90 * math.Pi / 180 56 | // Convert 1.5708 radians to degrees 57 | d90 := r90 * (180 / math.Pi) 58 | fmt.Printf("%f radians = %f degrees\n", r90, d90) 59 | pl("Sin(90) =", math.Sin(r90)) 60 | 61 | // There are also functions for Cos, Tan, Acos, Asin 62 | // Atan, Asinh, Acosh, Atanh, Atan2, Cosh, Sinh, Sincos 63 | // Htpot 64 | } 65 | -------------------------------------------------------------------------------- /GoCore/gotut4ex.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "log" 7 | "os" 8 | "strconv" 9 | "strings" 10 | ) 11 | 12 | // Create alias to long function names 13 | var pl = fmt.Println 14 | 15 | func main() { 16 | 17 | // Setup buffered reader that gets text from the keyboard 18 | reader := bufio.NewReader(os.Stdin) 19 | 20 | fmt.Print("Enter Number 1 : ") 21 | num1, err := reader.ReadString('\n') 22 | if err != nil { 23 | log.Fatal(err) 24 | } 25 | 26 | // Trims whitespace from guess 27 | num1 = strings.TrimSpace(num1) 28 | iNum1, err := strconv.Atoi(num1) 29 | if err != nil { 30 | log.Fatal(err) 31 | } 32 | 33 | fmt.Print("Enter Number 2 : ") 34 | num2, err := reader.ReadString('\n') 35 | if err != nil { 36 | log.Fatal(err) 37 | } 38 | 39 | // Trims whitespace from guess 40 | num2 = strings.TrimSpace(num2) 41 | iNum2, err := strconv.Atoi(num2) 42 | if err != nil { 43 | log.Fatal(err) 44 | } 45 | 46 | // Use Printf to create formatted string 47 | fmt.Printf("%s + %s = %d\n", num1, num2, 48 | (iNum1 + iNum2)) 49 | } 50 | -------------------------------------------------------------------------------- /GoCore/gotut5.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | var pl = fmt.Println 6 | 7 | func main() { 8 | // ----- FOR LOOPS ----- 9 | // for initialization; condition; postStatement {BODY} 10 | // Print numbers 1 through 5 11 | for x := 1; x <= 5; x++ { 12 | pl(x) 13 | } 14 | // Do the opposite 15 | for x := 5; x >= 1; x-- { 16 | pl(x) 17 | } 18 | 19 | // x is out of the scope of the for loop so it doesn't exist 20 | // pl("x :", x) 21 | 22 | // For is used to create while loops as well 23 | fX := 0 24 | for fX < 5 { 25 | pl(fX) 26 | fX++ 27 | } 28 | 29 | // Cycle through an array with range 30 | // More on arrays later 31 | // We don't need the index so we ignore it 32 | // with the blank identifier _ 33 | aNums := []int{1, 2, 3} 34 | for _, num := range aNums { 35 | pl(num) 36 | } 37 | 38 | // We can allow a condition in the for loop 39 | // to decide when to exit 40 | xVal := 1 41 | for true { 42 | if xVal == 5 { 43 | // Break exits the loop 44 | break 45 | } 46 | pl(xVal) 47 | xVal++ 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /GoCore/gotut5ex.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "log" 7 | "math/rand" 8 | "os" 9 | "strconv" 10 | "strings" 11 | "time" 12 | ) 13 | 14 | var pl = fmt.Println 15 | 16 | func main() { 17 | // Setup buffered reader that gets text from the keyboard 18 | reader := bufio.NewReader(os.Stdin) 19 | 20 | seedSecs := time.Now().Unix() // Returns seconds as int 21 | rand.Seed(seedSecs) 22 | randNum := rand.Intn(50) + 1 23 | 24 | for true { 25 | fmt.Print("Guess a number between 0 and 50 : ") 26 | pl("Random Number is :", randNum) 27 | guess, err := reader.ReadString('\n') 28 | if err != nil { 29 | log.Fatal(err) 30 | } 31 | 32 | // Trims whitespace from guess 33 | guess = strings.TrimSpace(guess) 34 | iGuess, err := strconv.Atoi(guess) 35 | if err != nil { 36 | log.Fatal(err) 37 | } 38 | if iGuess > randNum { 39 | pl("Lower") 40 | } else if iGuess < randNum { 41 | pl("Higher") 42 | } else { 43 | pl("You Guessed it") 44 | break 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /GoCore/gotut6.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | "unicode/utf8" 7 | ) 8 | 9 | var pl = fmt.Println 10 | 11 | func main() { 12 | // ----- STRINGS ----- 13 | // Strings are arrays of bytes []byte 14 | // Escape Sequences : \n \t \" \\ 15 | sV1 := "A word" 16 | 17 | // Replacer that can be used on multiple strings 18 | // to replace one string with another 19 | replacer := strings.NewReplacer("A", "Another") 20 | sV2 := replacer.Replace(sV1) 21 | pl(sV2) 22 | 23 | // Get length 24 | pl("Length : ", len(sV2)) 25 | 26 | // Contains string 27 | pl("Contains Another :", strings.Contains(sV2, "Another")) 28 | 29 | // Get first index match 30 | pl("o index :", strings.Index(sV2, "o")) 31 | 32 | // Replace all matches with 0 33 | // If -1 was 2 it would replace the 1st 2 matches 34 | pl("Replace :", strings.Replace(sV2, "o", "0", -1)) 35 | 36 | // Remove whitespace characters from beginning and end of string 37 | sV3 := "\nSome words\n" 38 | sV3 = strings.TrimSpace(sV3) 39 | 40 | // Split at delimiter 41 | pl("Split :", strings.Split("a-b-c-d", "-")) 42 | 43 | // Upper and lowercase string 44 | pl("Lower :", strings.ToLower(sV2)) 45 | pl("Upper :", strings.ToUpper(sV2)) 46 | 47 | // Prefix or suffix 48 | pl("Prefix :", strings.HasPrefix("tacocat", "taco")) 49 | pl("Suffix :", strings.HasSuffix("tacocat", "cat")) 50 | 51 | // ----- RUNES ----- 52 | // In Go characters are called Runes 53 | // Runes are unicodes that represent characters 54 | rStr := "abcdefg" 55 | 56 | // Runes in string 57 | pl("Rune Count :", utf8.RuneCountInString(rStr)) 58 | 59 | // Print runes in string 60 | for i, runeVal := range rStr { 61 | // Get index, Rune unicode and character 62 | fmt.Printf("%d : %#U : %c\n", i, runeVal, runeVal) 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /GoCore/gotut7.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | var pl = fmt.Println 9 | 10 | func main() { 11 | 12 | // ----- TIME ----- 13 | // Get day, month, year and time data 14 | // Get current time 15 | now := time.Now() 16 | pl(now.Year(), now.Month(), now.Day()) 17 | pl(now.Hour(), now.Minute(), now.Second()) 18 | 19 | // Set a location to get time 20 | loc, err := time.LoadLocation("America/New_York") 21 | if err != nil { 22 | fmt.Println(err) 23 | } 24 | fmt.Printf("Time in New York %s\n", now.In(loc)) 25 | 26 | // Change location to Shanghai 27 | loc, _ = time.LoadLocation("Asia/Shanghai") 28 | fmt.Printf("Time in Shanghai %s\n", now.In(loc)) 29 | 30 | // Get times using different time standards 31 | locEST, _ := time.LoadLocation("EST") 32 | locUTC, _ := time.LoadLocation("UTC") 33 | locMST, _ := time.LoadLocation("MST") 34 | fmt.Printf("EST : %s\n", now.In(locEST)) 35 | fmt.Printf("UTC : %s\n", now.In(locUTC)) 36 | fmt.Printf("MST : %s\n", now.In(locMST)) 37 | 38 | // Calculate time since birthdate 39 | // Year, month, day, hour, minute, second 40 | // nanosecond and time zone 41 | birthDate := time.Date(1974, time.December, 42 | 21, 11, 30, 10, 0, time.Local) 43 | 44 | // Get difference between past date and now 45 | diff := now.Sub(birthDate) 46 | 47 | // Difference in days 48 | fmt.Printf("Days Alive: %d days\n", 49 | int(diff.Hours()/24)) 50 | 51 | // Hours 52 | fmt.Printf("Hours Alive: %d hours\n", 53 | int(diff.Hours())) 54 | } 55 | -------------------------------------------------------------------------------- /GoCore/gotut8.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | var pl = fmt.Println 8 | 9 | func main() { 10 | // ----- ARRAYS ----- 11 | // Collection of values with the same data type 12 | // and the size can't be changed 13 | // Default values are 0, 0.0, false or "" 14 | 15 | // Declare integer array with 5 elements 16 | var arr1 [5]int 17 | 18 | // Assign value to index 19 | arr1[0] = 1 20 | 21 | // Declare and initialize 22 | arr2 := [5]int{1, 2, 3, 4, 5} 23 | 24 | // Get by index 25 | pl("Index 0 :", arr2[0]) 26 | 27 | // Length 28 | pl("Arr Length :", len(arr2)) 29 | 30 | // Iterate with index 31 | for i := 0; i < len(arr2); i++ { 32 | pl(arr2[i]) 33 | } 34 | 35 | // Iterate with range 36 | for i, v := range arr2 { 37 | fmt.Printf("%d : %d\n", i, v) 38 | } 39 | 40 | // Multidimensional Array 41 | arr3 := [2][2]int{ 42 | {1, 2}, 43 | {3, 4}, 44 | } 45 | 46 | // Print multidimensional array 47 | for i := 0; i < 2; i++ { 48 | for j := 0; j < 2; j++ { 49 | pl(arr3[i][j]) 50 | } 51 | } 52 | 53 | // String into slice of runes 54 | aStr1 := "abcde" 55 | rArr := []rune(aStr1) 56 | for _, v := range rArr { 57 | fmt.Printf("Rune Array : %d\n", v) 58 | } 59 | 60 | // Byte array to string 61 | byteArr := []byte{'a', 'b', 'c'} 62 | bStr := string(byteArr[:]) 63 | pl("I'm a string :", bStr) 64 | } 65 | -------------------------------------------------------------------------------- /GoCore/gotut9.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | var pl = fmt.Println 8 | 9 | func main() { 10 | // ----- SLICES ----- 11 | // Slices are like arrays but they can grow 12 | // var name []dataType 13 | // Create a slice with make 14 | sl1 := make([]string, 6) 15 | 16 | // Assign values by index 17 | sl1[0] = "Society" 18 | sl1[1] = "of" 19 | sl1[2] = "the" 20 | sl1[3] = "Simulated" 21 | sl1[4] = "Universe" 22 | 23 | // Size of slice 24 | pl("Slice Size :", len(sl1)) 25 | 26 | // Cycle with for 27 | for i := 0; i < len(sl1); i++ { 28 | pl(sl1[i]) 29 | } 30 | 31 | // Cycle with range 32 | for _, x := range sl1 { 33 | pl(x) 34 | } 35 | 36 | // Create a slice literal 37 | sl2 := []int{12, 21, 1974} 38 | pl(sl2) 39 | 40 | // A slice points at an array and you can create a slice 41 | // of an array (A slice is a view of an underlying array) 42 | // You can have multiple slices point to the same array 43 | sArr := [5]int{1, 2, 3, 4, 5} 44 | // Start at 0 index up to but not including the 2nd index 45 | sl3 := sArr[0:2] 46 | pl(sl3) 47 | 48 | // Get slice from beginning 49 | pl("1st 3 :", sArr[:3]) 50 | 51 | // Get slice to the end 52 | pl("Last 3 :", sArr[2:]) 53 | 54 | // If you change the array the slice also changes 55 | sArr[0] = 10 56 | pl("sl3 :", sl3) 57 | 58 | // Changing the slice also changes the array 59 | sl3[0] = 1 60 | pl("sArr :", sArr) 61 | 62 | // Append a value to a slice (Also overwrites array) 63 | sl3 = append(sl3, 12) 64 | pl("sl3 :", sl3) 65 | pl("sArr :", sArr) 66 | 67 | // Printing empty slices will return nils which show 68 | // as empty slices 69 | sl4 := make([]string, 6) 70 | pl("sl4 :", sl4) 71 | pl("sl4[0] :", sl4[0]) 72 | } 73 | -------------------------------------------------------------------------------- /GoCore/sudoku.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | ) 7 | 8 | /* 9 | SUDOKU RULES 10 | 1. 9 by 9 square 11 | 2. Each row and column must contain numbers 1-9 12 | 3. Each 3x3 square must contain numbers 1-9 13 | 4. No repeats allowed in rows, columns or squares 14 | */ 15 | 16 | // Outputs the current board to screen 17 | func displayBoard(puzz [][]int) { 18 | puzz_cols := len(puzz[0]) 19 | // Cycles through rows in the puzz 20 | for i := 0; i < len(puzz); i++ { 21 | // Cycle through columns in puzz 22 | for j := 0; j < puzz_cols; j++ { 23 | fmt.Print(strconv.Itoa(puzz[i][j]) + " ") 24 | } 25 | fmt.Print("\n") 26 | } 27 | } 28 | 29 | func getEmptySpace(puzz [][]int) (int, int) { 30 | puzz_cols := len(puzz[0]) 31 | // Cycles through rows in the puzz 32 | for i := 0; i < len(puzz); i++ { 33 | // Cycle through columns in puzz 34 | for j := 0; j < puzz_cols; j++ { 35 | if puzz[i][j] == 0 { 36 | return i, j 37 | } 38 | } 39 | } 40 | return -1, -1 41 | } 42 | 43 | // Receives slice, number to check, row & 44 | // column and decides if that number fits 45 | // the rules of the game 46 | func isNumValid(puzz [][]int, guess int, row int, column int) bool { 47 | 48 | // Cycle through all values in row to see 49 | // if the row is valid (We only want index 50 | // which is the 1st value) 51 | for index := range puzz { 52 | // Use index for cycling 53 | // Check if any of the values are equal 54 | // to our guess and also that we didn't 55 | // already place it there in this 56 | // function 57 | if puzz[row][index] == guess && column != index { 58 | return false 59 | } 60 | } 61 | return true 62 | } 63 | 64 | func main() { 65 | 66 | // Holds starting puzzle 67 | puzz := [][]int{ 68 | {0, 0, 0, 0, 3, 5, 0, 7, 0}, 69 | {2, 5, 0, 0, 4, 6, 8, 0, 1}, 70 | {0, 1, 3, 7, 0, 8, 0, 4, 9}, 71 | {1, 9, 0, 0, 0, 7, 0, 0, 4}, 72 | {0, 0, 5, 0, 0, 2, 0, 9, 6}, 73 | {8, 0, 2, 0, 9, 4, 0, 0, 7}, 74 | {3, 7, 0, 0, 0, 9, 0, 0, 0}, 75 | {0, 6, 1, 0, 7, 0, 0, 0, 0}, 76 | {4, 0, 0, 5, 8, 1, 0, 0, 0}, 77 | } 78 | 79 | // ----- TESTING FUNCTIONS ----- 80 | // Displays current board 81 | displayBoard(puzz) 82 | // Returns first open space 83 | row, _ := getEmptySpace(puzz) 84 | if row != -1 { 85 | fmt.Println(getEmptySpace(puzz)) 86 | } else { 87 | fmt.Println("Puzzle is Solved") 88 | } 89 | // Testing if a guess is valid 90 | // Is 1 valid for row 1 91 | fmt.Println(isNumValid(puzz, 1, 0, 0)) 92 | // Is 7 valid for row 1 93 | fmt.Println(isNumValid(puzz, 7, 0, 0)) 94 | 95 | } 96 | -------------------------------------------------------------------------------- /GoCore/sudoku2.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | ) 7 | 8 | /* 9 | SUDOKU RULES 10 | 1. 9 by 9 square 11 | 2. Each row and column must contain numbers 1-9 12 | 3. Each 3x3 square must contain numbers 1-9 13 | 4. No repeats allowed in rows, columns or squares 14 | */ 15 | 16 | // Outputs the current board to screen 17 | func displayBoard(puzz [][]int) { 18 | puzz_cols := len(puzz[0]) 19 | // Cycles through rows in the puzz 20 | for i := 0; i < len(puzz); i++ { 21 | // Cycle through columns in puzz 22 | for j := 0; j < puzz_cols; j++ { 23 | fmt.Print(strconv.Itoa(puzz[i][j]) + " ") 24 | } 25 | fmt.Print("\n") 26 | } 27 | } 28 | 29 | func getEmptySpace(puzz [][]int) (int, int) { 30 | puzz_cols := len(puzz[0]) 31 | // Cycles through rows in the puzz 32 | for i := 0; i < len(puzz); i++ { 33 | // Cycle through columns in puzz 34 | for j := 0; j < puzz_cols; j++ { 35 | if puzz[i][j] == 0 { 36 | return i, j 37 | } 38 | } 39 | } 40 | return -1, -1 41 | } 42 | 43 | // Receives slice, number to check, row & 44 | // column and decides if that number fits 45 | // the rules of the game 46 | func isNumValid(puzz [][]int, guess int, row int, column int) bool { 47 | 48 | // Cycle through all values in row to see 49 | // if the row is valid (We only want index 50 | // which is the 1st value) 51 | for index := range puzz { 52 | // Use index for cycling 53 | // Check if any of the values are equal 54 | // to our guess and also that we didn't 55 | // already place it there in this 56 | // function 57 | if puzz[row][index] == guess && column != index { 58 | return false 59 | } 60 | } 61 | 62 | for index := range puzz { 63 | if puzz[index][column] == guess && column != index { 64 | return false 65 | } 66 | } 67 | 68 | // Is number valid for box? 69 | // Row 0 & Column 3 70 | // Row - (Row % 3) + Value for cycling (0-2) 71 | // 0 - (0 % 3) + 0 = 0 - 0 + 0 = 0 (1st row in box) 72 | // 0 - (0 % 3) + 1 = 0 - 0 + 1 = 1 (1st row in box) 73 | // 0 - (0 % 3) + 2 = 0 - 0 + 2 = 2 (1st row in box) 74 | 75 | // Col - (Col % 3) + Value for cycling (0-2) 76 | // 3 - (3 % 3) + 0 = 3 - 0 + 0 = 3 (1st col in box) 77 | // 3 - (3 % 3) + 1 = 3 - 0 + 1 = 4 (1st col in box) 78 | // 3 - (3 % 3) + 2 = 3 - 0 + 2 = 5 (1st col in box) 79 | 80 | for k := 0; k < 3; k++ { 81 | for l := 0; l < 3; l++ { 82 | if puzz[row-row%3+k][column-column%3+l] == guess && (row-row%3+k != row || column-column%3+l != column) { 83 | return false 84 | } 85 | } 86 | } 87 | 88 | return true 89 | } 90 | 91 | func main() { 92 | 93 | // Holds starting puzzle 94 | puzz := [][]int{ 95 | {0, 0, 0, 0, 3, 5, 0, 7, 0}, 96 | {2, 5, 0, 0, 4, 6, 8, 0, 1}, 97 | {0, 1, 3, 7, 0, 8, 0, 4, 9}, 98 | {1, 9, 0, 0, 0, 7, 0, 0, 4}, 99 | {0, 0, 5, 0, 0, 2, 0, 9, 6}, 100 | {8, 0, 2, 0, 9, 4, 0, 0, 7}, 101 | {3, 7, 0, 0, 0, 9, 0, 0, 0}, 102 | {0, 6, 1, 0, 7, 0, 0, 0, 0}, 103 | {4, 0, 0, 5, 8, 1, 0, 0, 0}, 104 | } 105 | 106 | // ----- TESTING FUNCTIONS ----- 107 | // Displays current board 108 | displayBoard(puzz) 109 | // Returns first open space 110 | row, _ := getEmptySpace(puzz) 111 | if row != -1 { 112 | fmt.Println(getEmptySpace(puzz)) 113 | } else { 114 | fmt.Println("Puzzle is Solved") 115 | } 116 | // Testing if a guess is valid 117 | fmt.Println(isNumValid(puzz, 1, 0, 6)) 118 | 119 | } 120 | -------------------------------------------------------------------------------- /GoCore/sudoku3.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | ) 7 | 8 | /* 9 | SUDOKU RULES 10 | 1. 9 by 9 square 11 | 2. Each row and column must contain numbers 1-9 12 | 3. Each 3x3 square must contain numbers 1-9 13 | 4. No repeats allowed in rows, columns or squares 14 | */ 15 | 16 | // Outputs the current board to screen 17 | func displayBoard(puzz [][]int) { 18 | puzz_cols := len(puzz[0]) 19 | // Cycles through rows in the puzz 20 | for i := 0; i < len(puzz); i++ { 21 | // Cycle through columns in puzz 22 | for j := 0; j < puzz_cols; j++ { 23 | fmt.Print(strconv.Itoa(puzz[i][j]) + " ") 24 | } 25 | fmt.Print("\n") 26 | } 27 | } 28 | 29 | func getEmptySpace(puzz [][]int) (int, int) { 30 | puzz_cols := len(puzz[0]) 31 | // Cycles through rows in the puzz 32 | for i := 0; i < len(puzz); i++ { 33 | // Cycle through columns in puzz 34 | for j := 0; j < puzz_cols; j++ { 35 | if puzz[i][j] == 0 { 36 | return i, j 37 | } 38 | } 39 | } 40 | return -1, -1 41 | } 42 | 43 | // Receives slice, number to check, row & 44 | // column and decides if that number fits 45 | // the rules of the game 46 | func isNumValid(puzz [][]int, guess int, row int, column int) bool { 47 | 48 | // Cycle through all values in row to see 49 | // if the row is valid (We only want index 50 | // which is the 1st value) 51 | for index := range puzz { 52 | // Use index for cycling 53 | // Check if any of the values are equal 54 | // to our guess and also that we didn't 55 | // already place it there in this 56 | // function 57 | if puzz[row][index] == guess && column != index { 58 | return false 59 | } 60 | } 61 | 62 | for index := range puzz { 63 | if puzz[index][column] == guess && column != index { 64 | return false 65 | } 66 | } 67 | 68 | // Is number valid for box? 69 | // Row 0 & Column 3 70 | // Row - (Row % 3) + Value for cycling (0-2) 71 | // 0 - (0 % 3) + 0 = 0 - 0 + 0 = 0 (1st row in box) 72 | // 0 - (0 % 3) + 1 = 0 - 0 + 1 = 1 (1st row in box) 73 | // 0 - (0 % 3) + 2 = 0 - 0 + 2 = 2 (1st row in box) 74 | 75 | // Col - (Col % 3) + Value for cycling (0-2) 76 | // 3 - (3 % 3) + 0 = 3 - 0 + 0 = 3 (1st col in box) 77 | // 3 - (3 % 3) + 1 = 3 - 0 + 1 = 4 (1st col in box) 78 | // 3 - (3 % 3) + 2 = 3 - 0 + 2 = 5 (1st col in box) 79 | 80 | for k := 0; k < 3; k++ { 81 | for l := 0; l < 3; l++ { 82 | if puzz[row-row%3+k][column-column%3+l] == guess && (row-row%3+k != row || column-column%3+l != column) { 83 | return false 84 | } 85 | } 86 | } 87 | return true 88 | } 89 | 90 | /* 91 | ------------------------- 92 | | 0 0 0 | 0 3 5 | 0 7 0 | 93 | | 2 5 0 | 0 4 6 | 8 0 1 | 94 | | 0 1 3 | 7 0 8 | 0 4 9 | 95 | ------------------------- 96 | | 1 9 0 | 0 0 7 | 0 0 4 | 97 | | 0 0 5 | 0 0 2 | 0 9 6 | 98 | | 8 0 2 | 0 9 4 | 0 0 7 | 99 | ------------------------- 100 | | 3 7 0 | 0 0 9 | 0 0 0 | 101 | | 0 6 1 | 0 7 0 | 0 0 0 | 102 | | 4 0 0 | 5 8 1 | 0 0 0 | 103 | ------------------------- 104 | 105 | // Recursion Problem (Solution) 106 | // 1. Cycle across the rows column by column (1-9) 107 | // 2. Check if valid number 108 | // a. If true update array 109 | // b. If false change back to 0 110 | // c. If false find a new value for previous we 111 | // thought was correct 112 | // 3. Check next column 113 | */ 114 | 115 | func main() { 116 | 117 | // Holds starting puzzle 118 | puzz := [][]int{ 119 | {0, 0, 0, 0, 3, 5, 0, 7, 0}, 120 | {2, 5, 0, 0, 4, 6, 8, 0, 1}, 121 | {0, 1, 3, 7, 0, 8, 0, 4, 9}, 122 | {1, 9, 0, 0, 0, 7, 0, 0, 4}, 123 | {0, 0, 5, 0, 0, 2, 0, 9, 6}, 124 | {8, 0, 2, 0, 9, 4, 0, 0, 7}, 125 | {3, 7, 0, 0, 0, 9, 0, 0, 0}, 126 | {0, 6, 1, 0, 7, 0, 0, 0, 0}, 127 | {4, 0, 0, 5, 8, 1, 0, 0, 0}, 128 | } 129 | 130 | // ----- TESTING FUNCTIONS ----- 131 | // Displays current board 132 | displayBoard(puzz) 133 | // Returns first open space 134 | row, _ := getEmptySpace(puzz) 135 | if row != -1 { 136 | fmt.Println(getEmptySpace(puzz)) 137 | } else { 138 | fmt.Println("Puzzle is Solved") 139 | } 140 | // Testing if a guess is valid 141 | fmt.Println(isNumValid(puzz, 1, 0, 6)) 142 | 143 | } 144 | -------------------------------------------------------------------------------- /GoCore/sudoku4.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | ) 7 | 8 | /* 9 | SUDOKU RULES 10 | 1. 9 by 9 square 11 | 2. Each row and column must contain numbers 1-9 12 | 3. Each 3x3 square must contain numbers 1-9 13 | 4. No repeats allowed in rows, columns or squares 14 | */ 15 | 16 | // Outputs the current board to screen 17 | func displayBoard(puzz [][]int) { 18 | puzz_cols := len(puzz[0]) 19 | // Cycles through rows in the puzz 20 | for i := 0; i < len(puzz); i++ { 21 | // Cycle through columns in puzz 22 | for j := 0; j < puzz_cols; j++ { 23 | fmt.Print(strconv.Itoa(puzz[i][j]) + " ") 24 | } 25 | fmt.Print("\n") 26 | } 27 | } 28 | 29 | func getEmptySpace(puzz [][]int) (int, int) { 30 | puzz_cols := len(puzz[0]) 31 | // Cycles through rows in the puzz 32 | for i := 0; i < len(puzz); i++ { 33 | // Cycle through columns in puzz 34 | for j := 0; j < puzz_cols; j++ { 35 | if puzz[i][j] == 0 { 36 | return i, j 37 | } 38 | } 39 | } 40 | return -1, -1 41 | } 42 | 43 | // Receives slice, number to check, row & 44 | // column and decides if that number fits 45 | // the rules of the game 46 | func isNumValid(puzz [][]int, guess int, row int, column int) bool { 47 | 48 | // Cycle through all values in row to see 49 | // if the row is valid (We only want index 50 | // which is the 1st value) 51 | for index := range puzz { 52 | // Use index for cycling 53 | // Check if any of the values are equal 54 | // to our guess and also that we didn't 55 | // already place it there in this 56 | // function 57 | if puzz[row][index] == guess && column != index { 58 | return false 59 | } 60 | } 61 | 62 | // NEW Check if column is valid 63 | for index := range puzz { 64 | if puzz[index][column] == guess && column != index { 65 | return false 66 | } 67 | } 68 | 69 | // NEW Check if the box is valid 70 | // We need to convert all rows and columns 71 | // into their 3x3 version so we can cycle 72 | // through them 73 | 74 | // We need to do math to generate the row and column 75 | // numbers to check in our slice 76 | 77 | // Let's use Row 0 Column 3 as an example 78 | // Row - (Row % 3) + Val for Cycling (0-2) 79 | // 0 - (0 % 3) + 0 = 0 - 0 + 0 = 0 (1st row in box) 80 | // 0 - (0 % 3) + 1 = 0 - 0 + 1 = 1 (2nd row in box) 81 | // 0 - (0 % 3) + 2 = 0 - 0 + 2 = 2 (3rd row in box) 82 | 83 | // Col - (Col % 3) + Val for Cycling (0-2) 84 | // 3 - (3 % 3) + 0 = 3 - 0 + 0 = 3 (1st col in box) 85 | // 3 - (3 % 3) + 1 = 3 - 0 + 1 = 4 (2nd col in box) 86 | // 3 - (3 % 3) + 2 = 3 - 0 + 2 = 5 (3rd col in box) 87 | 88 | for k := 0; k < 3; k++ { 89 | for l := 0; l < 3; l++ { 90 | // We need to check if any element in the box 91 | // is equal to what we just added but skip 92 | // checking the position we just placed our 93 | // value in 94 | if puzz[row-row%3+k][column-column%3+l] == guess && (row-row%3+k != row || column-column%3+l != column) { 95 | return false 96 | } 97 | } 98 | } 99 | 100 | return true 101 | } 102 | 103 | /* 104 | ------------------------- 105 | | 0 0 0 | 0 3 5 | 0 7 0 | 106 | | 2 5 0 | 0 4 6 | 8 0 1 | 107 | | 0 1 3 | 7 0 8 | 0 4 9 | 108 | ------------------------- 109 | | 1 9 0 | 0 0 7 | 0 0 4 | 110 | | 0 0 5 | 0 0 2 | 0 9 6 | 111 | | 8 0 2 | 0 9 4 | 0 0 7 | 112 | ------------------------- 113 | | 3 7 0 | 0 0 9 | 0 0 0 | 114 | | 0 6 1 | 0 7 0 | 0 0 0 | 115 | | 4 0 0 | 5 8 1 | 0 0 0 | 116 | ------------------------- 117 | 6 4 8 1 2 #9 (Change 9 to 0 and try another 2) 118 | 9 2 (1st row done) 119 | 7 9 3 (2nd row done) 120 | #9 121 | ------------------------- 122 | | 6 4 8 | 1 3 5 | 9 7 2 | 123 | | 2 5 7 | 9 4 6 | 8 3 1 | 124 | | 0 1 3 | 7 0 8 | 0 4 9 | 125 | ------------------------- 126 | */ 127 | 128 | /* 129 | 9 8 4 1 3 5 6 7 2 130 | 2 5 7 9 4 6 8 3 1 131 | 6 1 3 7 2 8 5 4 9 132 | 1 9 6 3 5 7 2 8 4 133 | 7 4 5 8 1 2 3 9 6 134 | 8 3 2 6 9 4 1 5 7 135 | 3 7 8 2 6 9 4 1 5 136 | 5 6 1 3 7 4 9 2 8 137 | 4 2 9 5 8 1 7 6 3 138 | */ 139 | 140 | // Recursively solves puzzle by placing values 141 | // if it reaches a point where there is no 142 | // valid answer it changes the previous 143 | // supposedly correct answer back and tries 144 | // another value for what we previously though was 145 | // correct 146 | 147 | // By using this backtracking when we get to the 9 9 148 | // position on our board we know we solved the puzzle 149 | func solvePuzzle(puzz [][]int) bool { 150 | // Check for empty space and if there 151 | // is none return true meaning the puzzle 152 | // is solved, otherwise solve the puzzle 153 | row, column := getEmptySpace(puzz) 154 | if row == -1 { 155 | return true 156 | } else { 157 | row, column = getEmptySpace(puzz) 158 | } 159 | 160 | // Check if we can add a 1 through 9 into the 161 | // empty space 162 | for i := 1; i <= 9; i++ { 163 | // Is this a valid number? 164 | if isNumValid(puzz, i, row, column) { 165 | // If so put it in the empty space 166 | puzz[row][column] = i 167 | 168 | // Continue until solvePuzzle with new puzz 169 | // until it returns true meaning we no longer 170 | // have empty spaces and we are finished 171 | if solvePuzzle(puzz) { 172 | return true 173 | } 174 | // If solvePuzzle doesn't return true we 175 | // reset to an empty space and backtrack 176 | // and try the next value in the for loop 177 | puzz[row][column] = 0 178 | } 179 | } 180 | return false 181 | } 182 | 183 | func main() { 184 | 185 | // Holds starting puzzle 186 | puzz := [][]int{ 187 | {0, 0, 0, 0, 3, 5, 0, 7, 0}, 188 | {2, 5, 0, 0, 4, 6, 8, 0, 1}, 189 | {0, 1, 3, 7, 0, 8, 0, 4, 9}, 190 | {1, 9, 0, 0, 0, 7, 0, 0, 4}, 191 | {0, 0, 5, 0, 0, 2, 0, 9, 6}, 192 | {8, 0, 2, 0, 9, 4, 0, 0, 7}, 193 | {3, 7, 0, 0, 0, 9, 0, 0, 0}, 194 | {0, 6, 1, 0, 7, 0, 0, 0, 0}, 195 | {4, 0, 0, 5, 8, 1, 0, 0, 0}, 196 | } 197 | 198 | // ----- TESTING FUNCTIONS ----- 199 | // Displays current board 200 | displayBoard(puzz) 201 | // Returns first open space 202 | row, _ := getEmptySpace(puzz) 203 | if row != -1 { 204 | fmt.Println(getEmptySpace(puzz)) 205 | } else { 206 | fmt.Println("Puzzle is Solved") 207 | } 208 | // Testing if a guess is valid 209 | // Is 1 valid for row 1 210 | // fmt.Println(isNumValid(puzz, 1, 0, 0)) 211 | // Is 7 valid for row 1 212 | // fmt.Println(isNumValid(puzz, 7, 0, 0)) 213 | 214 | // NEW 215 | // Testing if row and column is valid 216 | fmt.Println(isNumValid(puzz, 1, 0, 0)) 217 | fmt.Println(isNumValid(puzz, 6, 0, 0)) 218 | fmt.Println(isNumValid(puzz, 9, 0, 0)) 219 | fmt.Println(isNumValid(puzz, 2, 0, 1)) 220 | 221 | fmt.Println(isNumValid(puzz, 7, 4, 0)) 222 | fmt.Println(isNumValid(puzz, 8, 4, 1)) 223 | 224 | displayBoard(puzz) 225 | fmt.Println() 226 | solvePuzzle(puzz) 227 | displayBoard(puzz) 228 | } 229 | -------------------------------------------------------------------------------- /PostgreSQL and Go.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/derekbanas/golang-udemy/169b23d59d49e6ac0a08861966b988356bfc54f4/PostgreSQL and Go.zip -------------------------------------------------------------------------------- /Postgres-Files/PostgreSQL 10 Similar Like and Regex.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/derekbanas/golang-udemy/169b23d59d49e6ac0a08861966b988356bfc54f4/Postgres-Files/PostgreSQL 10 Similar Like and Regex.docx -------------------------------------------------------------------------------- /Postgres-Files/PostgreSQL 11 Views.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/derekbanas/golang-udemy/169b23d59d49e6ac0a08861966b988356bfc54f4/Postgres-Files/PostgreSQL 11 Views.docx -------------------------------------------------------------------------------- /Postgres-Files/PostgreSQL 12 SQL Functions.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/derekbanas/golang-udemy/169b23d59d49e6ac0a08861966b988356bfc54f4/Postgres-Files/PostgreSQL 12 SQL Functions.docx -------------------------------------------------------------------------------- /Postgres-Files/PostgreSQL 13 SQL Functions 2.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/derekbanas/golang-udemy/169b23d59d49e6ac0a08861966b988356bfc54f4/Postgres-Files/PostgreSQL 13 SQL Functions 2.docx -------------------------------------------------------------------------------- /Postgres-Files/PostgreSQL 14 pgSQL Functions.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/derekbanas/golang-udemy/169b23d59d49e6ac0a08861966b988356bfc54f4/Postgres-Files/PostgreSQL 14 pgSQL Functions.docx -------------------------------------------------------------------------------- /Postgres-Files/PostgreSQL 15 pgSQL Functions 2.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/derekbanas/golang-udemy/169b23d59d49e6ac0a08861966b988356bfc54f4/Postgres-Files/PostgreSQL 15 pgSQL Functions 2.docx -------------------------------------------------------------------------------- /Postgres-Files/PostgreSQL 16 pgSQL 3.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/derekbanas/golang-udemy/169b23d59d49e6ac0a08861966b988356bfc54f4/Postgres-Files/PostgreSQL 16 pgSQL 3.docx -------------------------------------------------------------------------------- /Postgres-Files/PostgreSQL 17 Stored Procedures.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/derekbanas/golang-udemy/169b23d59d49e6ac0a08861966b988356bfc54f4/Postgres-Files/PostgreSQL 17 Stored Procedures.docx -------------------------------------------------------------------------------- /Postgres-Files/PostgreSQL 18 Triggers.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/derekbanas/golang-udemy/169b23d59d49e6ac0a08861966b988356bfc54f4/Postgres-Files/PostgreSQL 18 Triggers.docx -------------------------------------------------------------------------------- /Postgres-Files/PostgreSQL 19 Cursors.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/derekbanas/golang-udemy/169b23d59d49e6ac0a08861966b988356bfc54f4/Postgres-Files/PostgreSQL 19 Cursors.docx -------------------------------------------------------------------------------- /Postgres-Files/PostgreSQL 2 Intro Code.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/derekbanas/golang-udemy/169b23d59d49e6ac0a08861966b988356bfc54f4/Postgres-Files/PostgreSQL 2 Intro Code.txt -------------------------------------------------------------------------------- /Postgres-Files/PostgreSQL 20.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/derekbanas/golang-udemy/169b23d59d49e6ac0a08861966b988356bfc54f4/Postgres-Files/PostgreSQL 20.docx -------------------------------------------------------------------------------- /Postgres-Files/PostgreSQL 3 Data Types.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/derekbanas/golang-udemy/169b23d59d49e6ac0a08861966b988356bfc54f4/Postgres-Files/PostgreSQL 3 Data Types.docx -------------------------------------------------------------------------------- /Postgres-Files/PostgreSQL 4 INSERT ALTER CUSTOM TYPES.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/derekbanas/golang-udemy/169b23d59d49e6ac0a08861966b988356bfc54f4/Postgres-Files/PostgreSQL 4 INSERT ALTER CUSTOM TYPES.docx -------------------------------------------------------------------------------- /Postgres-Files/PostgreSQL 5 Organizing Tables.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/derekbanas/golang-udemy/169b23d59d49e6ac0a08861966b988356bfc54f4/Postgres-Files/PostgreSQL 5 Organizing Tables.docx -------------------------------------------------------------------------------- /Postgres-Files/PostgreSQL 6 Altering Tables.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/derekbanas/golang-udemy/169b23d59d49e6ac0a08861966b988356bfc54f4/Postgres-Files/PostgreSQL 6 Altering Tables.docx -------------------------------------------------------------------------------- /Postgres-Files/PostgreSQL 7 Inserting Data.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/derekbanas/golang-udemy/169b23d59d49e6ac0a08861966b988356bfc54f4/Postgres-Files/PostgreSQL 7 Inserting Data.docx -------------------------------------------------------------------------------- /Postgres-Files/PostgreSQL 8 Getting Data from One Table.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/derekbanas/golang-udemy/169b23d59d49e6ac0a08861966b988356bfc54f4/Postgres-Files/PostgreSQL 8 Getting Data from One Table.docx -------------------------------------------------------------------------------- /Postgres-Files/PostgreSQL 9 Getting Data From Multiple Tables.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/derekbanas/golang-udemy/169b23d59d49e6ac0a08861966b988356bfc54f4/Postgres-Files/PostgreSQL 9 Getting Data From Multiple Tables.docx -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # golang-udemy 2 | Code from my Go Udemy course. It covers the core language with a focus on problem solving. It then focuses on creating complex web applications in stages. As an added benefit I also provide a tutorial on PostgreSQL. 3 | -------------------------------------------------------------------------------- /web1/go.mod: -------------------------------------------------------------------------------- 1 | module web1 2 | 3 | go 1.18 4 | -------------------------------------------------------------------------------- /web1/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "net/http" 7 | ) 8 | 9 | func main() { 10 | http.HandleFunc("/", func(w http.ResponseWriter, 11 | r *http.Request) { 12 | nb, err := fmt.Fprintf(w, "Hello Browser") 13 | if err != nil { 14 | fmt.Println(err) 15 | } 16 | fmt.Printf("Bytes Written : %d", nb) 17 | }) 18 | err := http.ListenAndServe("localhost:8080", nil) 19 | log.Fatal(err) 20 | } 21 | -------------------------------------------------------------------------------- /web2/go.mod: -------------------------------------------------------------------------------- 1 | module web2 2 | 3 | go 1.18 4 | -------------------------------------------------------------------------------- /web2/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "html/template" 7 | "log" 8 | "net/http" 9 | ) 10 | 11 | func write(writer http.ResponseWriter, 12 | msg string) { 13 | _, err := writer.Write([]byte(msg)) 14 | if err != nil { 15 | log.Fatal(err) 16 | } 17 | } 18 | 19 | func renderTemplate(w http.ResponseWriter, tmpl string) { 20 | parsedTemplate, err := template.ParseFiles("./templates/" + tmpl) 21 | errorCheck(err) 22 | err = parsedTemplate.Execute(w, nil) 23 | errorCheck(err) 24 | } 25 | 26 | func errorCheck(err error) { 27 | if err != nil { 28 | log.Fatal(err) 29 | } 30 | } 31 | 32 | func homeHandler(w http.ResponseWriter, 33 | request *http.Request) { 34 | renderTemplate(w, "home.page.tmpl") 35 | } 36 | 37 | func addHandler(writer http.ResponseWriter, 38 | request *http.Request) { 39 | write(writer, "Hello internet\n") 40 | sum := getSum(5, 4) 41 | output := fmt.Sprintf("5 + 4 = %d\n", sum) 42 | write(writer, output) 43 | } 44 | 45 | func getSum(x, y int) int { 46 | return x + y 47 | } 48 | 49 | func divideHandler(writer http.ResponseWriter, 50 | request *http.Request) { 51 | v, err := getQuotient(5, 4) 52 | if err != nil { 53 | write(writer, "can't divide by zero\n") 54 | } else { 55 | output := fmt.Sprintf("5 / 4 = %.2f\n", v) 56 | write(writer, output) 57 | } 58 | } 59 | 60 | func getQuotient(x, y float32) (float32, error) { 61 | if y == 0 { 62 | err := errors.New("cannot divide by zero") 63 | return 0, err 64 | } else { 65 | return (x / y), nil 66 | } 67 | } 68 | 69 | func main() { 70 | http.HandleFunc("/", homeHandler) 71 | http.HandleFunc("/getsum", addHandler) 72 | http.HandleFunc("/divide", divideHandler) 73 | 74 | err := http.ListenAndServe("localhost:8080", nil) 75 | log.Fatal(err) 76 | } 77 | -------------------------------------------------------------------------------- /web2/templates/about.page.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 |

About Us

11 |

We will talk about ourselves here

12 | 13 | -------------------------------------------------------------------------------- /web2/templates/home.page.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 |

Home

11 |

This is the best web page ever

12 | 13 | -------------------------------------------------------------------------------- /web3 - 29.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/derekbanas/golang-udemy/169b23d59d49e6ac0a08861966b988356bfc54f4/web3 - 29.zip -------------------------------------------------------------------------------- /web3 11-12.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/derekbanas/golang-udemy/169b23d59d49e6ac0a08861966b988356bfc54f4/web3 11-12.zip -------------------------------------------------------------------------------- /web3 13.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/derekbanas/golang-udemy/169b23d59d49e6ac0a08861966b988356bfc54f4/web3 13.zip -------------------------------------------------------------------------------- /web3 14.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/derekbanas/golang-udemy/169b23d59d49e6ac0a08861966b988356bfc54f4/web3 14.zip -------------------------------------------------------------------------------- /web3 21 - 28.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/derekbanas/golang-udemy/169b23d59d49e6ac0a08861966b988356bfc54f4/web3 21 - 28.zip -------------------------------------------------------------------------------- /web3-1-6.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/derekbanas/golang-udemy/169b23d59d49e6ac0a08861966b988356bfc54f4/web3-1-6.zip -------------------------------------------------------------------------------- /web3-10.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/derekbanas/golang-udemy/169b23d59d49e6ac0a08861966b988356bfc54f4/web3-10.zip -------------------------------------------------------------------------------- /web3-7.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/derekbanas/golang-udemy/169b23d59d49e6ac0a08861966b988356bfc54f4/web3-7.zip -------------------------------------------------------------------------------- /web3-8-9.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/derekbanas/golang-udemy/169b23d59d49e6ac0a08861966b988356bfc54f4/web3-8-9.zip --------------------------------------------------------------------------------