CurrencyConverter
Конвертер валют
Как вообще работает этот код?
Сначала создается структура для парсинга данных с json в строку и другие типы для упрощения работы. В моём случае она выглядит так:
type CurrencyData struct { Valute map[string]struct { CharCode string `json:"CharCode"` Value float64 `json:"Value"` } `json:"Valute"`}
По желанию можно структуру поменять, если Вы собираетесь использовать для получения данных о валютах другой сайт, или же вам нужно больше данных по типу ID и т.д.
Сайт для справки:
Если вы решили парсить всю информацию о валютах с этого сайта, указанного в url, Ваша структура может выглядеть примерно так:
type CurrencyData struct { Valute map[string]struct { ID string `json:"ID"` NumCode string `json:"NumCode"` CharCode string `json:"CharCode"` Nominal int `json:"Nominal"` Name string `json:"Name"` Value float64 `json:"Value"` Previous float64 `json:"Previous"` } `json:"Valute"`}
Дальше мы объявляем функцию, в которой делаем запрос на получение данных из этого сайта. Для этого нужен доступ в Интернет(логично), и доступ на сайт(В моем случае он открытый):
func getCurrencyRates() (map[string]float64, error) { // создается запрос на получение данных с урла resp, err := http.Get(url) if err != nil { return nil, err }
И вот, как только мы получили данные, читаем, если они есть:
body, err := ioutil.ReadAll(resp.Body) if err != nil { return nil, err }
Затем в действие приходит структура, которую мы создали ранее.
Объявляем её в коде и начинаем парсить json данные(если они пришли):
var data CurrencyData err = json.Unmarshal(body, &data) if err != nil { return nil, err }
А затем, мы создаем карту, в которую помещаем данные о валюте:
rates := make(map[string]float64)
И, завершаем функцию выводом всех доступных(распарсенных) на данный момент валют:
for key, valute := range data.Valute { rates[valute.CharCode] = valute.Value fmt.Printf("Валюта %s: %f\n", key, valute.Value) }
Есть вторая функция, основная, в которой проходят расчёты и т.д.
Сначала мы её объявляем, в аргументы передаем 2 объекта типа string и 1 типа float64, а сама функция имеет типы float64, error:
func Convert(choose1, choose2 string, amount float64) (float64, error) { rates, err := getCurrencyRates() if err != nil { fmt.Println("Ошибка получения курса валют:", err) }
Также, в данном куске кода есть обращение к функции выше, а ещё происходит обращение, то есть код дальше не пойдёт, если, например, данных нет или они не распарсились.
Затем мы запрашиваем у пользователя первую валюту, если её ввели, к примеру, маленькими буквами(сама валюта KZT, а ввели ее - kzT, то маленькие буквы преобразятся в заглавные), ну а ещё проверка на существование валюты:
fmt.Println("Выберите валюту для первого значения") fmt.Scanln(&choose1) // в случае если человек пишет маленьким регистром, то преобразуем к верхнему регистру choose1 = strings.ToUpper(choose1) _, exists1 := rates[choose1] // проверка на существование валюты if !exists1 { return 0, errors.New("Такой валюты не существует или выбрана неверная валюта") }
Подобный принцип и со второй валютой, но я добавил проверку на одинаковые валюты:
if rates[choose2] == rates[choose1] { return 0, errors.New("Вы ввели одинаковые валюты") }
Далее запрашивается количество первой валюты, и сама формула вычисления:
fmt.Println("Выберите количество", rates[choose1]) fmt.Scanln(&amount) result := amount * rates[choose1] / rates[choose2]
return result, nil
Выполнив тест, можно проверить, как работает код.