Задачи для начинающих
Знакомый в Уни, начал подкидывать задачки. Возможно будет интересно и тем кто хочет научится программированию. Выкладывайте свои ответы - обсудим.
Вначале задача в том виде, как рассказали по телефону. Я ее протестировал на "кошках" - решают без каких либо проблем, в общем виде.
1. Есть террариум в котором нужно поддерживать постоянную заданную температуру, для этого есть функции "ВключитьНагрев", "ОтключитьНагрев".
Требуется вначале построить Flussdiagram, а потом уже прогу на питоне.
Для начала попробуйте просто описать алгоритм используя конструкции "Делай ..." и "Если ... То... Иначе..."
Специально написал немного меньше чем надо. Допишите сами чего еще не достаёт для постновки задачи.
Выкладывайте свои ответы - обсудим.
А если не будут обсуждать, а будут смеятся над ответом, или пойдут ироничные или саркастические шутки?
Смотря какой террариум. Если он большой, то я предпологаю что в террариуме должно находится несколько датчиков температуры, а так-же несколько подогревательных элементов, допустим по бокам, и посередине. Ведь в квартире иногда бывают 2 или 3 обогревателя, но в константу MAX_COUNT_SENSORS можно просто установить значение 1, тогда будет от одного датчика проверяться. И если это проект для ардуино, то датчики будут возвращать скорей всего числа с плавоющей точкой, что-то вроде около нуля, а range в Python отказывается иметь дело с float, берёт только целые числа. Причём датчики ардуино, будут давать погрешность, калибровка датчиков (термометров) это тот ещё геморрой. А MicroPython какой-нибудь урезаный, там нет прям таких крутых библиотек как в нормальном Python 3.x
Требуется вначале построить Flussdiagram, а потом уже прогу на питоне.
Ох, а мне вот проще наоборот.
"Делай ..." и "Если ... То... Иначе..."
А мне больше нравится использовать ...in range...
if avg_temp in range(MIN, MED): ... elif avg_temp in range(MED, MAX): ... elif avg_temp > MAX: ... else: ...
Начну с кода, а завтра попробую Flussdiagram нарисовать.
import random import sys #Константы-------------- MIN_TEMP = 0 #Минимальная температура MED_TEMP = 5 #Средняя температура MAX_TEMP = 10 #Максимальная температура STEP = 1 #Шаг MAX_COUNT_SENSORS = 5 #Максимальное количество сенсоров #Функци----------------- #Поиск среднего значения def avg(items): return sum(items) / len(items) #Делаем теплее def make_warm(i, idx): #Инкрементация массива idx индекса i, на один шаг, с шагом STEP i[idx] += STEP #Делаем холоднее def make_cold(i, idx): #Декрементация массива idx индекс i, на один шаг, с шагом STEP i[idx] -= STEP #Остужаем всё def make_cold_all(i): #Декрементация всех элеметнов массива i, с шагом STEP for x in i: i[i.index(x)] -= STEP #Сброс def restart_all(mv, i): #Устанавливаем для каждого элемента массива i, значение mv for x in i: i[i.index(x)] = mv #Начало----------------- #Инициализация переменных temp = [] # Массив со значением от датчиков index = 0 # Индекс avg_temp = 0 # Средняя температура cmd = '' # Команда, Y-дальше мониторить/A-выключить подогрев/N-выход times = 0 # Сколько раз убавлять температуру #Инициализация #temp = [1, 3, 4, 5, 10] #Главная программа------ try: #Рандомно генерируем температуру for i in range(MAX_COUNT_SENSORS): temp.append(random.randint(MIN_TEMP, MAX_TEMP)) while True: #Получаем среднее значение avg_temp = avg(temp) if avg_temp != None: avg_temp = round(avg(temp)) #Выдаём все значения температуры for i in temp: print(i) #Перенос на новую строку print('') #Среднее значение print(avg_temp) #Если среднее значение находится между минимальной и средней температуры, то: if avg_temp in range(MIN_TEMP, MED_TEMP): #Холодно print('Холодно, включаю подогреватель') #Получаем индекс массива минимальной температуры index = temp.index(min(temp)) #Подогреваем make_warm(temp, index) #Если среднее значение находится между средней и максимальной температуры, то elif avg_temp in range(MED_TEMP, MAX_TEMP): print('Нормальная температура, отключаю подогреватель') #Понижаем температуру make_cold_all(temp) #Если температура выше максимальной температуры, то elif avg_temp >= MAX_TEMP: print('Жарко, отключаю подогреватель') #Понижаем температуру index = temp.index(max(temp)) make_cold(temp, index) #Иначе ошибка else: print('Ошибка, датчики температуры сбрасываются на минимальную температуру') #Сбрасывем температуру, до минимального значения restart_all(MIN_TEMP, temp) #Спрашиваем, что делать дальше, Y-дальше, A-выключить подогрев, N-нет cmd = input('Дальше (Y-да/A-выключить подогрев/N-нет)?').upper() #Если нажали на клавишу N, то завершаем программу if cmd == 'N': break #Если нажали на клавишу A, то отключаем подогрев elif cmd == 'A': try: #Пытаемся выключить на n-раз times = int(input('На сколько выключить?')) except Exception as err: print('Ошибка ', err) else: #остужаем n-раз for _ in range(0, times): make_cold_all(temp) except Exception as err: print('Ошибка ', err)
В данной ситуации, т.е. в этом алгоритме выше MED_TEMP не поднимается, поэтому в данном алгоритме, т.е. строка elif avg_temp in range(MED, MAX): бесполезна.
если не будут обсуждать, а будут смеятся над ответом, или пойдут ироничные или саркастические шутки?
ну я надеюсь, что не будут. Все же тема обучение и начинающие.
Хотя иногда бывает действительно сложно удержаться.
А мне больше нравится использовать
В институте как и на работе - делаешь не так как нравится, а так как хотят.
Код пока не смотрел, слишком много. Там должно быть весьма немного. И пожалуйста, длинные простыни в приложение.
Смотря какой террариум
Это нужно узнавать ДО начала работы. Но в принципе не интересует, так как уже есть функции включить подогрев и выключить.
И если это проект для ардуино
Для данного этапа подобные мелочи не интересуют в принципе. Это всё на потом когда будет понимание проблем.
Ну и Вы вроде не такой уж и начинающий
или пойдут ироничные или саркастические шутки?
-----
Так обязательно пойдут.
Бо, это не то что сказано, а то как воспринято.
Просто научись извлекать из этого пользу.
А мне больше нравится использовать ...in range...
-----
А мне - когда код выполняет обработку данных.
калибровка датчиков (термометров) это тот ещё геморрой.
-----
Угу... а представь себе, что помимо просто калибровки еще надо учитывать нелинейность самого датчика...
И что датчиков не 1-2, а пара сотен на каждом блоке, а блоков может быть... много.
И вот когда ты нарисуешь свой ин-рандже на каждый датчик придет дядя и обязательно сломает этот датчик и его надо будет заменять...
А ты уже и забыл что, где и как у тебя соспагетчено...
НП.
Если взять из жизни... можно составить примерный алгоритм, допустим если тело человека ниже 32 градусов, то можно сказать это мертвец, если же выше 41, то тоже мертвец, т.к. белки начинают сварачивается. Если выше 38 дают таблетки, а если ниже 32, то будет скорей всего какая-нибудь диагностика. значения констант MIN_TEMP, MED_TEMP, и MAX_TEMP зависят от того, смотря кто в террариуме живёт. Я думаю что в промежутки MIN_TEMP и MED_TEMP нужно включать обогрев, а если выше MED_TEMP отключать. калибровка датчиков это геморрой, а значения температуры от датчиков скорей всего будет очень маленьким 0.000...
Не-а. Так нельзя. При учебных задачах надо исходить из того, что всё работает идеально, если не оговорено иначе. А то любую задачу можно своими выдумками усложнить до бесконечности.
А что если в датчике ошибка, а что ессли обогреватель вкоючается только если кго последовательно три раза включить и два раза выключить, а что если нагреватель расположен под потолком, а датчик на полу, а что если в террариуме дырка и как не нагревай, температура будет падать, а что если террариум стоит на улице при -50...
Вот структограмма, рисовал её этой программой https://www.struktograf.de/, температура сначало повышается до 37, потом понижается до 34, и так туда сюда прыгает в диапазоне 34..37 градусов...:
Правда сначало накалякал код на vb6, потом превратил в структограмму, завтра на Python переделаю...:
Private temp As Integer Private cmd As Integer Private c As Long Private Const MIN_TEMP = 34 Private Const MAX_TEMP = 38 Private Sub Form_Load() i = 0 cmd = 0 c = Me.BackColor Me.Timer1.Enabled = True Me.Timer1.Interval = 100 End Sub Private Sub Timer1_Timer() Me.Caption = i If cmd = 0 Then i = i + 1 If i > MAX_TEMP Then Me.BackColor = vbRed cmd = 1 End If ElseIf cmd = 1 Then i = i - 1 If i < MIN_TEMP Then Me.BackColor = c cmd = 0 End If End If End Sub
При учебных задачах надо исходить из того...
-----
...чему требуется научить.
АлехНек пока не сформулировал какая будет цель обучения.
Можно предположить - не программа регулирования температуры в террариуме - это только средство.
А что если...
-----
Корректным ответом будет машина состояний.
Полная. Или дополненная фиктивным состоянием до полной.
Но построение оной в качестве "задачи для начинающих" в плане обучения программированию (не конкретному языку) не есть правильный подход - нет базы на которую можно положить имплементацию указанной машины.
К сожалению, приходится не только хвалить но и ругать.
Замечательный пример, как НЕ нужно писать программы.
Вот перлы, которые ну никак не предполагались при описании задачи
Рандомно генерируем температуру Получаем среднее значение Получаем индекс массива минимальной температуры Иначе ошибка Спрашиваем, что делать дальше, Y-дальше, A-выключить подогрев, N-нет
Ну не нужно из пушки палить по воробьям
тоже задачки кидать
Хорошее решение, только номер не забудьте им дать. И отвечающий тоже должен номер задачи написать к чему ответ.
Ну и проверять нужно будет решения с комментариями, что правильно и что неправильно.
Я правда, для первого раза, небольшие заковырки специально делаю. Но уже думаю и так видно чем задача из реальной жизни может отличаться от учебной.
Ну а что можно сделать в форуме в одной ветке?
-----
Вообще-то, много чего.
Например, можно запостить полного Страуструпа и свои комментарии к каждой его сентенции.
немного показать, что такое программирование и с чем его едят
-----
Опять таки - данное не может быть целью так как является средством.
Ну и как средство оно зависит от того к кому применяется.
Мне вот насколько будет полезно? Угу...
Аналогично будет для тех, кто уже понимает самый базис. Ну может маленькая практика в плюсе.
А для тех кто не понимает - для них тоже бесполезно - им надо объяснять что такое Если...то...иначе... и зачем оно надо, и как из него построить заданное.
Кстати, мне тут пришла в голову мысль - самый лучший задачник по программированию - поваренная книга. У нее один недостаток - на выходе хоть что-то, но будет...
Немножко чему то научится.
-----
Месяца три надо постить описание элементов языка и давать задачи, которые подогнаны под то, чтобы решение без использования описанного элемента было много сложнее, чем с ним, и при этом переход от постановки задачи к необходимости использования элемента не должен быть явным.
При этом нужно дополнительно контролировать усвоенность и применение элементов изученных ранее.
Тогда можно чему то научить.
Ну и дополнительно: откуда взялась максимальная, минимальная температура и какие то команды?
Допустим минимальная температура 20, максимальная 35. Датчик в реальном времени измеряет температуру, а дальше программа обращается к шине данных, там из аналога переводится в цифровое значение, и программа получает значение ввиде каких-то чисел. Если температура 18, то включается подогрев, как достигает в террариуме значение 35, подогрев отключается. А cmd = 0 включает подогрев и мериет температуру, cmd = 1 отключает подогрев, но продолжает дальше мерить температуру, и снижает температуру. Покуда это симулятор, мы симулируем датчик температуры, и подогрев. Если бы это был бы не симулятор, то вместо cmd мы бы назвали бы heater, и он принимал бы булевое значение, если бы температура была бы ниже минимума, то программа бы устанавлива heater = true, и дальше мерила бы температуру. Всё просто:
//Константы МАКСИМЛЬНАЯ_ТЕМПЕРАТУРА = 35 МИНИМАЛЬНАЯ_ТЕМПЕРАТУРА = 18 //Инициализация текущая_температура = 0 обогреватель = выкл // Цикл циклить пока True: текущая_температура = получить_текущую_температуру() запуск_обогревателя(обогреватель) если текущая_температура > МАКСИМЛЬНАЯ_ТЕМПЕРАТУРА то: обогреватель = выкл. если текущая_температура < МИНИМАЛЬНАЯ_ТЕМПЕРАТУРА то: обогреватель = вкл.
А если несколько датчиков температуры и несколько подогревов, то можно вынести это в функцию... или можно даже использовать мистер Фред. В данном алгоритме попахивает многозадачностью, я бы в данном проекте попытался бы использовать бы FreeRTOS это легковесная многозадачная ОС реального времени для IoT.
P.S.:С кодом на Python-е получилась каша, потому-что мне в лом было заниматься заниматься с мистерм Фредом и с таймерами, по мне так изврат когда в консольном приложение используют потоки или таймеры.