Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
184 changes: 83 additions & 101 deletions internal/spentcalories/spentcalories.go
Original file line number Diff line number Diff line change
@@ -1,117 +1,99 @@
package spentcalories

import (
"fmt"
"log"
"strconv"
"strings"
"time"
"fmt"
"strconv"
"strings"
"time"
)

const (
stepLengthCoefficient = 0.414
mInKm = 1000
minInH = 60
walkingCaloriesCoefficient = 0.029
)

func parseTraining(data string) (int, string, time.Duration, error) {
parts := strings.Split(data, ",")
if len(parts) != 3 {
return 0, "", 0, fmt.Errorf("неверный формат данных")
}

steps, err := strconv.Atoi(parts[0])
if err != nil {
return 0, "", 0, fmt.Errorf("ошибка парсинга шагов: %v", err)
}

activityType := parts[1]

duration, err := time.ParseDuration(parts[2])
if err != nil {
return 0, "", 0, fmt.Errorf("ошибка парсинга времени: %v", err)
}

return steps, activityType, duration, nil
// Distance вычисляет дистанцию в километрах по количеству шагов
func Distance(steps int) float64 {
return float64(steps) * 0.00075
}

func distance(steps int, height float64) float64 {
stepLength := height * stepLengthCoefficient
distanceMeters := float64(steps) * stepLength
return distanceMeters / mInKm
// MeanSpeed вычисляет среднюю скорость в км/ч
func MeanSpeed(distance float64, duration time.Duration) float64 {
hours := duration.Hours()
if hours == 0 {
return 0
}
return distance / hours
}

func meanSpeed(steps int, height float64, duration time.Duration) float64 {
if duration <= 0 {
return 0
}
dist := distance(steps, height)
hours := duration.Hours()
return dist / hours
// ParseTraining парсит строку с данными тренировки
func ParseTraining(input string) (steps int, duration time.Duration, err error) {
parts := strings.Fields(input)
if len(parts) != 3 {
return 0, 0, fmt.Errorf("неверный формат данных")
}

// Парсим шаги
steps, err = strconv.Atoi(parts[0])
if err != nil || steps <= 0 {
return 0, 0, fmt.Errorf("неверное количество шагов")
}

// Парсим продолжительность
duration, err = time.ParseDuration(parts[1] + parts[2])
if err != nil || duration <= 0 {
return 0, 0, fmt.Errorf("неверная продолжительность")
}

return steps, duration, nil
}

func RunningSpentCalories(steps int, weight, height float64, duration time.Duration) (float64, error) {
if steps <= 0 || weight <= 0 || height <= 0 || duration <= 0 {
return 0, fmt.Errorf("некорректные входные параметры")
}

speed := meanSpeed(steps, height, duration)
durationMinutes := duration.Minutes()

calories := (weight * speed * durationMinutes) / minInH
return calories, nil
// WalkingSpentCalories вычисляет количество сожженных калорий при ходьбе
func WalkingSpentCalories(steps int, duration time.Duration, weight, height float64) float64 {
if steps <= 0 || duration <= 0 || weight <= 0 || height <= 0 {
return 0
}

distance := Distance(steps)
speed := MeanSpeed(distance, duration)

// Формула для ходьбы
return (0.035 * weight + (speed*speed/height) * 0.029 * weight) * duration.Hours()
}

func WalkingSpentCalories(steps int, weight, height float64, duration time.Duration) (float64, error) {
if steps <= 0 || weight <= 0 || height <= 0 || duration <= 0 {
return 0, fmt.Errorf("некорректные входные параметры")
}

speed := meanSpeed(steps, height, duration)
durationMinutes := duration.Minutes()

calories := (weight * speed * durationMinutes) / minInH
calories *= walkingCaloriesCoefficient
return calories, nil
// RunningSpentCalories вычисляет количество сожженных калорий при беге
func RunningSpentCalories(steps int, duration time.Duration, weight float64) float64 {
if steps <= 0 || duration <= 0 || weight <= 0 {
return 0
}
distance := Distance(steps)
speed := MeanSpeed(distance, duration)
// Формула для бега
return (0.035 * weight + (speed/1.5) * 0.035 * weight) * duration.Hours()
}

func TrainingInfo(data string, weight, height float64) (string, error) {
steps, activityType, duration, err := parseTraining(data)
if err != nil {
log.Println(err)
return "", err
}

var result string
var calories float64
var dist float64
var speed float64

switch activityType {
case "Бег", "бег":
calories, err = RunningSpentCalories(steps, weight, height, duration)
if err != nil {
return "", err
}
dist = distance(steps, height)
speed = meanSpeed(steps, height, duration)
result = fmt.Sprintf("Тип тренировки: Бег\nДлительность: %.2f ч.\nДистанция: %.2f км.\nСкорость: %.2f км/ч\nСожгли калорий: %.2f",
duration.Hours(), dist, speed, calories)

case "Ходьба", "ходьба":
calories, err = WalkingSpentCalories(steps, weight, height, duration)
if err != nil {
return "", err
}
dist = distance(steps, height)
speed = meanSpeed(steps, height, duration)
result = fmt.Sprintf("Тип тренировки: Ходьба\nДлительность: %.2f ч.\nДистанция: %.2f км.\nСкорость: %.2f км/ч\nСожгли калорий: %.2f",
duration.Hours(), dist, speed, calories)

default:
return "", fmt.Errorf("неизвестный тип тренировки")
}

return result, nil
// TrainingInfo возвращает информацию о тренировке в виде строки
func TrainingInfo(trainingType string, input string, weight, height float64) (string, error) {
steps, duration, err := ParseTraining(input)
if err != nil {
return "", err
}

distance := Distance(steps)
speed := MeanSpeed(distance, duration)

var calories float64
switch trainingType {
case "Ходьба":
calories = WalkingSpentCalories(steps, duration, weight, height)
case "Бег":
calories = RunningSpentCalories(steps, duration, weight)
default:
return "", fmt.Errorf("неизвестный тип тренировки: %s", trainingType)
}

info := fmt.Sprintf("Тип тренировки: %s\n", trainingType)
info += fmt.Sprintf("Длительность: %.2f ч.\n", duration.Hours())
info += fmt.Sprintf("Дистанция: %.2f км.\n", distance)
info += fmt.Sprintf("Скорость: %.2f км/ч\n", speed)
info += fmt.Sprintf("Сожгли калорий: %.2f", calories)

return info, nil
}
Loading