149 lines
3.2 KiB
Go
149 lines
3.2 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/json"
|
|
"flag"
|
|
"fmt"
|
|
"html/template"
|
|
"log"
|
|
"math"
|
|
"os"
|
|
"os/signal"
|
|
"strings"
|
|
"syscall"
|
|
|
|
"google.golang.org/genai"
|
|
)
|
|
|
|
func main() {
|
|
ctx, can := signal.NotifyContext(context.Background(), syscall.SIGINT)
|
|
defer can()
|
|
if err := run(ctx); err != nil && ctx.Err() == nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
func run(ctx context.Context) error {
|
|
fs := flag.NewFlagSet(os.Args[0], flag.ContinueOnError)
|
|
n := fs.Int("n", 1, "loops")
|
|
model := fs.String("m", "gemini-2.5-flash", "model to use")
|
|
|
|
if err := fs.Parse(os.Args[1:]); err != nil {
|
|
return err
|
|
}
|
|
city := strings.Title(fs.Args()[0])
|
|
|
|
client, err := genai.NewClient(ctx, nil)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
descriptors := []string{
|
|
`Literally poison in the air that politicians are adamant against doing anything to mitigate`,
|
|
`Drought worst-case`,
|
|
`Wildfire risk`,
|
|
`Hurricane`,
|
|
`Earthquake`,
|
|
`Tornado`,
|
|
`Crime`,
|
|
`Consistent Air Pollution`,
|
|
`Transient Air Pollution (from wildfires, etc)`,
|
|
`Colorado river distribution conflict / reduced capacity`,
|
|
`PFAS`,
|
|
`Homelessness`,
|
|
`Neighbors disappointed in church attendance`,
|
|
`Hot`,
|
|
`Personal gripes`,
|
|
`Alcohol universal`,
|
|
`Few traffic destination hubs`,
|
|
`Popularity of booze`,
|
|
`Tourist destination (eg Branson-like)`,
|
|
`Weed universal`,
|
|
`Greater cost of living than Utah`,
|
|
`Traffic >= Bend at 3k/sqmi`,
|
|
`Lots of schools`,
|
|
`Coffee shops`,
|
|
`Yummy resturaunts`,
|
|
`Board game stores`,
|
|
`Home for < 400k`,
|
|
`20min drive to fun`,
|
|
`Would we get out and be active? Bike++`,
|
|
`Close airport`,
|
|
`DnD Players`,
|
|
`Trees!`,
|
|
`Population is college educated`,
|
|
`Home for < 600k`,
|
|
`Software developers per capita`,
|
|
`Fiber-speed internet`,
|
|
`Organic Groceries`,
|
|
`Close hospital for emergency situations`,
|
|
`Home for < 800`,
|
|
`Hematologist reasonably close`,
|
|
`Does it have the vibes?`,
|
|
`Concrete Jungle`,
|
|
}
|
|
|
|
tmpl, err := template.New("tmpl").Parse(`
|
|
For the city {{.City}}, answer the following descriptors '1' for true or '0' for false. Output only a JSON object mapping descriptors to answers.
|
|
|
|
{{ range .Descriptors -}}
|
|
* {{ . }}
|
|
{{ end }}
|
|
`)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
w := bytes.NewBuffer(nil)
|
|
if err := tmpl.Execute(w, map[string]any{
|
|
"City": city,
|
|
"Descriptors": descriptors,
|
|
}); err != nil {
|
|
return err
|
|
}
|
|
//panic(w.String())
|
|
|
|
results := make([][]float64, len(descriptors))
|
|
for i := 0; i < *n; i++ {
|
|
result, err := client.Models.GenerateContent(
|
|
ctx,
|
|
*model,
|
|
genai.Text(w.String()),
|
|
nil,
|
|
)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
text := "{" + strings.Split(strings.Split(result.Text(), "{")[1], "}")[0] + "}"
|
|
|
|
var m map[string]any
|
|
if err := json.Unmarshal([]byte(text), &m); err != nil {
|
|
return err
|
|
}
|
|
for j, d := range descriptors {
|
|
if v, ok := m[d]; ok {
|
|
k := fmt.Sprint(v)
|
|
if k == "1" {
|
|
results[j] = append(results[j], 1.0)
|
|
} else {
|
|
results[j] = append(results[j], 0.0)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
log.Printf("%+v", results)
|
|
//log.Println(text)
|
|
for i := range descriptors {
|
|
sum := 0.0
|
|
for j := range results[i] {
|
|
sum += results[i][j]
|
|
}
|
|
avg := sum / float64(len(results[i]))
|
|
fmt.Println(math.Round(avg))
|
|
}
|
|
|
|
return ctx.Err()
|
|
}
|