next() — выглядит как более короткий хак, чем с pairs. И не решает проблему если нужен именно размер, а не проверка на пустоту. Размер «массива» тут не в тему.
PS: Размер таблицы‐массива узнаётся за O(log(table_size)) (O(table_size), если размер таблицы больше MAX_INT/2 или таблица специальным образом построена) в lua. Не знаю, что в luajit (но тесты показывают, что чтобы там ни было, оно не даёт O(1)), но в lua-5.3.4 используется бинарный поиск; в лучшем случае бинарный поиск по массиву, в худшем — по хэшу. Они как‐то ухитряются делать это быстро (скорее всего, мои тесты просто все прошли как бинарный поиск по массиву), но идея мне всё равно не нравится.
На JS я практически ничего не писал, поэтому сравнить не могу. Но второе негативное ощущение от lua — это стандартная библиотека, выглядящая как куча недоделок:
Из всех возможных манипуляций с переменными окружения вам доступно только получение значения переменной. Получить полный список, а также добавить либо изменить значение нельзя.
Нельзя менять рабочий каталог.
Есть удаление каталогов, но рекурсивное удаление вам придётся писать самим.
Есть два способа запустить процесс, но ни одного — запустить со списком аргументов. Чего‐то вроде shellescape() тоже нет.
Нельзя запустить процесс в фоне и общаться с ним. Можно только либо читать его вывод (документация, кстати, не говорит о том, будет ли это stdout, stderr или оба сразу, но проверка показывает, что только stdout), либо писать ему в stdin.
В регулярных выражениях есть такие вещи как %{number} или %b(), но нет банального |. И ещё регулярные выражения не компилируются, так что вы можете только надеяться на оптимизатор, либо на то, что компиляция не занимает долгое время (что, скорее всего, говорит о низкой скорости работы результата).
Нельзя узнать число элементов в таблице. В т.ч., проверить не пуста ли она, не используя pairs().
Upstream нарушает обратную совместимость в минорных версиях. В частности, из‐за этого «нет» побитовых операций в стандартной поставке — обновляться с 5.1 просто нельзя, т.к. многие нужные пакеты забили на обновление. Команда luajit работает в этом отношении намного лучше.
Я не ожидаю Python’овского «batteries included», но мало что из того, что всё‐таки есть, выполняет свои функции полностью.
Ещё, я совершенно не понимаю, почему нельзя писать {}[key] и "%d":format(num) без дополнительной пары скобок. Полагаю, это потому, что func 'abc'.foo работает как (func('abc')).foo (с таблицей аналогично), но не понятно, зачем было делать выбор в пользу менее читаемого синтаксиса.
Ещё можно отметить то, что в таблицах нельзя хранить nil, зато отсутствующие в таблице ключи и неопределённые переменные имеют это значение. Иногда удобно, но слишком часто служит источником ошибок. Кроме того, языком полностью игнорируется расхождение в числе аргументов при объявлении и вызове функции — недостающие аргументы просто забиваются nil’ами (если только функция не с ... — тут вы всегда можете понять, использовали ли nil или просто не написали аргумент), «лишние» аргументы молча игнорируются.
Ожидал увидеть описание приложения, реализующего VPN‐over‐что‐то (пример с DNS и для linux; для Android есть именно VPN‐over‐DNS, но я не видел про него статьи). Но тут всего лишь короткая заметка про сайт с iframe.
Какой компилятор lua в LLVM? Я нашёл только устаревший (последнее изменение в январе 2012) llvm-lua и вот такую ветку комментариев, предположительно, от автора, о том, что llvm-lua потребляет слишком много ресурсов и не годится для этой задачи.
А в javascript, нативный код, Java (точнее, GraalVM) можно всё, что LLVM поддерживает. Может и в .net можно, в поиске слишком много результатов про использование LLVM как компилятора для .net.
Я видел быструю операционистку без десятипальцевого набора. Половина времени — переключение на мышку, слепая печать в школе тут поможет только из расчёта «может дизайнеры приложений будут больше времени уделять возможности не отрывать руку от клавиатуры, а менеджеры — обучению использованию этой возможности». Но, скорее всего, этого не случится.
Почему не делают? Простые GUI вроде примеров из Взаимодействие bash-скриптов с пользователем пишут безо всякого ООП. Ещё есть LabVIEW, используется у нас на работе — «лицевые панели» виртуальных приборов вполне себе GUI. «Внутрях» у kdialog и LabVIEW, может, и какой‐нибудь C++ (а у второго, может, и нет, я не знаю), программист для создания GUI на основе этих инструментов ООП использовать почти наверняка не будет.
Из чего‐то более сложного я могу вспомнить только про Web‐приложения и то, что не все javascript framework’и, про которые можно прочитать на хабре, используют ООП. Но в любом случае, «давно никто не делает» и «в сложных графических приложениях (почти?) всегда используется ООП» — это совершенно разные вещи.
У нас в школе были и ассемблер, и лого с черепашкой, и какие‐то CISCO’вские курсы по сетям. Вопрос в том, какие цели у курса информатики: понимание, как работает компьютер и понимание, как эффективно за ним работать — это уже разные вещи и «слепая печать» относится ко второй, многопоточное программирование (и ассемблер, но не GUI и не ООП) к первой. А не слишком пригодный для написания скриптов Pascal нужен вообще для третьего: чтобы школьники научились структурному программированию (или хотя бы просто научились программировать).
Конкретно для «осознанной профориентации» в минимальное время, вообще‐то, лучше взять … POSIX shell. И затронуть сразу профессии программиста и администратора, попутно показав как можно облегчить себе жизнь скриптами и дав один из широко и реально используемых языков. А лишнее время направить на информационную безопасность, с практикой, углублённым объяснением механизмов работы уязвимостей (ещё в таком контексте объяснение «как работает компьютер» пойдёт куда лучше) и пропагандой открытого кода импортозамещения.
Связи лучше подсвечивать, создавая жирный красный фон, а не перекрашивая их: в LabVIEW много недостатков, но разноцветные линии разной фактуры, соответствующие разным типам к ним не относятся. Но такая подсветка типов плохо совместима с перекрашиванием на diff’е. Ещё одна проблема для diff’ов (кстати, у меня также не решённая, нужно переделать предложение по нумерации узлов; только то, что я пока могу придумать сделает их названия сильно длиннее): если я удалил узел и вставил на место точно такой же, то они подсвечиваются также, как если бы я вставил другой узел (т.е. один удалён, один добавлен).
Оператор от подобной функции будет отличаться тем, что если default_value — на самом деле какое‐то вычисляемое выражение, то оно вычисляться не будет. Судя по картинке выше, называть новые функции «оператором Элвиса» неверно (иначе зачем существует Get версия?), но когда я прочитал про это в статье, то очень удивился: оператор, выглядящий как функция — разработчики Java совсем с ума сошли?
Главное, что в вашем примере все данные о нодах хранятся в одном месте, и ещё это JSON. Получить нормальные diff’ы в текстовом виде вам так не светит¹: diff любит помещать скобочки не там, где нужно (с т.з. читаемости), у JSON принципиальная проблема с завершающей запятой (которая также плохо отражается на diff’ах), а часто повторяющиеся метаданные вроде "group": null делают «проблему скобочек» ещё острее. Ну и при чтении diff’а положение узлов в графике не важно совершенно (пока не увидите, не поймёте, нормально ли получилось), а такие изменения будут перемешиваться с логикой.
А про «графический diff»: во‐первых, сложно сделать удобно. Во‐вторых, ну сделаете вы графический diff, а смотреть его как? Схемы хранятся в VCS, VCS обычно является частью чего‐то более крупного вроде github, а веб‐интерфейс «чего‐то крупного» показывать ваши diff’ы не умеет, и учиться не будет, пока вы не станете достаточно популярны (впрочем, в некоторых случаях вы можете научить его сами различными способами, в т.ч. дополнениями для браузера). Если придумать правильное представление, то можно хотя бы получить возможность делать review на уровне «а следует ли мне вообще идти смотреть графический diff», а в идеальном случае должно даже позволить себя читать.
¹ Плюс ещё LabVIEW позволяет размещать провода как вы хотите, а не «у нас соединение с нодой X, а провод проведём как‐нибудь сами»; и у того, и у другого варианта есть плюсы и минусы, но diff’ы в случае, если вы засунете описание пути провода к описанию соединений, станут ещё менее читаемыми.
Разумеется. Я просто написал, как бы я подошёл к представлению виртуальных инструментов LabVIEW для случая «нужно получить хотя бы относительно читаемый diff», а, возможно, иногда даже получать нормально работающее слияние виртуальных инструментов как текстовых файлов. Соответственно, и метаданные, и код, и представление должны быть все представлены в этом файле.
Текст, что выше должен описывать простейший виртуальный инструмент, который вызывает виртуальный инструмент My Wait.vi с данными из терминала timeout, в случае, если на входе нет ошибки, и пересылает ошибку на выход, если она есть. Правда, я уже заметил у себя ошибки, но на идею они не влияют.
Я как‐то думал, как выглядело бы представление LabVIEW’шных виртуальных инструментов в формате, который производил бы относительно читаемые diff’ы. Основная суть идеи в том, что метаданные отдельно, логика отдельно, представление отдельно. Если правильно выбрать способ сортировки данных одного уровня иерархии и разбивки на строки, то можно получить относительно читаемые diff’ы. Правда, в моём примере ниже нужно больше внимания уделить алгоритму генерации имени проводов.
Если что, получилось что‐то вроде (мысленно удалите комментарии)
%YAML 1.2
---
description: Wait for delay milliseconds.
# …
# Other metadata from VI properties
# …
icon:
palette:
a: {A: 0x00, R: 0x00, G: 0xff, B: 0x00}
b: {A: 0x00, R: 0x00, G: 0xff, B: 0x00}
# “Image” key uses single-character ARGB colors from palette.
# UTF-8 in case ASCII is not enough.
image: |
bbbbbbbbbb
baaaaaaaab
bbbbbbbbbb
baaaaaaaab
baaaaaaaab
baaaaaaaab
bbbbbbbbbb
terminals:
pattern:
left: 3
top: 0
bottom: 0
right: 3
list:
- name: delay
caption: "delay (default 5000 ms)"
location: left 0
direction: input
type: I32
- name: error in
caption: "error in (no error)"
location: left 2
direction: output
type: error cluster
- name: error out
caption: error out
location: right 2
direction: output
type: error cluster
code:
# Code: contains all used nodes and their relations, but not their positions
# or positions of the wires.
#
# The code is created as following: first all node names are determined.
# Then AST is sorted so that if node B has inputs wired to outputs of node A
# then node A appears first. Should that not allow determining the order
# then nodes are sorted alphabetically.
#
# After sorting is complete all nodes are appended indexes to make them
# unique. Indexes are tracked in runtime and preserved so the below index
# order only keeps being perfect on the first save.
#
# Note: if node was replaced via “Replace” context menu it still keeps its
# index: this is one of the main points in having global incrementing indexes.
#
# Inputs/outputs are named after their nodes with terminal names appended.
# Should terminal name be not unique its position is appended.
#
# Only inputs/outputs which have wires receive their names: names in
# node dictionaries define connections.
- control/delay 0: {output: control/delay 0/output}
- control/error in 1: {output: control/error in 1/output}
- case structure 2:
selector: control/error in 1/output
# Terminal properties which do affect logic are defined here
use default if unwired:
- indicator/error out 5/input
cases:
Error:
# In some cases there is nothing, but wire; and it is significant
# for the logic.
- wire: !!set {control/error in 1/output, indicator/error out 5/input}
No Error:
# User VI: same as default ms waiter, just to show how it would look.
#
# Dictionary near the node maps terminals to connections.
- My Wait.vi 4: {wait: control/delay 0/output}
- indicator/error out 5: {input: indicator/error out 5/input}
# Define wire positions in a form [anchor (output terminal), relative
# x/y offset, anchor (input terminal)]. Wires without sources or with structure
# terminals as sources are listed from sink. Wires without sources or sinks just
# use [anchor, node name] with nearest anchor. No absolute positions used ever.
#
# Note: determining exact anchors still needs code above, pairs in wire
# position only reference nodes.
#
# Since wire may have more then one sink this is a list of lists of lists,
# innermost list is a 2-tuple (type, data).
#
# Structure terminal positions are also defined here.
wires:
control/delay 0/output:
- [[source, control/delay 0], [structure terminal, [case structure 2, +1, 0]], [case, No Error], [sink, MyWait.vi]]
control/error in 1/output:
- [[source, control/error in 1], [structure terminal, [case structure 2, +1, 0]], [case, Error], [structure terminal, [case structure 2, +5, 0]]]
indicator/error out 5/input:
- [[sink, indicator/error out 5], [structure terminal, [case structure 2, -1, 0]]]
# Node positions and properties that do not affect logic.
nodes:
control/delay 0:
type: control
terminal: delay
# Position is absolute
position: [0, 1]
label:
# label position relative to position
position: [-1, -1]
visible: true
view: icon
control/error in 1:
type: control
terminal: error in
position: [0, 0]
label:
position: [-1, -1]
visible: true
view: icon
case structure 2:
type: case structure
position: [1, 2]
size: [5, 2]
label:
text: Case Structure
visible: false
position: [0, 0]
# Case visible by default
selected case: No Error
MyWait.vi 4:
type: VI
# Logical location (which structure, which case) is defined by logic.
position: [2, 1]
label:
position: [-1, -1]
visible: false
view: icon
indicator/error out 5:
type: indicator
position: [6, 0]
label:
position: [-1, -1]
visible: true
view: icon
Про кнопку не знал, но проблемы она не снимает: клавиатурное сочетание на все действия по выравниванию одно. Буду на работе, посмотрю, нельзя ли назначить разные на разные действия, а не одно на повторение последнего действия.
Блоки не всегда подходят: в хосте можно что‐то сообразить на куче различных видов ссылок или с глобальными переменными, но на FPGA первого нет, а второе жрёт ресурсы, из‐за чего такое объединение получается менее оптимальным, чем хотелось бы (в смысле, либо жрёт ресурсы, либо требует выноса в основную VI того, что я на хосте выносить не стал бы). (Впрочем здесь есть возможность задействовать VHDL, только пока руки не дошли.)
LabVIEW позволяет размещать комментарии в произвольном месте, что даёт возможность подписывать длинные провода и неочевидные моменты. Плюс названия циклов и фреймов, если они не очевидны или если мне захотелось их назвать. Ну и необходимые вещи вроде названий VI’ек и их иконки.
Вообще‐то у LabVIEW есть какая‐то система документирования, но т.к. я, во‐первых, не знаю, как посмотреть документацию из свойств VI методом, отличным от «открыть VI и пойти смотреть свойства», и, во‐вторых, такая документация относится только к VI целиком и частично закрывается нормальным названием файла и иконкой, то мною эта функциональность как раз‐таки не используется.
А я на нём «пишу» (на версии 2015). Нет практически никаких средств улучшения представления кода, даже аналогов команд из Altium Designer «выровнять по левому/правому/верхнему/нижнему» краю, из‐за чего бо́льшая часть времени тратится на то, чтобы «код» был поддерживаемым. Нет масштабирования! Проблема с «цикломатической сложностью на пиксель» элегантно «решается» блоками вроде «case structure», которые в принципе не позволяют увидеть весь код сразу.
Нормально у них с мозгом, потому что они нормально выполняют свою работу. А у меня ответ был на то, что в бюджетных учреждениях зовут «программистов» на каждый чих: в тех учреждениях, с которыми я контактировал, не зовут.
Не раз видел как в бюджетном учреждении (МФЦ) сотрудники вполне себе доставали из принтера картридж (с целью потрясти или обнаружить замятую бумагу) или замятую бумагу (с открытием различных дверок и возможным доставанием картриджа). Вероятно, у вас либо возможность что‐то печатать не так уж критична, либо проблемы с принтером возникают редко. Впрочем, есть ещё вариант с другой проблемой: пользователь просто не знает, у кого картридж на балансе, и, соответственно, может ли он его себе вставлять вообще.
Кстати, работал в финансовой/риэлторской конторе курьером, 3 (празднования, точнее, много празднований: корпоративы были, но не так уж много и денег не собирали, если не идёшь), 6 (границы) и 8 (начальственный ступор) не видел. 12 (нерешительные кадры), 13 (язык документации), 11 (внезапный декрет) и 10 (расходная часть) также не видел, но тут скорее «не замечал» либо «не мог заметить».
next()
— выглядит как более короткий хак, чем сpairs
. И не решает проблему если нужен именно размер, а не проверка на пустоту. Размер «массива» тут не в тему.PS: Размер таблицы‐массива узнаётся за O(log(table_size)) (O(table_size), если размер таблицы больше MAX_INT/2 или таблица специальным образом построена) в lua. Не знаю, что в luajit (но тесты показывают, что чтобы там ни было, оно не даёт O(1)), но в lua-5.3.4 используется бинарный поиск; в лучшем случае бинарный поиск по массиву, в худшем — по хэшу. Они как‐то ухитряются делать это быстро (скорее всего, мои тесты просто все прошли как бинарный поиск по массиву), но идея мне всё равно не нравится.
На JS я практически ничего не писал, поэтому сравнить не могу. Но второе негативное ощущение от lua — это стандартная библиотека, выглядящая как куча недоделок:
shellescape()
тоже нет.%{number}
или%b()
, но нет банального|
. И ещё регулярные выражения не компилируются, так что вы можете только надеяться на оптимизатор, либо на то, что компиляция не занимает долгое время (что, скорее всего, говорит о низкой скорости работы результата).pairs()
.Я не ожидаю Python’овского «batteries included», но мало что из того, что всё‐таки есть, выполняет свои функции полностью.
Ещё, я совершенно не понимаю, почему нельзя писать
{}[key]
и"%d":format(num)
без дополнительной пары скобок. Полагаю, это потому, чтоfunc 'abc'.foo
работает как(func('abc')).foo
(с таблицей аналогично), но не понятно, зачем было делать выбор в пользу менее читаемого синтаксиса.Ещё можно отметить то, что в таблицах нельзя хранить
nil
, зато отсутствующие в таблице ключи и неопределённые переменные имеют это значение. Иногда удобно, но слишком часто служит источником ошибок. Кроме того, языком полностью игнорируется расхождение в числе аргументов при объявлении и вызове функции — недостающие аргументы просто забиваются nil’ами (если только функция не с...
— тут вы всегда можете понять, использовали ли nil или просто не написали аргумент), «лишние» аргументы молча игнорируются.Ожидал увидеть описание приложения, реализующего VPN‐over‐что‐то (пример с DNS и для linux; для Android есть именно VPN‐over‐DNS, но я не видел про него статьи). Но тут всего лишь короткая заметка про сайт с iframe.
Какой компилятор lua в LLVM? Я нашёл только устаревший (последнее изменение в январе 2012) llvm-lua и вот такую ветку комментариев, предположительно, от автора, о том, что llvm-lua потребляет слишком много ресурсов и не годится для этой задачи.
А в javascript, нативный код, Java (точнее, GraalVM) можно всё, что LLVM поддерживает. Может и в .net можно, в поиске слишком много результатов про использование LLVM как компилятора для .net.
А что не так с
?
Я видел быструю операционистку без десятипальцевого набора. Половина времени — переключение на мышку, слепая печать в школе тут поможет только из расчёта «может дизайнеры приложений будут больше времени уделять возможности не отрывать руку от клавиатуры, а менеджеры — обучению использованию этой возможности». Но, скорее всего, этого не случится.
Я вообще не знаю, зачем в школе учить создание GUI. Но «особые случаи» проще и всё ещё полезны.
Почему не делают? Простые GUI вроде примеров из Взаимодействие bash-скриптов с пользователем пишут безо всякого ООП. Ещё есть LabVIEW, используется у нас на работе — «лицевые панели» виртуальных приборов вполне себе GUI. «Внутрях» у kdialog и LabVIEW, может, и какой‐нибудь C++ (а у второго, может, и нет, я не знаю), программист для создания GUI на основе этих инструментов ООП использовать почти наверняка не будет.
Из чего‐то более сложного я могу вспомнить только про Web‐приложения и то, что не все javascript framework’и, про которые можно прочитать на хабре, используют ООП. Но в любом случае, «давно никто не делает» и «в сложных графических приложениях (почти?) всегда используется ООП» — это совершенно разные вещи.
У нас в школе были и ассемблер, и лого с черепашкой, и какие‐то CISCO’вские курсы по сетям. Вопрос в том, какие цели у курса информатики: понимание, как работает компьютер и понимание, как эффективно за ним работать — это уже разные вещи и «слепая печать» относится ко второй, многопоточное программирование (и ассемблер, но не GUI и не ООП) к первой. А не слишком пригодный для написания скриптов Pascal нужен вообще для третьего: чтобы школьники научились структурному программированию (или хотя бы просто научились программировать).
Конкретно для «осознанной профориентации» в минимальное время, вообще‐то, лучше взять … POSIX shell. И затронуть сразу профессии программиста и администратора, попутно показав как можно облегчить себе жизнь скриптами и дав один из широко и реально используемых языков. А лишнее время направить на информационную безопасность, с практикой, углублённым объяснением механизмов работы уязвимостей (ещё в таком контексте объяснение «как работает компьютер» пойдёт куда лучше) и пропагандой
открытого кодаимпортозамещения.Связи лучше подсвечивать, создавая жирный красный фон, а не перекрашивая их: в LabVIEW много недостатков, но разноцветные линии разной фактуры, соответствующие разным типам к ним не относятся. Но такая подсветка типов плохо совместима с перекрашиванием на diff’е. Ещё одна проблема для diff’ов (кстати, у меня также не решённая, нужно переделать предложение по нумерации узлов; только то, что я пока могу придумать сделает их названия сильно длиннее): если я удалил узел и вставил на место точно такой же, то они подсвечиваются также, как если бы я вставил другой узел (т.е. один удалён, один добавлен).
Оператор от подобной функции будет отличаться тем, что если default_value — на самом деле какое‐то вычисляемое выражение, то оно вычисляться не будет. Судя по картинке выше, называть новые функции «оператором Элвиса» неверно (иначе зачем существует Get версия?), но когда я прочитал про это в статье, то очень удивился: оператор, выглядящий как функция — разработчики Java совсем с ума сошли?
Главное, что в вашем примере все данные о нодах хранятся в одном месте, и ещё это JSON. Получить нормальные diff’ы в текстовом виде вам так не светит¹: diff любит помещать скобочки не там, где нужно (с т.з. читаемости), у JSON принципиальная проблема с завершающей запятой (которая также плохо отражается на diff’ах), а часто повторяющиеся метаданные вроде
"group": null
делают «проблему скобочек» ещё острее. Ну и при чтении diff’а положение узлов в графике не важно совершенно (пока не увидите, не поймёте, нормально ли получилось), а такие изменения будут перемешиваться с логикой.А про «графический diff»: во‐первых, сложно сделать удобно. Во‐вторых, ну сделаете вы графический diff, а смотреть его как? Схемы хранятся в VCS, VCS обычно является частью чего‐то более крупного вроде github, а веб‐интерфейс «чего‐то крупного» показывать ваши diff’ы не умеет, и учиться не будет, пока вы не станете достаточно популярны (впрочем, в некоторых случаях вы можете научить его сами различными способами, в т.ч. дополнениями для браузера). Если придумать правильное представление, то можно хотя бы получить возможность делать review на уровне «а следует ли мне вообще идти смотреть графический diff», а в идеальном случае должно даже позволить себя читать.
¹ Плюс ещё LabVIEW позволяет размещать провода как вы хотите, а не «у нас соединение с нодой X, а провод проведём как‐нибудь сами»; и у того, и у другого варианта есть плюсы и минусы, но diff’ы в случае, если вы засунете описание пути провода к описанию соединений, станут ещё менее читаемыми.
Разумеется. Я просто написал, как бы я подошёл к представлению виртуальных инструментов LabVIEW для случая «нужно получить хотя бы относительно читаемый diff», а, возможно, иногда даже получать нормально работающее слияние виртуальных инструментов как текстовых файлов. Соответственно, и метаданные, и код, и представление должны быть все представлены в этом файле.
Текст, что выше должен описывать простейший виртуальный инструмент, который вызывает виртуальный инструмент
My Wait.vi
с данными из терминалаtimeout
, в случае, если на входе нет ошибки, и пересылает ошибку на выход, если она есть. Правда, я уже заметил у себя ошибки, но на идею они не влияют.Я как‐то думал, как выглядело бы представление LabVIEW’шных виртуальных инструментов в формате, который производил бы относительно читаемые diff’ы. Основная суть идеи в том, что метаданные отдельно, логика отдельно, представление отдельно. Если правильно выбрать способ сортировки данных одного уровня иерархии и разбивки на строки, то можно получить относительно читаемые diff’ы. Правда, в моём примере ниже нужно больше внимания уделить алгоритму генерации имени проводов.
Если что, получилось что‐то вроде (мысленно удалите комментарии)
Про кнопку не знал, но проблемы она не снимает: клавиатурное сочетание на все действия по выравниванию одно. Буду на работе, посмотрю, нельзя ли назначить разные на разные действия, а не одно на повторение последнего действия.
Блоки не всегда подходят: в хосте можно что‐то сообразить на куче различных видов ссылок или с глобальными переменными, но на FPGA первого нет, а второе жрёт ресурсы, из‐за чего такое объединение получается менее оптимальным, чем хотелось бы (в смысле, либо жрёт ресурсы, либо требует выноса в основную VI того, что я на хосте выносить не стал бы). (Впрочем здесь есть возможность задействовать VHDL, только пока руки не дошли.)
LabVIEW позволяет размещать комментарии в произвольном месте, что даёт возможность подписывать длинные провода и неочевидные моменты. Плюс названия циклов и фреймов, если они не очевидны или если мне захотелось их назвать. Ну и необходимые вещи вроде названий VI’ек и их иконки.
Вообще‐то у LabVIEW есть какая‐то система документирования, но т.к. я, во‐первых, не знаю, как посмотреть документацию из свойств VI методом, отличным от «открыть VI и пойти смотреть свойства», и, во‐вторых, такая документация относится только к VI целиком и частично закрывается нормальным названием файла и иконкой, то мною эта функциональность как раз‐таки не используется.
А я на нём «пишу» (на версии 2015). Нет практически никаких средств улучшения представления кода, даже аналогов команд из Altium Designer «выровнять по левому/правому/верхнему/нижнему» краю, из‐за чего бо́льшая часть времени тратится на то, чтобы «код» был поддерживаемым. Нет масштабирования! Проблема с «цикломатической сложностью на пиксель» элегантно «решается» блоками вроде «case structure», которые в принципе не позволяют увидеть весь код сразу.
Нормально у них с мозгом, потому что они нормально выполняют свою работу. А у меня ответ был на то, что в бюджетных учреждениях зовут «программистов» на каждый чих: в тех учреждениях, с которыми я контактировал, не зовут.
Не раз видел как в бюджетном учреждении (МФЦ) сотрудники вполне себе доставали из принтера картридж (с целью потрясти или обнаружить замятую бумагу) или замятую бумагу (с открытием различных дверок и возможным доставанием картриджа). Вероятно, у вас либо возможность что‐то печатать не так уж критична, либо проблемы с принтером возникают редко. Впрочем, есть ещё вариант с другой проблемой: пользователь просто не знает, у кого картридж на балансе, и, соответственно, может ли он его себе вставлять вообще.
Кстати, работал в финансовой/риэлторской конторе курьером, 3 (празднования, точнее, много празднований: корпоративы были, но не так уж много и денег не собирали, если не идёшь), 6 (границы) и 8 (начальственный ступор) не видел. 12 (нерешительные кадры), 13 (язык документации), 11 (внезапный декрет) и 10 (расходная часть) также не видел, но тут скорее «не замечал» либо «не мог заметить».