QuickScript.NET in ArchestrA. Using array in scripting

QuickScript.NET. Почти тот же VisualBasic. Синтаксис схож: объявить также массив не получилось, документация этот момент не освещала, на глаза попался блог двух инженеров. Алилуя, вот оно. Ниже приведен практический пример. 

{EDIT THIS BLOCK IF 16 PENS IS NOT ENOUTH}

DIM HistServer AS Message;
HistServer = "CHESV02HIST";

DIM i AS INTEGER;

DIM LocalArray[16] As Message;

{WRITE YOUR HISTORY TAG AS TEXT HERE }

LocalArray[1] = "PID12010107.PAR_PV";
LocalArray[2] = "PID12010107.PAR_EXTSP";
LocalArray[3] = "PID12010107.PAR_OPSP";
LocalArray[4] = "V12010107.PAR_OUTPUT";
LocalArray[5] = "";
LocalArray[6] = "";
LocalArray[7] = "";
LocalArray[8] = "";
LocalArray[9] = "";
LocalArray[10] = "";
LocalArray[11] = "";
LocalArray[12] = "";
LocalArray[13] = "";
LocalArray[14] = "";
LocalArray[15] = "";
LocalArray[16] = "";

TestTag = LocalArray[1];

{WRITE NUMBER OF BUTTON HERE}
ActiveButton = 1;

{DO NOT EDIT}
aaHistClientTrend.AddMultipleTags = true;
aaHistClientTrend.ClearTags();
aaHistClientTrend.SetDuration("01:00:00");

FOR i = 1 TO 16 STEP 1
    IF LocalArray[i] <> "" THEN
        aaHistClientTrend.AddAnyTag(HistServer, LocalArray[i]);
    ENDIF;
NEXT;

aaHistClientTrend.AddMultipleTags = false;

FOR i = 1 TO 16
    IF LocalArray[i] <> "" THEN
        aaHistClientTrend.SetTagPenWidth( HistServer, LocalArray[i], 2);
    ENDIF;
NEXT;

aaHistClientTrend.ScaleAutoAllTags();

Метод решения больших задач. Принцип "разделяй и властвуй"

Один из методов решения большой задачи состоит в разбиении ее на ряд задач поменьше.

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

Пример, допустим, нас попросили написать программу для автоматизации продаж в книжном магазине. Книжный магазин ведет запись проданных книг. Регистрируется название книги и издательство, причем запись идет в том порядке, в каком книги продаются. Каждые две недели владелец магазина вручную подсчитывает количество проданных книг с одинаковым названием и количество проданных книг от каждого издателя. Этот список сортируется по издателям и используется для составления последующего заказа книг.

Тогда задача книжного магазина делится на четыре подзадачи:
1) прочитать файл с записями о продажах;
2) подсчитать количество продаж по названиям и по изделиям;
3) отсортировать записи по издателям;
4) вывести результат.

Решения для подзадач 1), 2) и 4) известны, их не нужно делить на более мелкие подзадачи. А вот 3) слишком сложна. Будем дробить ее дальше.

3.1) Отсортировать записи по издателям;
3.2) для каждого издателя отсортировать записи по названиям;
3.3) сравнить соседние записи в группе каждого изделия. Для каждой одинаковой пары увеличить счетчик для первой записи и удалить вторую.

Эти подзадачи решаются легко. Теперь мы знаем, как решить исходную, большую задачу. Более того, мы видим, что первоначальный список подзадач был не совсем правильным. Правильная последовательность действий такова:
прочитать файл с записями о продажах;
отсортировать этот файл: сначала по издателям, внутри каждого издателя - по названиям. Удалить повторяюшиеся названия, наращивая счетчик.
Вывести результат в новый файл.

Результирующая последовательность действий называется алгоритмом.

Следующий шаг - перевести наш алгоритм на некоторый язык программирования, например на C++.

Отсюда видно, что программист отличается от других человеко-профессий тем, что алгоритмы реализуется с помощью языков программирования, в то время как остальные ("непрограммистские") реализуется иначе, ведь все в нашей жизни (большинство) применимо к принципу детализации.

Вывод: "разделяй и властвуй"!

Пять правил программирования Роба Пайка



Пять правил программирования, написанных Робом Пайком:

You can’t tell where a program is going to spend its time. Bottlenecks occur in surprising places, so don’t try to second guess and put in a speed hack until you’ve proven that’s where the bottleneck is.
  1. Measure. Don’t tune for speed until you’ve measured, and even then don’t unless one part of the code overwhelms the rest.
  2. Fancy algorithms are slow when n is small, and n is usually small. Fancy algorithms have big constants. Until you know that n is frequently going to be big, don’t get fancy. (Even if n does get big, use Rule 2 first.)
  3. Fancy algorithms are buggier than simple ones, and they’re much harder to implement. Use simple algorithms as well as simple data structures.
  4. Data dominates. If you’ve chosen the right data structures and organized things well, the algorithms will almost always be self-evident. Data structures, not algorithms, are central to programming.
Роб Пайк участвовал в разработке операционных систем Inferno, Plan 9, а также языков Alef, Limbo, Newsqueak и на данный момент занят языком Go.

Перевод (копипаст с блога http://vladimir-vg.github.com/) этих пяти правил:
  1. Никто не знает какая часть кода будет потреблять больше ресурсов. Узкие места бывает в совершенно неожиданных точках, поэтому не пытайтесь угадывать и как-то оптимизировать код до тех пор пока вы на деле не выяснили что эта часть действительно является узким местом.
  2. Измеряйте. Не пытайтесь оптимизировать пока вы не провели измерений. И даже после этого, не оптимизируйте, пока не убедитесь что эта часть кода тяжелее всего остального.
  3. Нетривиальные алгоритмы работают медленно если достаточно маленькое, и обычно именно так и случается. Зато в них достаточно большие константы сложности. Пока не убедитесь что будет достаточно большим, не усложняйте код нетривиальными алгоритмами. (И даже если достаточно велико, убедитесь что выполняется второе правило)
  4. В нетривиальных алгоритмах гораздо легче ошибиться и их гораздо сложнее реализовать. Используйте простые алгоритмы и простые структуры данных.
  5. Данные важнее кода. Если вы правильно подберёте структуры данных, то код будет почти очевидным. Именно данные являются главной вещью в программировании, а не код.

C++. Спецификатор inline. Заметка

Заглянем в википедию: "
Спецификатор inline позволяет объявлять inline-функции. Функция, определённая внутри тела класса, является inline по умолчанию. Изначально inline-функции задумывались как функции, являющиеся хорошими кандидатами на оптимизацию, при которой в местах обращения к функции компилятор вставит тело этой функции, а не код вызова. В действительности компилятор не обязан реализовывать подстановку тела для inline-функций, но может, исходя из заданных критериев оптимизации, выполнять подстановку тела для функций, которые не объявлены как inline. Пожалуй, наиболее значимой особенностью inline-функции является то, что она может многократно определяться в нескольких единицах трансляции (при этом inline-функция должна быть определена во всех единицах трансляции, где она используется), в то время как функция, не являющаяся inline, может определяться в программе не более одного раза. Пример:
inline double Sqr(double x) {return x*x;}. "

Вследствие абстракции данных члены - функции классов выносят за их пределы, поэтому нужно не забывать описывать такие функции с префиксом inline, но это не панацея, так как компилятор сам решает как именно ему действовать в этой ситуации (в принципе, если функция несложна, то думаю, компилятор даст зеленый свет на активацию inline для сие функций).

C++. Список инициализации членов в конструкторе. Альтернативный синтаксис

Существует альтернативный синтаксис инициализации членов классов используя так называемый список инициализации, в котором через запятую указываются имена и начальные значения. Например, конструктор по умолчанию можно переписать следующим образом:
 
// конструктор по умолчанию класса Test с использованием
// списка инициализации членов int member1, double member2, int member3
 
inline Test:: Test() : member1(0), member2( 0.0 ), member3( 0 ) {};
 
Такой список допустим только в определении, но не в объявлении конструктора. Он помещается между списком параметров и телом конструктора и отделяется двоеточием. Вот как выглядит конструктор с двумя параметрами при частичном использовании списка инициализации членов:
 
inline Test:: Test(int m1, double m2, int m3) : member1(m1), member2(m2), member3(m3) {};
 
Важно помнить о соблюдении порядка объявления членов, которые мы хотим инициализировать через список в конструкторе: порядок объявления должен быть равнозначен порядку инициализации, например:
 
class Test {
    // Порядок объявления членов класса
    int b;
    int a;
public:
    Test(int x) : a(x), b(a) {}; // Нарушен порядок
};
 
При этом компилятор может не проругаться, однако переменные будут содержать неоднозначные значения (мягко говоря). На последок небольшой рабочий пример.
 
#include <iostream>
using namespace std;
 
class Test {
   int a;
   int b;
public:   Test() : a(16), b(61) {};
   //Test(int x) : a(x), b(a) {}; // Нарушен порядок
   void show() {cout << "a = " << a << " b = " << b << endl;};
};
 
int main() {
   Test t;
   //Test t(5); // Для вызова конструктора с нарушенным поядком объявления и инициализации
   t.show();
}