Консультация № 165344
19.04.2009, 15:51
0.00 руб.
0 24 1
Здравствуйте! У меня программа которая должнв выводить столбцовую диаграмму упеваемости учеников в классе, если известно количество отличников, хорошистов и т.д. Вроде сделал, но есть некоторые вопросы такие, как:
1) вывод идёт под столбцам сверху, а мне надо снизу;
2) как под столбцами разместить подпись с оценками, то есть столбец и под ним надпись с оценкой;
3) и можно ли в стобце вывести кто какую оценку получил.
Помогите пожалуйста

Приложение:
Program KKR4_10;
uses CRT,Graph;
const MaxNumberOfStudents=99;
type TStudent=record
Name:string[25];
Mark:2..5;
end;
TListOfStudents=record
Items:array[1..MaxNumberOfStudents] of TStudent;
Count:integer;
end;
TJournal=record
Group:string[6];
Students:TListOfStudents;
end;
type ArrayMarks=array[1..4] of integer;

Procedure InputStudent(var s:TStudent);
begin
write(' Ученик: ');
readln(s.Name);
write(' Оценка: ');
readln(s.Mark);
end;

Procedure InputListOfStudents(var j:TListOfStudents);
var i:integer;
begin
write('Введите число учеников: ');
readln(j.Count);
writeln('Список учеников и оценок:');
for i:=1 to j.Count do
begin
write('№',i );
InputStudent(j.Items[i]);
end;
clrscr;
end;

Procedure InputJournal(var j:TJournal);
begin
write('Класс: ');
readln(j.Group);
InputListOfStudents(j.Students);
end;

Procedure OutputRegister(mark:byte; Magazine:TJournal);
var i:integer;
begin
writeln(' Класс - ',Magazine.Group);
writeln('Оценка ученика - (',mark,'):');
for i:=1 to Magazine.Students.Count do
if Magazine.Students.Items[i].Mark=mark then
writeln(Magazine.Students.Items[i].name);
readln;
end;

{Procedure Diagramma (Magazine:TJournal; var sm:ArrayMarks);
var i,j:byte;
begin
for i:=1 to Magazine.Students.Count do
if Magazine.Students.Items[i].Mark=2 then
sm[1]:=sm[1]+1
else if Magazine.Students.Items[i].Mark=3 then
sm[2]:=sm[2]+1
else if Magazine.Students.Items[i].Mark=4 then
sm[3]:=sm[3]+1
else if Magazine.Students.Items[i].Mark=5 then
sm[4]:=sm[4]+1;
for i:=1 to 4 do
begin
textcolor(i);
write('Kolichestvo ',i+1,' ');
for j:=1 to sm[i]*2 do
write(#178);
write(' ',sm[i]);
writeln;
end;
readln;
end;}

Function CountCoordinateForY(sm:ArrayMarks; i:integer):integer;
var y:integer;
begin
Y:=sm[i];
CountCoordinateForY:=round(200/Y);
end;

Procedure Diagramma(Magazine:Tjournal; sm:ArrayMarks);
var driver,mode,Err,i:integer;
begin
clrscr;
driver:=detect;
InitGraph(driver,mode,'C:\BGI');
Err:=GraphResult;
if Err<>grOK then
writeln('Ошибка при инициализации графического режима')
else
begin
SetViewPort(0,0,200,300,ClipOff);
for i:=1 to Magazine.Students.Count do
if Magazine.Students.Items[i].Mark=2 then
sm[1]:=sm[1]+1
else if Magazine.Students.Items[i].Mark=3 then
sm[2]:=sm[2]+1
else if Magazine.Students.Items[i].Mark=4 then
sm[3]:=sm[3]+1
else if Magazine.Students.Items[i].Mark=5 then
sm[4]:=sm[4]+1;
{SetColor(Red);
Rectangle(0,0,75,CountCoordinateForY(sm,1));
SetColor(blue);
Rectangle(75,0,150,CountCoordinateForY(sm,2));
SetColor(green);
Rectangle(150,0,225,CountCoordinateForY(sm,3));
SetColor(yellow);
Rectangle(225,0,300,CountCoordinateForY(sm,4));}
{SetFillStyle(8,Red);
Bar(0,0,75,CountCoordinateForY(sm,1));
SetFillStyle(8,Yellow);
Bar(75,0,150,CountCoordinateForY(sm,2));
SetFillStyle(8,Blue);
Bar(150,0,225,CountCoordinateForY(sm,3));
SetFillStyle(8,Green);
Bar(225,0,300,CountCoordinateForY(sm,4));}
SetFillStyle(8,Red);
Bar3D(0,0,75,CountCoordinateForY(sm,1),0,TopOn);
SetFillStyle(8,Yellow);
Bar3D(75,0,150,CountCoordinateForY(sm,2),0,TopOn);
SetFillStyle(8,Blue);
Bar3D(150,0,225,CountCoordinateForY(sm,3),0,TopOn);
SetFillStyle(8,Green);
Bar3D(225,0,300,CountCoordinateForY(sm,4),0,TopOn);
{SetFillStyle(8,Red);
Bar3D(0,CountCoordinateForY(sm,1),75,200,0,TopOn);
SetFillStyle(8,Yellow);
Bar3D(75,CountCoordinateForY(sm,2),15,200,0,TopOn);
SetFillStyle(8,Blue);
Bar3D(150,CountCoordinateForY(sm,3),225,200,0,TopOn);
SetFillStyle(8,Green);
Bar3D(225,CountCoordinateForY(sm,4),300,200,0,TopOn);}
end;
end;

var j:TJournal;
sm:ArrayMarks;
begin
clrscr;
InputJournal(j);
OutputRegister(5,j);
OutputRegister(4,j);
OutputRegister(3,j);
OutputRegister(2,j);
Diagramma(j,sm);
readln;
end.

Обсуждение

Неизвестный
20.04.2009, 19:39
общий
Help
Неизвестный
20.04.2009, 23:25
общий
это ответ
Здравствуйте, Gparev

Во первых:
Ваша функция CountCoordinateForY не правильно считает высоту столбца
При таком подходе: round(200/Y) - у вас получается, что чем больше учеников
получило такую оценку, тем ниже будет столбец. Надо так: 202-round(200/Y).
т.о. получим: максимальная высота столбца будет 200 (если все 99 учеников
получили одну оценку), минимальная 2 - если такой ученик только 1.

Так же здесь вы не учитываете, что ни одного ученика с такой оченкой может
не оказаться и в таком случае программа вылетит с ошибкой "деление на 0".

Вообщем сделать надо так:
if y<>0 then CountCoordinateForY:=202-round(200/Y) else CountCoordinateForY:=0;

Во-вторых:
В процедуре Diagramma
1.Зачем то устанавливаете ViewPort - это лишнее
2.При подсчете оценок в массив sm[] - вы его не удосужились
проинициализировать, а вам никто не гарантирует, что в нем изначально
будут нули поэтому перед циклом подсчета надо бы добавить:

for i:=1 to 4 do sm[i]:=0;

Ну и в третьих по вашим вопросам:
1.В графическом режиме в паскале координаты (0,0) расположены в верхнем
левом углу, т.о. если по оси x у нас все более менее понятно (она идет
слева-направо), то ось y получается перевернутой, она идет сверху вниз.
Поэтому и диаграмма у вас выходит перевернутой. Для того чтобы этого не
происходило и все вернулось "с головы на ноги" все кординаты y при отрисовке
любого объекта необходимо "переворачивать", т.е. Yэкранный=GetMaxY-Yнаш.
т.о. мы сместим точку начала координат из левого верхнего угла в левый
нижний. Например, отрисовка вашего столбца диаграммы должна выглядеть так:

Bar3D(0,GetMaxY,75,GetMaxY-CountCoordinateForY(sm,1),0,TopOn);

Если вам необходимо еще и подписать столбики, то тогда нам нужно сместить
Y=0 не в самый низ экрана, а скажем оставив 30 точек на подпись
соответственно Yэкранный=GetMaxY-30-Yнаш - и столбик уже будет рисоваться так:

Bar3D(0,GetMaxY-30,75,GetMaxY-30-CountCoordinateForY(sm,1),0,TopOn);

2.Для вывода подписей к столбцам, используйте OutTextXY(). (Не забудьте
перевернуть координату y), как в предыдущем пункте.

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

С уважением, Дмитрий
Неизвестный
21.04.2009, 16:12
общий
Спасибо, учёл все ваши рекомендации. Вот еще вопрос - как бы мне вывести оценку и кто имеет эту оценку на столбике??? Я попробовал, но толку мало:
Код:
Function CountCoordinateForY(sm:ArrayMarks; i:integer):integer;
var y:integer;
begin
Y:=sm[i];
if Y<>0 then
CountCoordinateForY:=GetMaxY-round(200/Y)
else CountCoordinateForY:=0;
end;

Procedure ChartOfMarks (Magazine:Tjournal; sm:ArrayMarks; mark:byte; X,Y:integer);
var driver,mode,Err,i:integer;
begin
clrscr;
driver:=detect;
InitGraph(driver,mode,'C:\BGI');
Err:=GraphResult;
if Err<>grOK then
writeln('Ошибка при инициализации графического режима')
else
begin
for i:=1 to 4 do
sm[i]:=0;
for i:=1 to Magazine.Students.Count do
if Magazine.Students.Items[i].Mark=2 then
sm[1]:=sm[1]+1
else if Magazine.Students.Items[i].Mark=3 then
sm[2]:=sm[2]+1
else if Magazine.Students.Items[i].Mark=4 then
sm[3]:=sm[3]+1
else if Magazine.Students.Items[i].Mark=5 then
sm[4]:=sm[4]+1;
SetFillStyle(8,Red);
Bar3D(0,GetMaxY,150,CountCoordinateForY(sm,1),0,TopOn);
SetFillStyle(8,Yellow);
Bar3D(150,GetMaxY,600,CountCoordinateForY(sm,2),0,TopOn);
SetFillStyle(8,Blue);
Bar3D(300,GetMaxY,450,CountCoordinateForY(sm,3),0,TopOn);
SetFillStyle(8,Green);
Bar3D(450,GetMaxY,600,CountCoordinateForY(sm,4),0,TopOn);
for i:=1 to Magazine.Students.Count do
if Magazine.Students.Items[i].Mark=mark then
OutTextXY(X,Y,Magazine.Students.Items[i].name);
end;
end;

var j:TJournal;
sm:ArrayMarks;
begin
clrscr;
InputJournal(j);
OutputRegister(5,j);
OutputRegister(4,j);
OutputRegister(3,j);
OutputRegister(2,j);
ChartOfMarks(j,sm,2,75,100);
ChartOfMarks(j,sm,3,225,100);
ChartOfMarks(j,sm,4,300,100);
ChartOfMarks(j,sm,5,375,100);
readln;
end.
Неизвестный
21.04.2009, 20:02
общий
Попробуйте так:

Добавьте еще две переменные в вашу процедуру например k,m: integer
и измените ваш код
for i:=1 to Magazine.Students.Count do
if Magazine.Students.Items[i].Mark=mark then
OutTextXY(X,Y,Magazine.Students.Items[i].name);

на
m:=0;
for k:=2 to 5 do
for i:=1 to Magazine.Students.Count do
if Magazine.Students.Items[i].Mark=k then begin
OutTextXY(X+(k-2)*150,Y+10*m,Magazine.Students.Items[i].name); { 150 - расстояние между столбиками по Х, }
{ 10 - расстояние между строк (надо подгонять) }
inc(m);
end;

Т.о. переменную mark из параметров можно убрать, а в теле основной программы оставить только один вызов процедуры отрисовки диаграммы
ChartOfMarks(j,sm,75,100); { 75 начало вывода текста по X, 100 начало вывода текста по Y }
иначе у вас каждый раз графика переинициализируется и все с экрана естественно стирает, поэтому у вас только последний текстовый вывод оставался, да еще и в одной позиции все имена вывводились.

С уважением, Дмитрий.
давно
Старший Модератор
31795
6196
21.04.2009, 22:21
общий
Тимошенко Дмитрий & Gparev:

Диаграмма - это процентное отношение чего-то к чему-то, правильно?
round(200/Y)(или её вариации) такая запись ошибочна, т.к. нужно относить максимальное значение столбца, в графическом режиме=200 умноженное на количество учеников имеющих данную оценку разделенное на на общее количество учеников

Блин, переделайте в круговую диаграмму, где максимальное значение(столбца )= 360 градусов. Вы поймете о чем я.
Вычисление информации, не должно влиять на её вывод, вывод- вторичен, т.к. только отображает полученную информацию. При таком отношении, полученную информацию нужно пересчитывать постоянно(переписывать программу), при изменении условий вывода.

И как дополнение, если не используется 3-х мерность Bar3D(0,GetMaxY,75,GetMaxY-CountCoordinateForY(sm,1),[u]0[/u],TopOn);, то к чему использовать именно эту функцию, если есть простой Bar
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Неизвестный
22.04.2009, 07:28
общий
2Зенченко Константин Николаевич: Да, все правильно насчет round(200/Y). Что-то я затупил немного. А насчет Bar3D, так там не только это, там еще пол программы можно оптимизировать.

2Gparev: Правильно замечание сделали. Лучше сделать так: CountCoordinateForY:=GetMaxY-round(200*Y/CountStudents)
(и в параметрах надо передавать еще и общее количество студентов)

С уважением, Дмитрий
Неизвестный
22.04.2009, 22:02
общий
Мне надо по заданию в столбцовую(((
Неизвестный
22.04.2009, 22:13
общий
Учёл всё и переделал я формулу. Но у меня опять выводятся непонятные столбцы:
Код:
Function CountCoordinateForY (Magazine:TJournal; sm:ArrayMarks; i:integer):integer;
var y:integer;
begin
Y:=sm[i];
if Y<>0 then
CountCoordinateForY:=GetMaxY-round(200*Y/Magazine.Students.Count)
else CountCoordinateForY:=0;
end;

Procedure ChartOfMarks (Magazine:Tjournal; sm:ArrayMarks; X,Y:integer);
var driver,mode,Err,i:integer;
k,m:integer;
begin
clrscr;
driver:=detect;
InitGraph(driver,mode,'C:\BGI');
Err:=GraphResult;
if Err<>grOK then
writeln('Ошибка при инициализации графического режима')
else
begin
for i:=1 to 4 do
sm[i]:=0;
for i:=1 to Magazine.Students.Count do
if Magazine.Students.Items[i].Mark=2 then
sm[1]:=sm[1]+1
else if Magazine.Students.Items[i].Mark=3 then
sm[2]:=sm[2]+1
else if Magazine.Students.Items[i].Mark=4 then
sm[3]:=sm[3]+1
else if Magazine.Students.Items[i].Mark=5 then
sm[4]:=sm[4]+1;
SetFillStyle(8,Red);
Bar(0,GetMaxY,150,CountCoordinateForY(Magazine,sm,1));
SetFillStyle(8,Yellow);
Bar(150,GetMaxY,300,CountCoordinateForY(Magazine,sm,2));
SetFillStyle(8,Blue);
Bar(300,GetMaxY,450,CountCoordinateForY(Magazine,sm,3));
SetFillStyle(8,Green);
Bar(450,GetMaxY,600,CountCoordinateForY(Magazine,sm,4));
m:=0;
for k:=2 to 5 do
for i:=1 to Magazine.Students.Count do
if Magazine.Students.Items[i].Mark=k then
begin
OutTextXY(X+(k-2)*150,Y+10*m,Magazine.Students.Items[i].name);
inc(m);
end;
SetTextStyle(5,0,5);
OutTextXY(75,20,'2');
OutTextXY(225,20,'3');
OutTextXY(375,20,'4');
OutTextXY(525,20,'5');
end;
end;

var j:TJournal;
sm:ArrayMarks;
begin
clrscr;
InputJournal(j);
OutputStudentsWithMarks(5,j);
OutputStudentsWithMarks(4,j);
OutputStudentsWithMarks(3,j);
OutputStudentsWithMarks(2,j);
ChartOfMarks(j,sm,75,100);
ChartOfMarks(j,sm,225,100);
ChartOfMarks(j,sm,300,100);
ChartOfMarks(j,sm,375,100);
readln;
end.

Всё перепутано и для некоторых оценок не выводится список студентов, имеющих эту оценку. Не понимаю в чём причина(((
давно
Старший Модератор
31795
6196
22.04.2009, 22:32
общий
Gparev:
Мне надо по заданию в столбцовую(((

Вопрос состоит в том, что преподаватель может сказать - "мне понравилось как ты написал программу для столбиков, а теперь напиши для круга или для секторов".
В любом случае на вход подпрограммы вывода диаграммы(столбик, круг или сектор) должны подаватся одинаковые результаты расчетов, которые общие для любой диаграммы, а уж как выводить решает только данная подпрограмма.

ps: мне не сложно написать эту программу, но дело принципа, эксперт ответил, пусть раставит всё по полочкам в своём ответе. Если будет "форсмажор" только тогда вмешаюсь, сейчас только контролирую и подсказываю.

Тимошенко Дмитрий:
Так начинайте подсакзывать, как оптимизировать.
На кнопку "отправить ответ" все нажимают.
А толком обьяснить, не все могут.
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Неизвестный
22.04.2009, 23:12
общий
Преподаватель не может, так как это задание как раз стоит в следующем варианте)))
давно
Старший Модератор
31795
6196
22.04.2009, 23:23
общий
вывод диаграммы смотрите ниже, только капельку переделал Ваш код(лишнее закоментрировал):
Код:

uses CRT,Graph;
const MaxNumberOfStudents=99;
type TStudent=record
Name:string[25];
Mark:2..5;
end;
TListOfStudents=record
Items:array[1..MaxNumberOfStudents] of TStudent;
Count:integer;
end;
TJournal=record
Group:string[6];
Students:TListOfStudents;
end;
type ArrayMarks=array[1..4] of integer;

Procedure InputStudent(var s:TStudent);
begin
write(' Ученик: ');
readln(s.Name);
write(' Оценка: ');
readln(s.Mark);
end;

Procedure InputListOfStudents(var j:TListOfStudents);
var i:integer;
begin
write('Введите число учеников: ');
readln(j.Count);
writeln('Список учеников и оценок:');
for i:=1 to j.Count do
begin
write('№',i );
InputStudent(j.Items[i]);
end;
clrscr;
end;

Procedure InputJournal(var j:TJournal);
begin
write('Класс: ');
readln(j.Group);
InputListOfStudents(j.Students);
end;

Procedure OutputRegister(mark:byte; Magazine:TJournal);
var i:integer;
begin
writeln(' Класс - ',Magazine.Group);
writeln('Оценка ученика - (',mark,'):');
for i:=1 to Magazine.Students.Count do
if Magazine.Students.Items[i].Mark=mark then
writeln(Magazine.Students.Items[i].name);
readln;
end;

Function CountCoordinateForY (Magazine:TJournal; sm:ArrayMarks; i:integer):integer;
var y:integer;
begin
Y:=sm[i];
{ if Y<>0 then}
CountCoordinateForY:=GetMaxY-round(200*Y/Magazine.Students.Count)
{ else CountCoordinateForY:=0;}
end;

Procedure ChartOfMarks (Magazine:Tjournal; sm:ArrayMarks; X,Y:integer);
var driver,mode,Err,i:integer;
k,m:integer;
begin
clrscr;
driver:=detect;
InitGraph(driver,mode,'C:\BGI');
Err:=GraphResult;
if Err<>grOK then
writeln('Ошибка при инициализации графического режима')
else
begin
for i:=1 to 4 do
sm[i]:=0;
for i:=1 to Magazine.Students.Count do
if Magazine.Students.Items[i].Mark=2 then
sm[1]:=sm[1]+1
else if Magazine.Students.Items[i].Mark=3 then
sm[2]:=sm[2]+1
else if Magazine.Students.Items[i].Mark=4 then
sm[3]:=sm[3]+1
else if Magazine.Students.Items[i].Mark=5 then
sm[4]:=sm[4]+1;
SetFillStyle(8,Red);
Bar(0,GetMaxY,150,CountCoordinateForY(Magazine,sm,1));
SetFillStyle(8,Yellow);
Bar(150,GetMaxY,300,CountCoordinateForY(Magazine,sm,2));
SetFillStyle(8,Blue);
Bar(300,GetMaxY,450,CountCoordinateForY(Magazine,sm,3));
SetFillStyle(8,Green);
Bar(450,GetMaxY,600,CountCoordinateForY(Magazine,sm,4));
m:=0;
for k:=2 to 5 do
for i:=1 to Magazine.Students.Count do
if Magazine.Students.Items[i].Mark=k then
begin
OutTextXY(X+(k-2)*150,Y+10*m,Magazine.Students.Items[i].name);
inc(m);
end;
SetTextStyle(5,0,5);
OutTextXY(75,20,'2');
OutTextXY(225,20,'3');
OutTextXY(375,20,'4');
OutTextXY(525,20,'5');
end;
end;

var j:TJournal;
sm:ArrayMarks;
begin
clrscr;
InputJournal(j);
{ OutputStudentsWithMarks(5,j);
OutputStudentsWithMarks(4,j);
OutputStudentsWithMarks(3,j);
OutputStudentsWithMarks(2,j);}
ChartOfMarks(j,sm,75,100);
ChartOfMarks(j,sm,225,100);
ChartOfMarks(j,sm,300,100);
ChartOfMarks(j,sm,375,100);
readln;
end.

Выводом надписей пока не занимался
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Неизвестный
22.04.2009, 23:57
общий
2Зенченко Константин Николаевич
Так мне-то тоже не сложно написать - хочется чтобы человек сам понял и сделал. Тем более, что он просил не готовую программу, а именно помочь разобраться что не так в его коде?
Счас добъемся, чтобы она заработала, а потом подоптимизируем, если человек захочет.

2Gparev
Опять я накосячил: (что значит не проверить)
Цикл вывода надписей должен быть таким, т.е. m:=0 надо перенести внутрь первого цикла, а то надписи выводятся "лесенкой"

for k:=2 to 5 do begin
m:=0;
for i:=1 to Magazine.Students.Count do
if Magazine.Students.Items[i].Mark=k then
begin
OutTextXY(X+(k-2)*150,Y+10*m,Magazine.Students.Items[i].name);
inc(m);
end;
end;

А часть студентов у вас не выводится, потому что вы мой пост выше не внимательно прочитали:
Цитата: "...в теле основной программы оставить только один вызов процедуры отрисовки диаграммы
ChartOfMarks(j,sm,75,100); { 75 начало вывода текста по X, 100 начало вывода текста по Y }
иначе у вас каждый раз графика переинициализируется и все с экрана естественно стирает, поэтому у вас только последний текстовый вывод оставался,..."

С уважением, Дмитрий
Неизвестный
23.04.2009, 22:07
общий
спасибо, завтра буду преподу показывать)))
давно
Старший Модератор
31795
6196
23.04.2009, 22:24
общий
Gparev:
Показывать это одно, а вот расказать, что там написано - это на Вашей совести, т.к. любой из экспертов портала сможет отстоять свою точку зрения(по поводу написания программы и он за свои слова отвечает), а Вы сможете разобратся, что "Вы" там написали. Проанализируйте код, найдите ключевые моменты, т.к. потом именно Вам нужно будет, именно это объяснять.
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Неизвестный
24.04.2009, 06:37
общий
Я так понимаю - оптимизировать не будем . Ну да и ладно.
Неизвестный
24.04.2009, 20:43
общий
Ну, во первых я там абсолютно всё понял и разобрался, а, во вторых, что же ещё можно здесь оптимизировать?
Код:
uses CRT,Graph;
const MaxNumberOfStudents=99;
type TStudent=record
Name:string[25];
Mark:2..5;
end;
TListOfStudents=record
Items:array[1..MaxNumberOfStudents] of TStudent;
Count:integer;
end;
TJournal=record
Group:string[6];
Students:TListOfStudents;
end;
type ArrayMarks=array[1..4] of integer;

Procedure InputStudent (var s:TStudent);
begin
write(' Ученик: ');
readln(s.Name);
write(' Оценка: ');
readln(s.Mark);
end;

Procedure InputListOfStudents (var j:TListOfStudents);
var i:integer;
begin
write('Введите число учеников: ');
readln(j.Count);
writeln('Список учеников и оценок:');
for i:=1 to j.Count do
begin
write('№',i );
InputStudent(j.Items[i]);
end;
clrscr;
end;

Procedure InputJournal (var j:TJournal);
begin
write('Класс: ');
readln(j.Group);
InputListOfStudents (j.Students);
end;

Procedure OutputStudentsWithMarks(mark:byte; Magazine:TJournal);
var i:integer;
begin
writeln(' Класс - ',Magazine.Group);
writeln('Оценка ученика - (',mark,'):');
for i:=1 to Magazine.Students.Count do
if Magazine.Students.Items[i].Mark=mark then
writeln(Magazine.Students.Items[i].name);
readln;
end;

Function CountCoordinateForY(Magazine:TJournal; sm:ArrayMarks; i:integer):integer;
var y:integer;
begin
Y:=sm[i];
CountCoordinateForY:=GetMaxY-round(200*Y/Magazine.Students.Count);
end;

Procedure OutputToChartOfMarksNames(Magazine:TJournal);
var m,k,X,Y,i:integer;
begin
for k:=2 to 5 do
begin
m:=0;
for i:=1 to Magazine.Students.Count do
if Magazine.Students.Items[i].Mark=k then
begin
OutTextXY(X+(k-2)*150,GetMaxY-(Y+10*m),Magazine.Students.Items[i].name);
inc(m);
end;
end;
end;

Procedure CountMarks(var sm:ArrayMarks; Magazine:TJournal);
var i:integer;
begin
for i:=1 to 4 do
sm[i]:=0;
for i:=1 to Magazine.Students.Count do
if Magazine.Students.Items[i].Mark=2 then
sm[1]:=sm[1]+1
else if Magazine.Students.Items[i].Mark=3 then
sm[2]:=sm[2]+1
else if Magazine.Students.Items[i].Mark=4 then
sm[3]:=sm[3]+1
else if Magazine.Students.Items[i].Mark=5 then
sm[4]:=sm[4]+1;
end;

Procedure ChartOfMarks (Magazine:Tjournal; X,Y:integer);
var driver,mode,Err,i:integer;
k,m:integer;
sm:ArrayMarks;
begin
clrscr;
driver:=detect;
InitGraph(driver,mode,'C:\BGI');
Err:=GraphResult;
if Err<>grOK then
writeln('Ошибка при инициализации графического режима')
else
begin
CountMarks(sm,Magazine);
SetFillStyle(8,Red);
Bar(0,GetMaxY,150,CountCoordinateForY(Magazine,sm,1));
SetFillStyle(8,Yellow);
Bar(150,GetMaxY,300,CountCoordinateForY(Magazine,sm,2));
SetFillStyle(8,Blue);
Bar(300,GetMaxY,450,CountCoordinateForY(Magazine,sm,3));
SetFillStyle(8,Green);
Bar(450,GetMaxY,600,CountCoordinateForY(Magazine,sm,4));
OutputToChartOfMarksNames(Magazine);
SetTextStyle(5,0,5);
OutTextXY(75,20,'2');
OutTextXY(225,20,'3');
OutTextXY(375,20,'4');
OutTextXY(525,20,'5');
end;
end;

var j:TJournal;
begin
clrscr;
InputJournal(j);
OutputStudentsWithMarks(5,j);
OutputStudentsWithMarks(4,j);
OutputStudentsWithMarks(3,j);
OutputStudentsWithMarks(2,j);
ChartOfMarks(j,75,100);
readln;
end.

З. Ы.: преподу показал и рассказал))) Друг друга поняли.
З. Ы. Ы.: нам лекции вообще не дают, не читают, вот и приходится у вас спрашивать(((
давно
Старший Модератор
31795
6196
24.04.2009, 21:04
общий
Gparev:
Берете этот участок кода :
Код:
Procedure CountMarks(var sm:ArrayMarks; Magazine:TJournal);
var i:integer;
begin
for i:=1 to 4 do
sm[i]:=0;
for i:=1 to Magazine.Students.Count do
if Magazine.Students.Items[i].Mark=2 then
sm[1]:=sm[1]+1
else if Magazine.Students.Items[i].Mark=3 then
sm[2]:=sm[2]+1
else if Magazine.Students.Items[i].Mark=4 then
sm[3]:=sm[3]+1
else if Magazine.Students.Items[i].Mark=5 then
sm[4]:=sm[4]+1;
end;

и меняете на это:
Код:
Procedure CountMarks(var sm:ArrayMarks; Magazine:TJournal);
var i:integer;
begin
for i:=1 to 4 do
sm[i]:=0;
for i:=1 to Magazine.Students.Count do
inc(sm[Magazine.Students.Items[i].Mark-1]);
end;

Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Неизвестный
25.04.2009, 06:44
общий
А этот
Код:

Function CountCoordinateForY(Magazine:TJournal; sm:ArrayMarks; i:integer):integer;
var y:integer;
begin
Y:=sm[i];
CountCoordinateForY:=GetMaxY-round(200*Y/Magazine.Students.Count);
end;

на этот
Код:

Function CountCoordinateForY(Magazine:TJournal; sm:ArrayMarks; i:integer):integer;
begin
CountCoordinateForY:=GetMaxY-round(200*sm[i]/Magazine.Students.Count);
end;

или вообще эту функцию убрать и вычислять координату прямо в тексте.
Неизвестный
25.04.2009, 11:06
общий
И опять вопрос по этой задаче: как внедрить драйвера графики и шрифтов в тело программы? Если это возможно конечно...
давно
Старший Модератор
31795
6196
25.04.2009, 11:26
общий
Модули графики и шрифтов Вы никак не можете внедрить, т.к. они подгружаются динамически, т.е. вовремя работы программы и Вы можете кстати менять различные драйвера и шрифты, т.е. переходить с одного режима на другой, именно по этой причине. Но при загрузке они занимают одну и туже область памяти, процессор только выводить или выполняет, то что там записанно. Единственный выход, это писать драйвер в самом коде, но тогда Вам нужно будет переписать все стандатные функции + знание прямого управления видеоконтролером.
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Неизвестный
25.04.2009, 13:21
общий
Не могу с вами согласиться Профессор. Все прекрасно интегрируется, и шрифты, и драйверы. Об этом даже в Help написано.

Вот вам для примера интеграция EGAVGA.BGI.

1. Для начала конвертим файл EGAVGA.BGI в OBJ с помощью утилиты BINOBJ
BINOBJ EGAVGA.BGI EGAVGA.OBJ EGAVGADRIVER
2. Далее к программе добавляем след. строки в области определений:
{$L EGAVGA.OBJ}
procedure EGAVGADRIVER; external; - для линковки драйвера с экзешником и объявления ссылки на него.

а в самом начале программы (обязательно до вызова InitGraph), регистрируем наш драйвер
if RegisterBGIDriver(@EGAVGADRIVER)<0 Then begin
writeln('Не могу зарегистрировать видео-драйвер!!!');
halt;
end;

Аналогично действуем со шрифтами, используя RegisterBGIFont. Хотя в данной программе они не используются.

И насчет ваших изменений в коде - они конечно укорачивают процедуру, но, т.к. на этапе ввода оценка не проверяется на принадлежность диапазону (1..5) то ваш код может вызвать ошибку, если пользователь введет оценку не из этого диапазона. А в исходном варианте такие оценки просто игнорировались.

С уважением, Дмитрий
давно
Старший Модератор
31795
6196
28.04.2009, 21:38
общий
Тимошенко Дмитрий:
Упс, ассемблер мне на голову.
Кстати: из 5-ти компиляторов Рascal'я(которые есть у меня), только в ВР есть BINOBJ.
Поэтому как-то этот момент не расматривал, а если мне что-то нужно пишу сам.
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Неизвестный
28.04.2009, 21:47
общий
Вы знаете, есть мнение "что все уже написано до нас" и порой бывает проще найти готовое, чем заново написать самому.
Хотя это "на любителя", кто к чему привык. Я обычно тоже пишу сам, если что-то понадобится. Просто иногда обидно бывает, пишешь, пишешь, а потом натыкаешься на уже готовое, и думаешь чего я заморачивался лучше бы сразу "в поиск" пошел.
Неизвестный
29.04.2009, 20:55
общий
я использовал ZOBJ
Форма ответа