Вы уже написали свои первые 1000 строк кода и сейчас хотите сделать их понятнее, потому что внесение изменений занимает столько-же времени, сколько написать заново, но советы из ООП, SOLID, clean architecture и т.д. непонятны вам.
Если вы написали 1000 строк, думать о том как сделать код легко сопровождаемым рано. Я вот написал наверно не менее пол миллиона и до сих пор не могу понять как ООП и SOLID может мне помочь справиться со сложностью по сравнению с процедурным слилем и god-объектами :). Или могу. Пока не уверен.
По мне, здесь нужно разделять цели.
Первая цель - научиться писать работающий код больше чем с двумя условиями и не тонуть в нем.
Вторая цель - научиться писать код, который выглядит профессионально. То что он будет выглядеть профессионально не означает, что он будет проще. Это будет просто обезьянье подражание профессионализму, но без этого видимого профессионализма и видимой стандартности решений не возьмут на работу.
Третья цель - а как действительно написать простой понятный код для сложных проблем? И тут рецепта как такового нет. Наверно каждый расскажет свой некий путь.
Самая сложная цель - третья.
Начать лучше с того, что простейшим путем борьбы со сложностью является то что раньше называли "структурное программирование", когда общая функция решает задачу и затем она вызывает под-функции, решающие частные задачи и так далее. В самом низу находятся функции, уже работающие непосредственно с данными.
Научившись применять этот стиль мышления, можно двигаться дальше.
При этом есть два направления - от структурного к чисто функциональному стилю и к ООП стилю.
Функциональный стиль начинается с того, что мы перестаем пользоваться глобальными данными по возможности и стараемся писать чистые функции. Это хорошо работает когда нужно реализовать по настоящему сложный алгоритм.
ООП стиль начинается с того, что некая одна функция выполняясь запускает внутри себя другие функции, которые имеют дело с одними и теми же данными. В итоге мы имеем слишком много передаваемых данных и соблазн замкнуть эти алгоримты в некий небольшой изолированный модуль, к котором эти данные будут доступны функциям глобально (объект).
Здесь можно создать объект. При этом по мне, важно помнить, что мы создаем объект как "элемент поведения", а не как данные о неком доменном объекте оснащенные поведением. Второй путь хорош для UI фреймворков (кнопка-объект), может быть для игр, но создает очень много сложностей в других случаях (ИМХО).
Такой объект может создаваться операцией new, отрабатывать и тут же удаляться. Это нормально. В этом случае он мало отличается от функции.
Или объект может быть постоянно существующим в памяти и реагировать на обращения, например как кнопка в UI (правда если это кнопка не в React, где она создается при каждом обновлении экрана по новой).
Дальше, если хочется, то можно попробовать оснасить структуры данных, описывающие доменные объекты поведением. Т.е. ввести не просто объекты как элементы поведения, но объекты соответствующие доменным объектам. Попробуйте, но у меня не разу это ничего не упростило. Тут можно дискутировать.
Описанного выше пройденного пути уже достаточно, чтобы написать в одиночку программу на десятки тыщ строк кода и не увязнуть.
Но что если мы пишем код все вместе большими командами?
В мозгу у человека есть некое интуитивное ощущение универсальности. Если я описываю неккие классы и функции, что я делаю? Решаю конкретную задачи или пишу фреймворк всех времен и народов для решения всего класса подобных задач.
Первое, что нужно уметь, это всегда решая конкретную задачу чуть-чуть писать фреймворк для решения подобных задач, но без фанатизма. Это делает систему более пластичной к будущим изменениям и даже может сделать ее понятнее, если соблюдать баланс.
Второе - это тесты. Когда вы написали программу подумайте, можно ли ее разобрать на части , каждую часть поставить на стенд и испытать абстрактно, выполняет ли она ту логику для которой написано? Если нельзя, это все еще плохой код. Если уже можно, значит теперь мы победили сложность окончательно.
Дальше можно уже подумать про SOLID.
Допустим, мы запихнули в один объект и некую абстрактную логику и обращение к конкретному девайсу. Т.е. нарушили "S". Как теперь ее тестировать? Стенд для испытания этого объекта станет очень сложным и специфичным. А еще непонятным. Делим это на две части и все становится проще. Здесь необходимость тестировать помогает нам осознать важность S.
Допустим, при малейшем изменении задачи нам придется лезть в кишки объекта и все там менять, вместо того чтобы добавить новое поведение не меняя объекта (буква "O")? Это значит в нашем решении было недостаточно "фреймворковости", оно было слишком частным, или это может означать что мы распилили на объекты искусственно, не в том месте как надо (что по сути близко к недостатку "фреймворковости" по сути).
Мы ставим объект на стенд для тестирования и прямо не знаем с чего начать. У него столько методов! Здесь мы нарушили букву "I". На стенде тестируемый интерфейс должен выглядеть предельно просто и понятно - зачем он и как проверить что он это делает. Клиенты у интерфейса могут быть сегодня одни а завтра другие, но если он понятно тестируется, он уже соблюдает I в достаточной мере.
Есть замечательный принцип, использованный природой - каждый ген (а ген это элемент поведения, т.е. объект) вездесущ и активируется по месту в той части программы где он нужен. Значит для изменения программы достаточно добавить до кучи новый ген или подменить существующий. Этот замечательный принцип нужно не упустить и в разработке где возможно. Это "D".
Недавно вышел именно учебник, "Modern C++ for Absolute Beginners" (подзаголовок: "A Friendly Introduction to C++ Programming Language and C++11 to C++20 Standards"), Slobodan Dmitrović. Есть ещё пара недавних книг (не учебников), в которые я заглядывал: "Modern C++ Tutorial: C++11/14/17/20 On the Fly", Changkun Ou и "C++ Best Practices", Jason Turner. От комментариев, что в этих книгах хорошо / плохо воздержусь, заглядывал только поверхностно. Возможно, стоит обратить внимание на вышедшее летом 2018-го второе издание "A Tour of C++ (C++ In-Depth Series)", Bjarne Stroustrup.
Вот канала мужика с самопечатными, полупокупными, boston-dynamics-подобными, с силовым фидбаком, и всякими разными роботами https://www.youtube.com/watch?v=3S9IIUGvTK0
Хоть и по английски, но все разжеванно и понятно
Хотите узнать про маркетинг с кучей клёвых историй - https://www.coursera.org/learn/marketing-digital (тут может и остальыне курсы специализации крутые, но я прошёл в своё время только 1, причём так проникся, что заплатил за сертификат просто из признательности к преподу)
Геймификация? «Их есть у меня» - https://www.coursera.org/learn/gamification (ещё один курс, где я заплатил не за пользу, а скорее из-за признательности к преподу и уже после прохождения)
Она правда сложновата, надо что-то по статистике хорошее взять в нагрузку (на курсере не знаю ничего, но есть крутой курс от Анатолия Карпова на степике stepik.org/course/76/syllabus)
Так же пригодится что-то по python, тут опять же нет серебрянной пули:
На курсере так много курсов (что-то порядка 3800, если я правильно запомнил из последней рекламы), что очень сложно охватить всё. Есть реальные крутые, но в большинстве случаев надо пробовать, т.к. мусора там гораздо больше 50%. Увы.
Признаю это как фанат курсеры.
Можно и нужно, только на каждый успешный пример будет хорошо если десяток примеров отрицательных, которые демотивируют :( По идее, заявитель не обязан разбираться в нормах права и может просто пожаловаться, а уже регулятор должен смотреть: было ли реальное нарушение прав, или показалось. Собственно, в этом и состоит их работа, за которую мы им платим. На практике часто бывает, что посылаешь готовую «палку» — прям копируй в протокол, подписывай сам и оформляй, «дело раскрыто», но нет — идут отписки. Коллективные обращения имеют больший вес, чинуши все-таки боятся огласки и массовости. А депутатские запросы… формально — да, фактически — от многих факторов зависит. В свое время это был бизнес, запросами пытались получить коммерческую информацию из госведомств, они научились отфутболивать таких коммерсантов из Госдумы, а вместе с ними и всех остальных.
Юсть сеть «юридических клиник», сеть ПЦПИ, другие аналогичные инициативы, где гражданина примут, выслушают, помогут составить заявление, причем во многих случаях бесплатно.
Understanding map, apply, bind
я думал, что я понял. После прочтения этой статьи я уже нихера не понимаю.
Категория – любой примитивный или составной тип данных...
Я, как очень плохо учивший математику, понял категорию как некое обобщение над множествами, а сами множества являются одной из категорий (Set). А тип, вроде как, как раз укладывается в теорию множеств, как множество всех его допустимых значений. Так тип категория или нет?
Честно говоря, объяснение в порядке "функтор — аппликативный функтор — монада" понятнее, хотя, возможно, я его понял неправильно.
Функтор — отображение морфизма из одной категории в другую. Кстати, о map. После некоторых размышлений мне стало казаться, что название функции означает не то, что она применяет некую функцию к контейнеру (как мы привыкли во всех языках, где есть map), а именно отображение функции в другую категорию. Например, отображает морфизм "+" в категории чисел, в категорию "Maybe чисел". Мне это (либо очень очевидное, либо очень неправильное) понимание пришло в голову, если рассмотреть сигнатуру не как привычную функцию с двумя аргументами map(f, container) -> container, а как каррированную:
fmap:: (a->b) -> fa -> fb
Я прав?
Аппликативный функтор. А вот тут непонятно. Не, смотришь на картинки, на код, это, вроде, тоже самое, но для двух аргументов в контейнерах. Но что-то непонятно. Ладно, вот еще картинки с описанием. Это когда функции в контейнерах и аргументы в контейнерах. Понятнее не стало, да еще и не совпадает.
Монада. Такая штука, которая, в отличие от функтора, умеет работать не только с функциями a -> b, но и a -> m b:
bind :: m a -> (a -> m b) -> m b
Вроде бы, понятно, зачем оно нужно. И понятно, какую проблему (по сравнению с функтором) решает эта сигнатура, на примере тех же Maybe очень понятно. Вот мы имеем цепочку каких-то функций, каждая возвращает Maybe, их друг с другом биндим, все очень круто. А вот почему монада — контейнер? То, что условный Maybe/Option/Nullable итп контейнеры — понятно. Зачем bind при работе с контейнерами — понятно. Но что-то интуитивного понимания нет. И еще почему "монада позволяет описать последовательность" (или что-то в этом роде)?
З.Ы. Монада — тайпкласс. "Что-то" реализующее некие определенные методы является монадой. И "что-то" имеет какие-то данные, реализуем "интерфейс" (в курсе, что это очень грубая аналогия) монады (имея знание о структуре данных), чтобы функции, работающие с монадами, могла работать с нашим типом. Окей. Но с таким же успехом и функтор — контейнер, нет?
У Финляндии, Норвегии, Дании, Швеции и Ирландии есть программы привлечения разработчиков и других востребованных профессий, которые дают рабочую визу, при этом без особого конкурса / многолетних очередей, а у многих даже без требования высшего образования по специальности.
По поводу езды по компасу — можно посмотреть ardumower (автономная газонокосилка на arduino mega 2560 или arduino due), Inav (коптеры и колесные роботы на stm32f3/4/7), openpilot (коптеры и колесные роботы на тех же контроллерах), ну и мой проект github.com/~vasimv/OMower — колесный робот на arduino due или собственной плате. Во всех есть нужные калманы и/или более продвинутые фильтры (Madgwick/Mahony). В моем еще есть поддержка получения координат от RTK (нужен внешний микрокомпьютер с rtklib), остальные тоже теоретически с ним смогут, но не проверял как хорошо.
Этого может не хватить даже для одновременной уборки пылесосом(более 2квт) и сушки волос феном(более 3квт у проф моделей).
Берем примерный дом 10 на 10, без окон и дверей. Получаем 320 м2 ограждающих конструкций. Умножает на 40 градусов перепада для самого холодного дня. И умножаем на 0.25 Вт\(м2*градус С) — теплопроводность 20см пенопласта хорошего качества. Получаем теплопотери конструкции 3.2квт. Но у нас дом без окон и дверей. В который ни кто не заходит и не выходит, и сделанный идеально без мостиков холода. И БЕЗ ВЕНТИЛЯЦИИ.
Прикинуть потери через двери и окна на глаз можно легко — они составляют половину от общих теплопотерь дома. Если хотите — пересчитайте из расчета одно окно на каждые 10м2, если меньше то будет темно и не соотв санитарным нормам. Итого уже 6.4квт.
Но мы еще не проветриваем, а проветривать нужно. Минимально допустимая кратность воздухообмена 3м3 на каждые 1м2 площади. Для нас это 300 м3 в час. Далее считаем количество тепла необходимое для подогрева входящего воздуха, формулы можете найти сами, а ответ 4.3квт. Можно поставить рекуператор, который в идеальных условиях имеет эффективность в 50%. Итого будет 2.2 квт на догрев воздуха.
Итого 8.8 квт только на отопление. Если пенопласта поставить пол метра — то теплопотери сократятся всего на 2квт из 9. Можно отказаться от окон, ставить одно окно на каждые 20м2, досвечивать диодами, еще минус 1.5 квт. Все еще не влезаем в 5квт. Можно меньше дышать, оставлять в помещении пыль, выделения из мебели и терпеть повышенные уровни СО2 — тогда влезем в 5квт. Но это не жизнь и не дом, это бытовка для строителей или бараки для гетто.
Пойдем обратным путем и посчитаем площадь дома которую сможем отопить. И это будет около 50м2. Это 6м на 8м, крупный дачный домик или стандартный сельский домик довоенной эпохи. Но утепленный 20см! пенопласта.
Отопить что-либо более менее приличное за 5квт можно только тепловым насосом.
Ещё очень круто, когда длинный рецепт, вроде как разбитый на шаги по порядку, внезапно заканчивается «и добавьте сюда ложку соды, перемешанной с соусом, и настоянной на малом огне 45 минут». Проверка на внимательность и логику — если не прочитал заранее, покупай машину времени.
Тц. Не топчитесь по радостной правой картине мира, результат при любой исходе нерадостен.
Если вы написали 1000 строк, думать о том как сделать код легко сопровождаемым рано. Я вот написал наверно не менее пол миллиона и до сих пор не могу понять как ООП и SOLID может мне помочь справиться со сложностью по сравнению с процедурным слилем и god-объектами :). Или могу. Пока не уверен.
По мне, здесь нужно разделять цели.
Первая цель - научиться писать работающий код больше чем с двумя условиями и не тонуть в нем.
Вторая цель - научиться писать код, который выглядит профессионально. То что он будет выглядеть профессионально не означает, что он будет проще. Это будет просто обезьянье подражание профессионализму, но без этого видимого профессионализма и видимой стандартности решений не возьмут на работу.
Третья цель - а как действительно написать простой понятный код для сложных проблем? И тут рецепта как такового нет. Наверно каждый расскажет свой некий путь.
Самая сложная цель - третья.
Начать лучше с того, что простейшим путем борьбы со сложностью является то что раньше называли "структурное программирование", когда общая функция решает задачу и затем она вызывает под-функции, решающие частные задачи и так далее. В самом низу находятся функции, уже работающие непосредственно с данными.
Научившись применять этот стиль мышления, можно двигаться дальше.
При этом есть два направления - от структурного к чисто функциональному стилю и к ООП стилю.
Функциональный стиль начинается с того, что мы перестаем пользоваться глобальными данными по возможности и стараемся писать чистые функции. Это хорошо работает когда нужно реализовать по настоящему сложный алгоритм.
ООП стиль начинается с того, что некая одна функция выполняясь запускает внутри себя другие функции, которые имеют дело с одними и теми же данными. В итоге мы имеем слишком много передаваемых данных и соблазн замкнуть эти алгоримты в некий небольшой изолированный модуль, к котором эти данные будут доступны функциям глобально (объект).
Здесь можно создать объект. При этом по мне, важно помнить, что мы создаем объект как "элемент поведения", а не как данные о неком доменном объекте оснащенные поведением. Второй путь хорош для UI фреймворков (кнопка-объект), может быть для игр, но создает очень много сложностей в других случаях (ИМХО).
Такой объект может создаваться операцией new, отрабатывать и тут же удаляться. Это нормально. В этом случае он мало отличается от функции.
Или объект может быть постоянно существующим в памяти и реагировать на обращения, например как кнопка в UI (правда если это кнопка не в React, где она создается при каждом обновлении экрана по новой).
Дальше, если хочется, то можно попробовать оснасить структуры данных, описывающие доменные объекты поведением. Т.е. ввести не просто объекты как элементы поведения, но объекты соответствующие доменным объектам. Попробуйте, но у меня не разу это ничего не упростило. Тут можно дискутировать.
Описанного выше пройденного пути уже достаточно, чтобы написать в одиночку программу на десятки тыщ строк кода и не увязнуть.
Но что если мы пишем код все вместе большими командами?
В мозгу у человека есть некое интуитивное ощущение универсальности. Если я описываю неккие классы и функции, что я делаю? Решаю конкретную задачи или пишу фреймворк всех времен и народов для решения всего класса подобных задач.
Первое, что нужно уметь, это всегда решая конкретную задачу чуть-чуть писать фреймворк для решения подобных задач, но без фанатизма. Это делает систему более пластичной к будущим изменениям и даже может сделать ее понятнее, если соблюдать баланс.
Второе - это тесты. Когда вы написали программу подумайте, можно ли ее разобрать на части , каждую часть поставить на стенд и испытать абстрактно, выполняет ли она ту логику для которой написано? Если нельзя, это все еще плохой код. Если уже можно, значит теперь мы победили сложность окончательно.
Дальше можно уже подумать про SOLID.
Допустим, мы запихнули в один объект и некую абстрактную логику и обращение к конкретному девайсу. Т.е. нарушили "S". Как теперь ее тестировать? Стенд для испытания этого объекта станет очень сложным и специфичным. А еще непонятным. Делим это на две части и все становится проще. Здесь необходимость тестировать помогает нам осознать важность S.
Допустим, при малейшем изменении задачи нам придется лезть в кишки объекта и все там менять, вместо того чтобы добавить новое поведение не меняя объекта (буква "O")? Это значит в нашем решении было недостаточно "фреймворковости", оно было слишком частным, или это может означать что мы распилили на объекты искусственно, не в том месте как надо (что по сути близко к недостатку "фреймворковости" по сути).
Мы ставим объект на стенд для тестирования и прямо не знаем с чего начать. У него столько методов! Здесь мы нарушили букву "I". На стенде тестируемый интерфейс должен выглядеть предельно просто и понятно - зачем он и как проверить что он это делает. Клиенты у интерфейса могут быть сегодня одни а завтра другие, но если он понятно тестируется, он уже соблюдает I в достаточной мере.
Есть замечательный принцип, использованный природой - каждый ген (а ген это элемент поведения, т.е. объект) вездесущ и активируется по месту в той части программы где он нужен. Значит для изменения программы достаточно добавить до кучи новый ген или подменить существующий. Этот замечательный принцип нужно не упустить и в разработке где возможно. Это "D".
Это был мой путь. Кто прошел иной путь, делитесь.
Недавно вышел именно учебник, "Modern C++ for Absolute Beginners" (подзаголовок: "A Friendly Introduction to C++ Programming Language and C++11 to C++20 Standards"), Slobodan Dmitrović. Есть ещё пара недавних книг (не учебников), в которые я заглядывал: "Modern C++ Tutorial: C++11/14/17/20 On the Fly", Changkun Ou и "C++ Best Practices", Jason Turner. От комментариев, что в этих книгах хорошо / плохо воздержусь, заглядывал только поверхностно. Возможно, стоит обратить внимание на вышедшее летом 2018-го второе издание "A Tour of C++ (C++ In-Depth Series)", Bjarne Stroustrup.
Вот канала мужика с самопечатными, полупокупными, boston-dynamics-подобными, с силовым фидбаком, и всякими разными роботами https://www.youtube.com/watch?v=3S9IIUGvTK0
Хоть и по английски, но все разжеванно и понятно
Скажем, для развлечения и общего развития рекомендую:
Если вы хотите изучить машинное обучение (сильно модная ныне тема), то по любому пригодится специализация www.coursera.org/specializations/machine-learning-data-analysis
Она правда сложновата, надо что-то по статистике хорошее взять в нагрузку (на курсере не знаю ничего, но есть крутой курс от Анатолия Карпова на степике stepik.org/course/76/syllabus)
Так же пригодится что-то по python, тут опять же нет серебрянной пули:
Если нужны базовые знания об HTML+JS+CSS (ну на уровне контент-менеджера или просто навести «порядок» в голове), то неплохая спека - https://www.coursera.org/specializations/web-design
Хотите получить введение в управление проектами - https://www.coursera.org/learn/uva-darden-project-management
А про GIT рекомендую новичкам https://www.coursera.org/learn/version-control-with-git
На курсере так много курсов (что-то порядка 3800, если я правильно запомнил из последней рекламы), что очень сложно охватить всё. Есть реальные крутые, но в большинстве случаев надо пробовать, т.к. мусора там гораздо больше 50%. Увы.
Признаю это как фанат курсеры.
Юсть сеть «юридических клиник», сеть ПЦПИ, другие аналогичные инициативы, где гражданина примут, выслушают, помогут составить заявление, причем во многих случаях бесплатно.
Внезапно оказалось, что разработчикам на Python слова вроде «Монада», «Функтор» и уж тем более «Апликативный функтор» – не знакомы совсем.
Потому мы пришли к другому решению: выкинуть все сложные слова. И заменить их более интуитивно понятными. Монада = контейнер. Функтор = Mappable.
А все объяснения «зачем?!» строить через решение понятных практических задач. Например:
— Монады можно использовать для обработки ошибок вместо исключений
— А еще для внедрения зависимостей
— Ну и чтобы писать асинхронный код!
На мой взгляд — сработало отлично! Многие только потом узнали, куда они ввязались.
После прочтения ряда статей:
я думал, что я понял. После прочтения этой статьи я уже нихера не понимаю.
Я, как очень плохо учивший математику, понял категорию как некое обобщение над множествами, а сами множества являются одной из категорий (Set). А тип, вроде как, как раз укладывается в теорию множеств, как множество всех его допустимых значений. Так тип категория или нет?
Честно говоря, объяснение в порядке "функтор — аппликативный функтор — монада" понятнее, хотя, возможно, я его понял неправильно.
Функтор — отображение морфизма из одной категории в другую. Кстати, о
map
. После некоторых размышлений мне стало казаться, что название функции означает не то, что она применяет некую функцию к контейнеру (как мы привыкли во всех языках, где естьmap
), а именно отображение функции в другую категорию. Например, отображает морфизм "+" в категории чисел, в категорию "Maybe чисел". Мне это (либо очень очевидное, либо очень неправильное) понимание пришло в голову, если рассмотреть сигнатуру не как привычную функцию с двумя аргументамиmap(f, container) -> container
, а как каррированную:Я прав?
Аппликативный функтор. А вот тут непонятно. Не, смотришь на картинки, на код, это, вроде, тоже самое, но для двух аргументов в контейнерах. Но что-то непонятно. Ладно, вот еще картинки с описанием. Это когда функции в контейнерах и аргументы в контейнерах. Понятнее не стало, да еще и не совпадает.
Монада. Такая штука, которая, в отличие от функтора, умеет работать не только с функциями
a -> b
, но иa -> m b
:Вроде бы, понятно, зачем оно нужно. И понятно, какую проблему (по сравнению с функтором) решает эта сигнатура, на примере тех же
Maybe
очень понятно. Вот мы имеем цепочку каких-то функций, каждая возвращаетMaybe
, их друг с другом биндим, все очень круто. А вот почему монада — контейнер? То, что условныйMaybe
/Option
/Nullable
итп контейнеры — понятно. Зачем bind при работе с контейнерами — понятно. Но что-то интуитивного понимания нет. И еще почему "монада позволяет описать последовательность" (или что-то в этом роде)?З.Ы. Монада — тайпкласс. "Что-то" реализующее некие определенные методы является монадой. И "что-то" имеет какие-то данные, реализуем "интерфейс" (в курсе, что это очень грубая аналогия) монады (имея знание о структуре данных), чтобы функции, работающие с монадами, могла работать с нашим типом. Окей. Но с таким же успехом и функтор — контейнер, нет?
Но потом вспомнил, что я сегодня с похмелья, и полез на Bit Twiddling Hacks :)
У Финляндии, Норвегии, Дании, Швеции и Ирландии есть программы привлечения разработчиков и других востребованных профессий, которые дают рабочую визу, при этом без особого конкурса / многолетних очередей, а у многих даже без требования высшего образования по специальности.
Начатый когда-то список требований для переезда в разные страны.
В отрасли embedded и микроконтроллеров это все, что позволяет получить исполняемый код из графических моделей.
Для Си кода у меня такой список:
MATLAB Embedded/Simulink Coder http://www.mathworks.nl/products/embedded-coder/
Gene-Auto http://geneauto.gforge.enseeiht.fr/
SCADE http://www.esterel-technologies.com/products/scade-suite/
dSPACE TargetLink http://www.dspace.com/en/inc/home/products/sw/pcgs/targetli.cfm
PLECS Coder http://www.plexim.com/products/plecs_coder
Synphony Model Compiler http://www.synopsys.com/Systems/BlockDesign/HLS/Pages/default.aspx
Evidence E4 Coder — http://www.e4coder.com/
National Instruments Labview — Z-brain — http://www.schmid-engineering.ch/de/151/ZBrain_System.htm
IMACS GmbH radCASE www.radcase.de
AdaCore QGen http://www.adacore.com/qgen
Для ПЛИСов — т.е. генерация VHDL/Verilog:
MATLAB HDL Coder http://www.mathworks.nl/products/hdl-coder
Xilinx System Generator for DSP http://www.xilinx.com/products/design-tools/vivado/integration/sysgen/index.htm
Altera DSP Builder http://www.altera.com/products/software/products/dsp/dsp-builder.html
Synphony Model Compiler http://www.synopsys.com/Tools/Implementation/FPGAImplementation/Pages/synphony-model-compiler.aspx
National Instruments LabView — only on LabView Hardware — http://www.ni.com/labview/fpga/
Altera Quartus II/prime (provides block diagram editor, Altera only) https://www.altera.com/products/design-software/fpga-design/quartus-prime/overview.html
Lattice Diamond(provides block diagram editor, Lattice only) http://www.latticesemi.com/en/Products/DesignSoftwareAndIP/FPGAandLDS/LatticeDiamond.aspx
Microsemi Libero SOC (provides block diagram editor, Microsemi only) http://www.microsemi.com/products/fpga-soc/design-resources/design-software/libero-soc
Xilinx Vivado IP integrator (provides block diagram editor, Xilinx only series 7 and up) http://www.xilinx.com/products/design-tools/vivado/integration.html
Mentor Graphics HDL Designer (provides block/state diagram editor) https://www.mentor.com/products/fpga/hdl_design/hdl_designer_series/
Aldec Active-HDL (provides block/state diagram editor) https://www.aldec.com/en/solutions/fpga_design/graphical_text_design_entry
HDL Works Ease (provides block/state diagram editor) https://www.hdlworks.com/
Берем примерный дом 10 на 10, без окон и дверей. Получаем 320 м2 ограждающих конструкций. Умножает на 40 градусов перепада для самого холодного дня. И умножаем на 0.25 Вт\(м2*градус С) — теплопроводность 20см пенопласта хорошего качества. Получаем теплопотери конструкции 3.2квт. Но у нас дом без окон и дверей. В который ни кто не заходит и не выходит, и сделанный идеально без мостиков холода. И БЕЗ ВЕНТИЛЯЦИИ.
Прикинуть потери через двери и окна на глаз можно легко — они составляют половину от общих теплопотерь дома. Если хотите — пересчитайте из расчета одно окно на каждые 10м2, если меньше то будет темно и не соотв санитарным нормам. Итого уже 6.4квт.
Но мы еще не проветриваем, а проветривать нужно. Минимально допустимая кратность воздухообмена 3м3 на каждые 1м2 площади. Для нас это 300 м3 в час. Далее считаем количество тепла необходимое для подогрева входящего воздуха, формулы можете найти сами, а ответ 4.3квт. Можно поставить рекуператор, который в идеальных условиях имеет эффективность в 50%. Итого будет 2.2 квт на догрев воздуха.
Итого 8.8 квт только на отопление. Если пенопласта поставить пол метра — то теплопотери сократятся всего на 2квт из 9. Можно отказаться от окон, ставить одно окно на каждые 20м2, досвечивать диодами, еще минус 1.5 квт. Все еще не влезаем в 5квт. Можно меньше дышать, оставлять в помещении пыль, выделения из мебели и терпеть повышенные уровни СО2 — тогда влезем в 5квт. Но это не жизнь и не дом, это бытовка для строителей или бараки для гетто.
Пойдем обратным путем и посчитаем площадь дома которую сможем отопить. И это будет около 50м2. Это 6м на 8м, крупный дачный домик или стандартный сельский домик довоенной эпохи. Но утепленный 20см! пенопласта.
Отопить что-либо более менее приличное за 5квт можно только тепловым насосом.
github.com/bol-van/zapret
За пять минут в гугле можно найти больше интересных ссылок, чем в этой статье.
Вот, например:
Или вот, из Git репозитория awesome-RemoteWork:
https://whoishiring.io/
https://weworkremotely.com. A page of 37Signals.
http://careers.stackoverflow.com/jobs/remote. Job page of StackOverflow.
http://www.flexjobs.com/jobs/ a service purely focusing on telecommuting, part-time, flexible jobs.
http://www.reddit.com/r/forhire/new/. Subreddit for hiring, not purely a remote job page but have a lots.
http://hnhiring.me/ an aggregator site collects job from HackerNews, easier to read.
http://workinstartups.com/ not all jobs are remote but it has.
https://angel.co/jobs, a lots of startup jobs, set filter for "Remote OK" will show remote jobs.
https://remotecoder.io/
http://www.authenticjobs.com/#onlyremote=1
http://www.remoteyear.com/jobs/, job board of RemoteYear program.
http://nomadjobs.io/
http://jobmote.com/
http://workingnomads.co/
http://www.teamed.io/
http://www.toptal.com
http://automattic.com/work-with-us/. Made https://wordpress.com/, has remote working culture and employees are from everywhere in the world.
https://www.wfh.io/, 100% remote tech-oriented job board
http://jobs.remotive.io/, weekly update with remote jobs from startups.
http://remoteok.io/ a remote job aggregator. Job from Angel List, Stackoverflow,…
http://remotus.com/ a fulltime jobs for developers, still under construction. Seems have a lots of startup jobs.
http://www.candoerz.com/ hourly update remote, relocate, freelance jobs aggregator.
А вот еще из Git репозитория awesome-remote-job:
performed
После этой штуки уже даже не страшно: