package main import ( "encoding/csv" "encoding/json" "fmt" "log" "math/rand" "os" "github.com/brianvoe/gofakeit/v6" ) type User struct { UID string `json:"uid"` FirstName string `json:"first_name"` LastName string `json:"last_name"` Status string `json:"status"` ExamID string `json:"exam_id"` } type Config struct { NumberOfUsers int `json:"number_of_users"` PercentStatus map[string]int `json:"percent_status"` } var statuses = []string{"JD", "LLM", "MCL", "PHD", "SJD", "MLS", "SPEC", "MNR", "CERT"} func main() { data, err := os.ReadFile("config.json") if err != nil { log.Fatalf("failed to read config.json: %v", err) } var config Config if err := json.Unmarshal(data, &config); err != nil { log.Fatalf("failed to parse config.json: %v", err) } total := 0 for _, v := range config.PercentStatus { total += v } if total != 100 { log.Fatalf("percent_status values must total 100, got %d", total) } // Build a weighted list of statuses weightedStatuses := make([]string, 0, 100) for status, pct := range config.PercentStatus { for i := 0; i < pct; i++ { weightedStatuses = append(weightedStatuses, status) } } // Generate unique ExamIDs and UIDs examIDs := uniqueNumericStrings(4, config.NumberOfUsers) uids := uniqueNumericStrings(10, config.NumberOfUsers) users := make([]User, config.NumberOfUsers) for i := range users { users[i] = User{ UID: uids[i], FirstName: gofakeit.FirstName(), LastName: gofakeit.LastName(), Status: weightedStatuses[rand.Intn(len(weightedStatuses))], ExamID: examIDs[i], } } f, err := os.Create("users.csv") if err != nil { log.Fatalf("failed to create users.csv: %v", err) } defer f.Close() w := csv.NewWriter(f) if err := w.Write([]string{"uid", "first_name", "last_name", "status", "exam_id"}); err != nil { log.Fatalf("failed to write csv header: %v", err) } for _, u := range users { if err := w.Write([]string{u.UID, u.FirstName, u.LastName, u.Status, u.ExamID}); err != nil { log.Fatalf("failed to write csv row: %v", err) } } w.Flush() if err := w.Error(); err != nil { log.Fatalf("csv flush error: %v", err) } fmt.Printf("Generated %d users to users.csv\n", config.NumberOfUsers) } // uniqueNumericStrings generates n unique zero-padded numeric strings of the given digit length. func uniqueNumericStrings(digits, n int) []string { max := 1 for i := 0; i < digits; i++ { max *= 10 } if n > max { log.Fatalf("cannot generate %d unique %d-digit strings (max %d)", n, digits, max) } seen := make(map[int]struct{}, n) results := make([]string, 0, n) format := fmt.Sprintf("%%0%dd", digits) for len(results) < n { v := rand.Intn(max) if _, exists := seen[v]; !exists { seen[v] = struct{}{} results = append(results, fmt.Sprintf(format, v)) } } return results }