PascalABC.NET официальный канал
Відкрити в Telegram
Официальный канал языка и системы программирования PascalABC.NET
Показати більше1 864
Підписники
-624 години
-57 днів
-2330 днів
Архів дописів
RayTracer, поправленный ИИ
Давний пример, публиковался здесь.
Попросил ИИ его ускорить. Ускорил в 10 раз
https://gist.github.com/miks1965/592a9ee7a812cafa89dde0440b8ee9a3
Сейчас эта сцена рендерится за 0.3 сек.
Чтож, спасибо, Claude!
Расширение PascalABC.NET для VS Code на Mac — работает! 🍎
Доступна версия 0.5.1 расширения PascalABC.NET для Visual Studio Code.
На macOS уже работают:
✅ запуск программ
✅ подсветка синтаксиса
✅ IntelliSense — автодополнение и информация о символах
Скачать расширение можно здесь:
https://pascalabc.net/vscode/
PascalABC․NET + VS Code + .NET 10
В PascalABC․NET 4.0 появился официальный плагин для Visual Studio Code.
Он поддерживает:
◉ компиляцию и запуск программ;
◉ IntelliSense;
◉ диагностику ошибок;
◉ подсказки типов и параметров;
◉ .NET Framework 4.8 и .NET 10.
С .NET 10 PascalABC․NET можно использовать в VS Code на Windows, Linux и macOS.
На скриншоте — PascalABC․NET в VS Code с работающим IntelliSense и запуском программы под .NET 10.
🚀 Предварительная версия PascalABC․NET 4.0.1 уже доступна
На странице скачивания PascalABC․NET появился новый раздел — «Предварительная версия». Сейчас в нём доступна PascalABC․NET 4.0.1 Beta. Именно эта версия будет постепенно накапливать новые возможности и последние исправления.
По мере готовности она станет основной версией PascalABC․NET, а пока её можно использовать для знакомства с нововведениями и тестирования.
Сейчас доступны:
— StandardPack 4.0.1 Beta
— консольный компилятор 4.0.1 Beta для .NET 10
— список изменений в 4.0.1
Скачать предварительную версию:
https://pascalabc.net/ssyilki-dlya-skachivaniya/
🎓 ML PascalABC․NET — машинное обучение без внешних зависимостей
Одно из главных нововведений PascalABC.NET 4.0 — новая библиотека ML PascalABC․NET.
Это уже не набор отдельных учебных алгоритмов, а целостная библиотека для анализа данных и классического машинного обучения.
В ней есть всё необходимое для полного ML-процесса:
● работа с табличными данными (
DataFrame), статистика и визуализация
● подготовка признаков: пропуски, кодирование категорий, масштабирование
● классификация и регрессия: Logistic Regression, kNN, Decision Tree, Random Forest, Gradient Boosting
● кластеризация: KMeans и DBSCAN
● метрики, разбиение выборок и кросс-валидация
● ML-конвейеры для объединения подготовки данных и моделей
● встроенные датасеты для обучения и экспериментов
API библиотеки построен вокруг привычной современной схемы Fit / Transform / Predict. По организации работы и удобству программирования ML PascalABC.NET следует подходам scikit-learn, оставаясь при этом нативной библиотекой PascalABC․NET.
И принципиальный момент — никаких внешних зависимостей. DataFrame, линейная алгебра, модели, препроцессинг, метрики и валидация реализованы непосредственно в экосистеме PascalABC․NET.
Мы подготовили отдельный сайт с документацией, обучающими материалами и примерами:
ML PascalABC.NET — документация и обучение
Если вы хотите познакомиться с машинным обучением на PascalABC․NET, теперь для этого есть полноценная среда — от загрузки и подготовки данных до обучения модели и оценки её качества.🎓 С Днём знаний!
Поздравляем всех подписчиков канала PascalABC․NET с началом нового учебного года! К 1 сентября у PascalABC․NET сразу несколько важных обновлений.
Новый сайт pascalabc.net.
Современный дизайн, новая структура и удобный доступ к материалам о системе, документации и обучении.
Заходите, смотрите и делитесь впечатлениями в комментариях!
PascalABC․NET 4.0.
● В новой версии появилась собственная библиотека ML PascalABC․NET для машинного обучения — без внешних зависимостей. Теперь задачи анализа данных и классического машинного обучения можно решать средствами самого PascalABC․NET.
● Ещё одно важное обновление — компилятор для .NET 10.0.
С 1 сентября! Успешного и интересного учебного года!
У официального канала PascalABC.NET появилось зеркало в MAX:
https://max.ru/channel_pabc_official
Оба канала заработают полным ходом с сентября.
Появилась также группа для обсуждения в MAX вот с такой красивой пригласительной ссылкой
https://max.ru/join/D28ks-E4Olzc7BN7mVlAqhNr-NXbgijzaRnGNQ9FXZQ
Она также полноценно заработает с сентября. Кому удобнее обсуждать в MAX - присоединяйтесь!
Вычисление выражений с помощью Eval
В модуле Utils появилась стандартная функция Eval позволяющая вычислять арифметические выражения, заданные в виде строки
Выражение например можно ввести с клавиатуры
uses Utils;
begin
Println(Eval('2 + 3 * 4'));
Println(Eval('(2.4 + 3 % 2) * 6 - 1'));
Println(Eval('(5 > 3) and (2 < 4)'));
Println(Eval('IIF(17 % 2 = 0, ''even'', ''odd'')'));
Println(Eval('Len(''PascalABC.NET'')'));
var i := EvalInt('2 + 3');
var x := EvalReal('10 / 4.0');
var b := EvalBool('(10 >= 5) and (3 <> 4)');
var s := EvalStr('''PascalABC'' + ''.NET''');
Println(i, x, b, s)
end.Запомним этот день и час
Все тесты под .NET 10 прошли. Консольный компилятор работает!
01.08.2026 г.
21.54
Понятно из-за чего - двумерные Generic-массивы.
Попросил Codex разобраться.
И тут - произошла потрясающая вещь!
Codex нашел ошибку не в PascalABC.NET, а в Runtime .Net 9.0!
Причем, Codex сам проверил, что на компьютере установлен Runtime .NET 10.0, откомпилировал пример под ней и убедился, что он работает!
Программист пытался бы исправить ошибку, предполагая что она внутри PascalABC.NET, потратив на это безрезультатно неопределенное время...
Даже не знаю, что еще говорить... Одни эмоции )
Нет, знаю :)
Следующим запросом я попросил перевести весь проект под .NET 10.0. Codex любезно согласился, попросил сделать коммит на Github от греха, пошуршал, ответил вот это:
===============================
Проект переведён на .NET 10.
Изменено:
целевая платформа, каталог
bin\net10 и символ NET10_0 в [Directory.Build.props (line 5)](D:/PABC_Console_Git_NET9/Directory.Build.props:5);
автоматическое копирование Lib, Lng, Ico и Highlighting из bin\shared;
генерируемые runtimeconfig.json теперь используют .NET 10 в [NETGenerator.cs (line 205)](D:/PABC_Console_Git_NET9/src/NETGenerator/NETGenerator.cs:205);
исправлено падение MarkSequencePoint без отладочного документа в [NETGenerator.cs (line 319)](D:/PABC_Console_Git_NET9/src/NETGenerator/NETGenerator.cs:319);
TestRunner переключён на bin\net10 в [runtests.bat (line 1)](D:/PABC_Console_Git_NET9/TestSuite/runtests.bat:1);
обновлён README.
===================
То есть сделал больше чем от него ожидалось - не только перевел проект под .NET 10, но и автоматически создал для него папку, нашел на компьютере и скопировал дополнительные файлы, необходимые для запуска, проверил, что запускаются старые тесты, исправил за компанию еще одну ошибку с MarkSequencePoint, обновил ReadMe где упоминалось что используется .NET 9, и порекомендовал установить VS 2026.
Уф...
Ощущения - Codex-агент - это такой джинн из бутылки, который является опытным программистом и за токены делает крайне нетривиальные действия и дает советы.
Что ж - пишите комментарии!PascalABC.NET под net 9 и Codex
Как знают читатели нашего канала, мы давно пытаемся перевести консольный компилятор PascalABC.NET с .NET Framework под современный .NET.
С версии .NET 9.0 это стало возможно - появилась возможность генерировать сборку и сохранять ее на диск.
Примерно год назад нам удалось создать компилирующийся проект консольного компилятора - в нем проходило примерно 95% наших тестов.
Но некоторые тесты падали из-за различий в NET Framework и .NET 9.0.
Этот год мы собирались с духом чтобы начать их исправлять.
И вот - возникла идея загрузить проект в Codex и пообщаться с ним, как можно исправить некоторые ошибки.
В этом посте делюсь, как была исправлена одна.
Вот этот код
type
Days = (Mon,Tue,Wed,Thi,Fri,Sat);
begin
var ld := new List<Days>;
end.
падал на строке
il.Emit(OpCodes.Newobj, cnstr);которая генерировала IL код вызова конструктора List. Понятно, что дело именно в нашем пользовательском типе enum Days, потому что на других типах всё работает. И вот - вишенка на торте - проект загружен в Codex и после пары запросов с просьбой исследовать проект и главный файл генерации IL-кода я загрузил код падающего теста и задал вопрос, можно ли исправить ошибку. Полминуты. Да-да, CODEX думал ровно полминуты. И затем выдал: Ошибка исправлена в NETGenerator.cs (line 2665) Всё! Ошеломленный, я пообщался еще с Codex о причине ошибки: Но
PersistedAssemblyBuilder в .NET 9 при выполнении:
il.Emit(OpCodes.Newobj, cnstr);пытается найти исходное metadata-определение
.ctor. Для generic-типа с аргументом EnumBuilder он этого сделать не может и выдаёт:
A MemberInfo that matches '.ctor' could not be foundПри этом внутри
EnumBuilder уже существует настоящий TypeBuilder, описывающий создаваемое перечисление. Исправление состоит в том, чтобы при формировании generic-типа передавать именно его.
Но - основная интрига прямо сейчас.
Год - страх человека исправить непростую ошибку из за отсутствия отсутствие нормальной документации.
И полминуты на исправление ошибки ИИ-агентом.📌 ЕГЭ по информатике: задача №3 в новой версии PascalABC.NET
В преддверии ЕГЭ по информатике покажем, как можно решать задачу №3 из демо варианта с помощью новых возможностей PascalABC.NET.
Задача №3 обычно связана с поиском данных в таблицах: нужно объединить несколько листов, отфильтровать строки по условиям и посчитать итоговую величину.
В новой версии PascalABC.NET это можно сделать в стиле современных инструментов анализа данных — через
DataFrame.
uses MLABC;
begin
var movement := DataFrame.FromODS('DEMO_3.ods', 'Движение_товаров');
var goods := DataFrame.FromODS('DEMO_3.ods', 'Товар');
var shops := DataFrame.FromODS('DEMO_3.ods', 'Магазин');
var d1 := new DateTime(2024, 10, 5);
var d2 := new DateTime(2024, 10, 14);
var df := movement
.Join(goods, 'Артикул')
.Join(shops, 'ID магазина');
var answer :=
df.Filter(r ->
(r['Наименование товара'] = 'Варенец термостатный') and
(r['Район'] = 'Нагорный') and
(r['Тип операции'] = 'Продажа') and
(r['Дата'] >= d1) and
(r['Дата'] <= d2)
)
.Sum(r ->
r['Количество упаковок, шт'] *
r['Цена за упаковку']
);
Println(answer);
end.
Что здесь происходит:
1️⃣ Загружаем три таблицы из ODS-файла: движение товаров, список товаров и список магазинов.
2️⃣ Объединяем таблицы:
movement .Join(goods, 'Артикул') .Join(shops, 'ID магазина')После этого в одной таблице оказываются и данные о продажах, и названия товаров, и районы магазинов. 3️⃣ Фильтруем только нужные строки: товар —
Варенец термостатный;
район — Нагорный;
операция — Продажа;
дата — с 5 по 14 октября 2024 года включительно.
4️⃣ Считаем итоговую сумму продаж:
Количество упаковок * Цена за упаковкуи суммируем по всем найденным строкам. Такой код хорошо показывает, что PascalABC.NET развивается не только как учебный язык программирования, но и как удобная среда для работы с таблицами, данными и задачами анализа информации. Задача №3 ЕГЭ становится не набором ручных действий в электронных таблицах, а понятной программой: загрузили данные, объединили таблицы, отфильтровали, посчитали ответ. 🚀 PascalABC.NET — современное программирование для школы, ЕГЭ и реальных задач анализа данных. Скачайте последнюю версию!
В DataFrameABC появился тип DateTime
В табличных данных часто встречаются столбцы с датами: дата регистрации, время создания заказа, момент события в логе и т.д.
Теперь в DataFrameABC для таких данных есть отдельный тип столбца:
ColumnType.ctDateTimeЭто значит, что дату и время можно хранить не как строку, а как полноценное значение
DateTime.
uses MLABC;
begin
var text := '''
id,created_at,name
1,2024-01-15,Alice
2,2024-01-16 12:30:00,Bob
''';
var schema := new Dictionary<string, ColumnType>;
schema['created_at'] := ColumnType.ctDateTime;
var df1 := CsvLoader.LoadFromLines(
text.ToLines,
schema := schema
);
Println('Явная схема:');
df1.Print;
Println(df1.DateTime('created_at')[0].Year);
var df2 := CsvLoader.LoadFromLines(
text.ToLines,
inferTypes := True
);
Println;
Println('Автоопределение:');
df2.Print(dateTimeFormat := 'dd.MM.yy');
Println(df2.GetColumnType('created_at'));
end.
В первом случае тип столбца задаётся явно через схему:
schema['created_at'] := ColumnType.ctDateTime;После этого к значениям можно обращаться как к
DateTime:
df1.DateTime('created_at')[0].Year
Во втором случае используется автоопределение типов:
inferTypes := True
CsvLoader сам распознаёт столбец created_at как дату и время.
При выводе можно задать формат отображения:
df2.Print(dateTimeFormat := 'dd.MM.yy');Тип
DateTime делает работу с временными данными в DataFrameABC более естественной: даты больше не нужно хранить как обычные строки, а значит, их можно корректно обрабатывать, форматировать и использовать дальше при подготовке данных для анализа и машинного обучения.7 июня на мехмате ЮФУ состоялось награждение победителей и призёров олимпиады PascalABC.NET 2026.
Поздравляем всех участников, победителей и призёров!
Для школьников 10–11 классов эта олимпиада имеет и практическое значение: победители и призёры, поступающие на мехмат ЮФУ, получат дополнительно 10 баллов к суммарному баллу ЕГЭ.
Отдельно отметим, что ряд задач был специально ориентирован на лаконичные решения на PascalABC.NET. Многие участники успешно воспользовались выразительными возможностями языка и показали, что короткая программа вполне может быть точной, понятной и эффективной.
Желаем ребятам дальнейших успехов в программировании и ждём новых участников в следующем году!
Конкатенация DataFrame-ов в MLABC
uses MLABC;
begin
var df1 := DataFrame.FromCsvText('''
id,name,age
1,Ann,10
2,Bob,12
''');
var df2 := DataFrame.FromCsvText('''
id,name,age
3,Cat,11
4,Dan,13
''');
var df := DataFrame.Concat(df1, df2);
df.Print;
end.
Результат
┌────┬──────┬─────┐ │ id │ name │ age │ ├────┼──────┼─────┤ │ 1 │ Ann │ 10 │ │ 2 │ Bob │ 12 │ │ 3 │ Cat │ 11 │ │ 4 │ Dan │ 13 │ └────┴──────┴─────┘
DataFrame.Concat выполняет вертикальную конкатенацию датафреймов с обязательной проверкой схемы.
Проверяются:
- количество столбцов;
- имена столбцов;
- порядок столбцов;
- типы данных.
Если схемы несовместимы — будет сгенерировано исключение. Это защищает от случайного объединения несовместимых таблиц и делает работу с данными более предсказуемой и безопасной.
Всё как в pandas только лучше :)Олимпиада PascalABC.NET 2026
16 мая прошла олимпиада по программированию Мехмат - PascalABC.NET 2026
В ней приняло участие 49 школьников Ростова и области
Приводим задачу C1 и ее решение
begin
var words := ReadString.ToWords;
Print(words.GroupBy(w -> w.Order.JoinToString).Max(g -> g.Count));
end.Простой текстовый редактор в GraphWPF
uses GraphWPF;
var (x,y) := (0.0,0.0);
procedure KeyPress(c: char);
begin
if c = ' ' then
c := Chr($A0);
TextOut(x,y,c);
x += TextWidth(c);
end;
procedure KeyDown(k: Key);
begin
case k of
Key.Enter: begin
x := 0;
y += TextHeight('q');
end;
Key.Back: if x > 0 then
begin
x -= TextWidth('n');
FillRectangle(x,y,TextWidth('n'),TextHeight('n'));
end;
end;
end;
begin
Font.Size := 20;
Font.Name := 'Consolas';
OnKeyPress := KeyPress;
OnKeyDown := KeyDown;
end.
Демонстрация событий клавиатуры в GraphWPF для создания игрушечного текстового редактора.
Можно набирать текст, стирать последний символ, используя BackSpace, и переходить на следующую строкуТабличная предобработка: Imputer и OrdinalEncoder
Один из важных этапов работы с табличными данными — предобработка: заполнение пропусков, кодирование категориальных признаков, масштабирование числовых данных и другие преобразования.
Пример: сначала заполним пропуск в числовом столбце
population средним значением, а затем закодируем категориальный столбец region числами.
uses MLABC;
begin
var df := DataFrame.FromCsvText('''
city,population,region
Ростов-на-Дону,1142,Юг
Таганрог,NA,Юг
Воронеж,1058,Центр
Курск,452,Центр
Белгород,392,Центр
''');
Println('Исходные данные:');
df.Print;
Println;
// Заполняем пропуск в числовом столбце средним значением
var imputer := new Imputer(['population']);
df := imputer.FitTransform(df);
// Кодируем названия регионов числами 0, 1, 2, ...
var encoder := new OrdinalEncoder('region');
df := encoder.FitTransform(df);
Println('После Imputer и OrdinalEncoder:');
df.Print;
end.
Вывод:
Исходные данные:
city population region
Ростов-на-Дону 1142 Юг
Таганрог NA Юг
Воронеж 1058 Центр
Курск 452 Центр
Белгород 392 Центр
После Imputer и OrdinalEncoder:
city population region
Ростов-на-Дону 1142.00 0
Таганрог 761.00 0
Воронеж 1058.00 1
Курск 452.00 1
Белгород 392.00 1
Imputer анализирует данные на этапе Fit и запоминает значение, которым нужно заменить пропуски. В данном примере для столбца population используется среднее значение.
OrdinalEncoder преобразует строковые категории в числовые коды: разные значения столбца region получают номера 0, 1, 2, ...
Такой подход реализует привычную для ML-библиотек схему Fit/Transform: сначала объект настраивается по данным, затем применяет преобразование к таблице.
#MLABCТабличная предобработка: Imputer и OrdinalEncoder
Один из важных этапов работы с табличными данными — предобработка: заполнение пропусков, кодирование категориальных признаков, масштабирование числовых данных и другие преобразования.
Пример: сначала заполним пропуск в числовом столбце
population средним значением, а затем закодируем категориальный столбец region числами.
uses MLABC;
begin
var df := DataFrame.FromCsvText('''
city,population,region
Ростов-на-Дону,1142,Юг
Таганрог,NA,Юг
Воронеж,1058,Центр
Курск,452,Центр
Белгород,392,Центр
''');
Println('Исходные данные:');
df.Print;
Println;
// Заполняем пропуск в числовом столбце средним значением
var imputer := new Imputer(['population']);
df := imputer.FitTransform(df);
// Кодируем названия регионов числами 0, 1, 2, ...
var encoder := new OrdinalEncoder('region');
df := encoder.FitTransform(df);
Println('После Imputer и OrdinalEncoder:');
df.Print;
end.
Вывод:
Исходные данные:
city population region
Ростов-на-Дону 1142 Юг
Таганрог NA Юг
Воронеж 1058 Центр
Курск 452 Центр
Белгород 392 Центр
После Imputer и OrdinalEncoder:
city population region
Ростов-на-Дону 1142.00 0
Таганрог 761.00 0
Воронеж 1058.00 1
Курск 452.00 1
Белгород 392.00 1
Imputer анализирует данные на этапе Fit и запоминает значение, которым нужно заменить пропуски. В данном примере для столбца population используется среднее значение.
OrdinalEncoder преобразует строковые категории в числовые коды: разные значения столбца region получают номера 0, 1, 2, ...
Такой подход реализует привычную для ML-библиотек схему Fit/Transform: сначала объект настраивается по данным, затем применяет преобразование к таблице.Не надо слов, не надо паники
(это мой последний день на Титанике 🚢)
В новой библиотеке ML для PascalABC.NET появился встроенный датасет TitanicRu — классическая задача бинарной классификации: предсказать, выжил пассажир или нет.
Причём поля датасета уже русифицированы:
●
Возраст
● Пол
● Класс
● ЦенаБилета
● ПортПосадки
● Выжил
и т.д.
Ниже — полный пример ML pipeline:
● загрузка датасета,
● обработка пропусков,
● кодирование категориальных признаков,
● разделение train/test,
● нормализация,
● обучение моделей,
● сравнение качества.
uses MLABC;
begin
var ds := Datasets.TitanicRu;
var df := ds.Data.Drop(['Id', 'Имя']);
// Заполняем пропуски
var ageImputer := new Imputer(['Возраст']);
df := ageImputer.FitTransform(df);
var portImputer := new Imputer('Саутгемптон', ['ПортПосадки']);
df := portImputer.FitTransform(df);
// Кодируем категориальные признаки числами.
var sexEncoder := new LabelEncoder('Пол');
df := sexEncoder.FitTransform(df);
var portEncoder := new LabelEncoder('ПортПосадки');
df := portEncoder.FitTransform(df);
var features := ['Класс', 'Пол', 'Возраст', 'БратьяИСупруги',
'РодителиИДети', 'ЦенаБилета', 'ПортПосадки'];
var X := df.ToMatrix(features);
var y := df.GetIntColumn('Выжил');
var (Xtrain, Xtest, ytrain, ytest) :=
Validation.TrainTestSplit(X, y, testRatio := 0.2, seed := 42);
var scaler := new StandardScaler;
scaler.Fit(Xtrain);
var XtrainScaled := scaler.Transform(Xtrain);
var XtestScaled := scaler.Transform(Xtest);
var lr := new LogisticRegression(
learningRate := 0.01,
epochs := 2000
);
lr.Fit(XtrainScaled, ytrain);
var predLR := lr.Predict(XtestScaled);
var tree := new DecisionTreeClassifier(
maxDepth := 5,
minSamplesLeaf := 3,
minSamplesSplit := 6
);
tree.Fit(Xtrain, ytrain);
var predTree := tree.Predict(Xtest);
var forest := new RandomForestClassifier(
nTrees := 100,
maxDepth := 6,
minSamplesLeaf := 3,
minSamplesSplit := 6
);
forest.Fit(Xtrain, ytrain);
var predForest := forest.Predict(Xtest);
Println('Сравнение моделей на TitanicRu');
Println($'LogisticRegression: Accuracy = {Metrics.Accuracy(ytest, predLR):F3}');
Println($'DecisionTreeClassifier: Accuracy = {Metrics.Accuracy(ytest, predTree):F3}');
Println($'RandomForestClassifier: Accuracy = {Metrics.Accuracy(ytest, predForest):F3}');
end.
Типичный результат:
LogisticRegression: Accuracy = 0.787
DecisionTreeClassifier: Accuracy = 0.809
RandomForestClassifier: Accuracy = 0.831
Получается практически sklearn-style ML прямо в PascalABC.NET:
● Imputer
● LabelEncoder
● StandardScaler
● TrainTestSplit
● LogisticRegression
● DecisionTreeClassifier
● RandomForestClassifier
● Metrics.Accuracy
без внешних зависимостей и с полностью типизированным API.