Appending to maps don't work unless reversed

The following code prints from a map, and waits to scan userInput. If the userInput is “?”, it appends to the map. The append does not seem to work unless the code is qaPair[two] = one, whereas I require it to be qaPair[one] = two in one if block and the former in another.

I also seem to get premature termination at times when I have appended using the userInput. For example, if the number of pairs is 13 (added 3 to 10), sometimes it gets terminated at 12/13.

Can someone please help me with the code logic here? I don’t seem to understand the reason behind these quirks

package main

import (
	"encoding/csv"
	"flag"
	"fmt"
	"log"
	"math/rand"
	"os"
	"os/exec"
	"runtime"
	"time"

	"github.com/fatih/color"
)

var (
	flagNoColor = flag.Bool("no-color", false, "disable color output")
	csvPath = flag.String("src", "src.csv", "source")
	lang = flag.Int("l", -1, "language")
	num = flag.Int("n", -1, "number")
)

var clear map[string]func()

func init() {
	clear = make(map[string]func())
		clear["linux"] = func() {
		cmd := exec.Command("clear")
		cmd.Stdout = os.Stdout
		cmd.Run()
	}
	clear["windows"] = func() {
		cmd := exec.Command("cmd", "/c", "cls")
		cmd.Stdout = os.Stdout
		cmd.Run()
	}
}

func CallClear() {
	value, ok := clear[runtime.GOOS]
	if ok {
		value()
	} else {
		panic("Panic!")
	}
}

func random(min int, max int) int {
	return rand.Intn((max-min) + 1) + min
}

func main() {

	flag.Parse()

	file, err := os.Open(*csvPath)
	if err != nil {
		log.Println(err)
		return
	}
	defer file.Close()

	csvReader := csv.NewReader(file)

	csvData, err := csvReader.ReadAll()
	if err != nil {
		log.Println(err)
		return
	}

	qaRaw := make(map[string]string, len(csvData))
	for _, data := range csvData {
		qaRaw[data[0]] = data[1]
	}

	qaPair := make(map[string]string)

	if *num != -1 {
		i := 1
		for one, two := range qaRaw {
			if i <= *num {
				qaPair[one] = two
			}
			i++
		}
	} else {
		for one, two := range qaRaw {
			qaPair[one] = two
		}
	}

	done := make(chan bool)

	go func() {
		if *flagNoColor {
			color.NoColor = true
		}
		white := color.New(color.FgWhite)
		boldWhite := white.Add(color.Bold)

		qNum := 0

		for one, two := range qaPair {
			rand.Seed(time.Now().UnixNano())
			randomNum := random(1, 2)
			CallClear()
			if *lang != -1 {
				randomNum = *lang
			}
			qNum++
			var userInput string
			boldWhite.Printf("\n #\t%d / %d\n", qNum, len(qaPair))
			if randomNum == 1 {
				boldWhite.Printf("\n Q\t%s", one)
				fmt.Scanln()
				boldWhite.Printf("\n A\t%s", two)
				fmt.Scanln(&userInput)
				if userInput == "?" {
					qaPair[two] = one
				}
			} else if randomNum == 2 {
				boldWhite.Printf("\n Q\t%s", two)
				fmt.Scanln()
				boldWhite.Printf("\n A\t%s", one)
				fmt.Scanln(&userInput)
				if userInput == "?" {
					qaPair[two] = one
				}
			}
			CallClear()
		}
		done <- true
	}()

	select {
		case <-done:
	}

}

Here is a .csv file with sample data

"hola","hi"
"sí","yes"
"¿qué pasa?","what's up?"
"¡vamos!","let's go!"
"¡salud!","cheers!; bless you!"
"no","no"
"por favor","please"
"lo siento","I'm sorry"
"buenos días","good morning"
"buenas noches","good night"

I’m not really sure what you mean/expect, and the example is a bit long. A short reproduction on play.golang.org would be nice.

In general, you don’t “append” to maps. They contain key-value pairs - setting a value for a key will overwrite the previous value if there was one, or create a new key-value pair if there wasn’t one.

1 Like

Hello,

This is from golang spec:

" … A nil map is equivalent to an empty map except that no elements may be added … "

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.