Смекни!
smekni.com

Генерация дидактических материалов по математике (стр. 1 из 2)

В те времена, когда я преподавал математику в школе (1990-1997), столкнулся с проблемой отсутствия достаточного количества дидактических материалов на печатной основе для проведения занятий. В частности, при проведении контрольных работ было лишь два варианта заданий, и, естественно, ученики списывали, что, с моей точки зрения, недопустимо. Тогда я стал придумывать варианты заданий и распечатывать их с помощью старенькой пишущей машинки. Сразу замечу, что занятие это рутинное, абсолютно не творческое и скучное — придумать 20-25 однотипных вариантов с разным содержанием. Тем не менее, один год я такое практиковал.

Когда в институте меня стали учить программированию, тут же возникла идея приспособить для создания дидактических материалов компьютер. Он для этих целей идеально подходил, поскольку позволял автоматизировать не только распечатку текста, но и сам процесс его разработки. Действительно, достаточно запрограммировать образец для одного задания, и согласно ему будет получено любое количество заданий. Но и здесь были свои проблемы, связанные с тем, что сгенерированный текст DOS приходилось затем "доводить до ума" (ставить верхние и нижние индексы, рисовать дроби и т.д.) с помощью текстового редактора типа ChiWriter или Lexicon, причем конечный продукт выглядел в результате достаточно нелепо и коряво.

Технология окончательно сформировалась в 1994 г., когда я познакомился с системой форматирования текстов LaTeX, позволяющей форматировать тексты, содержащие математические формулы любой сложности. Обычно в основу самостоятельной или контрольной работы закладываются уже существующие дидактические материалы к тому или иному школьному учебнику математики, и по этому образу и подобию готовится работа, где данные в каждом из вариантов различные. Таким образом складывается иллюзия наличия такого же количества вариантов, сколько учеников в классе.

Наличие отдельного напечатанного варианта при проведении контрольной или самостоятельной работы имеет ряд преимуществ перед отсутствием такового: во-первых, решается проблема списывания — каждый учащийся вынужден обрабатывать свои данные (правда, при этом можно в качестве образца использовать работу соседа, но это было и при традиционном проведении контрольной работы); во-вторых, нет необходимости перед началом урока втискивать текст контрольной работы на доску (очень не люблю писать на доске!); в-третьих, ни для кого не является секретом, что зрение большинства учащихся в настоящее время ослаблено, и им приходится подходить к доске или переспрашивать учителя для уточнения текста задания, при указанном подходе проблема снимается. Можно найти и другие достоинства, мною не отмеченные, я думаю... Есть и свои недостатки — учителю затем нужно проверить не 2 варианта, а 25-30. Не всякий при нынешней загруженности на это решится. Но при желании число существенно разных вариантов можно сократить до 5-10.

Продемонстрирую на паре-тройке примеров технологию подготовки текста в формате LaTeX.

Пример 1. Алгебраическое выражение.

Одно из наиболее часто встречающихся в 5-7 классах заданий — вычисление значения выражения. Генерируя такие выражения, нужно учитывать такие обстоятельства, как:

1) соответствие изучаемой теме и возрасту учащихся (например, в 5 классе значение выражения не должно быть равно отрицательному числу);

2) после выполнения очередного действия полученное значение должно получиться проще и приемлемым для выполнения следующего действия, где это значение используется (т.е. некоторые величины в выражении будут случайными, другие — вычисляемыми);

3) при записи десятичной дроби в школьной математике используется десятичная запятая, а при записи на компьютере — десятичная точка;

4) если в записи выражения используются десятичные дроби, то они должны быть несократимыми и правильными.

Учитывая приведенные выше соображения, покажем на примере следующего числового выражения получение его аналогов:

Проанализируем данное выражение. Его значение равно 2,32 и получается как разность двух произведений. Таким образом, значение выражения — произвольное рациональное число, модуль которого не больше 10. Значение первого и второго произведений — десятичные дроби, это соответственно 2,62 и 0,3. При генерации произведений будем ориентироваться также на десятичные значения. В первом произведении первый сомножитель — сумма обыкновенных дробей с разными знаменателями, НОД которых отличен от 1, а второй сомножитель — число, которое можно сократить с общим знаменателем первого сомножителя. Второе произведение — произведение обыкновенной и десятичной дроби, которые нужно подобрать так, чтобы результат был точной десятичной дробью.

Приступим к генерации выражения. Пусть A=НОД(B,C), где B, C — знаменатели дробей суммы. Тогда B=A*B1, C=A*C1, где B1, C1 — случайные числа. D, F — числители рассматриваемых дробей, причем D<B, F<C. Целую часть первого слагаемого можно сгенерировать случайным образом. Второй сомножитель в первом произведении получаем так: K=НОК(B,C)*R/100, 1<R<10 — случайное число.

Аналогично получаем второй сомножитель. Не нужно забывать о том, что значение выражения по абсолютной величине не должно превышать 10.

Таким образом, выражение может быть получено с помощью следующего фрагмента программы:

B1 := 1 + Random(9);

C1 := 1 + Random(9);

A := 2 + Random(4); {НОД знаменателей дробей суммы}

B := A * B1; {Знаменатель первой дроби}

C := A * C1; {Знаменатель второй дроби}

D := 1 + Random(B — 2); {Числитель первой дроби}

F := 1 + Random(C — 2); {Числитель второй дроби}

K := Nod(D, B); {НОД чисел D, B}

D := D Div K; {Сокращение первой дроби}

B := B Div K;

K := Nod(F, C); {НОДчисел F, C}

F := F Div K; {Сокращение второй дроби}

C := C Div K;

K := B * C Div Nod(B, C) * (1 + Random(7)); {Второй сомножитель

в первом произведении}

Repeat

Repeat

M := 3 + Random(6); {Одно из чисел, на которое будет

производиться сокращение во втором произведении}

Ch1 := M * (1 + Random(3)) {Числитель второй дроби}

Until Odd(M) and Odd(Ch1);

Zn := M * 5; {Знаменатель первого сомножителя во втором

произведении}

SS := 2 + Random(4);

Zn1 := Stepen(2, SS); {Знаменатель второго сомножителя -

случайная степень числа 2}

Ch := Zn1 Div 2; {Числитель первой дроби}

Until (Ch < Zn) And (Ch1 < Zn1); {Повторяем генерацию дробей,

пока числители не станут

меньше знаменателей}

S := Nod(Ch, Zn);

Ch := Ch Div S; {Сокращение дроби}

Zn := Zn Div S;

Ch1 := Ch1 * Stepen(10, SS); {Подготовка числителя

второй дроби к целочисленному

делению}

{Печать результата генерации в файл Name}

WriteLn(Ch1, ' ', Zn1);

Write(Name, '$$&bsol;left(', 1 + Random(3), '&bsol;frac{', D);

Write(Name, '}{', B, '}+&bsol;frac{', F, '}{', C, '}&bsol;right)&bsol;cdot');

Write(Name, K Div 100, '{,}', K Mod 100, '-&bsol;frac{', Ch);

WriteLn(Name, '}{', Zn, '}&bsol;cdot 0{,}', Ch1 Div Zn1, '.$$')

В фрагменте программы использованы функции пользователя: Nod(A, B) — НОД(A,B); Stepen(A,B) — AB. Указанные функции должны быть описаны в программе.

Результаты работы программы для количества заданий, равного 5:

$$&bsol;left(1&bsol;frac{2}{3}+&bsol;frac{5}{8}&bsol;right)&bsol;cdot0{,}48-&bsol;frac{4}{35}&bsol;cdot 0{,}875.$$

$$&bsol;left(3&bsol;frac{1}{2}+&bsol;frac{1}{7}&bsol;right)&bsol;cdot0{,}98-&bsol;frac{8}{35}&bsol;cdot

0{,}4375.$$

$$&bsol;left(2&bsol;frac{10}{27}+&bsol;frac{1}{18}&bsol;right)&bsol;cdot2{,}7-&bsol;frac{8}{25}&bsol;cdot

0{,}3125.$$

$$&bsol;left(2&bsol;frac{1}{2}+&bsol;frac{5}{6}&bsol;right)&bsol;cdot0{,}24-&bsol;frac{4}{15}&bsol;cdot 0{,}375.$$

$$&bsol;left(1&bsol;frac{5}{6}+&bsol;frac{3}{5}&bsol;right)&bsol;cdot1{,}5-&bsol;frac{4}{35}&bsol;cdot 0{,}875.$$

Результат обработки этого файла будет следующим:

Пример 2. Квадратное уравнение.

Настоящий пример несколько проще предыдущего. Рассмотрим два случая: а) корни уравнения — целые; б) корни уравнения — обыкновенные дроби.

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

Задания под в, г предполагают наличие двух различных корней, являющихся обыкновенными правильными дробями. Алгоритм получения соответствующих коэффициентов в этом случае более громоздкий, хотя в основу положена всё та же теорема Виета. Изначально опять же генерируем ненулевые различные корни уравнения, а затем на их основе получаем уравнение в целыми коэффициентами. В примере это делается поэтапно: сначала — корни уравнения; затем — коэффициенты уравнения — обыкновенные дроби, наконец, коэффициенты — целые числа, причем НОК(A, B, C) = 1.

Ниже приводятся законченный фрагмент программы, генерирующий задания, пример работы этой программы и результат обработки файла, полученного с помощью программы.

Program Kw;

Var F : Text;

{Процедура, производящая начальные установки в формате LaTeXа}

Procedure UST;

Begin

WriteLn(F, '&bsol;documentstyle[12pt,a4wide]{article}');

WriteLn(F, '&bsol;topmargin-3cm');

WriteLn(F, '&bsol;pagestyle{empty}');

WriteLn(F, '&bsol;setlength{&bsol;textheight}{27cm}');

WriteLn(F, '&bsol;setlength{&bsol;textwidth}{16cm}');

WriteLn(F, '&bsol;begin{document}');

END;

{НОД}

Function Nod (X, Y : Integer) : Integer;

Begin

WHILE X <> Y Do

IF X > Y THEN X := X — Y ELSE Y := Y — X;

Nod := X

END;

{НОК}

Function NoK (X, Y : Integer) : Integer;

Begin

NoK := X * Y Div NoD(X, Y)

END;

Var X1, I, X2, A, C, B : Integer;

Ch, Ch1, Zn, Zn1, BCh, BZn, CCh, CZn, J, V, Vsp : Integer;

Begin

Assign(F, 't:&bsol;rustex&bsol;kw_ur.tex');

ReWrite(F);

UST;

Randomize;

{Корни уравнения (целые)}

Repeat X1 := -10 + Random(21) Until X1 <> 0;

Repeat X2 := -10 + Random(21) Until X2 <> 0;

B := -(X1 + X2);

C := X1 * X2;

WriteLn(F, '&bsol;begin{tabular}{ll}');

Write(F, 'а)~$x^2');

If B <> 0

Then Begin

If B > 0

Then If B <> 1 Then Write(F, '+', B) Else Write(F, '+')

Else If B <> -1 Then Write(F, B) Else Write(F, '-');

Write(F, 'x');

End;

If C <> 0 Then If C < 0 Then Write(F, C) Else Write(F, '+', C);

WriteLn(F, '=0$;& б)~$');

Repeat X1 := -10 + Random(21) Until X1 <> 0;

Repeat X2 := -10 + Random(21) Until (X2 <> 0) And (X2 <> X1);

B := -(X1 + X2);

C := X1 * X2;

Write(F, 'x^2');

If B <> 0

Then Begin

If B > 0

Then If B <> 1 Then Write(F, '+', B) Else Write(F, '+')

Else If B <> -1 Then Write(F, B) Else Write(F, '-');