_ums_

tracker

Oct 13th, 2023
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 8.15 KB | None | 0 0
  1. package main
  2.  
  3. // импортируйте нужные пакеты
  4. import (
  5.     "fmt"
  6.     // ...
  7.     "strconv"
  8.     "strings"
  9.     "time"
  10. )
  11.  
  12. const (
  13.     K1 = 0.035
  14.     K2 = 0.029
  15. )
  16.  
  17. var (
  18.     Format     = "20060102 15:04:05" // формат даты и времени
  19.     StepLength = 0.65                // длина шага в метрах
  20.     Weight     = 75.0                // вес кг
  21.     Height     = 1.75                // рост м
  22.     Speed      = 1.39                // скорость м/с
  23. )
  24.  
  25. // parsePackage разбирает входящий пакет в параметре data.
  26. // Возвращаемые значения:
  27. // t — дата и время, указанные в пакете
  28. // steps — количество шагов
  29. // ok — true, если время и шаги указаны корректно и false — в противном случае
  30. func parsePackage(data string) (t time.Time, steps int, ok bool) {
  31.     // 1. разделите строку на две части по запятой в слайс ds
  32.     // 2. проверьте, чтобы ds состоял из двух элементов
  33.     // ...
  34.     ds := strings.Split(data, ",")
  35.     if len(ds) != 2 {
  36.         return
  37.     }
  38.     var err error
  39.     // получаем время time.Time
  40.     t, err = time.Parse(Format, ds[0])
  41.     if err != nil {
  42.         return
  43.     }
  44.     // получаем количество шагов
  45.     steps, err = strconv.Atoi(ds[1])
  46.     if err != nil || steps < 0 {
  47.         return
  48.     }
  49.     // отмечаем, что данные успешно разобраны
  50.     ok = true
  51.     return
  52. }
  53.  
  54. // stepsDay перебирает все записи слайса, подсчитывает и возвращает
  55. // общее количество шагов.
  56. // тема оптимизации не затрагивается, поэтому можно
  57. // использовать parsePackage для каждого элемента списка
  58. // ...
  59. func stepsDay(storage []string) int {
  60.     var stepsForDay int
  61.     for _, v := range storage {
  62.         _, steps, _ := parsePackage(v)
  63.         stepsForDay = stepsForDay + steps
  64.     }
  65.     return stepsForDay
  66. }
  67.  
  68. // calories возвращает количество килокалорий, которые потрачены на
  69. // прохождение указанной дистанции (в метрах) со скоростью 5 км/ч.
  70. func calories(distance float64) float64 {
  71.     timeInMotion := distance / Speed / 60
  72.     caloriesForDay := (K1*Weight + (Speed*Speed/Height)*K2*Weight) * timeInMotion
  73.     return caloriesForDay
  74.     // ...
  75. }
  76.  
  77. // achievement возвращает мотивирующее сообщение в зависимости от
  78. // пройденного расстояния в километрах.
  79. func achievement(distance float64) string {
  80.     var motivation string
  81.     switch {
  82.     case distance >= 6.5:
  83.         motivation = "Отличный результат! Цель достигнута.\n"
  84.     case distance >= 3.9:
  85.         motivation = "Неплохо! День был продуктивный.\n"
  86.     case distance >= 2.0:
  87.         motivation = "Завтра наверстаем!\n"
  88.     default:
  89.         motivation = "Лежать тоже полезно. Главное — участие, а не победа!\n"
  90.     }
  91.     return motivation
  92. }
  93.  
  94. // showMessage выводит строку и добавляет два переноса строк.
  95. func showMessage(s string) {
  96.     fmt.Println(s)
  97.     fmt.Println("")
  98. }
  99.  
  100. // AcceptPackage обрабатывает входящий пакет, который передаётся в
  101. // виде строки в параметре data. Параметр storage содержит пакеты за текущий день.
  102. // Если время пакета относится к новым суткам, storage предварительно
  103. // очищается.
  104. // Если пакет валидный, он добавляется в слайс storage, который возвращает
  105. // функция. Если пакет не валидный, storage возвращается без изменений.
  106. func AcceptPackage(data string, storage []string) []string {
  107.     // 1. используйте parsePackage для разбора пакета.
  108.     //    t, steps, ok := parsePackage(data)
  109.     //    выведите сообщение в случае ошибки
  110.     //    также проверьте количество шагов на равенство нулю
  111.     // ...
  112.     t, steps, ok := parsePackage(data)
  113.     if !ok {
  114.         showMessage("ошибочный формат пакета")
  115.         return storage
  116.     }
  117.  
  118.     if steps < 0 {
  119.         showMessage("ошибочный формат пакета")
  120.         return storage
  121.     }
  122.  
  123.     // 2. получите текущее UTC время и сравните дни
  124.     //    выведите сообщение, если день в пакете t.Day() не совпадает
  125.     //    с текущим днём
  126.     // ...
  127.  
  128.     now := time.Now().UTC()
  129.     if t.Day() != now.Day() {
  130.         showMessage("неверный день")
  131.         return storage
  132.     }
  133.  
  134.     // выводим ошибку, если время в пакете больше текущего времени
  135.     if t.After(now) {
  136.         showMessage(`некорректное значение времени`)
  137.         return storage
  138.     }
  139.  
  140.     // проверки для непустого storage
  141.     if len(storage) > 0 {
  142.         // 3. достаточно сравнить первые len(Format) символов пакета с
  143.         //    len(Format) символами последней записи storage.
  144.         //    если меньше или равно, то ошибка — некорректное значение времени
  145.         // ...
  146.         lastTime, _, _ := parsePackage(storage[len(storage)-1])
  147.         if lastTime == t || t.Before(lastTime) {
  148.             showMessage(`некорректное значение времени`)
  149.             return storage
  150.         }
  151.  
  152.         // смотрим, наступили ли новые сутки — YYYYMMDD — 8 символов
  153.         if data[:8] != storage[len(storage)-1][:8] {
  154.             // если наступили
  155.             // то обнуляем слайс с накопленными данными
  156.             storage = storage[:0]
  157.         }
  158.     }
  159.     // остаётся совсем немного
  160.     // 5. добавить пакет в storage
  161.     storage = append(storage, data)
  162.     // 6. получить общее количество шагов
  163.     stepsDay := stepsDay(storage)
  164.     // 7. вычислить общее расстояние (в метрах)
  165.     distanceDay := float64(stepsDay) * StepLength
  166.     // 8. получить потраченные килокалории
  167.     caloriesDay := calories(distanceDay)
  168.     // 9. получить мотивирующий текст
  169.     motivation := achievement(distanceDay / 1000)
  170.     // 10. сформировать и вывести полный текст сообщения
  171.     fmt.Printf("Время: %s.\n", t.Format("15:04:05"))
  172.     fmt.Printf("Количество шагов за сегодня: %d.\n", stepsDay)
  173.     fmt.Printf("Дистанция составила %.2f км.\n", distanceDay/1000)
  174.     fmt.Printf("Вы сожгли %.2f ккал.\n", caloriesDay)
  175.     fmt.Println(motivation)
  176.     // 11. вернуть storage
  177.     // ...
  178.  
  179.     return storage
  180. }
  181.  
  182. func main() {
  183.     // вы можете сразу проверить работу функции AcceptPackage
  184.     // на небольшом тесте.
  185.     // Если запустить программу после 05:00 UTC, то последнее
  186.     // сообщение должно быть таким:
  187.     // Время: 04:45:21.
  188.     // Количество шагов за сегодня: 16956.
  189.     // Дистанция составила 11.02 км.
  190.     // Вы сожгли 664.23 ккал.
  191.     // Отличный результат! Цель достигнута.
  192.  
  193.     now := time.Now().UTC()
  194.     today := now.Format("20060102")
  195.  
  196.     // данные для самопроверки
  197.     input := []string{
  198.         "01:41:03,-100",
  199.         ",3456",
  200.         "12:40:00, 3456 ",
  201.         "something is wrong",
  202.         "02:11:34,678",
  203.         "02:11:34,792",
  204.         "17:01:30,1078",
  205.         "03:25:59,7830",
  206.         "04:00:46,5325",
  207.         "04:45:21,3123",
  208.     }
  209.  
  210.     var storage []string
  211.     storage = AcceptPackage("20230720 00:11:33,100", storage)
  212.     for _, v := range input {
  213.         storage = AcceptPackage(today+" "+v, storage)
  214.     }
  215. }
  216.  
Add Comment
Please, Sign In to add comment