Опубликованы конспекты лекций по курсу Основы программирования (сен-дек 2017)
https://drive.google.com/file/d/1bmzWPX5PFwoUwJXYAlDVK-Ri7AnhFeBj/view?usp=sharing
Огромное спасибо Ломакиной Евгении!
Опубликованы конспекты лекций по курсу Основы программирования (сен-дек 2017)
https://drive.google.com/file/d/1bmzWPX5PFwoUwJXYAlDVK-Ri7AnhFeBj/view?usp=sharing
Огромное спасибо Ломакиной Евгении!
Опубликована программа курса Основы программирования для подготовки к экзамену
https://drive.google.com/file/d/1AoXj7LLErlURN01cKT7U4ZBpkGoqf13H/view?usp=sharing
Станислав Станиславович, подскажите, пожалуйста, почему тип предиката, объявленный в библиотеке, не виден в основной программе? На лекции мы разбирали такой пример, относящийся к 54 вопросу экзаменационной программы:
library MyLib;
procedure p := Print(1);
function add(a, b: real) := a + b;
type
  IntPredicate = integer->boolean;
end.
{$reference MyLib.dll}
begin
  p;
  println;
  print(Add(7, 333));
  var f: IntPredicate;
  f := x -> x < 5;
  if f(2) then 
    print('<5');
end.
При компилировании основной программы возникает ошибка:
Неизвестное имя 'IntPredicate', при этом подпрограммы библиотеки (p и add) работают нормально.
Хороший вопрос. Синонимы типов не сохраняются в dll, потому что в .NET для них нет никаких сущностей. Поэтому это можно считать особенностью PascalABC.NET
Станислав Станиславович,как правильно реализовать печать последовательности? Нужен ли для этого оператор yield?
Дело в том, что тот вариант, который мы писали на лекции ничего не печатает. А если попытаться взять напечатанные элементы и еще раз их напечатать, то получится что-то странное.
///Метод взятия первых n элементов последовательности 
function Take<T>(seq: sequence of T; n: integer): sequence of T;
begin
  var c := 0;
  foreach var x in seq do
  begin
    yield x;
    c += 1;
    if c = n then 
      exit
  end
end;
///Метод печати элементов последовательности 
function MyPrint<T>(seq: sequence of T): sequence of T;
begin
  foreach var x in seq do 
  begin
    print(x);
    yield x
  end
end;
begin
  var q := Seq(5, 6, -5, 1, 2, 3, 4, 7, 8, 9, -11);
  
  MyPrint(Take(q, 6));
  println;
  
  Take(MyPrint(q), 6).Print;
  
end.Да, не очень удачную функцию написал я на лекции для печати. Дело в том, что она возвращает последовательность, а последовательность ленива. Чтобы она “выполнилась”, необходимо превратить её в скаляр любым способом - например:
MyPrint(Take(q, 6)).Count;
Немного глуповато выглядит.
Правильнее написать просто процедуру, печатающую последовательность безо всякого yield:
procedure MyPrint<T>(seq: sequence of T);
begin
  foreach var x in seq do 
    print(x);
end;
Понятно. Спасибо большое!
Станислав Станиславович, проконсультируйте, пожалуйста, насчет использования метода GroupBy. В примере мы группировали массив студентов. Однако возникает сложность при проходе по каждому элементу группы. То есть не работает цикл foreach var s in g do, где g — элемент условно двумерной последовательности gg.
Возникает ошибка «name не объявлен в типе integer».
type
  student = auto class
  public 
    Name: string;
    Age: integer;
    Group: integer;
  end;
begin
  var a := arr(new Student('Иванов', 20, 1), new Student('Петров', 19, 2),
  new Student('Сидоров', 17, 1), new Student('Зайцев', 16, 3), new Student('Шевченко', 21, 2));
  
  var gg := a.GroupBy(s -> s.Group).OrderBy(g -> g.Key);
  gg.Println;
  
  foreach var g in gg do
  begin
    print(g.key);
    {g.println;}
    foreach var s in g do
      print(s.name, s.Age);
  end;
  
end.
Можно, конечно, убрать внутренний foreach и печатать через g.println;. Но так неудобно, ведь будет выводиться группа студента несколько раз:
1 (Иванов,20,1) (Сидоров,17,1)
Я скопировал код к себе - он работает. Выводит:
[(Иванов,20,1),(Сидоров,17,1)] [(Петров,19,2),(Шевченко,21,2)] [(Зайцев,16,3)]
1 Иванов 20 Сидоров 17 2 Петров 19 Шевченко 21 3 Зайцев 16 
Может, у Вас старая версия Паскаля? Посмотрите, какая версия и от какого числа
Да, действительно, дело было в версии Паскаля. На сборке 1534 от 09.09.17 не работает, а вот на 1611 от 06.01.18 все в порядке
Мне кажется, что в выложенных лекциях ошибка в бинарном поиске, там не r:=k, а r:=k-1 иначе цикл не прервется
Да, точно. Правильный код такой:
function BinarySearch(a: array of integer; x: integer): integer;
begin
  var k: integer;
  var (l,r) := (0, a.Length-1); 
  repeat
    k := (l+r) div 2;
    if x>a[k] then
      l := k+1
    else r := k-1;
  until (a[k]=x) or (l>r);
  Result := a[k]=x ? k : -1;
end;
Станислав Станиславович, у меня какая-то проблема с композицией функция, если я ее делаю обобщенной функцией(как на лекции) возникает исключение, но с определенным типом все хорошо, можете проконсультировать?
Это связано с тем, что Sin и Cos перегружены для типа Complex. И компилятор не может выбрать. Так всё работает:
function Si(x: real) := Sin(x);
function Co(x: real) := Cos(x);
function Comp<T>(f,g: T->T): T->T := x->f(g(x));
begin
  Comp(Si,Co);
end.
Нам на практике еще давали такой способ решения: явно указать тип, подставляемый вместо T, насколько я понимаю.
function Composition<T>(f1, f2: T->T): T->T := x -> f1(f2(x));
begin
  var f := Composition&<Real>(sin, cos);
  print(f(pi));
end.
Так тоже работает 
Какую официальную шпаргалку можно взять на экзамен? Случайно, не этот файл? Шпаргалка PascalABC.NET 2017.pdf (232,6 КБ)
Да, она самая
Конечно работает! В моём примере компилятор тип T сам старается - выводит, а тут Вы ему явно помогаете 
Извините пожалуйста, забыл спросить на консультации, а как работает сортировка массива записи по критерию сравнения(это вопрос 86), как я понял, мы придумываем критерий, определяем для него в отдельной процедуре правило, по которому будем сравнивать и затем просто сортируем массив, используя вместо операции сравнения нашу процедуру. Так ли это?
Ну да, именно так. И можно тогда сделать процедуру обобщённой
 Институт математики, механики и компьютерных наук ЮФУ, 2005–2021
 Институт математики, механики и компьютерных наук ЮФУ, 2005–2021