diff --git a/Configuration/GlobalAssemblyInfo.cs b/Configuration/GlobalAssemblyInfo.cs index 26e0d8256..a29e6016e 100644 --- a/Configuration/GlobalAssemblyInfo.cs +++ b/Configuration/GlobalAssemblyInfo.cs @@ -15,7 +15,7 @@ internal static class RevisionClass public const string Major = "3"; public const string Minor = "8"; public const string Build = "3"; - public const string Revision = "3159"; + public const string Revision = "3166"; public const string MainVersion = Major + "." + Minor; public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision; diff --git a/Configuration/Version.defs b/Configuration/Version.defs index fc8823cee..c266819c1 100644 --- a/Configuration/Version.defs +++ b/Configuration/Version.defs @@ -1,4 +1,4 @@ -%MINOR%=8 -%REVISION%=3159 %COREVERSION%=3 +%REVISION%=3166 +%MINOR%=8 %MAJOR%=3 diff --git a/Release/pabcversion.txt b/Release/pabcversion.txt index 074bf89e0..ad79c5767 100644 --- a/Release/pabcversion.txt +++ b/Release/pabcversion.txt @@ -1 +1 @@ -3.8.3.3159 +3.8.3.3166 diff --git a/ReleaseGenerators/PascalABCNET_version.nsh b/ReleaseGenerators/PascalABCNET_version.nsh index 91e03ee45..99b08a551 100644 --- a/ReleaseGenerators/PascalABCNET_version.nsh +++ b/ReleaseGenerators/PascalABCNET_version.nsh @@ -1 +1 @@ -!define VERSION '3.8.3.3159' +!define VERSION '3.8.3.3166' diff --git a/ReleaseGenerators/sect_Core.nsh b/ReleaseGenerators/sect_Core.nsh index eb3875fc3..640ab5078 100644 --- a/ReleaseGenerators/sect_Core.nsh +++ b/ReleaseGenerators/sect_Core.nsh @@ -26,6 +26,7 @@ File "..\bin\ControlLibrary.sdcl" File "..\bin\AvalonDock.dll" File "..\bin\Mono.Cecil.dll" + File "..\bin\TeacherControlPlugin.dll" ;File "libs\System.Core.dll" File "gacutil.exe" File "gacutil.exe.config" @@ -65,6 +66,7 @@ ${AddFile} "TreeConverter.dll" ${AddFile} "OptimizerConversion.dll" ${AddFile} "Mono.Cecil.dll" + ${AddFile} "TeacherControlPlugin.dll" ${AddFile} "License.txt" ${AddFile} "copyright.txt" ${AddFile} "pabcnetc.exe.config" diff --git a/TestSuite/CompilationSamples/SF.pas b/TestSuite/CompilationSamples/SF.pas index dc28c1215..66128aa79 100644 --- a/TestSuite/CompilationSamples/SF.pas +++ b/TestSuite/CompilationSamples/SF.pas @@ -147,6 +147,12 @@ function Dst(Self: sequence of T): sequence of T; extensionmethod := Self.Dis /// Преобразует последовательность в строку function ToS(Self: sequence of T; delim: string): string; extensionmethod := Self.JoinToString(delim); +/// Преобразует последовательность в строку +function JtS(Self: sequence of T; delim: string): string; extensionmethod := Self.JoinToString(delim); + +/// Преобразует последовательность в строку +function JtS(Self: sequence of T): string; extensionmethod := Self.JoinToString(); + /// Сливает последовательнсть строк в одну строку function Concat(Self: sequence of string): string; extensionmethod := Self.JoinToString(''); @@ -207,6 +213,9 @@ function SelM(Self: sequence of T; transform: T->sequence of T1): sequence /// Преобразует последовательность, используя функцию transform function Sel(Self: sequence of T; transform: T->T1): sequence of T1; extensionmethod := Self.Select(transform); +/// Преобразует последовательность, используя функцию transform с индексом +function Sel(Self: sequence of T; transform: (T,int)->T1): sequence of T1; extensionmethod := Self.Select(transform); + /// Создаёт словарь в ссответствии с заданными функциями проекции на ключ и значение function ToD(Self: sequence of T; keySelector: T->TKey; valueSelector: T->TValue): Dictionary; extensionmethod := Self.ToDictionary(keySelector,valueSelector); @@ -222,6 +231,9 @@ function Agr(Self: sequence of T; seed: TAcc; func: (TAcc,T)->TAcc): TAc /// Фильтрует последовательность по условию cond function Wh(Self: sequence of T; cond: T->boolean): sequence of T; extensionmethod := Self.Where(cond); +/// Фильтрует последовательность по условию cond с индексом +function Wh(Self: sequence of T; cond: (T,integer)->boolean); extensionmethod := Self.Where(cond); + /// Группирует элементы последовательности в соответствии с заданной функцией проекции на ключ группы function GrBy(Self: sequence of T; selector: T->TKey): sequence of System.Linq.IGrouping; extensionmethod := Self.GroupBy(selector); diff --git a/VisualPlugins/TraningControlPlugin/TeacherControlPlugin.cs b/VisualPlugins/TraningControlPlugin/TeacherControlPlugin.cs index 055c4c13f..eadf2cdfd 100644 --- a/VisualPlugins/TraningControlPlugin/TeacherControlPlugin.cs +++ b/VisualPlugins/TraningControlPlugin/TeacherControlPlugin.cs @@ -192,9 +192,11 @@ namespace VisualPascalABCPlugins // При запуске кнопки плагина показываются // Дома: всегда у тех, у кого установлен плагин // Мехмат: при наличии lightpt в текущей папке или при наличии auth.dat в корне сетевого диска !!! - if (!IsMechmath) // дома - всегда - InitItems(MenuItems, ToolBarItems); - else // это мехмат + //if (!IsMechmath) // дома - всегда + // InitItems(MenuItems, ToolBarItems); + //else // это мехмат + + // SSM 20/06/22 Решил включить плагин в инсталлят и показывать кнопки только если есть lightpt.dat в текущем или auth.dat в корне сетевого { if (IsLightPTInWorkingDirectiry()) // если lightpt.dat существует в текущем InitItems(MenuItems, ToolBarItems); @@ -211,7 +213,7 @@ namespace VisualPascalABCPlugins { if (Item == null) // Если не показали кнопки, то нет смысла в дальнейших действиях - плагин неактивен { - AddMessage("Плагин Teacher Control отключён. Не выполнено условие LightPTExists || AuthExists"); + AddMessage("TeacherControlPlugin deactivated"); // Не выполнено условие LightPTExists || AuthExists return; } menuItem = (ToolStripMenuItem)Item.menuItem; diff --git a/bin/Lib/LightPT.pas b/bin/Lib/LightPT.pas index 7a167d82e..5d657e871 100644 --- a/bin/Lib/LightPT.pas +++ b/bin/Lib/LightPT.pas @@ -5,6 +5,9 @@ unit LightPT; {$reference System.Management.dll} uses __RedirectIOMode; +// Любые существенные изменения в этом модуле влияют на все Tasks, составленные всеми. +// Они перестанут компилироваться, что плохо !!! + uses System.Management; uses System.Security.Cryptography; uses System.IO; @@ -24,7 +27,7 @@ const lightptname = 'lightpt.dat'; type MessageColorT = (MsgColorGreen, MsgColorRed, MsgColorOrange, MsgColorMagenta, MsgColorGray); - TaskStatus = (Solved, IOError, BadSolution, PartialSolution, InitialTask, BadInitialTask, NotUnderControl, InitialTaskPT4, ErrFix, Demo); // Короткий результат для БД + TaskStatus = (NotUnderControl, Solved, IOError, BadSolution, PartialSolution, InitialTask, BadInitialTask, InitialTaskPT4, ErrFix, Demo); // Короткий результат для БД type PTException = class(Exception) @@ -159,6 +162,8 @@ type function AddRange(sq: sequence of string): ObjectList; begin lst.AddRange(sq.Select(x -> object(x))); Result := Self end; function AddRange(sq: sequence of char): ObjectList; begin lst.AddRange(sq.Select(x -> object(x))); Result := Self end; function AddRange(sq: sequence of boolean): ObjectList; begin lst.AddRange(sq.Select(x -> object(x))); Result := Self end; + function AddRange(sq: sequence of object): ObjectList; begin lst.AddRange(sq); Result := Self end; + function AddRange(sq: sequence of System.Type): ObjectList; begin lst.AddRange(sq.Select(x -> object(x))); Result := Self end; function AddFill(n: integer; elem: object): ObjectList; begin lst.AddRange(ArrFill(n,elem)); Result := Self end; function AddArithm(n: integer; a0,step: integer): ObjectList; begin lst.AddRange(ArrGen(n,a0,x->x+step).Select(x -> object(x))); Result := Self end; function AddArithm(n: integer; a0,step: real): ObjectList; begin lst.AddRange(ArrGen(n,a0,x->x+step).Select(x -> object(x))); Result := Self end; @@ -323,6 +328,7 @@ begin TaskResult := InitialTask; end; +// По сути отдельные функции - это неправильно. Необходим CheckInitialInputOutput procedure CheckInitialOutput(params a: array of object); begin InitialOutput(a); @@ -460,6 +466,13 @@ begin InputList.Add(Result); end; +function Random(a, b: char): char; +begin + Result := PABCSystem.Random(a, b); + if IsPT then exit; + InputList.Add(Result); +end; + function Random2(a, b: integer): (integer, integer); begin Result := PABCSystem.Random2(a, b); @@ -476,6 +489,58 @@ begin InputList.Add(Result[1]); end; +function Random2(a, b: char): (char, char); +begin + Result := PABCSystem.Random2(a, b); + if IsPT then exit; + InputList.Add(Result); +end; + +function Random3(a, b: integer): (integer, integer, integer); +begin + Result := PABCSystem.Random3(a, b); + if IsPT then exit; + InputList.Add(Result[0]); + InputList.Add(Result[1]); + InputList.Add(Result[2]); +end; + +function Random3(a, b: real): (real, real, real); +begin + Result := PABCSystem.Random3(a, b); + if IsPT then exit; + InputList.Add(Result[0]); + InputList.Add(Result[1]); + InputList.Add(Result[2]); +end; + +function Random3(a, b: char): (char, char, char); +begin + Result := PABCSystem.Random3(a, b); + if IsPT then exit; + InputList.Add(Result[0]); + InputList.Add(Result[1]); + InputList.Add(Result[2]); +end; + +/// Возвращает массив размера n, заполненный случайными целыми значениями +function ArrRandomInteger(n: integer; a: integer; b: integer): array of integer; +begin + Result := PABCSystem.ArrRandomInteger(n, a, b); + if IsPT then exit; + for var i:=0 to n-1 do + InputList.Add(Result[i]); +end; + +/// Возвращает массив размера n, заполненный случайными вещественными значениями +function ArrRandomReal(n: integer; a: real; b: real): array of real; +begin + Result := PABCSystem.ArrRandomReal(n, a, b); + if IsPT then exit; + for var i:=0 to n-1 do + InputList.Add(Result[i]); +end; + function ReadString: string; begin Result := PABCSystem.ReadString; @@ -508,7 +573,6 @@ begin DoNewLineBeforeMessage := False; end; - procedure Print(params args: array of object); begin foreach var ob in args do @@ -711,7 +775,7 @@ begin TaskResult := Solved; // Несоответствие типов for var i := 0 to mn - 1 do - begin + begin if (a[i].GetType.Name = 'RuntimeType') and (a[i] <> OutputList[i].GetType) then raise new OutputTypeException(i + 1, TypeToTypeName(a[i] as System.Type), TypeName(OutputList[i])) else if (a[i].GetType.Name <> 'RuntimeType') and (a[i].GetType <> OutputList[i].GetType) then @@ -731,6 +795,17 @@ begin end; end; +/// Не меняет TaskResult если типы правильные +procedure CheckInputTypes(a: array of System.Type); +begin + // Несоответствие количества вводимых параметров + if a.Length <> InputList.Count then + raise new InputCountException(InputList.Count, a.Length); + for var i := 0 to a.Length - 1 do + if a[i] <> InputList[i].GetType then + raise new InputTypeException(i + 1, TypeToTypeName(a[i]), TypeName(InputList[i])); +end; + procedure CheckOutputSeq(a: sequence of integer) := CheckOutput(ToObjArray(a.ToArray)); procedure CheckOutputSeq(a: sequence of real) := CheckOutput(ToObjArray(a.ToArray)); @@ -752,7 +827,7 @@ end; procedure FilterOnlyNumbers; begin - OutputList := OutputList.Where(x -> (x is integer) or (x is real)).ToList; + OutputList := OutputList.Where(x -> (x is integer) or (x is real) or (x is int64)).ToList; end; function MsgColorCode(color: MessageColorT): char; @@ -1130,8 +1205,15 @@ begin // Есть проблема паузы при плохой сети WriteInfoToRemoteDatabase(auth,LessonName,TaskName,TaskResult.ToString, AdditionalInfo); except + on e: System.AggregateException do + begin + foreach var x in e.InnerExceptions do + if x is HTTPRequestException then + ColoredMessage(x.InnerException?.Message??'',MsgColorGray) + else ColoredMessage(x.Message,MsgColorGray); + end; on e: Exception do - Console.WriteLine(e.Message); + ColoredMessage(e.Message,MsgColorGray); end; end; diff --git a/bin/Lib/SF.pas b/bin/Lib/SF.pas index dc28c1215..66128aa79 100644 --- a/bin/Lib/SF.pas +++ b/bin/Lib/SF.pas @@ -147,6 +147,12 @@ function Dst(Self: sequence of T): sequence of T; extensionmethod := Self.Dis /// Преобразует последовательность в строку function ToS(Self: sequence of T; delim: string): string; extensionmethod := Self.JoinToString(delim); +/// Преобразует последовательность в строку +function JtS(Self: sequence of T; delim: string): string; extensionmethod := Self.JoinToString(delim); + +/// Преобразует последовательность в строку +function JtS(Self: sequence of T): string; extensionmethod := Self.JoinToString(); + /// Сливает последовательнсть строк в одну строку function Concat(Self: sequence of string): string; extensionmethod := Self.JoinToString(''); @@ -207,6 +213,9 @@ function SelM(Self: sequence of T; transform: T->sequence of T1): sequence /// Преобразует последовательность, используя функцию transform function Sel(Self: sequence of T; transform: T->T1): sequence of T1; extensionmethod := Self.Select(transform); +/// Преобразует последовательность, используя функцию transform с индексом +function Sel(Self: sequence of T; transform: (T,int)->T1): sequence of T1; extensionmethod := Self.Select(transform); + /// Создаёт словарь в ссответствии с заданными функциями проекции на ключ и значение function ToD(Self: sequence of T; keySelector: T->TKey; valueSelector: T->TValue): Dictionary; extensionmethod := Self.ToDictionary(keySelector,valueSelector); @@ -222,6 +231,9 @@ function Agr(Self: sequence of T; seed: TAcc; func: (TAcc,T)->TAcc): TAc /// Фильтрует последовательность по условию cond function Wh(Self: sequence of T; cond: T->boolean): sequence of T; extensionmethod := Self.Where(cond); +/// Фильтрует последовательность по условию cond с индексом +function Wh(Self: sequence of T; cond: (T,integer)->boolean); extensionmethod := Self.Where(cond); + /// Группирует элементы последовательности в соответствии с заданной функцией проекции на ключ группы function GrBy(Self: sequence of T; selector: T->TKey): sequence of System.Linq.IGrouping; extensionmethod := Self.GroupBy(selector); diff --git a/bin/Lib/XLSX.pas b/bin/Lib/XLSX.pas index a89a5f992..efd38bd15 100644 --- a/bin/Lib/XLSX.pas +++ b/bin/Lib/XLSX.pas @@ -3,6 +3,7 @@ interface function ReadXLSX(fileName: string): Dictionary; +function ReadXlsxAsInts(fileName: string; sheetNum: integer := 0): array of array of integer; function ToDate(Self: string): DateTime; implementation @@ -25,7 +26,7 @@ begin Result := DateTime.Parse(Self); end; -function ToCR(Self: string):(integer,integer); extensionmethod; // 'AA7' -> (6,26) +function ToCR(Self: string): (integer,integer); extensionmethod; // 'AA7' -> (6,26) begin var clm := 0; var row := 0; @@ -68,8 +69,15 @@ begin end; LU := (l, u); RD := (r, d); - end else // готовые габариты из таблицы - (LU, RD) := dim.GetAttribute('ref').Split(':').Sel(s -> s.ToCR); + end else begin // готовые габариты из таблицы + var ref := dim.GetAttribute('ref'); + if ':' in ref then + (LU, RD) := ref.Split(':').Sel(s -> s.ToCR) + else begin + RD := ref.ToCR; + LU := RD; + end; + end; var (w, h) := (RD[1] - LU[1] + 1, RD[0] - LU[0] + 1); var sheet: array of array of string; @@ -135,4 +143,7 @@ begin end; end; +function ReadXlsxAsInts(fileName: string; sheetNum: integer) + := ReadXLSX(fileName).Values.Skip(sheetNum).First.Select(r->r.Select(c->c.ToInteger).ToArray).ToArray; + end. \ No newline at end of file