Но наверняка найдётся что-нибудь более качественное на гитхабе.
P.S. Мда, такое впечатление что этот стандартный профайлер делал школьник, даже окна не настроены нормально))) (ну то есть даёт менять размер, так что контролы не помещаются…)
Подскажите пожалуйста. Как сделать учет, склад и соединить это с считывателей QR или штрих кодов?
Есть ли готовые примеры?
Что нужно:
например:
пробирка - штук на складе, штук выдано, цена такая-то, возможно несколько фото пробирки.
при скармливании программе штрих кода или qr > штук на складе-1 выдано+1.
С чего начать? в чем хранить? как взаимодействовать с внешними устройствами?
Хранить скорее всего в словаре, с ключами - записями (хранящими QR код и кастомными операторами сравнения на равенство и методом получения хеш-кода), и значениями - классами хранящими информацию о кол-ве и о самом товаре.
Есть ли формула вроде RNG или способ через Seq/Where получить случайную уникальную последовательность, допустим, от 0 до 100 без повторений и без вспомогательного буфера (в данном случае, на 101 элемент)? Или хоть подскажите, что искать.
А с чего вы решили что там не будет повторяющихся чисел?
Это плохо, вероятность маленькая но всё же может сломаться, особенно если возможных значений не так много. В таких случаях всё же лучше бесконечную последовательности делать.
namespace ConsoleApplication8_Timers
{
class Program
{
static void PrintTime(object state)
{
Console.Clear();
Console.WriteLine("Текущее время: "+
DateTime.Now.ToLongTimeString());
}
static void Main()
{
// Делегат для типа Timer
TimerCallback timeCB = new TimerCallback(PrintTime);
Timer time = new Timer(timeCB, null, 0, 1000);
Console.WriteLine("Нажми чтоб выйти");
Console.ReadLine();
}
}
}
получается
uses System.Threading;
procedure PrintTime(state: object);
begin
print('Текущее время: ', DateTime.Now.ToLongTimeString());
end;
begin
// Делегат для типа Timer
var timeCB: TimerCallback = new TimerCallback(PrintTime); //ОШИБКА: нужен объект
var time: timer = new Timer(timeCB, null, 0, 1000);
Print ('Нажми чтоб выйти');
ReadLine();
end.
однако или что-то снова под вечер туплю, или же есть нюанс
TimerCallback - это тип делегата, то есть процедуры в данном случае. У него есть operator implicit как у любого другого делегата, для совместимости с другими делегатами у которых такие же параметры и возвращаемое значение:
uses System.Threading;
procedure PrintTime(state: object);
begin
print('Текущее время: ', DateTime.Now.ToLongTimeString());
end;
begin
// Делегат для типа Timer
var timeCB: TimerCallback := PrintTime;
var time: timer = new Timer(timeCB, nil, 0, 1000);//вообще, можно и саму PrintTime передавать в конструктор
Print ('Нажми чтоб выйти');
readln();
end.
Что касается конструктора - я не уверен на 100%, но поидее должно работать так:
uses System.Threading;
type
t1 = class
procedure PrintTime(state: object);
begin
print('Текущее время: ', DateTime.Now.ToLongTimeString());
end;
end;
begin
var a := new t1;
var timeCB: TimerCallback := new TimerCallback(
a,//объект для которого будет вызываться метод. Если метод статичный - передавайте nil
System.Delegate(a.PrintTime).Method.MethodHandle.Value
);
var time: timer = new Timer(timeCB, nil, 0, 1000);
Print('Нажми чтоб выйти');
readln();
end.
(Правда, сейчас получаем внутреннюю ошибку))) #1552)
Кстати, глобальные подпрограммы как в вашей программе - тоже при компиляции превращаются в статичные методы. То есть для них в качестве объекта тоже надо передавать nil.
Правда, в несколько раз медленнее… Но ведь Range(a, b) – это родной дотнетовский? Странное поведение такого распространённого генератора…Что ж, спасибо за подсказку, будем знать.
Дело не в генераторе а в том как вы его используете. Range возвращает yield последовательность, то есть чтоб вычислить её длину - надо пройтись по всем элеметам.
А .ToArray позволено пройтись по последовательности только 1 раз. То есть перед тем как он узнает сколько всего есть елементов - ему придётся куда то сохранить те элементы по которым он пройдёт. Поэтому он работает так (я декомпилировал):
Создаётся массив на 4 элемента и заполняется. Если не хватило - создаётся массив в 2 раза больше, в него копируется то что есть, предыдущий удаляется и заполнение продолжается для нового массива. Последнее повторяется пока yield последовательность не скажет что достигли последнего элемента. В самом конце создаётся ещё 1 массив, уже с нужным кол-вом элементов, и в него снова копируется то что прочитали.
Но, кстати, если на вход в .ToArray подать IList<T> последовательность (то есть любой список, массив, словарь, всё с известной длиной) - будет создан только 1 массив, нужной длины.
В общем у ленивых вычислений свои применения, а у IList<T>-ов - свои. К примеру это:
Range(1,100).Sum
Будет лучше чем это (по скорости Range может капельку медленней, а по памяти - огромное преимущество):
ArrGen(100,i->i+1).Sum
Надеюсь, понятно почему. Если нет - почитайте презентацию по ленивым вычислениям, на pascalabc.net (да название паскаля работает как ссылка). Эту презентацию создавали преподаватели с корочкой, а не самозванцы вроде меня)) Так что там должно рассказываться лучше.
Недавно пользуюсь PascalABC, но часто появляется проблема, когда выполнение программы запускается, компиляция проходит, ошибок нет, программа запущена, но фразы не выводятся в окне вывода. Выглядит это все так: