learned I didn't need git for external modules and different folders can have different mains

This commit is contained in:
2024-02-03 11:00:34 -05:00
parent 943191e9dd
commit 19b1581f10
37 changed files with 439 additions and 16 deletions

View File

@ -0,0 +1,22 @@
package main
import (
"fmt"
"log"
"os"
"strconv"
)
func main() {
arguments := os.Args[1:]
var sum float64 = 0
for _, argument := range arguments {
number, err := strconv.ParseFloat(argument, 64)
if err != nil {
log.Fatal(err)
}
sum += number
}
sampleCount := float64(len(arguments))
fmt.Printf("Average: %0.2f\n", sum/sampleCount)
}

View File

@ -0,0 +1,18 @@
package main
import "fmt"
func sum(numbers ...int) int {
var sum int = 0
for _, number := range numbers {
sum += number
}
return sum
}
func main() {
fmt.Println(sum(4, 1, 9, 2))
fmt.Println(sum(7))
}

View File

@ -0,0 +1,24 @@
package main
import (
"fmt"
"strings"
"trying_out_go/pkg/datafile"
"trying_out_go/pkg/keyboard"
)
func averageHeadFirstSolution() {
fmt.Printf("What is the name of the file: ")
fileString, err := keyboard.GetString()
Error(err)
fileString = strings.TrimSpace(fileString)
numbers, err := datafile.GetFloats(fileString)
Error(err)
var sum float64 = 0
for _, number := range numbers {
sum += number
}
sampleCount := float64(len(numbers))
fmt.Printf("Average: %0.2f\n", sum/sampleCount)
}

View File

@ -0,0 +1,26 @@
package main
import (
"fmt"
"os"
"strconv"
)
func averageCalc(numbers ...float64) float64 {
var sum float64 = 0
for _, number := range numbers {
sum += number
}
return sum / float64(len(numbers))
}
func averageHeadFirstVariadic() {
arguments := os.Args[1:]
var numbers []float64
for _, argument := range arguments {
number, err := strconv.ParseFloat(argument, 64)
Error(err)
numbers = append(numbers, number)
}
fmt.Printf("Average: %0.2\n", averageCalc(numbers...))
}

View File

@ -0,0 +1,37 @@
package main
import (
"bufio"
"fmt"
"log"
"os"
"strconv"
"strings"
"trying_out_go/pkg/keyboard"
)
func averageMySolution() {
fmt.Printf("What is the name of the file: ")
fileString, err := keyboard.GetString()
Error(err)
fileString = strings.TrimSpace(fileString)
file, err := os.Open(fileString)
Error(err)
var sum float64 = 0
scanner := bufio.NewScanner(file)
counter := 0
for scanner.Scan() {
number, err := strconv.ParseFloat(scanner.Text(), 64)
Error(err)
sum += number
counter++
}
err = file.Close()
Error(err)
if scanner.Err() != nil {
log.Fatal(scanner.Err())
}
sampleCount := float64(counter)
fmt.Printf("Average: %0.2f\n", sum/sampleCount)
}

View File

@ -0,0 +1,16 @@
package main
import "fmt"
func average(numbers ...float64) float64 {
var sum float64 = 0
for _, number := range numbers {
sum += number
}
return sum / float64(len(numbers))
}
func averageVariadic() {
fmt.Println(average(100, 50))
fmt.Println(average(90.7, 89.7, 98.5, 92.3))
}

View File

@ -0,0 +1,24 @@
// from chapter 10
package main
import (
"fmt"
"trying_out_go/pkg/calendar"
)
func companyCalendar() {
event := calendar.Event{}
err := event.SetTitle("Mom's Birthday")
Error(err)
err = event.SetYear(2019)
Error(err)
err = event.SetMonth(5)
Error(err)
err = event.SetDay(27)
Error(err)
fmt.Println(event.Title())
fmt.Println(event.Year())
fmt.Println(event.Month())
fmt.Println(event.Day())
}

View File

@ -0,0 +1,56 @@
// from Chapter 7 of Head First Go
package main
import (
"fmt"
"sort"
"strings"
"trying_out_go/pkg/datafile"
"trying_out_go/pkg/keyboard"
)
func countVotes() {
fmt.Printf("What is the name of the file: ")
fileString, err := keyboard.GetString()
Error(err)
fileString = strings.TrimSpace(fileString)
lines, err := datafile.GetStrings(fileString)
Error(err)
// Count the hard way with slices
var names []string
var counts []int
for _, line := range lines {
matched := false
for i, name := range names {
if name == line {
counts[i]++
matched = true
}
}
if matched == false {
names = append(names, line)
counts = append(counts, 1)
}
}
for i, name := range names {
fmt.Printf("%s: %d\n", name, counts[i])
}
fmt.Println("")
// Easy way
votes := make(map[string]int)
var namesMap []string
for _, line := range lines {
votes[line]++
}
for name := range votes {
namesMap = append(namesMap, name)
}
sort.Strings(namesMap)
for _, name := range namesMap {
fmt.Printf("%v: %v\n", name, votes[name])
}
}

View File

@ -0,0 +1,28 @@
package main
import (
"fmt"
"os"
"path/filepath"
)
func scanDirectory(path string) {
fmt.Println(path)
files, err := os.ReadDir(path)
if err != nil {
panic(err)
}
for _, file := range files {
filePath := filepath.Join(path, file.Name())
if file.IsDir() {
scanDirectory(filePath)
} else {
fmt.Println(filePath)
}
}
}
func directory() {
scanDirectory("../../trying_out_go")
}

13
cmd/playground/double.go Normal file
View File

@ -0,0 +1,13 @@
package main
import "fmt"
func makeDouble(number *int) {
*number *= 2
}
func double() {
amount := 6
makeDouble(&amount)
fmt.Println(amount)
}

10
cmd/playground/error.go Normal file
View File

@ -0,0 +1,10 @@
package main
import "log"
func Error(err error) {
if err != nil {
log.Fatal(err)
}
return
}

66
cmd/playground/fuel.go Normal file
View File

@ -0,0 +1,66 @@
// part of chapter 9
package main
import "fmt"
type Liters float64
func (l Liters) String() string {
return fmt.Sprintf("%0.2f L", l)
}
type Gallons float64
func (g Gallons) String() string {
return fmt.Sprintf("%0.2f gal", g)
}
type Milliliters float64
func (m Milliliters) String() string {
return fmt.Sprintf("%0.2f mL", m)
}
func (l Liters) ToGallons() Gallons {
return Gallons(l * 0.264)
}
func (m Milliliters) ToGallons() Gallons {
return Gallons(m * 0.000264)
}
func (g Gallons) ToLiters() Liters {
return Liters(g * 3.785)
}
func (g Gallons) ToMilliliters() Milliliters {
return Milliliters(g * 3785.41)
}
func fuel() {
// long version
//var carFuel Gallons
//var busFuel Liters
//carFuel = Gallons(10.0)
//busFuel = Liters(240.0)
// short version
soda := Liters(2)
fmt.Printf("%0.0f liters equals %0.3f gallons\n", soda, soda.ToGallons())
water := Milliliters(500)
fmt.Printf("%0.0f milliliters equals %0.3f gallons \n", water, water.ToGallons())
//carFuel := Gallons(10.0)
//busFuel := Liters(240.0)
//
////if you want to convert between types, save variable with correct calculation
//carFuel += ToGallons(Liters(40.0))
//busFuel += ToLiters(Gallons(30.0))
//fmt.Printf("Car Fuel: %0.1f gallons\n", carFuel)
//fmt.Printf("Bus Fuel: %0.1f liters\n", busFuel)
milk := Gallons(2)
fmt.Printf("%0.0f gallons equals %0.3f liters\n", milk, milk.ToLiters())
fmt.Printf("%0.0f gallons equals %0.3f milliliters\n", milk, milk.ToMilliliters())
fmt.Println(Gallons(12.09285934))
fmt.Println(Liters(12.09285934))
fmt.Println(Milliliters(12.09285934))
}

47
cmd/playground/guess.go Normal file
View File

@ -0,0 +1,47 @@
package main
import (
"bufio"
"fmt"
"log"
"math/rand"
"os"
"strconv"
"strings"
)
func guess() {
numberToGuess := rand.Intn(100) + 1
for i := 10; i > 0; i-- {
fmt.Println("Please guess a number from 1 to 100")
fmt.Printf("You have %v guesses left.\n", i)
reader := bufio.NewReader(os.Stdin)
input, err := reader.ReadString('\n')
if err != nil {
log.Fatal(err)
}
input = strings.TrimSpace(input)
guess, err := strconv.Atoi(input)
if err != nil {
log.Fatal(err)
}
if guess == numberToGuess {
fmt.Println("Great job! You guessed it!")
os.Exit(0)
}
if guess > numberToGuess {
fmt.Println("Oops. Your guess was HIGH.")
continue
}
if guess < numberToGuess {
fmt.Println("Oops. Your guess was LOW.")
continue
}
if i == 1 {
fmt.Printf("Sorry. You didn't guess my number. It was: %v\n", numberToGuess)
os.Exit(0)
}
}
}

View File

@ -0,0 +1,46 @@
// from chapter 8 of head first go
package main
import (
"fmt"
"trying_out_go/pkg/magazine"
)
func printInfo(s *magazine.Subscriber) {
fmt.Println("Name:", s.Name)
fmt.Println("Monthly rate:", s.Rate)
fmt.Println("Active?:", s.Active)
}
func defaultSubscriber(name string) *magazine.Subscriber {
s := magazine.Subscriber{
Name: name,
Rate: 5.99,
Active: true,
}
s.Street = "123 Oak St."
s.City = "Omaha"
s.State = "NE"
s.PostalCode = "68111"
return &s
}
// accept a point to modify original struct
func applyDiscount(s *magazine.Subscriber) {
s.Rate = 4.99
}
func magazineSubscribers() {
employee := magazine.Employee{Name: "Joy Carr", Salary: 60000}
fmt.Println(employee.Name)
fmt.Println(employee.Salary)
subscriber := defaultSubscriber("Aman Singh")
applyDiscount(subscriber)
printInfo(subscriber)
fmt.Println(subscriber.State)
subscriber2 := defaultSubscriber("Beth Ryan")
printInfo(subscriber2)
}

View File

@ -0,0 +1,12 @@
package main
import "fmt"
func myIntPointer() {
var myInt int
var myIntPointer *int
myInt = 42
myIntPointer = &myInt
fmt.Println(*myIntPointer)
}

View File

@ -0,0 +1,25 @@
package main
import (
"fmt"
"log"
"trying_out_go/pkg/keyboard"
)
func passFail() {
fmt.Print("Enter a grade: ")
grade, err := keyboard.GetFloat()
if err != nil {
log.Fatal(err)
}
var status string
if grade >= 60 {
status = "passing"
} else {
status = "failing"
}
fmt.Println("A grade of", grade, "is", status)
}

View File

@ -0,0 +1,145 @@
package main
import (
"fmt"
"log"
"github.com/dixonwille/wmenu/v5"
)
func main() {
type program struct {
name string
launchFunction func()
}
programs := []program{
{
name: "Pass or Fail",
launchFunction: func() {
passFail()
},
},
{
name: "Guessing Game",
launchFunction: func() {
guess()
},
},
{
name: "Shopping List",
launchFunction: func() {
shopping()
},
},
{
name: "Commandline Test",
launchFunction: func() {
terminalTest()
},
},
{
name: "Wall Area",
launchFunction: func() {
wallArea()
},
},
{
name: "myIntPointer",
launchFunction: func() {
myIntPointer()
},
},
{
name: "Double",
launchFunction: func() {
double()
},
},
{
name: "Convert To Celsius",
launchFunction: func() {
toCelsius()
},
},
{
name: "Get the Average My Solution",
launchFunction: func() {
averageMySolution()
},
},
{
name: "Get the Average Head First Solution",
launchFunction: func() {
averageHeadFirstSolution()
},
},
{
name: "Get the Average Variadic",
launchFunction: func() {
averageVariadic()
},
},
{
name: "Slices",
launchFunction: func() {
slices()
},
},
{
name: "Variadic Functions",
launchFunction: func() {
variadic()
},
},
{
name: "Count Votes",
launchFunction: func() {
countVotes()
},
},
{
name: "Magazine Subscribers",
launchFunction: func() {
magazineSubscribers()
},
},
{
name: "Fuel",
launchFunction: func() {
fuel()
},
},
{
name: "Calendar",
launchFunction: func() {
companyCalendar()
},
},
{
name: "Directory List",
launchFunction: func() {
directory()
},
},
}
menu := wmenu.NewMenu("Choose a program.")
menu.Action(func(opts []wmenu.Opt) error {
fmt.Printf("You chose " + opts[0].Text + ". Launching...\n")
for _, v := range programs {
if v.name == opts[0].Text {
v.launchFunction()
}
}
return nil
})
menu.PadOptionID()
for _, option := range programs {
menu.Option(option.name, nil, false, nil)
}
err := menu.Run()
if err != nil {
log.Fatal(err)
}
}

107
cmd/playground/shopping.go Normal file
View File

@ -0,0 +1,107 @@
package main
import (
"fmt"
"os"
tea "github.com/charmbracelet/bubbletea"
)
type shoppingModel struct {
choices []string // items on the shopping list
cursor int // which shopping list item our cursor is pointing at
selected map[int]struct{} // which shopping items are selected
}
func initialModel() shoppingModel {
return shoppingModel{
// Our shopping list is a grocery list
choices: []string{"Buy Carrots", "Buy Celery", "Buy Kohlrabi"},
// A map which indicates which choices are selected. We're using
// the map like a mathematical set. The keys refer to the indexes
// of the `choices` slice, above.
selected: make(map[int]struct{}),
}
}
func (m shoppingModel) Init() tea.Cmd {
// Just return `nil`, which means "no I/O right now, please."
return nil
}
func (m shoppingModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
// Is it a key press?
case tea.KeyMsg:
// Cool, what was the actual key pressed?
switch msg.String() {
case "ctrl+c", "q":
return m, tea.Quit
// The "up" and "k" keys move the cursor up
case "up", "k":
if m.cursor > 0 {
m.cursor--
}
// The "down" and "j" keys move the cursor down
case "down", "j":
if m.cursor < len(m.choices)-1 {
m.cursor++
}
// The "enter" key and the spacebar (a literal space) toggle
// the selected state for the item that the cursor is pointing at.
case "enter", " ":
_, ok := m.selected[m.cursor]
if ok {
delete(m.selected, m.cursor)
} else {
m.selected[m.cursor] = struct{}{}
}
}
}
// Return the updated shoppingModel to the Bubble Tea runtime for processing.
// Note that we're not returning a command.
return m, nil
}
func (m shoppingModel) View() string {
// The header
s := "What should we buy at the market? \n\n"
// Iterate over our choices
for i, choice := range m.choices {
// Is the cursor pointing at this choice?
cursor := " " // no cursor
if m.cursor == i {
cursor = ">" // cursor!
}
// Is this choice selected?
checked := " " // not selected
if _, ok := m.selected[i]; ok {
checked = "x" // selected!
}
// Render the row
s += fmt.Sprintf("%s [%s] %s\n", cursor, checked, choice)
}
// The footer
s += "\nPress q to quit.\n"
// Send the UI for rendering
return s
}
func shopping() {
p := tea.NewProgram(initialModel())
if _, err := p.Run(); err != nil {
fmt.Printf("Alas, there's been an error: %v", err)
os.Exit(1)
}
}

41
cmd/playground/slices.go Normal file
View File

@ -0,0 +1,41 @@
package main
import "fmt"
func slices() {
var notes []string
notes = make([]string, 7)
notes[0] = "do"
notes[1] = "re"
notes[2] = "mi"
fmt.Println(notes[0])
fmt.Println(notes[1])
fmt.Println(len(notes))
primes := make([]int, 5)
primes[0] = 2
primes[1] = 3
primes[2] = 5
primes[3] = 7
primes[4] = 11
fmt.Println(primes[0])
fmt.Println(primes[1])
fmt.Println(primes[2])
fmt.Println(primes[3])
fmt.Println(primes[4])
fmt.Println(len(primes))
literalNotes := []string{"do", "re", "mi", "fa", "so", "la", "ti"}
fmt.Println(literalNotes[3], literalNotes[6], literalNotes[0])
literalPrimes := []int{
2,
3,
5,
}
fmt.Println(literalPrimes[0], literalPrimes[1], literalPrimes[2])
fmt.Println(literalPrimes, len(literalPrimes))
literalPrimes = append(literalPrimes, 7, 11)
fmt.Println(literalPrimes, len(literalPrimes))
}

86
cmd/playground/test.go Normal file
View File

@ -0,0 +1,86 @@
package main
import (
"fmt"
"os"
"github.com/charmbracelet/bubbles/list"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
)
var docStyle = lipgloss.NewStyle().Margin(1, 2)
type item struct {
title, desc string
}
func (i item) Title() string { return i.title }
func (i item) Description() string { return i.desc }
func (i item) FilterValue() string { return i.title }
type testModel struct {
list list.Model
}
func (m testModel) Init() tea.Cmd {
return nil
}
func (m testModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.KeyMsg:
if msg.String() == "ctrl+c" {
return m, tea.Quit
}
case tea.WindowSizeMsg:
h, v := docStyle.GetFrameSize()
m.list.SetSize(msg.Width-h, msg.Height-v)
}
var cmd tea.Cmd
m.list, cmd = m.list.Update(msg)
return m, cmd
}
func (m testModel) View() string {
return docStyle.Render(m.list.View())
}
func terminalTest() {
items := []list.Item{
item{title: "Raspberry Pis", desc: "I have em all over my house"},
item{title: "Nutella", desc: "It's good on toast"},
item{title: "Bitter melon", desc: "It cools you down"},
item{title: "Nice socks", desc: "And by that I mean socks without holes"},
item{title: "Eight hours of sleep", desc: "I had this once"},
item{title: "Cats", desc: "Usually"},
item{title: "Plantasia, the album", desc: "My plants love it too"},
item{title: "Pour over coffee", desc: "It takes forever to make though"},
item{title: "VR", desc: "Virtual reality...what is there to say?"},
item{title: "Noguchi Lamps", desc: "Such pleasing organic forms"},
item{title: "Linux", desc: "Pretty much the best OS"},
item{title: "Business school", desc: "Just kidding"},
item{title: "Pottery", desc: "Wet clay is a great feeling"},
item{title: "Shampoo", desc: "Nothing like clean hair"},
item{title: "Table tennis", desc: "Its surprisingly exhausting"},
item{title: "Milk crates", desc: "Great for packing in your extra stuff"},
item{title: "Afternoon tea", desc: "Especially the tea sandwich part"},
item{title: "Stickers", desc: "The thicker the vinyl the better"},
item{title: "20° Weather", desc: "Celsius, not Fahrenheit"},
item{title: "Warm light", desc: "Like around 2700 Kelvin"},
item{title: "The vernal equinox", desc: "The autumnal equinox is pretty good too"},
item{title: "Gaffers tape", desc: "Basically sticky fabric"},
item{title: "Terrycloth", desc: "In other words, towel fabric"},
}
m := testModel{list: list.New(items, list.NewDefaultDelegate(), 0, 0)}
m.list.Title = "My Fave Things"
p := tea.NewProgram(m, tea.WithAltScreen())
if _, err := p.Run(); err != nil {
fmt.Println("Error running program:", err)
os.Exit(1)
}
}

View File

@ -0,0 +1,18 @@
package main
import (
"fmt"
"log"
"trying_out_go/pkg/keyboard"
)
func toCelsius() {
fmt.Println("Enter a temperature in Fahrenheit: ")
fahrenheit, err := keyboard.GetFloat()
if err != nil {
log.Fatal(err)
}
celsius := (fahrenheit - 32) * 5 / 9
fmt.Printf("%0.2f degrees Celsius\n", celsius)
}

View File

@ -0,0 +1,33 @@
package main
import (
"fmt"
"math"
)
func maximum(numbers ...float64) float64 {
max := math.Inf(-1)
for _, number := range numbers {
if number > max {
max = number
}
}
return max
}
func inRange(min float64, max float64, numbers ...float64) []float64 {
var result []float64
for _, number := range numbers {
if number >= min && number <= max {
result = append(result, number)
}
}
return result
}
func variadic() {
fmt.Println(maximum(71.8, 56.2, 89.5))
fmt.Println(maximum(90.7, 89.7, 98.5, 92.3))
fmt.Println(inRange(1, 100, -12.5, 3.2, 0, 50, 103.5))
fmt.Println(inRange(-10, 10, 4.1, 12, -12, -5.2))
}

View File

@ -0,0 +1,44 @@
package main
import "fmt"
func paintNeeded(width float64, height float64) (paintNeededCalculated float64, anError error) {
area := width * height
if width < 0.0 {
return 0, fmt.Errorf("a width of %0.2f is invalid.", width)
}
if height < 0.0 {
return 0, fmt.Errorf("a height of %0.2f is invalid.", height)
}
return area / 10.0, nil
}
func printListersNeeded(amount float64) {
fmt.Printf("%.2f liters needed\n", amount)
}
func wallArea() {
var amount, total float64
amount, err := paintNeeded(4.2, 3.0)
if err != nil {
fmt.Println(err)
} else {
printListersNeeded(amount)
}
total += amount
amount, err = paintNeeded(-5.2, 3.5)
if err != nil {
fmt.Println(err)
} else {
printListersNeeded(amount)
}
total += amount
amount, err = paintNeeded(5.2, 5.0)
if err != nil {
fmt.Println(err)
} else {
printListersNeeded(amount)
}
total += amount
fmt.Printf("Total: %.2f liters\n", total)
}

52
cmd/sum/sum.go Normal file
View File

@ -0,0 +1,52 @@
package main
import (
"bufio"
"fmt"
"log"
"os"
"strconv"
)
func OpenFile(fileName string) (*os.File, error) {
fmt.Println("Opening", fileName)
return os.Open(fileName)
}
func CloseFile(file *os.File) {
fmt.Println("Closing file")
file.Close()
}
func GetFloats(fileName string) ([]float64, error) {
var numbers []float64
file, err := OpenFile(fileName)
if err != nil {
return nil, err
}
defer CloseFile(file)
scanner := bufio.NewScanner(file)
for scanner.Scan() {
number, err := strconv.ParseFloat(scanner.Text(), 64)
if err != nil {
return nil, err
}
numbers = append(numbers, number)
}
if scanner.Err() != nil {
return nil, scanner.Err()
}
return numbers, nil
}
func main() {
numbers, err := GetFloats(os.Args[1])
if err != nil {
log.Fatal(err)
}
var sum float64 = 0
for _, number := range numbers {
sum += number
}
fmt.Printf("Sum: %0.2f\n", sum)
}