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
181 changes: 80 additions & 101 deletions internal/spentcalories/spentcalories.go
Original file line number Diff line number Diff line change
@@ -1,117 +1,96 @@
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
func parseTraining(input string) (int, time.Duration, float64, error) {
parts := strings.Fields(input)
if len(parts) != 3 {
return 0, 0, 0, fmt.Errorf("неверный формат данных")
}

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

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

distance := float64(steps) * 0.00075

return steps, duration, distance, nil
}

func distance(steps int, height float64) float64 {
stepLength := height * stepLengthCoefficient
distanceMeters := float64(steps) * stepLength
return distanceMeters / mInKm
func distance(steps int, length float64) float64 {
return float64(steps) * length
}

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
func meanSpeed(steps int, length float64, duration time.Duration) float64 {
dist := distance(steps, length)
hours := duration.Hours()
if hours == 0 {
return 0
}
return dist / hours
}

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
func WalkingSpentCalories(steps int, weight float64, height float64, duration time.Duration) (float64, float64) {
if steps <= 0 || duration <= 0 || weight <= 0 || height <= 0 {
return 0, 0
}

length := 0.00075
dist := distance(steps, length)
speed := meanSpeed(steps, length, duration)

calories := (0.035 * weight + (speed*speed/height) * 0.029 * weight) * duration.Hours()
return calories, dist
}

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
func RunningSpentCalories(steps int, weight float64, height float64, duration time.Duration) (float64, float64) {
if steps <= 0 || duration <= 0 || weight <= 0 || height <= 0 {
return 0, 0
}
length := 0.00075
dist := distance(steps, length)
speed := meanSpeed(steps, length, duration)
calories := (0.035 * weight + (speed/1.5) * 0.035 * weight) * duration.Hours()
return calories, dist
}

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
func TrainingInfo(trainingType string, input string, weight, height float64) (string, error) {
steps, duration, _, err := parseTraining(input)
if err != nil {
return "", err
}

var calories, distance float64

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

speed := meanSpeed(steps, 0.00075, duration)

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