[GO] [Los] Erstellen Sie ein Tool, das den Rennwert des Pokémon zurückgibt, der von der Standardeingabe empfangen wurde

Hallo, das ist Yamauchi! Am 14. November 2020 wurde in unserer Niederlassung in Fukuoka eine fette Dose aufbewahrt. Es ist ein Name, der so etwas wie eine Übernachtung zu sein scheint, aber obwohl ich es seit ungefähr anderthalb Jahren mindestens einen Monat lang mache, habe ich immer noch nur einen Tagesausflug. .. .. Nun, lassen Sie es uns beiseite legen und ich werde das Tool vorstellen, das ich dieses Mal gemacht habe! Übrigens, ich bin ein super Anfänger in der Go-Sprache und es ist das erste Mal, dass ich so etwas wie ein Tool gemacht habe. Ich denke, es gibt verschiedene Probleme mit dem Code.

Eine grobe Einführung in dieses Tool

Für dieses Tool habe ich die API und die Seite, die sie trifft, separat erstellt. Dies ist das Repository. API:https://github.com/y-keisuke/pokemon Schlagende Seite: https://github.com/y-keisuke/pokemon_command Bitte betrachten Sie es mit dem Gefühl, dass Sie es überprüfen werden w

Ich wollte sie unbedingt in einem Repository zusammenfassen, wusste aber nicht, ob dies möglich ist. Deshalb habe ich die Repositorys aufgeteilt, sodass nur die Befehle, die ich später verwendete, Befehle an die Repositorys angehängt haben. Es spielt keine Rolle.

Deshalb ist es eine grobe Einführung, also ist die Bewegung so ↓ (Entschuldigung für die träge Bewegung, ich habe insgesamt 4 Mal getroffen) pokemon.gif

Es ist ziemlich rau, aber es sieht so aus.

Einführung auf der API-Seite

Zunächst habe ich auf der API-Seite json aus dem Repository hier ausgeliehen ↓. https://github.com/fanzeyi/pokemon.json/blob/master/pokedex.json

db.go Ich wollte wirklich eine DB vorbereiten, aber es war mühsam, also habe ich json verwendet, wie es ← ist Das ist db.go.


package db

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
)

type PokemonCollection struct {
	Pokemons []PokemonData
}

type PokemonData struct {
	Id   int         `json:"id"`
	Name PokemonName `json:"name"`
	Type []string    `json:"type"`
	Base PokemonBase `json:"base"`
}

type PokemonName struct {
	English  string `json:"english"`
	Japanese string `json:"japanese"`
	Chinese  string `json:"chinese"`
	French   string `json:"french"`
}

type PokemonBase struct {
	HP        int `json:"hp"`
	Attack    int `json:"attack"`
	Defense   int `json:"defense"`
	SpAttack  int `json:"spattack"`
	SpDefense int `json:"spdefense"`
	Speed     int `json:"speed"`
}

func GetPokemonCollection() PokemonCollection {
	raw, err := ioutil.ReadFile("./pokedex.json")
	if err != nil {
		fmt.Println(err.Error())
		os.Exit(1)
	}
	var pokemonCollection PokemonCollection
	json.Unmarshal(raw, &pokemonCollection)

	return pokemonCollection
}

Einige der oben definierten Strukturen sind genau die gleichen wie die von json. Die Struktur hat sich gegenüber dem geliehenen json leicht verändert. Die hier definierte GetPokemonCollection () fügt die JSON-Daten in die Struktur ein. Speziell

json.Unmarshal(raw, &pokemonCollection)

Dieser Teil ist in der Struktur verpackt. Diese Struktur wird als DB verwendet.

main.go

Als nächstes kommt main.go.

package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	pokemon2 "pokemon/pokemon"
)

func pokemonToJson(w http.ResponseWriter, r *http.Request) {
	name := r.FormValue("name")
	pokemon, err := pokemon2.GetPokemonBy(name)

    //Ich wusste nicht, wie ich json von Fehlerinformationen hier gut zurückgeben sollte
	if err != nil {
		log.Writer()
		http.Error(w, fmt.Sprintf("{\"err\":\"%s\"}", err), 200)
		return
	}
	pokemonJson, _ := json.Marshal(pokemon)
	fmt.Fprint(w, fmt.Sprintf("%+v", string(pokemonJson)))
}

func handleRequests() {
	http.HandleFunc("/", pokemonToJson)
	log.Fatal(http.ListenAndServe(":18888", nil))
}

func main() {
	handleRequests()
}

Was wir hier tun, ist "auf den Zugriff auf Port 18888 zu warten, die Zugriffsparameter zu überprüfen, die Pokemon-Daten abzurufen und den Rennwert mit json zurückzugeben".

Zuerst der Teil, der im Hafen 18888 wartet

//Hören Sie Port 18888
http.ListenAndServe(":18888", nil)

Schauen Sie sich dann die Zugriffsparameter an

//Rufen Sie den Parameter des Schlüssels namens name ab
name := r.FormValue("name")

Holen Sie sich außerdem Pokemon-Daten

//Holen Sie sich Pokemon mit GetPokemonBy in pokemon2 (Details unten)
pokemon, err := pokemon2.GetPokemonBy(name)

Schließlich gibt json den Rennwert zurück

//Konvertieren Sie die Struktur in json und kehren Sie dann zurück
pokemonJson, _ := json.Marshal(pokemon)
fmt.Fprint(w, fmt.Sprintf("%+v", string(pokemonJson)))

Gehen? Was kannst du es essen? Ich höre wahrscheinlich eine Stimme mit der Aufschrift "Ich drucke ohne Rückgabe!". Daher füge ich hinzu, dass Fprint eine Funktion ist, mit der Sie das Schreibziel angeben können, und diesmal schreibe ich an w (http.ResponseWriter). Es fühlt sich an, als würde es als Antwort zurückgegeben.

pokemon.go

Dies ist derjenige, der pokemon2 sagt. Es ist 2, weil es mit dem Projektnamen bedeckt war. Es ist ein hübscher NG-Name. Goland hat gute Arbeit geleistet ...

package pokemon

import (
	"errors"
	"pokemon/db"
)

type Pokemon struct {
	Name      string `json:"name"`
	HP        int    `json:"hp"`
	Attack    int    `json:"attack"`
	Defense   int    `json:"defense"`
	SpAttack  int    `json:"sp_attack"`
	SpDefense int    `json:"sp_defense"`
	Speed     int    `json:"speed"`
}

func GetPokemonBy(name string) (*Pokemon, error) {
	pokemonCollection := getPokemonCollection()
	for _, pokemon := range pokemonCollection.Pokemons {
		if pokemon.Name.Japanese == name {
			return getPokemonStruct(pokemon), nil
		}
	}
	return nil, errors.New("Pokemon nicht gefunden")
}

func getPokemonCollection() db.PokemonCollection {
	return db.GetPokemonCollection()
}

func getPokemonStruct(pokemon db.PokemonData) *Pokemon {
	return &Pokemon{
		Name: pokemon.Name.Japanese,
		HP: pokemon.Base.HP,
		Attack: pokemon.Base.Attack,
		Defense: pokemon.Base.Defense,
		SpAttack: pokemon.Base.SpAttack,
		SpDefense: pokemon.Base.SpDefense,
		Speed: pokemon.Base.Speed}
}

Im Moment werde ich nur die Funktion GetPokemonBy erklären, die von main.go aufgerufen wurde.

//Ich bekomme eine DB
pokemonCollection := getPokemonCollection()

Ich bekomme es über eine private Funktion, aber ich erinnere mich nicht warum.

for _, pokemon := range pokemonCollection.Pokemons {
	if pokemon.Name.Japanese == name {
		return getPokemonStruct(pokemon), nil
	}
}

Wenn der erfasste DB-Pokemon-Name mit dem im Parameter empfangenen Pokemon-Namen übereinstimmt, wird dieses Pokemon in eine neue Struktur gepackt und zurückgegeben.

Grob gesagt sieht die API-Seite so aus.

Schlagen Seite

Als nächstes kommt die Seite, die die API trifft.

main.go

Vorerst der Quellcode.

package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"pokemon_command/input"
	"pokemon_command/pokemon"
)

func main() {
	url := input.CreateUrl()

	resp, _ := http.Get(url)
	defer resp.Body.Close()

	byteArray, _ := ioutil.ReadAll(resp.Body)

	var errCheck map[string]string
	json.Unmarshal(byteArray, &errCheck)
	if val, ok := errCheck["err"]; ok {
		fmt.Println(val)
		return
	}

	pokemonStruct := pokemon.JsonToPokemon(byteArray)

	pokemon.PrintPokemon(pokemonStruct)
}

Dies ist eine Erklärung des Inhalts der Hauptfunktion.

//Details der Eingabe werden später beschrieben
url := input.CreateUrl()

Hier erhalten wir Standardeingaben und generieren eine URL, um die darauf basierende API aufzurufen.

resp, _ := http.Get(url)
defer resp.Body.Close()

Greifen Sie dann auf die generierte URL zu und erhalten Sie das Ergebnis.

byteArray, _ := ioutil.ReadAll(resp.Body)

Ruft den Text der empfangenen Antwort ab.

var errCheck map[string]string
json.Unmarshal(byteArray, &errCheck)
if val, ok := errCheck["err"]; ok {
	fmt.Println(val)
	return
}

Ich mache hier Fehlerbehandlung, kenne aber nicht die optimale Lösung. .. ..

//Pokemon wird später beschrieben
pokemonStruct := pokemon.JsonToPokemon(byteArray)
pokemon.PrintPokemon(pokemonStruct)

Der zuletzt empfangene JSON wird in der Struktur gespeichert und dann ausgegeben.

main.go sieht so aus.

input.go

package input

import (
	"bufio"
	"fmt"
	"os"
)

func CreateUrl() string {
	fmt.Print("Please enter the name of the Pokemon.\n>> ")
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Scan()
	return "http://localhost:18888/?name=" + scanner.Text()
}

Hier ist es keine große Sache, es akzeptiert Standardeingaben und generiert eine URL basierend auf diesen Eingaben.

fmt.Print("Please enter the name of the Pokemon.\n>> ")
scanner := bufio.NewScanner(os.Stdin)
scanner.Scan()

Diese drei Zeilen zeigen den Text an, der Sie zur Eingabe auffordert, und die Standardeingabe wird durch die Funktion des Bufio-Pakets erhalten.

return "http://localhost:8081/?name=" + scanner.Text()

Die URL wird durch Kombinieren der erhaltenen Zeichenfolgen generiert. Ich möchte etwas besseres schreiben.

pokemon.go

package pokemon

import (
	"encoding/json"
	"fmt"
	"log"
)

type Pokemon struct {
	Name string `json:"name"`
	HP int `json:"hp"`
	Attack int `json:"attack"`
	Defense int `json:"defense"`
	SpAttack int `json:"sp_attack"`
	SpDefense int `json:"sp_defense"`
	Speed int `json:"speed"`
}

func JsonToPokemon(pokemonJson []byte) *Pokemon {
	pokemon := new(Pokemon)
	err := json.Unmarshal(pokemonJson, pokemon)
	if err != nil {
		log.Fatal(err)
	}
	return pokemon
}

func PrintPokemon(pokemon *Pokemon) {
	fmt.Println("Name: ", pokemon.Name)
	fmt.Println("HP     : ", pokemon.HP)
	fmt.Println("Kogeki: ", pokemon.Attack)
	fmt.Println("Bougyo: ", pokemon.Defense)
	fmt.Println("Tokukou: ", pokemon.SpAttack)
	fmt.Println("Tokubo: ", pokemon.SpDefense)
	fmt.Println("Schnelligkeit: ", pokemon.Speed)
}

Auch hier ist es keine große Sache, nur eine Funktion, die den empfangenen JSON in eine Struktur packt und eine Funktion, die basierend auf dieser Struktur ausgibt. Ich habe nichts wirklich Wichtiges geschrieben, deshalb werde ich die Details weglassen.

Impressionen

Es ist ein ziemlich schlampiger Artikel, aber ← Mit dem Versuch, etwas mit GO zu machen, wollte ich diesmal so etwas wie "Eingabe mit Standardeingabe akzeptieren" machen, daher bin ich vorerst froh, dass ich es so implementieren konnte. Idealerweise sollten Sie so etwas wie den Befehl pokemon erstellen, und die Anzeige ändert sich je nach Option. Ich möchte so etwas machen, aber ich werde zu einem anderen Zeitpunkt mein Bestes geben.

Ich wollte die API nicht nur lokal, sondern jederzeit und überall aufrufen, also habe ich mich bei Sakura VPS angemeldet und die API dort abgelegt, daher werde ich das nächste Mal im Artikel darüber schreiben.

Das ist es!

Recommended Posts

[Los] Erstellen Sie ein Tool, das den Rennwert des Pokémon zurückgibt, der von der Standardeingabe empfangen wurde
[Bot dekodieren] Ich habe versucht, einen Bot zu erstellen, der mir den Rassenwert von Pokemon angibt
Erstellen Sie einen Datenrahmen aus den erfassten Textdaten des Bootsrennens
[Django] Erstellen Sie ein Formular, das automatisch die Adresse aus der Postleitzahl ausfüllt
Erstellen Sie ein Übersetzungswerkzeug mit dem Translate Toolkit
Lassen Sie Python den von der Standardeingabe eingegebenen JSON analysieren
Programmiersprache, die die Menschen vor NHK schützt
#Eine Funktion, die den Zeichencode einer Zeichenfolge zurückgibt
Erstellen Sie einen Chatbot, der die kostenlose Eingabe mit Word2Vec unterstützt
Erstellen Sie mit MeCab mit Discord einen Bot, der nur das Ergebnis der morphologischen Analyse zurückgibt
Ein Beispiel für einen Mechanismus, der eine Vorhersage von HTTP aus dem Ergebnis des maschinellen Lernens zurückgibt
Ich habe ein Tool erstellt, um automatisch ein einfaches ER-Diagramm aus der Anweisung CREATE TABLE zu generieren