master > master: code go - interactive mode eingerichtet
This commit is contained in:
		
							parent
							
								
									53978d584b
								
							
						
					
					
						commit
						324b8d2fcd
					
				@ -8,15 +8,14 @@ import (
 | 
			
		||||
	"ads/internal/core/logging"
 | 
			
		||||
	"ads/internal/menus"
 | 
			
		||||
	"ads/internal/setup"
 | 
			
		||||
	"reflect"
 | 
			
		||||
 | 
			
		||||
	// algorithm_search_binary "ads/internal/algorithms/search/binary"
 | 
			
		||||
	// algorithm_search_interpol "ads/internal/algorithms/search/interpol"
 | 
			
		||||
	// algorithm_search_ith_element "ads/internal/algorithms/search/ith_element"
 | 
			
		||||
	// algorithm_search_jump "ads/internal/algorithms/search/jump"
 | 
			
		||||
	// algorithm_search_poison "ads/internal/algorithms/search/poison"
 | 
			
		||||
	algorithm_search_binary "ads/internal/algorithms/search/binary"
 | 
			
		||||
	algorithm_search_interpol "ads/internal/algorithms/search/interpol"
 | 
			
		||||
	algorithm_search_ith_element "ads/internal/algorithms/search/ith_element"
 | 
			
		||||
	algorithm_search_jump "ads/internal/algorithms/search/jump"
 | 
			
		||||
	algorithm_search_poison "ads/internal/algorithms/search/poison"
 | 
			
		||||
	algorithm_search_sequential "ads/internal/algorithms/search/sequential"
 | 
			
		||||
	// algorithm_sum_maxsubsum "ads/internal/algorithms/sum/maxsubsum"
 | 
			
		||||
	algorithm_sum_maxsubsum "ads/internal/algorithms/sum/maxsubsum"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
/* ---------------------------------------------------------------- *
 | 
			
		||||
@ -43,6 +42,7 @@ var menuMain = menus.Menu{
 | 
			
		||||
	},
 | 
			
		||||
	Options: []menus.MenuOption{
 | 
			
		||||
		{Label: "Version des Programms anzeigen", Action: actionShowVersion},
 | 
			
		||||
		{Label: "Programm auf config Datei ausführen.", Action: actionRunOnConfig},
 | 
			
		||||
		{Label: "Suchalgorithmen", Submenu: &menuSearchAlgorithms},
 | 
			
		||||
		{Label: "Summenalgorithmen", Submenu: &menuSumAlgorithms},
 | 
			
		||||
	},
 | 
			
		||||
@ -56,14 +56,14 @@ var menuSearchAlgorithms = menus.Menu{
 | 
			
		||||
		"Algorithmus wählen",
 | 
			
		||||
	},
 | 
			
		||||
	Options: []menus.MenuOption{
 | 
			
		||||
		{Label: "Binärsuchalgorithmus"},
 | 
			
		||||
		{Label: "Interpolationsalgorithmus"},
 | 
			
		||||
		{Label: "Suche i. kleinstes Element"},
 | 
			
		||||
		{Label: "Suche i. kleinstes Element", SubLabel: "D & C"},
 | 
			
		||||
		{Label: "Sprungsuche", SubLabel: "linear"},
 | 
			
		||||
		{Label: "Sprungsuche", SubLabel: "exponentiell"},
 | 
			
		||||
		{Label: "Giftsuche"},
 | 
			
		||||
		{Label: "Giftsuche", SubLabel: "optimiert"},
 | 
			
		||||
		{Label: "Binärsuchalgorithmus", Action: actionAlgorithmSearchBinary},
 | 
			
		||||
		{Label: "Interpolationsalgorithmus", Action: actionAlgorithmSearchInterpolation},
 | 
			
		||||
		{Label: "Suche i. kleinstes Element", Action: actionAlgorithmSearchIthElement},
 | 
			
		||||
		{Label: "Suche i. kleinstes Element", SubLabel: "D & C", Action: actionAlgorithmSearchIthElementDc},
 | 
			
		||||
		{Label: "Sprungsuche", SubLabel: "linear", Action: actionAlgorithmSearchJump},
 | 
			
		||||
		{Label: "Sprungsuche", SubLabel: "exponentiell", Action: actionAlgorithmSearchJumpExp},
 | 
			
		||||
		{Label: "Giftsuche", Action: actionAlgorithmSearchPoison},
 | 
			
		||||
		{Label: "Giftsuche", SubLabel: "optimiert", Action: actionAlgorithmSearchPoisonFast},
 | 
			
		||||
		{Label: "Sequentiellsuchalgorithmus", Action: actionAlgorithmSearchSequential},
 | 
			
		||||
	},
 | 
			
		||||
	DefaultOption: -1,
 | 
			
		||||
@ -76,8 +76,8 @@ var menuSumAlgorithms = menus.Menu{
 | 
			
		||||
		"Algorithmus wählen",
 | 
			
		||||
	},
 | 
			
		||||
	Options: []menus.MenuOption{
 | 
			
		||||
		{Label: "Maximale Teilsumme", SubLabel: "brute force"},
 | 
			
		||||
		{Label: "Maximale Teilsumme", SubLabel: "D & C"},
 | 
			
		||||
		{Label: "Maximale Teilsumme", SubLabel: "brute force", Action: actionAlgorithmSumMaxsub},
 | 
			
		||||
		{Label: "Maximale Teilsumme", SubLabel: "D & C", Action: actionAlgorithmSumMaxsubDc},
 | 
			
		||||
	},
 | 
			
		||||
	DefaultOption: -1,
 | 
			
		||||
}
 | 
			
		||||
@ -86,23 +86,259 @@ var menuSumAlgorithms = menus.Menu{
 | 
			
		||||
 * ACTIONS - basic
 | 
			
		||||
 * ---------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
func actionShowVersion() error {
 | 
			
		||||
func actionShowVersion() (bool, error) {
 | 
			
		||||
	logging.LogInfo("Version des Programms")
 | 
			
		||||
	Version()
 | 
			
		||||
	return nil
 | 
			
		||||
	return false, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ---------------------------------------------------------------- *
 | 
			
		||||
 * ACTIONS - Algorithmen
 | 
			
		||||
 * ---------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
// TODO
 | 
			
		||||
func actionAlgorithmSearchSequential() error {
 | 
			
		||||
	input_L := []int{45, 67}
 | 
			
		||||
	input_x := 6
 | 
			
		||||
	menus.PromptValue("L", "Liste von Integers", "z.B. \033[1m5 73 42\033[0m", reflect.TypeOf([]int{}))
 | 
			
		||||
func actionRunOnConfig() (bool, error) {
 | 
			
		||||
	path, cancel, err := logging.Prompt("Pfad zur Configdatei bitte eingeben:")
 | 
			
		||||
	if cancel {
 | 
			
		||||
		err = nil
 | 
			
		||||
	} else if err == nil {
 | 
			
		||||
		err = RunNonInteractive(path)
 | 
			
		||||
	}
 | 
			
		||||
	return cancel, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func actionAlgorithmSearchBinary() (bool, error) {
 | 
			
		||||
	input_L, cancel, err := PromptInputListOfInt("L", "Liste von Werten", []string{
 | 
			
		||||
		"muss aufsteigend sortiert sein",
 | 
			
		||||
	})
 | 
			
		||||
	if cancel || err != nil {
 | 
			
		||||
		return cancel, err
 | 
			
		||||
	}
 | 
			
		||||
	input_x, cancel, err := PromptInputInteger("x", "Suchwert", []string{})
 | 
			
		||||
	if cancel || err != nil {
 | 
			
		||||
		return cancel, err
 | 
			
		||||
	}
 | 
			
		||||
	setup.DisplayStartOfCaseBlank()
 | 
			
		||||
	algorithm_search_binary.FancyBinarySearch(input_L, input_x)
 | 
			
		||||
	setup.DisplayEndOfCase()
 | 
			
		||||
	return cancel, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func actionAlgorithmSearchInterpolation() (bool, error) {
 | 
			
		||||
	input_L, cancel, err := PromptInputListOfInt("L", "Liste von Werten", []string{
 | 
			
		||||
		"muss aufsteigend sortiert sein",
 | 
			
		||||
		"sollte (idealerweise) nicht uniform verteilt sein",
 | 
			
		||||
	})
 | 
			
		||||
	if cancel || err != nil {
 | 
			
		||||
		return cancel, err
 | 
			
		||||
	}
 | 
			
		||||
	input_x, cancel, err := PromptInputInteger("x", "Suchwert", []string{})
 | 
			
		||||
	if cancel || err != nil {
 | 
			
		||||
		return cancel, err
 | 
			
		||||
	}
 | 
			
		||||
	setup.DisplayStartOfCaseBlank()
 | 
			
		||||
	algorithm_search_interpol.FancyInterpolationSearch(input_L, input_x, 0, len(input_L)-1)
 | 
			
		||||
	setup.DisplayEndOfCase()
 | 
			
		||||
	return cancel, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func actionAlgorithmSearchIthElement() (bool, error) {
 | 
			
		||||
	input_L, cancel, err := PromptInputListOfInt("L", "Liste von Werten", []string{})
 | 
			
		||||
	if cancel || err != nil {
 | 
			
		||||
		return cancel, err
 | 
			
		||||
	}
 | 
			
		||||
	input_i, cancel, err := PromptInputInteger("i", "Suchindex in sortierter Liste", []string{
 | 
			
		||||
		"sollte zw. 1 und len(L) liegen",
 | 
			
		||||
	})
 | 
			
		||||
	if cancel || err != nil {
 | 
			
		||||
		return cancel, err
 | 
			
		||||
	}
 | 
			
		||||
	setup.DisplayStartOfCaseBlank()
 | 
			
		||||
	algorithm_search_ith_element.FancyFindIthSmallest(input_L, input_i)
 | 
			
		||||
	setup.DisplayEndOfCase()
 | 
			
		||||
	return cancel, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func actionAlgorithmSearchIthElementDc() (bool, error) {
 | 
			
		||||
	input_L, cancel, err := PromptInputListOfInt("L", "Liste von Werten", []string{})
 | 
			
		||||
	if cancel || err != nil {
 | 
			
		||||
		return cancel, err
 | 
			
		||||
	}
 | 
			
		||||
	input_i, cancel, err := PromptInputInteger("i", "Suchindex in sortierter Liste", []string{
 | 
			
		||||
		"sollte zw. 1 und len(L) liegen",
 | 
			
		||||
	})
 | 
			
		||||
	if cancel || err != nil {
 | 
			
		||||
		return cancel, err
 | 
			
		||||
	}
 | 
			
		||||
	setup.DisplayStartOfCaseBlank()
 | 
			
		||||
	algorithm_search_ith_element.FancyFindIthSmallestDC(input_L, input_i)
 | 
			
		||||
	setup.DisplayEndOfCase()
 | 
			
		||||
	return cancel, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func actionAlgorithmSearchJump() (bool, error) {
 | 
			
		||||
	input_L, cancel, err := PromptInputListOfInt("L", "Liste von Werten", []string{
 | 
			
		||||
		"muss aufsteigend sortiert sein",
 | 
			
		||||
		"sollte (idealerweise) nicht uniform verteilt sein",
 | 
			
		||||
		"sollte (idealerweise) keine Duplikate enthalten",
 | 
			
		||||
	})
 | 
			
		||||
	if cancel || err != nil {
 | 
			
		||||
		return cancel, err
 | 
			
		||||
	}
 | 
			
		||||
	input_x, cancel, err := PromptInputInteger("x", "Suchwert", []string{})
 | 
			
		||||
	if cancel || err != nil {
 | 
			
		||||
		return cancel, err
 | 
			
		||||
	}
 | 
			
		||||
	input_m, cancel, err := PromptInputInteger("m", "Sprunggröße", []string{
 | 
			
		||||
		"sollte >= 2 sein",
 | 
			
		||||
	})
 | 
			
		||||
	if cancel || err != nil {
 | 
			
		||||
		return cancel, err
 | 
			
		||||
	}
 | 
			
		||||
	setup.DisplayStartOfCaseBlank()
 | 
			
		||||
	algorithm_search_jump.FancyJumpSearchLinear(input_L, input_x, input_m)
 | 
			
		||||
	setup.DisplayEndOfCase()
 | 
			
		||||
	return cancel, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func actionAlgorithmSearchJumpExp() (bool, error) {
 | 
			
		||||
	input_L, cancel, err := PromptInputListOfInt("L", "Liste von Werten", []string{
 | 
			
		||||
		"muss aufsteigend sortiert sein",
 | 
			
		||||
		"sollte (idealerweise) nicht uniform verteilt sein",
 | 
			
		||||
		"sollte (idealerweise) keine Duplikate enthalten",
 | 
			
		||||
	})
 | 
			
		||||
	if cancel || err != nil {
 | 
			
		||||
		return cancel, err
 | 
			
		||||
	}
 | 
			
		||||
	input_x, cancel, err := PromptInputInteger("x", "Suchwert", []string{})
 | 
			
		||||
	if cancel || err != nil {
 | 
			
		||||
		return cancel, err
 | 
			
		||||
	}
 | 
			
		||||
	setup.DisplayStartOfCaseBlank()
 | 
			
		||||
	algorithm_search_jump.FancyJumpSearchExponentiell(input_L, input_x)
 | 
			
		||||
	setup.DisplayEndOfCase()
 | 
			
		||||
	return cancel, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func actionAlgorithmSearchPoison() (bool, error) {
 | 
			
		||||
	input_L, cancel, err := PromptInputListOfInt("L", "Liste von Werten", []string{
 | 
			
		||||
		"muss genau eine 1 enthalten",
 | 
			
		||||
	})
 | 
			
		||||
	if cancel || err != nil {
 | 
			
		||||
		return cancel, err
 | 
			
		||||
	}
 | 
			
		||||
	setup.DisplayStartOfCaseBlank()
 | 
			
		||||
	algorithm_search_poison.FancyFindPoison(input_L)
 | 
			
		||||
	logging.Prompt("hallo")
 | 
			
		||||
	setup.DisplayEndOfCase()
 | 
			
		||||
	return cancel, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func actionAlgorithmSearchPoisonFast() (bool, error) {
 | 
			
		||||
	input_L, cancel, err := PromptInputListOfZeroOnes("L", "Liste von Getränken", []string{
 | 
			
		||||
		"muss genau eine 1 enthalten",
 | 
			
		||||
	})
 | 
			
		||||
	if cancel || err != nil {
 | 
			
		||||
		return cancel, err
 | 
			
		||||
	}
 | 
			
		||||
	setup.DisplayStartOfCaseBlank()
 | 
			
		||||
	algorithm_search_poison.FancyFindPoisonFast(input_L)
 | 
			
		||||
	setup.DisplayEndOfCase()
 | 
			
		||||
	return cancel, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func actionAlgorithmSearchSequential() (bool, error) {
 | 
			
		||||
	input_L, cancel, err := PromptInputListOfInt("L", "Liste von Werten", []string{})
 | 
			
		||||
	if cancel || err != nil {
 | 
			
		||||
		return cancel, err
 | 
			
		||||
	}
 | 
			
		||||
	input_x, cancel, err := PromptInputInteger("x", "Suchwert", []string{})
 | 
			
		||||
	if cancel || err != nil {
 | 
			
		||||
		return cancel, err
 | 
			
		||||
	}
 | 
			
		||||
	setup.DisplayStartOfCaseBlank()
 | 
			
		||||
	algorithm_search_sequential.FancySequentialSearch(input_L, input_x)
 | 
			
		||||
	setup.DisplayEndOfCase()
 | 
			
		||||
	return nil
 | 
			
		||||
	return cancel, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func actionAlgorithmSumMaxsub() (bool, error) {
 | 
			
		||||
	input_L, cancel, err := PromptInputListOfInt("L", "Liste von Werten", []string{})
 | 
			
		||||
	if cancel || err != nil {
 | 
			
		||||
		return cancel, err
 | 
			
		||||
	}
 | 
			
		||||
	setup.DisplayStartOfCaseBlank()
 | 
			
		||||
	algorithm_sum_maxsubsum.FancyMaxSubSum(input_L)
 | 
			
		||||
	setup.DisplayEndOfCase()
 | 
			
		||||
	return cancel, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func actionAlgorithmSumMaxsubDc() (bool, error) {
 | 
			
		||||
	input_L, cancel, err := PromptInputListOfInt("L", "Liste von Werten", []string{})
 | 
			
		||||
	if cancel || err != nil {
 | 
			
		||||
		return cancel, err
 | 
			
		||||
	}
 | 
			
		||||
	setup.DisplayStartOfCaseBlank()
 | 
			
		||||
	algorithm_sum_maxsubsum.FancyMaxSubSumDC(input_L)
 | 
			
		||||
	setup.DisplayEndOfCase()
 | 
			
		||||
	return cancel, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ---------------------------------------------------------------- *
 | 
			
		||||
 * CUSTOM PROMPTS für besondere Inputs
 | 
			
		||||
 * ---------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
func PromptInputInteger(name string, descr string, requirements []string) (int, bool, error) {
 | 
			
		||||
	type responseType struct {
 | 
			
		||||
		Response int `yaml:"response"`
 | 
			
		||||
	}
 | 
			
		||||
	var response = responseType{}
 | 
			
		||||
	var query = menus.PromptValueQuery{
 | 
			
		||||
		Description:  descr,
 | 
			
		||||
		Name:         name,
 | 
			
		||||
		Type:         "Integer",
 | 
			
		||||
		Requirements: &requirements,
 | 
			
		||||
		Response:     &response,
 | 
			
		||||
	}
 | 
			
		||||
	cancel, err := query.Prompt()
 | 
			
		||||
	return response.Response, cancel, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func PromptInputListOfInt(name string, descr string, requirements []string) ([]int, bool, error) {
 | 
			
		||||
	type responseType struct {
 | 
			
		||||
		Response []int `yaml:"response"`
 | 
			
		||||
	}
 | 
			
		||||
	var response = responseType{}
 | 
			
		||||
	var query = menus.PromptValueQuery{
 | 
			
		||||
		Description: descr,
 | 
			
		||||
		Name:        name,
 | 
			
		||||
		Type:        "Integerliste",
 | 
			
		||||
		ValidExamples: &[]string{
 | 
			
		||||
			"[1, 2, 7, 8, 5]",
 | 
			
		||||
			"[1000, 0, 4]",
 | 
			
		||||
		},
 | 
			
		||||
		Requirements: &requirements,
 | 
			
		||||
		Response:     &response,
 | 
			
		||||
	}
 | 
			
		||||
	cancel, err := query.Prompt()
 | 
			
		||||
	return response.Response, cancel, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func PromptInputListOfZeroOnes(name string, descr string, requirements []string) ([]int, bool, error) {
 | 
			
		||||
	type responseType struct {
 | 
			
		||||
		Response []int `yaml:"response"`
 | 
			
		||||
	}
 | 
			
		||||
	var response = responseType{}
 | 
			
		||||
	var query = menus.PromptValueQuery{
 | 
			
		||||
		Description: descr,
 | 
			
		||||
		Name:        name,
 | 
			
		||||
		Type:        "Liste von 0er und 1er",
 | 
			
		||||
		ValidExamples: &[]string{
 | 
			
		||||
			"[0, 0, 0, 1, 0]",
 | 
			
		||||
			"[1, 0, 1, 1]",
 | 
			
		||||
		},
 | 
			
		||||
		Requirements: &requirements,
 | 
			
		||||
		Response:     &response,
 | 
			
		||||
	}
 | 
			
		||||
	cancel, err := query.Prompt()
 | 
			
		||||
	return response.Response, cancel, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -24,12 +24,10 @@ import (
 | 
			
		||||
 * ---------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
// Liest Config Datei ein und führt Algorithmen auf Fälle durch
 | 
			
		||||
func RunNoninteractive(path string) error {
 | 
			
		||||
func RunNonInteractive(path string) error {
 | 
			
		||||
	var err error
 | 
			
		||||
	var err_case error
 | 
			
		||||
 | 
			
		||||
	logging.LogPlain(setup.Logo())
 | 
			
		||||
 | 
			
		||||
	// extrahiere user config
 | 
			
		||||
	config := setup.NewUserConfig()
 | 
			
		||||
	err = setup.GetUserConfig(path, &config)
 | 
			
		||||
@ -37,6 +35,8 @@ func RunNoninteractive(path string) error {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	logging.LogPlain(setup.Logo())
 | 
			
		||||
 | 
			
		||||
	// Fälle extrahieren
 | 
			
		||||
	cases := []types.UserConfigCase{}
 | 
			
		||||
	if config.Parts != nil && config.Parts.Cases != nil {
 | 
			
		||||
 | 
			
		||||
@ -6,10 +6,13 @@ package menus
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"ads/internal/core/logging"
 | 
			
		||||
 | 
			
		||||
	"gopkg.in/yaml.v3"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
/* ---------------------------------------------------------------- *
 | 
			
		||||
@ -22,6 +25,8 @@ func (menu Menu) ShowMenu() (bool, error) {
 | 
			
		||||
		index  int
 | 
			
		||||
		meta   bool
 | 
			
		||||
		quit   bool
 | 
			
		||||
		cancel bool
 | 
			
		||||
		err    error
 | 
			
		||||
	)
 | 
			
		||||
	var promptMessages []string
 | 
			
		||||
	var options [][2]string
 | 
			
		||||
@ -79,12 +84,18 @@ func (menu Menu) ShowMenu() (bool, error) {
 | 
			
		||||
			opt := menu.Options[index]
 | 
			
		||||
			// Entweder Untermenü öffnen oder Action ausführen
 | 
			
		||||
			if opt.Submenu != nil {
 | 
			
		||||
				quit, _ = opt.Submenu.ShowMenu()
 | 
			
		||||
				quit, err = opt.Submenu.ShowMenu()
 | 
			
		||||
				if quit {
 | 
			
		||||
					return true, nil
 | 
			
		||||
					return true, err
 | 
			
		||||
				}
 | 
			
		||||
			} else if opt.Action != nil {
 | 
			
		||||
				opt.Action()
 | 
			
		||||
				cancel, err = opt.Action()
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					logging.LogError(err)
 | 
			
		||||
				}
 | 
			
		||||
				if cancel {
 | 
			
		||||
					continue
 | 
			
		||||
				}
 | 
			
		||||
				quit := logging.PromptAnyKeyToContinue()
 | 
			
		||||
				// Falls während der Action der User Meta+D klickt, -> quit:
 | 
			
		||||
				if quit {
 | 
			
		||||
@ -100,3 +111,69 @@ func (menu Menu) ShowMenu() (bool, error) {
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ---------------------------------------------------------------- *
 | 
			
		||||
 * METHOD prompt values
 | 
			
		||||
 * ---------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
func (query *PromptValueQuery) Prompt() (bool, error) {
 | 
			
		||||
	var lines = []interface{}{}
 | 
			
		||||
	var responsePtr = query.Response
 | 
			
		||||
	var (
 | 
			
		||||
		line   string
 | 
			
		||||
		cancel bool
 | 
			
		||||
		err    error
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	// prüfen, dass response ein Ptr auf eine Struct ist:
 | 
			
		||||
	if !(reflect.ValueOf(responsePtr).Kind() == reflect.Ptr) || !(reflect.ValueOf(responsePtr).Elem().Kind() == reflect.Struct) {
 | 
			
		||||
		panic("Input muss ein Pointer auf einen struct sein")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// prompt message vorbereiten:
 | 
			
		||||
	lines = append(lines, fmt.Sprintf("%s, \033[1;3m%s\033[0m, als \033[1m%s\033[0m bitte eingeben.", query.Description, query.Name, query.Type))
 | 
			
		||||
	if query.ValidExamples != nil && len(*query.ValidExamples) > 0 {
 | 
			
		||||
		if len(*query.ValidExamples) == 1 {
 | 
			
		||||
			example := (*query.ValidExamples)[0]
 | 
			
		||||
			lines = append(lines, fmt.Sprintf("  \033[3;4mBeispiel von Input im gültigen Format:\033[0m \033[2m%s\033[0m", example))
 | 
			
		||||
		} else {
 | 
			
		||||
			lines = append(lines, fmt.Sprintf("  \033[3;4mBeispiele von Inputs im gültigen Format:\033[0m"))
 | 
			
		||||
			for _, example := range *query.ValidExamples {
 | 
			
		||||
				lines = append(lines, fmt.Sprintf("  - \033[2m%s\033[0m", example))
 | 
			
		||||
			}
 | 
			
		||||
			lines = append(lines, fmt.Sprintf("  - \033[2;3metc.\033[0m"))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if query.Requirements != nil && len(*query.Requirements) > 0 {
 | 
			
		||||
		if len(*query.Requirements) == 1 {
 | 
			
		||||
			requirement := (*query.Requirements)[0]
 | 
			
		||||
			lines = append(lines, fmt.Sprintf("  \033[3;4mInput muss erfüllen:\033[0m \033[2m%s\033[0m", requirement))
 | 
			
		||||
		} else {
 | 
			
		||||
			lines = append(lines, fmt.Sprintf("  \033[3;4mInput muss erfüllen:\033[0m"))
 | 
			
		||||
			for _, requirement := range *query.Requirements {
 | 
			
		||||
				lines = append(lines, fmt.Sprintf("  - \033[2m%s\033[0m", requirement))
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// prompt Eingabe eines Werts:
 | 
			
		||||
	for {
 | 
			
		||||
		line, cancel, err = logging.Prompt(lines...)
 | 
			
		||||
		if cancel {
 | 
			
		||||
			return true, nil
 | 
			
		||||
		}
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			logging.LogError(err, "")
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		line = fmt.Sprintf("\"response\": %s", line)
 | 
			
		||||
		err = yaml.Unmarshal([]byte(line), query.Response)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			logging.LogError(err, "")
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		break
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return cancel, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -6,7 +6,6 @@ package menus
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"reflect"
 | 
			
		||||
 | 
			
		||||
	"ads/internal/core/logging"
 | 
			
		||||
	"ads/internal/core/utils"
 | 
			
		||||
@ -76,16 +75,3 @@ func PromptListOfOptions(messages []string, options [][2]string, breaks []int, d
 | 
			
		||||
	}
 | 
			
		||||
	return choice, false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ---------------------------------------------------------------- *
 | 
			
		||||
 * METHOD prompt values
 | 
			
		||||
 * ---------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
func PromptValue(varname string, typename string, example string, t reflect.Type) (bool, error) {
 | 
			
		||||
	_, cancel, err := logging.Prompt(
 | 
			
		||||
		fmt.Sprintf("Bitte den Wert von \033[1m%s\033[0m als \033[1m%s\033[0m eingeben.", varname, typename),
 | 
			
		||||
		example,
 | 
			
		||||
	)
 | 
			
		||||
	// TODO: input parsen
 | 
			
		||||
	return cancel, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -14,7 +14,7 @@ type MenuOption struct {
 | 
			
		||||
	Label    string
 | 
			
		||||
	SubLabel string
 | 
			
		||||
	Submenu  *Menu
 | 
			
		||||
	Action   func() error // NOTE: in go, this is automatically a pointer type
 | 
			
		||||
	Action   func() (bool, error) // NOTE: in go, this is automatically a pointer type
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Menu struct {
 | 
			
		||||
@ -24,3 +24,34 @@ type Menu struct {
 | 
			
		||||
	Options        []MenuOption
 | 
			
		||||
	DefaultOption  int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ---------------------------------------------------------------- *
 | 
			
		||||
 * TYPES - prompt
 | 
			
		||||
 * ---------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
Usage
 | 
			
		||||
 | 
			
		||||
- Name: Variablenname
 | 
			
		||||
 | 
			
		||||
- Description:  Kurze Beschreibung der Variablen
 | 
			
		||||
 | 
			
		||||
- Type: Beschreiben des erwarteten Types der Variablen.
 | 
			
		||||
 | 
			
		||||
- Requirements: Liste von Anforderungen.
 | 
			
		||||
 | 
			
		||||
- Response: Ptr zur Struct, d. h. &responseType{}, wobei responseType eine struct der folgenden Form ist:
 | 
			
		||||
 | 
			
		||||
type responseType struct { Response #### `yaml:"response"` }
 | 
			
		||||
 | 
			
		||||
wobei #### = ein Typ
 | 
			
		||||
*/
 | 
			
		||||
type PromptValueQuery struct {
 | 
			
		||||
	Name          string
 | 
			
		||||
	Description   string
 | 
			
		||||
	Type          string
 | 
			
		||||
	ValidExamples *[]string
 | 
			
		||||
	Requirements  *[]string
 | 
			
		||||
	// Response muss ein Ptr auf eine Struct sein:
 | 
			
		||||
	Response interface{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -39,6 +39,12 @@ var optionsDebug = argparse.Options{
 | 
			
		||||
	Default:  false,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var optionsInteractive = argparse.Options{
 | 
			
		||||
	Help:     "Startet die App im interaktiven Modus.",
 | 
			
		||||
	Required: false,
 | 
			
		||||
	Default:  false,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var optionsColour = argparse.Options{
 | 
			
		||||
	Help:     "Ob Logging färblich angezeigt wird.",
 | 
			
		||||
	Required: false,
 | 
			
		||||
@ -60,15 +66,15 @@ func ParseCli(args []string) (*types.CliArguments, error) {
 | 
			
		||||
	var err error
 | 
			
		||||
	Parser = argparse.NewParser("cli parser", "Liest Optionen + Flags von Kommandozeile.")
 | 
			
		||||
	arguments := types.CliArguments{
 | 
			
		||||
		ModeHelp:        Parser.NewCommand("help", ""),
 | 
			
		||||
		ModeVersion:     Parser.NewCommand("version", "Ruft Endpunkt auf, der die Version anzeigt."),
 | 
			
		||||
		ModeRun:         Parser.NewCommand("run", "Ruft Endpunkt auf, der die Algorithmen laufen lässt."),
 | 
			
		||||
		ModeInteractive: Parser.NewCommand("it", "Startet die App im interaktiven Modus."),
 | 
			
		||||
		Quiet:           Parser.Flag("q", "quiet", &optionsQuiet),
 | 
			
		||||
		Debug:           Parser.Flag("", "debug", &optionsDebug),
 | 
			
		||||
		Checks:          Parser.String("", "checks", &optionsChecks),
 | 
			
		||||
		Colour:          Parser.String("", "colour", &optionsColour),
 | 
			
		||||
		ConfigFile:      Parser.String("", "config", &optionsConfigFile),
 | 
			
		||||
		ModeHelp:    Parser.NewCommand("help", ""),
 | 
			
		||||
		ModeVersion: Parser.NewCommand("version", "Ruft Endpunkt auf, der die Version anzeigt."),
 | 
			
		||||
		ModeRun:     Parser.NewCommand("run", "Ruft Endpunkt auf, der die Algorithmen laufen lässt."),
 | 
			
		||||
		Quiet:       Parser.Flag("q", "quiet", &optionsQuiet),
 | 
			
		||||
		Debug:       Parser.Flag("", "debug", &optionsDebug),
 | 
			
		||||
		Interactive: Parser.Flag("", "it", &optionsInteractive),
 | 
			
		||||
		Checks:      Parser.String("", "checks", &optionsChecks),
 | 
			
		||||
		Colour:      Parser.String("", "colour", &optionsColour),
 | 
			
		||||
		ConfigFile:  Parser.String("", "config", &optionsConfigFile),
 | 
			
		||||
	}
 | 
			
		||||
	err = Parser.Parse(args)
 | 
			
		||||
	return &arguments, err
 | 
			
		||||
 | 
			
		||||
@ -15,15 +15,15 @@ import (
 | 
			
		||||
 * ---------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
type CliArguments struct {
 | 
			
		||||
	ModeHelp        *argparse.Command
 | 
			
		||||
	ModeVersion     *argparse.Command
 | 
			
		||||
	ModeRun         *argparse.Command
 | 
			
		||||
	ModeInteractive *argparse.Command
 | 
			
		||||
	Quiet           *bool
 | 
			
		||||
	Debug           *bool
 | 
			
		||||
	Checks          *string
 | 
			
		||||
	Colour          *string
 | 
			
		||||
	ConfigFile      *string
 | 
			
		||||
	ModeHelp    *argparse.Command
 | 
			
		||||
	ModeVersion *argparse.Command
 | 
			
		||||
	ModeRun     *argparse.Command
 | 
			
		||||
	Quiet       *bool
 | 
			
		||||
	Debug       *bool
 | 
			
		||||
	Interactive *bool
 | 
			
		||||
	Checks      *string
 | 
			
		||||
	Colour      *string
 | 
			
		||||
	ConfigFile  *string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ---------------------------------------------------------------- *
 | 
			
		||||
@ -38,6 +38,10 @@ func (arguments CliArguments) DebugModeOn() bool {
 | 
			
		||||
	return *arguments.Debug
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (arguments CliArguments) InteractiveMode() bool {
 | 
			
		||||
	return *arguments.Interactive
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (arguments CliArguments) ShowChecks() bool {
 | 
			
		||||
	return !utils.IsFalse(*arguments.Checks)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -66,9 +66,11 @@ func main() {
 | 
			
		||||
		if arguments.ModeVersion.Happened() {
 | 
			
		||||
			endpoints.Version()
 | 
			
		||||
		} else if arguments.ModeRun.Happened() {
 | 
			
		||||
			err = endpoints.RunNoninteractive(arguments.GetConfigFile())
 | 
			
		||||
		} else if arguments.ModeInteractive.Happened() {
 | 
			
		||||
			err = endpoints.RunInteractive()
 | 
			
		||||
			if arguments.InteractiveMode() {
 | 
			
		||||
				err = endpoints.RunInteractive()
 | 
			
		||||
			} else {
 | 
			
		||||
				err = endpoints.RunNonInteractive(arguments.GetConfigFile())
 | 
			
		||||
			}
 | 
			
		||||
		} else { // } else if arguments.Help.Happened() {
 | 
			
		||||
			endpoints.Help()
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user