В офисе на странице списка таймеров вывести информацию суммарное время выполнения
Завершена
Проект: freecode.academy
Планируемый запуск: | Дата начала: | 01.03.2021 | Планируемое завершение: | Дата завершения: | 01.03.2021 |
Описание задачи
Вот здесь есть подсчет и форматирование затраченного времени : https://github.com/freecode-academy/freecode.academy/blob/e8dc066e7a539e87d1a87e72ada36f059a32d291/src/pages/Office/Timers/View/Timer/index.tsx#L13-L15
- ТехнологияТребуемый уровень
Проект | Задача | Статус | Дата постановки | Начало | Конец | Кто создал |
---|---|---|---|---|---|---|
freecode.academy | В офисе на странице списка таймеров вывести информацию суммарное время выполнения | Завершена | 24.02.2021 20:06:54 | 01.03.2021 15:01:00 | 01.03.2021 16:21:52 | |
freecode.academy | В офисе на странице списка таймеров вывести информацию суммарное время выполнения | Завершена | 24.02.2021 20:06:54 | 25.02.2021 16:17:19 | 26.02.2021 18:14:09 |
Я правильно понимаю, что вывод должен быть примерно там где сейчас заголовок лог выполнения?
И не совсем понятно суммарное время моих проектов или всех которые там отображаются. Я так понимаю еще нет функционала по выбору только моих проектов, значит всех получается?
>> Я правильно понимаю, что вывод должен быть примерно там где сейчас заголовок лог выполнения?
Да. В принципе, в любом месте можешь вывести, не критично.
>> И не совсем понятно суммарное время моих проектов или всех которые там отображаются. Я так понимаю еще нет функционала по выбору только моих проектов, значит всех получается?
Суммарное время всех полученых записей. Там найди где они перечисляются в цикле и набиваются в шаблоны. Вот так же возьми, перечисли их и посчитай все время. То есть по АПИ ничего запрашивать не надо, данные итак есть.
Думаю лучше здесь все-таки выводить после иконок.
Олег, ты совсем в другую степь полез. То общий каркас, при чем не самый оптимальный (я там экспериментирую).
Я же в задаче указал: Сама страница здесь: https://github.com/freecode-academy/freecode.academy/blob/e8dc066e7a539e87d1a87e72ada36f059a32d291/src/pages/Office/Timers/View/index.tsx
Вот там где-нибудь и воткни.
Вообщем у нас есть компонент отвечающий за время результаты он выводет в компоненте OfficeProjectPageViewTask вывод результатов мы договорились делать на этой странице так же в папке Timer есть еще один компонент OfficeTimersPage.
Ты написал:
Суммарное время всех полученых записей. Там найди где они перечисляются в цикле и набиваются в шаблоны. Вот так же возьми, перечисли их и посчитай все время.
Первый вопрос есть ли какой-нибудь алгоритм, как приступать к выполнению задачи, к примеру я в данный момент плохо понимаю, что где за что отвечает. Как я должен был бы начать эту задачу вижу файлы, но плохо понимаю, как они между собой связаны.
Второй вопрос по поводу места где они набиваются я правильно понимаю, что ты про этот код говорил:
Просто на самой странице тоже есть map:
Третий вопрос не понимаю, как мы результат должны получать через хук useState например или просто, нужно пременить js функцию после выполнения цикла и она все посчитает?
<< Первый вопрос есть ли какой-нибудь алгоритм, как приступать к выполнению задачи
Есть: Пришел, увидел, победил. Все как обычно...
<< Как я должен был бы начать эту задачу вижу файлы, но плохо понимаю, как они между собой связаны.
Олег, а как ты делал учебный проект с покемонами? Ведь ты же закладывал там как-то несколько файлов, связанных друг с другом. Или ты кому-то заплатил и за тебя сделали?
На самом деле тебя разброс файлов вообще особо не должен волновать. Какая разница один это файл или много? Главное - с чего начать. А я говорил с чего - с папки /pages. С нее все начинается, там весь роутинг. А далее юзай активно F12 (для быстрого перехода к сущности). Встал курсором, нажал F12, Перешел к сущности. Оттуда практически наверняка будет куда-нибудь в src/pages, где конечный код страниц находится. Там будет первичное получение нужных данных, которые будут передаваться в какую-нибудь вьюху (View). Вложенность может быть какая угодно, но суть все равно будет одна и та же: это будут реакт-компоненты, которые выводят другие реакт-компоненты, передавая в них пропсы (props) и оперируя своими стейтами (state). Все. Там другого практически ничего нет. Все остальное локально внутри компонента. Вот еще раз: я уже выше говорил, что Сама страница здесь: https://github.com/freecode-academy/freecode.academy/blob/e8dc066e7a539e87d1a87e72ada36f059a32d291/src/pages/Office/Timers/View/index.tsx
Это же всего три строчки. Что тут не ясно? Ты не понимаешь метода Array.map? Так зайди в уроки по JS и перепройди массивы.
Это основа. Практически все языки программирования держатся на трех китах: циклы, условия и еще что-то там. Если ты не понимаешь и не умеешь в if/else, то куда ты вообще можешь пойти? Если не понимаешь циклы (while, for и т.п.), то опять-таки, куда ты можешь пойти? Ты месяц делал покемонов, а в итоге простейшие операции с массивами не понимаешь? А знаешь почему? Помнишь этот мем?: "Отправили на экскурсию по заводу BMW, а потом заставляют наладить производство таких же машин". Вот ты посмотрел как кто-то там делает какой-то проект, от начала и до конца, так вот, даже если ты год потратишь и научиться по тому курсу делать этот проект с покемонами, то в лучшем случае ты научишься делать именно такие проекты с покемонами. А каков шанс на то, что к тебе придет заказчик и попросит вот ровно такой проект с покемонами? Даже если вот прям сильно такой же будет и ты сможешь его сделать на 90%, но не сможешь доделать оставшиеся 10%, то проект не сдан. Никто не примет проект со словами "Ну там осталось немного, найдите кого-нибудь, пусть доделает".
Я же на главной странице даже сделал ссылку для новеньких: https://freecode.academy/start/developers и главное там вот это:
Если вы решили изучить веб-программирование, мы попытаемся вам в этом помочь. Для этого разрабатывается и внедряется сразу несколько инструментов.
Данный раздел подходит для самостоятельного последовательного изучения основам веб-разработки. Рекомендуется следующая последовательность в изучении:
Для начала освоить
При чем лучше не последовательно полностью по курсу, а в первый день HTML и CSS, во второй JavaScript, в третий React, и далее по кругу. Реакт будет на первых парах сложен в восприятии, поэтому его можно в начале поменьше. Чувствуете, что ничего не понимаете - переключайтесь опять на HTML/CSS/JS. Все потому что Реакт, по сути, это JS+HTML - Переменные, свойства которых являются HTML-разметкой (очень условно, но близко к сути).
В каждом уроке есть вкладка Обсудить. Если вы зашли в нее и там нет еще ни одного сообщения, не стесняйтесь, смело пишите туда любые вопросы. Смысл данных уроков не в том, чтобы протестировать что вы умеете, а что нет (хотя и это тоже), а в том, чтобы вы научились чему-то новому, так что если что-то не ясно, обязательно спрашивайте. Все обсуждения попадают в общий блог Уроки.
Вот именно в такой последовательности. Ты должен знать основы JS обязательно. Прям каждый день по часу-два на эти уроки тратить, можно и по кругу, пока не почувствуешь уверенность в знаниях. А ты что сейчас делаешь? Не понял три строчки и пытаешься отъехать в то, что проект большой и запутанный? Нее, так дело не пойдет. Проблема явно не в проекте, а в знаниях и подходах.
Так вот, возвращаясь к задаче, ты мог бы для начала хотя бы сделать это:
Вот если бы ты это сделал, вот просто локально, и спросил "Колян, я вот сумел посчитать общее затраченное время, как мне....", а я вот даже не знаю что там еще спросить остается...
Вот тогда бы я понял, что локально ты в чем-то продвинулся... А вот потом уже будешь смотреть и в связи в файлах и т.п.
>> Второй вопрос по поводу места где они набиваются я правильно понимаю, что ты про этот код говорил:
Просто на самой странице тоже есть map:
Во-первых, я это показывал для примера. Во-вторых, в одном месте перечисление задач проекта, а в другом случае перечисление таймеров. Это как бы вообще не одно и то же.
А, и да, забыл сказать, о чем говорил уже не раз: для того, чтобы учиться, не обязательно только что-то самому создавать. Ведь можно и просто смотреть что делают другие и пытаться понять почему сделано так, что происходит и как происходит. Да, у меня тут есть сложные вещи, но есть и очень простые. Почаще заходи на страницу всех задач с пометкой "Нужна помощь": https://freecode.academy/tasks?needHelp=true, смотри те, что уже выполнены. Там, в своих задачах, я часто указываю ссылки на коммиты (Пометка Решение). Что может быть лучше? Вот тебе и задача с описанием, вот тебе и решение (как правило не особо большое). Бери, изучай.
Вот еще подсказка: если тебе хочется изучить код решения, но не очень удобно на гитхабе диффы смотреть, да еще хочется с кодом поиграться, можно же создать ветку из конкретного коммита.
К примеру, вот задача: https://freecode.academy/tasks/ckljv1vh67b8u0730duw8yph4
5f892c3b62d08884b953647c5327eeb1937756b5 - это хэш коммита. Ветку создаем так:
git checkout 5f892c3b62d08884b953647c5327eeb1937756b5 -b test_branch
Все, вот ты в бранче test_branch и ровно в этой точке. Запускай yarn dev, иди в код этих файлов и играйся с кодом.
Я правильно понимаю totalTime += ... считает сумму часов, а три точки ... это деструктуризация обращение к аргументу timer? Не совсем понимаю, как происходит суммирование времени время же - это не просто цифры, а имет свой формат, думал что его снчала надо преобразовать в unix time формат, а потом считать или пременить специальный метод, который все выполнит сам.
Олег, троеточие (деструктуризация) пишется только внутри объектов и массивов, то есть {...} и [...]. А здесь это было как в русском языке - "многоточие". То есть указание "продолжить свою логику". То есть имелось ввиду, что там ты напишешь свою логику для подсчета (ну, или выше, а там переменную передашь).
<< времени время же - это не просто цифры, а имет свой формат
Это зависит от того, чем является то, что ты называешь временем. Если ты имеешь строку типа "2021-01-01 23:59:59", то как тип, это вот та же строка и не более того. Это только можно рассчитывать на то, что она в себе имеет в качестве значения некую временную метку, но только рассчитывать, не более. От этого она временем не стала. А вот Объект Date - это уже самое что ни на есть время, то есть его можно таковым считать. Но оно не несет в себе форматирования. Форматирование - это операция, а вот временная метка - это значение. Очень важно понимать эти моменты.
Так вот, на счет твоего вопроса: я тебе почему постоянно говорю учить TypeScript? Вот приступишь к решению задачи, получишь переменную из объекта, и посмотри какого она вообще типа. Так вот, скорее всего она будет именно Date, а не script. То есть это будет именно объект даты.
Так вот, с датами можно выполнять математические и логические операции, так что stopedAt - createdAt вернет разницу в секундах (число). А moment используем как раз для форматирования. moment.utc(diff).format(format_string)
Доку по форматированию можешь посмотреть здесь: https://momentjs.com/docs/#/displaying/format/
Кстати, на том сайте, если открыть браузерную консоль, функция moment() доступна прям там. Можешь там же попробовать выполнить
Если я правиль понял в этом коде:
чтобы получить общую сумму просто нужно передать массив timer где у тебя стоит троеточие. Собственно, что я и попытался сделать, но когда я его туда добавил TS выдал ошибку Operator '+=' cannot be applied to types 'number' and 'Timer_Fragment'.ts(2365). Тогда я попробовал преоброзовать типы totalTime и
timersContent тоже в Timer_Fragment, так у timer у нас тип Timer_Fragment и ты вроде выше писал, что с такими объектами можно манипулировать (если конечно правильно понял), но TS все равно выдает ошибку и такое ощущение, что он все-таки его не преоброзовал, так как выше в коде:
let totalTime = 0; все равно определяется, как number, пробовал разные способы, там в коде закоммитил, чтобы было видно, что пробовал, но в итоге не получилось.
Плюс в этом коде:
TS выдает ошибку All destructured elements are unused. Гуглил, но ничего вразумительного не смог найти, как исправить.
Отправил коммит:
Я вот даже и не припомню когда в последний раз видел, чтобы так упорно пытались натянуть сову на глобус...
Ты опять слишком много написал и слишком много всего попробовал, забыв сосредоточиться на самом важном... Давай в блиц вопрос-ответ. Отчвечай четко на каждый вопрос, не убегая в сторону.
Здесь totalTime какой тип имеет?
А оператор += что выполняет?
Прибавляет и приравнивает
Оператор присваивания присваивает левому операнду значение, основанное на значении правого операнда.
Тут это называют Сложением с присваиванием, что более правильно.
Если у нас переменная имеет тип number, то значение какого типа к ней можно прибавить? Перечисли все.
Соответсвенно number, так я пытался timer присваивает значение number там оно есть закомичено, но не все равно ошибка, потом решил сделать наоборот и превратить totalTime в Timer_Fragment.
А timer какой тип имеет?
(parameter) timer: Timer_Fragment
Тип Timer_Fragment равен типу number?
Скорей всего нет - это же разные типы, но точно не уверен.
Вот тут прям в шок вводишь... Какие значения могут быть присвоены переменной с типом number? Перечисли штук пять, любых.
number, Infinity, NaN, string, undefined
Нет, я не говорил перечисли типы, которые ты знаешь. Я сказал перечислить значения, которые могут быть присвоены переменной с типом number. То есть
const a: number = 5;
const b: number = 4.5;
и т.д.
А теперь пришли общую структуру типа Timer_Fragment
Вот. Похоже на то, что можно задать переменную типа const c: Timer_Fragment = 7.7?
Да вроде не похоже, здесь только строковые типы и массивы.
Тогда получается я не понимаю, что делает этот код .
timers: OfficeTimersTimerProps['timer'][]
Хотел попросить тебя прислать сюда значение хоть одной переменной timer, но скорее всего и с этим не справшись. Вот смотри.
Вот смотри, это такая переменная (сильно урезанная, но все же). Как ты хотел это присвоить к числу?
>> Тогда получается я не понимаю, что делает этот код .
timers: OfficeTimersTimerProps['timer'][]
Этот код всего лишь говорит "Жду переменную timers, которая должна быть типом Массив типов OfficeTimersTimerProps['timer']".
А теперь вопрос: если переменная totalTime имеет тип number, а timer не является типом number (соответственно нельзя одно прибавить к другому), то почему ты вообще пытался эти две сущности сложить? На что рассчитывал? Какого эффекта ожидал? Что думал получить на выходе?
OfficeTimersTimerProps а здесь мы ей присваиваем Timer_Fragment. В итоге - это получается строка или массив или вообще объект?
На выходе, как всегда результат:)
>> В итоге - это получается строка или массив или вообще объект?
В итоге это получается массив Timer_Fragment. То есть Timer_Fragment[] это то же самое, что и Array<Timer_Fragment>, если тебе так понятней. Вопрос только в том, понимаешь ли ты в принципе, что такое массивы?
>> На выходе, как всегда результат:)
Олег, не до шуток. Какой результат ты ожидал? Что должно быть результатом?
Массивы я понимаю, что такое.
Олег, не до шуток. Какой результат ты ожидал? Что должно быть результатом?
Я думал он сложит этот массив и получит сумму.
А нужно складывать получается объекты массива timer?
Во-первых, timer - это не массив. Массив - это timers. Читать умеешь? А timer - это объект.
Во-вторых, даже если бы ты мог слошить массивы, то чтобы ты получил на выходе? Вот что?
> А нужно складывать получается объекты массива timer?
А в JS можно складывать объекты?
Что получится?
Я имел ввиду эллементы массива.
А элементами массива что является?
Параметры точно не помню, как они называются, то что лежит в самом массиве. Значения массива.
Олег, научись, если ты не знаешь, говорить, что ты не знаешь. Ты сам себя водишь за нос. Попадаешь в ловушку, думая, что примерно ты что-то понимаешь, просто не до конца. Так нельзя. Здесь так не работает. Это программирование. Если ты не до конца понимаешь с чем имеешь дело, значит это уже катастрофа. Ты должен учиться понимать каждый символ и каждую сущность, хотя бы в области того, с чем приходится заниматься в текущий момент.
Напомню, у тебя на входе переменная timers, являющаяся массивом, содержащим элементы типа Timer_Fragment, то есть ее тип Array<Timer_Fragment>. Перечисляя этот массив методом map(), у нас на каждой итерации входящий параметр - timer, являющийся элементом массива timers и он имеет тип Timer_Fragment.
Так на что ты рассчитывал, когда к переменной типа number пытался прибавить объект типа Timer_Fragment? На что? Как по-твоему должен был поступить компьютер и какой результат выдать?
Я его пытался привести к единому типу и рассчитывал получить сумму времени всех постов.
Каким образом ты планировал привести его к единому типу? С помощью какого механизма? Я тут не увидел ничего.
Вообще, справедливости ради, стоит заметить, что математические операции могут приводить к динамической смене типа. К примеру 1 + " волк" (то есть number + string) в результате даст строку "1 волк". Это есть суть "динамическая типизация", противоположность строгой типизации. TypeScript как раз и был создан, чтобы ввести строгую типизацию, чтобы избегать таких случаев. Потому что тот же BuldogPlusNosorog = Buldog + Nosorog на выходе даст "[object Object][object Object]", потому что в данном случае будет попытка выполнить BuldogPlusNosorog = Buldog.toString() + Nosorog.toString();
Так вот, когда ты пытался выполнить эту бессмыслицу, тебе TS сказал "Operator '+=' cannot be applied to types 'number' and 'Timer_Fragment'.ts(2365)", то есть он тебе очень конкретно сообщил, что нельзя объект прибавить к числу. И ты вместо того, чтобы подумать как сделать так, чтобы прибавлять число, стал думать о том, как число сделать не числом. Зачем так?
А теперь давай вернемся к постановке задачи. Было сказано: Надо на странице таймеров вывести суммарное затраченное время.
Так вот, каждая итерация у нас идет с объектом timer. Нам надо получить затраченное время. Так вот ответь, что является сутью "затраченное время" и как нам его вычислить из объекта timer?
И ты вместо того, чтобы подумать как сделать так, чтобы прибавлять число, стал думать о том, как число сделать не числом. Зачем так?
Так я таймер, тоже хотел сделать числом, я так и так пробовал. Просто так, как я еще не очень хорошо ориентируюсь в TS конструкциях я не до конца понял, что такое Timer_Fragment только сейчас понял, когда ты объяснил.
Так вот, каждая итерация у нас идет с объектом timer. Нам надо получить затраченное время. Так вот ответь, что является сутью "затраченное время" и как нам его вычислить из объекта timer?
Предполагаю, что нужно сложить все объекты timer в единный объект. Cложить все значения объектов timer в массиве timers?
<< Предполагаю, что нужно сложить все объекты timer в единный объект.
И что на выходе получить? Строку из кучи повторяющихся подстрок "[object Object]"? В любом случае, это опять неправильно и совсем не туда.
Еще раз читай внимательно: "Так вот ответь, что является сутью "затраченное время" и как нам его вычислить из объекта timer?".
Уточняю: я здесь употребил единичный объект timer. В текущй итерации он один и с ним только и работаем сейчас. Ни о каких массивах сейчас речи нет. Так что является сутью "затраченное время"? Как ты его можешь получить из объекта timer?
Возможно timer.id id каждого проекта, так как в нем получаем значение для каждого объекта timer в отдельности.
Получаем что-то, чтобы получить что-то, чтобы потом запросить что-то и там еще запросим что-то... Не слишком ли сложно? Опять ты в какую-то магию отправился.
Еще раз: как из текущего объекта timer вычислить затраченное время? Уточняю: ничего со стороны запрашивать не надо, никакие запросы выполнять не надо, никакие левые функции выполнять не надо. Все необходимое у нас уже есть в текущем объекте таймер. Так как вычислить "затраченное время"?
Если все в нем уже есть, как я и предполагал изначально, нужно просто его распарсить, чтобы получить тип number и присвоить totalTime.
Рука-лицо... Парсят строки, к примеру...
ОК, выражаясь твоими словами, как ты планируешь распарсить объект timer, чтобы получить тип number. Напиши здесь кодом. Это в одну строчку вполне уложиться можно.
var data = [{"test":3}]
var s = JSON.stringify(data);
var d = JSON.parse(s)[0].Spalte;
Где же ты дичи-то этой начитался? Где ты этому научился?
Во-первых, у тебя Spalte вообще отсутствует в исходных данных. У тебя data имеет тип Array<{test: number}>. Где ты там Spalte нашел, вообще не ясно.
Во-вторых, нафига объект приводить к строке, чтобы его обратно распарсить в объект и пытаться из него что-то получить? Даже если ты пытался на самом деле получить не Spalte, а тест, то твой код превращается вот в такое:
Все. Никаких stringify и parse.
В-третьих, какое это отношение имеет к объекту timer?
Ты так и не ответил на главный вопрос: что является сутью затраченного времени и как его вычислить? Отвечаю: затраченное время - это разнича между стартом таймера и остановом его. То есть дельта Конечного времени и Начального. Это, наверно, первые классы средней школы. Так вот, что в объекте таймера является начальным и конечным временем? Отвечаю:
- Начальное время - свойство createdAt
- Конечное время - свойство stopedAt
То есть для того, чтобы рассчитать затраченное время, достаточно было вычесть большее из меньшего, то есть
Все! Вот тебе разница в миллисекундах (то есть в тысячных секунды).
Единственное, вот если ты так прям напишешь, то TS ругнется на то, что stopedAt может отсутствовать. Это и логично. Ведь текущий таймер, пока не остановлен, не имеет значения stopedAt. Оно появится когда его остановят. То есть конечный подсчет будет выглядеть так:
То есть если время останова отсутствует, указываем текущее время актуальное, таким образом даже в текущем таймере мы посчитаем сколько времени затрачено конкретно на текущий момент.
Все. И diff будет иметь тип number, и его можно присваивать к totalTime. Что здесь не ясно? Как можно было усложнить такую простую задачу?
А еще я в задаче указывал на пример подсчета: https://github.com/freecode-academy/freecode.academy/blob/e8dc066e7a539e87d1a87e72ada36f059a32d291/src/pages/Office/Timers/View/Timer/index.tsx#L13-L15
Хоть здесь и используются moment(), суть от этого не меняется. Все равно высчитывается разность этих двух полей.
В итоге весь коммит всего лишь вот такой: https://github.com/freecode-academy/freecode.academy/commit/ead47f12bdf18a3225ad455ccbf53324a8586551