App Inventor — среда визуальной разработки android-приложений. MIT App Inventor — каждый может создать мобильное приложение Mit app inventor 2 приложения

27.06.2020

Начать хочется с того, что на habrahabr и geektimes есть несколько статей о предыдущей версии App Inventor. Вот они:

MIT открыл Google App Inventor в бета-версии
App Inventor - создание Android-приложений для каждого: Урок 1
Чтение XML файла с помощью App Inventor

Эта версия App Inventor (beta) проработала с 2011 по 2015 годы, но сейчас ее поддержка прекращена. С 2014 работает версия App Inventor 2, которая несовместима с предыдущей. До 2011 года существовала версия Google App Inventor в рамках Google Labs
Итак, App Inventor - среда визуальной разработки android-приложений, требующая от пользователя минимальных знаний программирования. Выглядит она так:

Работает эта среда разработки прямо из браузера. Скачивать и устанавливать ничего не нужно. Создавать приложения можно хоть с android-планшета, хоть с Ipad. Основное требование к «железу» это хорошее разрешение экрана. Для примера приведу скриншот с экрана разрешения FullHD. Можно сравнить его с предыдущим, который сделан c HD экрана.


Готовые приложения можно размещать в Play Market, для примера приведу аккаунт разработчика , в котором все приложения сделаны в App inventor.
Подробно описывать MIT App inventor 2 не буду, поскольку от предыдущей версии он отличается в основном множеством мелких усовершенствований, которые выходят в среднем раз в несколько недель. Прочитав статьи, указанные выше, можно легко освоить и текущую версию.
Во вконтакте есть достаточно живое сообщество , в котором участники делятся друг с другом опытом использования App Inventor.
Часть 2. App Inventor+Arduino проекты.
В последнее время бурно развивается тема «интернета вещей». Во многих проектах на эту тему используется ардуино. Иногда в таких проектах нужно создать android-приложение, тут и может понадобиться App Inventor 2. На habrahabr и geektimes есть несколько статей на эту тему.
1. App Inventor+Arduino проекты с использованием блютуз-соединения. (блютуз модуль HC-05\06\07)
Робот-пылесос на ардуино
Простая Bluetooth машинка на Arduino
Bluetooth пульт для телевизора на arduino
2. App Inventor+Arduino проект с использованием wi-fi соединения.(wi-fi модуль ESP8266)
Интернет Вещей (IoT) и водопровод
3.App Inventor+Arduino проект с использованием проводного соединения (Еthernet модуль Enc28j60)
Управление громкостью многозонного усилителя при помощи приложения для Android и Arduino
4.App Inventor+Arduino проект с использованием GPRS/GSM соединения (GPRS/GSM шилд SIM900)
Управление отоплением в загородном доме
Ну и закончить хотелось бы позитивной новостью, что с августа 2015 года App Inventor 2 поддерживает русский язык. Если у кого-то есть свои интересные приложения, сделанные в этой среде разработки, можно скидывать в комментарии, думаю многим будет интересно посмотреть какие еще можно делать приложения, используя App Inventor.
P.S. Сборник из более 100 обучающих материалов по ардуино для начинающих и профи
P.P.S. Онлайн курс по ардуино на гиктаймс

Сегодня на рынке труда мы наблюдаем настоящий бум на специалистов в области разработки приложений для мобильных устройств. Профессия разработчика мобильных приложений становится одной из самых востребованных. Но вот готова ли система образования ответить на этот вызов? Ведь чтобы диагностировать способности к программированию и вовремя заложить прочный фундамент из знаний и навыков, начинать нужно уже с раннего школьного возраста.

До недавнего времени проблема обучения школьников средних классов программированию казалась неразрешимой - прежде всего из-за отсутствия инструмента, который, с одной стороны, был бы достаточно прост в освоении, а с другой - позволял бы создавать действительно стоящие продукты. Попытки поголовно обучать школьников Бейсику или Паскалю приводили только к тому, что предмет «информатика» оказывался по зубам лишь очень узкому кругу учащихся - тем, кому в силу интеллектуальных особенностей, семейного воспитания или чрезвычайного везения с учителем удавалось продвинуться в освоении программирования дальше, чем другим. Для большинства остальных школьников информатика так и оставалась чем-то недоступным.

Ситуация начала меняться в начале 2000-х годов, с возникновением и развитием визуальных языков программирования, флагманом которых по праву считается язык Scratch. Этот язык совершил настоящую революцию в школьном преподавании программирования под десктопные ОС. Программировать на Scratch так же легко, как складывать детскую мозаику-паззл. Операторы и процедуры языка представляют собой цветные блоки. Перетаскивая и соединяя их, мы создаём программы. Ошибку в синтаксисе этого языка сделать просто невозможно - если блоки не встанут рядом, паззл просто не сложится.

App Inventor

Естественным развитием этого подхода стал язык программирования App Inventor, разработанный профессором Массачусетского технологического института (MIT) Халом Абелсоном в 2010 году. В основе его - тот же принцип перетаскивания визуальных кирпичиков и собирания программы из блоков.

Отличие App Inventor от Scratch состоит в том, что App Inventor ориентирован не на десктопное использование, а предназначен для создания приложений под мобильное устройство - смартфон или планшет с ОС Android. Он умеет, например, «понимать» данные акселерометра мобильного гаджета, управлять встроенной камерой, видит, как ориентирован телефон в пространстве и многое другое.

App Inventor - это полностью облачное приложение. Чтобы начать программировать на нём, нужен только интернет и браузер. Переход на страницу языка осуществляется по этой ссылке . Интерфейс на английском и на русском языках.

Интерфейс языка программирования MIT App Inventor состоит из двух основных частей - дизайнера и редактора блоков .

В дизайнере мы конструируем наше приложение из элементов - экранов, кнопок, ячеек, изображений, звуков.

В редакторе блоков мы программируем поведение этих элементов.

Интерфейс App Inventor прост и интуитивно понятен. Если вы захотите попробовать преподавать программирование на App Inventor в школе, рекомендуем сайт appinvent.ru , на котором собраны обучающие материалы для учителей.

Конкурс для школьников

А школьники, которые пройдут обучение по программированию на App Inventor в школе или самотоятельно, могут принять участие в конкурсе на разработку собственных мобильных приложений на App Inventor . Победитель конкурса получит планшетный компьютер от компании Samsung. Срок подачи работ - до 15 мая 2016 года.

Под операцией мы будем понимать последовательность действий, каждое из которых может содержать разное количество блоков.

Любую операцию можно поместить либо в блок обработки события, либо в блок процедуры. Расположение операции в блоке обработки события характеризуется простой, но в будущем это может привести ко многим проблемам, в отличие от использования её в процедуре, что позволят получить гибкий алгоритм. Рассмотрим это на примере простой операции присваивания глобальной переменной пустого списка, состоящей из двух блоков (рис. 1).

Рис. 1. Варианты расположения операции.

При размещении операции в блоке обработки события компонента (верхний вариант), она жестко привязывается к нему и становится недоступной для вызова из других блоков. Если эту операцию нужно вызвать из другого блока, то её придётся скопировать. Создавать копии операции нежелательно, потому что при изменении её алгоритма придётся вносить правку в каждую из них. Это повышает вероятность появления разных ошибок: можно забыть исправить какую-то копию, ошибиться при копировании блоков, вставке их и т.п. Размещение операции в блоке процедуры позволит вызывать её из других блоков и избежать описанных выше ошибок.

При работе в редакторе блоков иногда возникает необходимость вызова разных версий одной операции или разных операций. Для этого можно либо создать новые компоненты с новыми блоками обработки событий, либо использовать один существующий блок btnExecute, помещая в него вызов той или иной операции. В результате замены, отсоединённые операции превратятся в “плавающие” блоки (рис. 2), которые не принадлежат никакому групповому блоку.

Рис. 2. "Плавающие" блоки.

Если на рабочем поле таких плавающих блоков много, то разобраться с ними может будет непросто. Если с нижним блоком всё понятно - это блок вызова процедуры, то что делает сцепка блоков в верхней части рисунка? Это отдельная операция или действие, которое входит или входило в какую-то другую операцию? Но тогда где остальная часть этой операции? Добавление операции в блок процедуры позволит избавиться от непонятных “плавающих” блоков.

Для выполнения блока не обязательно помещать его в обработчик события. Можно нажать правой кнопкой мыши на нём и в появившемся контекстном меню выбрать опцию Do it.

Ещё один недостаток размещения операции в обработчике события связан с тем, что при случайном удалении компонента в дизайнере произойдёт удаление не только всех блоков, которые относятся к этому компоненту, но и всех вложенных в них блоков. Особенно досадно будет в том случае, если операция состояла из большого числа блоков (рис. 3). Если удалить компонент btnTest, то произойдёт удаление блока btnTest.Click со всем его содержимым.

Рис. 3. Нежелательная группировка блоков в обработчике события.

Какую операцию выполняют блоки на этом рисунке? Сразу ответить трудно. А при помещении их в отдельную процедуру всё сразу станет понятно из её названия setVarValue - задаёт значение переменной (рис. 4).

Рис. 4. Группировка боков в процедуре.

Блоки процедур и локальных переменных имеют настройку, доступную при щелчке по пиктограмме шестерёнки. Для блоков процедур она заключается в добавлении им входных параметров, а для блоков локальных переменных к созданию дополнительных входов. Это позволит четыре блока переменных превратить в один блок с четырьмя переменными (рис. 4). Является ли такое преобразование эквивалентным? Нет. Блок с несколькими локальными переменными имеет одну область видимости, что не позволяет внутри него получать значения его переменных. Например, невозможно переменной value (рис. 4) присвоить значение переменной key.

Перечислим обнаруженные нами недостатки размещения операции в блоке обработки события:

  • Жёсткая привязка к блоку события определённого типа выбранного компонента
  • Невозможно вызова операции из других блоков (значит, она не может стать библиотечной)
  • Удаление операции при удалении компонента
  • Образование непонятных “плавающих” групп блоков
  • Сложно быстро понять то, что делает операция

Избавиться от всех этих недостатков очень просто, если все операции помещать в процедуры.

При создании алгоритмов для простоты и скорости хочется разные операции поместить в одну процедуру, что приведёт к быстрому увеличению количества блоков и сложностям с пониманием её работы. Для исключения этого в программировании широко используется простое правило:

Одна функция (процедура) - одна операция

Это правило взято из жизненной практики. Представьте, что вы включаете свет в комнате, а при этом происходит включение телевизора, кондиционера и выключение компьютера. Понравится ли вам это? Нет, потому что это приведёт к путанице и неприятным ситуациям.
На рис. 4 в начале блока происходит вызов четырёх процедур - getKey (получить ключ), getNewVal (получить новое значение), getKeys (получить список ключей) и getIndex (получить индекс). Каждая из этих процедур выполняют одну операцию. После них идёт блок if, в котором происходит выполнение одной операции процедуры setVarValue1.
Можно ли в процедурах вместо локальных переменных использовать глобальные? Можно, но так делать не следует. Использование глобальных переменных внутри процедуры, во-первых, жёстко привязывает её к ним и, соответственно, к данному приложению, а, во-вторых, при помощи глобальных переменных внешние блоки из разных мест приложения могут оказывать влияние на внутренний механизм работы процедуры, что весьма нежелательно. Что может случиться, если пассажиры автобуса будут иметь доступ к его механизму?

Локальные переменные являются своего рода буфером. Если изменится имя глобальной переменной, то это не нарушит работу процедуры, потому что внутри неё используются имена локальных переменных, которые не менялись. В App Inventor при изменении имени глобальной переменной оно автоматически изменится во всех использующих его блоках. Отсюда следует важный вывод о том, что существующая в App Inventor автоматизация по проверке корректности типов переменных, переименованию переменных и и др., с одной стороны, упрощает разработку приложений, освобождая разработчика от размышления над этими вопросами, а, с другой стороны, способствует развитию навыка небрежного составления алгоритмов. Вообще говоря, данный навык может развиться при программировании на любом языке. Как этого избежать? Использовать рекомендации по созданию “чистого кода”, о чём написано немало книг. В MIT App Inventor получится использовать лишь малую долю этих рекомендаций, но следование им позволит улучшить алгоритмы и их читаемость при любом способе их создания - на листе бумаги, доске, при редактировании кода или работе с блоками.

Указанное выше правило следует использовать и в случае использования блоков обработки событий. На рис. 4 обработчик события Click производит только одну операцию - вызывает процедуру. А если из обработчика событий нужно вызвать несколько процедур? Тогда нужно понять, эта группа процедур выполняет одну или несколько операций? Если одну, то всё в порядке. Например, при инициализации приложения вызывается много процедур, но все они объединены одной операцией - инициализации.

Чем больше операций выполняет процедура, тем более тесной является её связь с данным проектом, и тем сложнее её адаптировать для работы в другом приложении. В идеальном случае процедуру общего назначения желательно делать независимой от данного приложения, чтобы появилась возможность поместить её в свою библиотеку для повторного использования в других приложениях.

В качестве хранилища библиотечных процедур в App Inventor можно использовать незадействованные экраны приложения. Библиотеки с небольшим количеством процедур можно располагать совместно на одном экране, а большие - на отдельных. В последнем случае перемещение всех блоков библиотеки в рюкзак можно будет выполнить при помощи одной операции.

Если библиотек накопилось много, то можно их оформить в виде шаблона приложения, в котором первый экран оставить пустым. Используем этот шаблон при создании нового приложения, а после его готовности создаём копию, из которой удаляются все библиотечные экраны.

Для исключения переименования глобальных переменных и нарушения работы библиотечных процедур при копировании их из рюкзака на экран приложения, который может иметь глобальные переменные с такими же именами, необходимо имена библиотечных блоков заранее составлять с префиксами, указывающих на библиотеку. Если библиотека для работы со списком пар имеет название libPairs. Тогда можно переменные, процедуры и компоненты в ней назвать так: libPairs_name, libPairs_setValue, libPairs_btnExecute.

Для более удобной работы с большим количеством блоков и перемещения их по рабочему полю, помимо кнопок масштабирования на области просмотра пригодится и масштабирование рабочей области браузера при помощи комбинации клавиш Ctrl- или Ctrl+.

Увеличить встроенную функциональность App Inventor можно при помощи web-технологий и расширений. В сети можно найти платные и бесплатные расширения (порядка 200 на puravidaapps.com), но возникают вопросы, а насколько сложно создавать свои, что они могут дать и стоит ли тратить время на это или лучше заняться чем-то другим?

Все компоненты и блоки, доступные в App Inventor, относятся к встроенным (внутренним), а расширения - к внешним.

Встроенные возможности предоставляют интересную функциональность для начинающих пользователей, удовлетворительную для опытных и недостаточную для программистов. При этом большинство пользователей предпочтут загружать готовые расширения, а не разрабатывать их. Из этого следует простой вывод о том, что разработка расширений может быть интересна, в основном, опытным пользователям и энтузиастам. Начинающих вполне устроят встроенные возможности и имеющиеся расширения, а программистам заниматься расширениями не интересно по причине необходимости выполнения двойной работы. Зачем тратить время на создание и отладку расширения ограниченной функциональности, а затем при помощи него создавать приложение ограниченной функциональности, если можно сразу писать код на Java, пользуясь всеми доступными возможностями Android Studio IDE и Android API?

Создавать расширения для AI несложно, если имеется какой-то опыт программирования и понимание основ ООП, но по указанным выше причинам этим серьёзно занимаются единицы. Создавать функциональные расширения непрактично, а вот написание простых дополнений для расширения встроенной функциональности или создания новой может показаться интересным и полезным в плане практики занятием. Но здесь нужно определиться с подходом. Можно либо следовать концепции AI - визуальное программирование, либо расширить её элементами текстового программирования.

Если сказать грубо, то App Inventor похож на айсберг, верхушка которого видна пользователям в виде встроенной функциональности, а под водой находится и недоступна значительно большая часть. Это сделано специально в соответствии с назначением данной IDE, требующей от пользователей минимальных знаний программирования. Заложенная в App Inventor модель работы изначально не рассчитана на большую функциональность. Добавление новых свойств вызовет рост количества блоков в геометрической прогрессии. Например, добавление свойства прозрачности приведёт к появлению двух блоков для каждого виджета (для установки и возврата значения). Если таких виджетов 5, то число блоков увеличится на 10. Добавили 10 свойств, на выходе получили 100 блоков. Дополнительно к этому появятся новые поля свойств в дизайнере. В этих условиях подход “простая IDE + расширения” выглядит обоснованным, но не для тех, кто предпочитает хорошую функциональность “из коробки” без необходимости поиска и установки дополнений.

Индивидуальная настройка свойств объектов и задание жесткой связи блоков на этапе разработки приложения, с одной стороны, упрощает разработку и позволяет избежать большого количества ошибок, но приводит к возникновению статичных приложений. Если к одному блоку присоединён другой блок, то это навсегда. Изменить свойство или выбрать другой объект на этапе выполнения приложения можно только в том случае, если эта возможность была изначально заложена на этапе разработки. Для этого необходимо использовать косвенный доступ к объектам. Например, можно создать список пар “название объекта - объект” для всех объектов, а затем использовать его в функциях для доступа к разным объектам. В этом случае принимающий блок будет связан не с конкретным объектом, а со списком, из которого нужный можно получить по его ключу-имени.

Если к сказанному выше добавить сложности с реализацией групповых операций, отсутствием виджетов, методов и других нюансов встроенной функциональности, то станет понятна причина появления AppyBuilder, Thunkable, Makeroid и др., в которых увеличение функциональности реализовано за счёт количества компонентов. Больше компонентов - больше блоков. А вот при помощи расширения можно увеличить функциональность качественным образом, например, использовать один блок для доступа к десяткам свойств десятка объектов. Вот это уже действительно интересно, поскольку дополняет визуальное программирование элементами текстового для компенсации ряда недостатков встроенной функциональности AI.

Смогут ли создавать расширения те, кто слабо знаком с программированием? Да, простые смогут, воспользовавшись подходом “скопируй и измени”, но определённая подготовка всё же требуется. Без неё будет непонятно, почему расширение не компилируется и что при этом пишется на экране. Также следует сказать о том, что часть расширения, работающего с объектами Android, удобее создавать и отлаживать в Android Studio.

Разработка расширений подойдёт тем, кого, в принципе, устраивает App Inventor, но хотелось бы что-то дополнить, улучшить и упростить, а заодно и попрактиковаться в Java. Если это ваш случай, то начнём с развёртывания среды разработки.

ВКонтакте есть группа Расширения для App Inventor , где на видео и в текстовом виде дано пошаговое руководство по созданию и настройке рабочей среды, а также простой пример, возвращающий слово Test. Дублировать данный материал не имеет смысла, а вот сам пример рассмотрим в качестве быстрого введения в тему.

package vlad; import com.google.appinventor.components.runtime.*; import com.google.appinventor.components.annotations.DesignerComponent; import com.google.appinventor.components.annotations.DesignerProperty; import com.google.appinventor.components.annotations.PropertyCategory; import com.google.appinventor.components.annotations.SimpleEvent; import com.google.appinventor.components.annotations.SimpleFunction; import com.google.appinventor.components.annotations.SimpleObject; import com.google.appinventor.components.annotations.SimpleProperty; import com.google.appinventor.components.common.ComponentCategory; import com.google.appinventor.components.common.PropertyTypeConstants; import com.google.appinventor.components.common.YaVersion; import com.google.appinventor.components.runtime.util.SdkLevel; @DesignerComponent(version = YaVersion.NOTIFIER_COMPONENT_VERSION, category = ComponentCategory.EXTENSION, description = "This is a test extension", nonVisible = true, iconName = "images/notifier.png") @SimpleObject(external=true) public final class TestExtension extends AndroidNonvisibleComponent implements Component { public TestExtension(ComponentContainer container) { super(container.$form()); } @SimpleFunction(description = "This function returns the \"Test\" string") public String Test() { return "Test"; } }

Код расширения включает в себя java-код класса и аннотации, начинающиеся с символа @. Аннотации используются для указания того, что блок кода под ними должен быть обработан простым компилятором. Простой компилятор просматривает аннотации и производит интеграцию расширения в среду разработки App Inventor - создаёт для указанной функции блок (функции или свойства), поле редактирования в дизайнере и выполняет другую работу.

@DesignerComponent указывает на общие параметры компонента и то, что он относится к категории расширений и является невизуальным (в настоящее время можно создавать только невизуальные компоненты расширения)

@SimpleObject указывает на компонент, а поле external=true на то, что компонент является внешним

@SimpleFunction указывает компилятору функцию, для которой нужно создать блок. Если функция возвращает значение, то выемка появится в его левой стороне. Если функция имеет параметры, то соответствующие им выемки будут в правой стороне.

Исходные коды классов можно посмотреть в директориях, соответствующих названиям пакетов:

com/google/appinventor/components/runtime - классы встроенных объектов.
com/google/appinventor/components/annotations - классы аннотации
com/google/appinventor/components/common - классы общего использования
com/google/appinventor/components/runtime/util - классы утилит

В настоящее время при помощи расширения можно создать только невизуальный компонент. Если необходимо создать визуальный компонент, перетаскиваемый на рабочее поле дизайнера, как и строенные виджеты, то для этого понадобится своя локальная копия App Inventor.

Попробуйте изменить надпись, скомпилировать, установить и выполнить блок. Если всё получилось, то рабочая среда настроена и можно идти дальше для создания более практичных и интересных вещей.

App Inventor - среда визуальной разработки android-приложений, требующая от пользователя минимальных знаний программирования. Первоначально разработана в Google Labs, после закрытия этой лаборатории была передана Массачусетскому технологическому институту. В начале марта 2011 года Массачусетский институт запустил публичную бета-версию проекта, доступную на сайте appinventor.mit.edu .

Работает эта среда разработки прямо из браузера. Скачивать и устанавливать ничего не нужно. Полученный результат можно просматривать на android-устройстве. Готовые приложения можно размещать в Play Market.

C августа 2015 года App Inventor 2 поддерживает русский язык .

В онлайн редакторе MIT App Inventor 2 приложения строятся на базе стандартных компонентов, которые являются основным элементом разработки Android-приложений.
Блоки App Inventor. Важные понятия и принципы

Блоки App Inventor представляют собой инструменты для оперирования компонентами и выглядят как пазлы.

Блоки в этом конструкторе приложений для Android разбиты на две большие группы по признаку – на что влияют и к чему относятся:

  • относящиеся непосредственно к компонентам
  • относящиеся к приложению в целом

Начнем с блоков, которые принадлежат компонентам. Их можно разделить на три типа, которые легко различить по цвету:

1. блоки, описывающие свойства компонента. Они зеленого цвета и выглядят так:

этот блок обозначает текущее свойство компонента. На данной картинке приведен блок цвета фона для текстового компонента TextBox1. Он подразумевает получение уже имеющегося значения.

а этот задает требуемое значение компоненту (присвоить TextBox1 фоновый цвет …). «set» - задать. Этот тип блока-свойства можно было бы отнести к командам (обработчикам), поскольку он действительно дает команду изменить какое-либо свойство компонента, в том числе, и значения полей. Однако разработчики App Inventor решили так – все же это и свойства тоже.

2. блоки-события, то есть, те блоки, которые отслеживают наступления какого-либо события в приложении, например, нажатие кнопки и далее запускают блок-команду. Они окрашены в бронзовый цвет и выглядят вот так:

этот блок, например, выполняет действие по нажатии кнопки (когда по Button3 кликнули сделать …)

3. блок-команда, в App Inventor этот блок еще часто называют обработчиком. Этот блок указывает, что нужно сделать с компонентом, к которому принадлежит блок:

Конкретно этот блок вызывает данные из таймера устройства.

Вторая группа блоков, относящихся ко всему приложению , организована несколько иначе.

Для начала вот их список подгрупп:

  • Logic blocks – логические блоки
  • Math blocks – математические блоки
  • Text blocks – текстовые блоки
  • Lists blocks – блоки для управления списками
  • Colors blocks – блоки для управления цветом
  • Variables blocks – блоки для управления переменными
  • Procedures blocks – блоки процедур.

Все они, за исключением Procedures blocks, встраиваются в другие блоки. То есть, они не могут служить изначальным блоком, в отличие от блоков-событий, принадлежащих компонентам – все действия производятся при каких-либо событиях с компонентами.

Вот здесь стоит рассказать еще о типах «пазлов». Итак, вы, наверное, заметили, что есть пазлы четырех видов.

Из их формы совершенно очевидно, что первым видом начинается любая цепочка в мобильном приложении. Это – событие и вполне логично, что оно инициирует все дальнейшие действия. И этот тип не отличается от принятого в этом конструкторе приложений для Android.

А вот следующие два вида блока по типологии App Inventor относятся к разным типам: свойствам и командам (обработчикам), соответственно. Но по форме пазла и по смыслу их можно было бы отнести к командам, так как они задают действие. Скажем, второй приведенный на картинке пазл даёт команду присвоить компоненту определенное значение , а третий пазл – вызвать компонент с определенным значением . Кроме того, эти пазлы являются «промежуточными», ими нельзя закончить цепочку.

А вот четвертый вид представляет собой конечное значение, существующее или рассчитываемое и им заканчиваются цепочки . Например, четвертая картинка представляет собой текущее значение компонента Clock1.

Компания Айтичер объявляет конкурс разработки мобильных приложений для ОС Андроид, созданных на языке программирования App Inventor .

Сроки проведения Конкурса
  • Прием и регистрация конкурсных работ: с 1 января по 15 мая 2017 года.
  • Рассмотрение работ конкурсным Жюри – с 15 по 30 мая 2017 года.
  • Объявление итогов конкурса 30 мая на портале конкурса.