Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум «Всё о Паскале» _ Задачи _ График курса доллара

Автор: Рэнэ 10.06.2007 11:12

Написать программу, которая выводит на экран графики динамики изменения максимального, минимального и среднего курсов
доллара за заданное количество дней. Показать градацию осей. Исходные данные сформировать в текстовом файле.
Построение графика оформить в виде процедур. Параметры процедуры: массив дат, количество дней, массивы максимальных,
минимальных и средних значений курса доллара.
Изображение должно занимать большую часть. Программа не должна опираться на конкретные значения экрана. mega_chok.gif wink.gif
Даже не знаю с чего начать, хоть подкиньте какую-нибудь похожую программу... так сказать для примера unsure.gif

Автор: volvo 10.06.2007 13:28

Если тебя устроит построение столбчатой диаграммы (гистограммы) - то вот здесь есть пример: http://forum.pascal.net.ru/index.php?s=&showtopic=4277&view=findpost&p=36908

Можно просто рисовать через LineTo... Это тоже где-то было, попробуй воспользоваться поиском...

Автор: Рэнэ 11.06.2007 7:16

Построение графика оформить в виде процедуры.
Параметры процедуры:
- массив дат(я так понимаю, что это массив значений Х)
- количество дней (количество х)
- масив максимального, минимального и среднего значений курса доллара (масивы знчений Y)

Как они должны быть записаны здесь?
И как потом используя их построить график (Procedure Vivod)?

Цитата
Program Grafic;
Uses Crt, Graph;
Var
x, y : integer;
St : String[4];
A, Mx, Mx01, Mx09, Msx, My, My09, My005, Msy : Integer;
F1: Text;
{-------Выход из графического режима----------}
PROCEDURE grafika_off;
BEGIN
closegraph;
ReadKey;
END;

{-------Переход в графический режим----------}
PROCEDURE grafika_on;
var
Ga, Gm, Error : Integer;
BEGIN
Ga := Detect;
Gm := Detect;
InitGraph (Ga, Gm, 'c:\bp\bgi');
Error := GraphResult;
If Error <> Grok Then
Begin
Writeln('Ошибка!Графический драйвер не найден',#10#13,GraphErrorMSG (Error));
Halt;
End;
End;
{-------Вывод данных из файла----------}
Procedure Vivod;
Begin
Assign (F1, 'c:\Vivod.txt');
Reset (F1);
While Not EOF (F1) do
begin
Readln (F1,x, y);
LineTo(round(Mx01+Msx*x),round(My09-Msy*y));
end;
Close (F1);
End;
{-------Определение используемых значений----------}
procedure Opredelenie;
Begin
Mx := GetMaxX;
Mx01 := Round (0.1* Mx);
Mx09 := Round (0.9* Mx);
My := GetMaxY;
My09 := Round (0.9*My);
My005 := Round (0.05* My);
SetColor (12);
end;
{-------Вывод осей координат----------}
procedure osikoord;
begin
Line (20, My09, Mx-10, My09);
Line (Mx01, My005, Mx01, My-9);

{Risovanie strelok}
Line (Mx-20, My09-3, Mx-10, My09);
Line (Mx-20, My09+3, Mx-10, My09);
Line (Mx01, My005, Mx01-3, My005+10);
Line (Mx01, My005, Mx01+3, My005+10);

{Nadpisi po osam X u Y}
SetTextStyle (0, 0, 2);
SetColor(14);
OutTextXY (Mx01-40, My005, ' Y ');
OutTextXY (Mx-40, My09-25, ' X ');
SetTextStyle (0, 0, 1);
SetColor(12);
End;
{-------Разметка осей----------}
procedure Razmetka;
begin
{Разметка оси Y}
Msy := Round (My09 / 40);
y := 1;
While y<=35 Do
Begin
Str (Y, St);
A := Round (My09 - Msy * y);
Line (Mx01+2, A, Mx01-2, A);
OutTextXY (Mx01-40, A-2, St);
y := y+1;
End;

{Разметка оси x}
Msx := Round (Mx09 / 20);
x := 1;
While x<=10 Do
Begin
Str (x, St);
A := Round (Mx01 + Msx * x);
Line (A, My09+3, A, My09-3 );
OutTextXY (A, My09+5, St);
x := x + 1;
end;
SetColor(2);
end;
{-------Вывод графика----------}
Procedure VivodGraph;
Begin
Opredelenie;
osikoord;
Razmetka;
Vivod;
readln;
End;
{-------Основная программа----------}
BEGIN
grafika_on;
VivodGraph;
grafika_off;
END.

Автор: Рэнэ 11.06.2007 17:50

Чуток переделала свой график... опять таки за исключением этих параметров процедур.. blum.gif
Теперь больше похоже на правду... только вот под осью Х лишняя линяя вылезает из точки (0,0), в чем проблема (см. пост выше)? give_rose.gif

Автор: Рэнэ 12.06.2007 19:46

Параметры процедуры: norespect.gif
- массив дат
- количество дней
- масив максимального, минимального и среднего значений курса доллара
Выдает мне сообщение "Нет возможности считать переменные данного типа", опять дело в типах данных? Или я с параметрами ошиблась? mega_chok.gif
Подскажите... give_rose.gif

Цитата
{-------Построение графика----------}
Procedure Draw;
const n=20;
type
MasDat=array[1..n] of Integer;
MasMax=array[1..35] of Real;
MasMin=array[1..35] of Real;
MasSred=array[1..35] of Real;
Var
x1,x2,x3:MasDat;
y1:MasMax;
y2:MasMin;
y3:MasSred;
Begin
Assign (F1, 'c:\Vivod.txt');
Reset (F1);
While Not EOF (F1) do
begin
Read (F1,x1);
Readln (F1,y2);
LineTo(round(Mx01+Msx*x1), round(My09-Msy*y2));

end;
Close (F1);
end;

Автор: volvo 12.06.2007 19:58

Цитата
Read (F1,x1);
- делать нельзя... Массивы читаются поэлементно... То же самое и строкой ниже.

Хотя, смотрю я на строку:
LineTo(round(Mx01+Msx*x1), round(My09-Msy*y2));
, и у меня почему-то такое чувство, что ты просто перепутала типы... Скорее всего, X1 и Y2 имеют просто типы Integer и Real соответственно...

Автор: Рэнэ 13.06.2007 9:28

С процедурами я вроде бы разобралась, но вот сам вывод графика что-то не получается... точки он выводит верно, но вот линии от одной точки до другой выводяться неправильно, но что хуже он рисует от последней выведенной точки линию вниз к оси (но ее быть не должно)... время поджимает, а никак понять не могу в чем тут дело? give_rose.gif

Цитата
Program Grafic;
Uses Crt, Graph;
Const n=20;
Type
MasData = Array[1..n] of Integer;
MasMax = Array[1..35] of Real;
MasMin = Array[1..35] of Real;
MasSred = Array[1..35] of Real;
Var
x: integer;
b: MasData;
d: MasData;
e: MasData;
c : MasMax;
k:MasMin;
l: MasSred;
y:real;
St : String[4];
A,i, Mx, Mx01, Mx09, Msx, My, My09, My005, Msy : Integer;
F1: Text;
{-------Выход из графического режима----------}
PROCEDURE grafika_off;
BEGIN
closegraph;
END;

{-------Переход в графический режим----------}
PROCEDURE grafika_on;
var
Ga, Gm, Error : Integer;
BEGIN
Ga := Detect;
Gm := Detect;
InitGraph (Ga, Gm, 'c:\bp\bgi');
Error := GraphResult;
If Error <> Grok Then
Begin
Writeln('Ошибка!Графический драйвер не найден',#10#13,GraphErrorMSG (Error));
Halt;
End;
End;
{-------Вывод данных из файла----------}
Procedure Vivod(var b: MasData;c: MasMax;d: MasData;k:MasMin;e: MasData;l: MasSred);
Begin
Assign (F1, 'c:\Vivod.txt');
Reset (F1);
While Not EOF (F1) do
begin
For i:=1 to n do
Read(F1,b[i],c[i]);
LineTo(round(Mx01+Msx*b[i]), round(My09-Msy*c[i]),100);
Read(F1,d[i],k[i]);
LineTo(round(Mx01+Msx*d[i]), round(My09-Msy*k[i]),10);
Read(F1,e[i],l[i]);
LineTo(round(Mx01+Msx*e[i]), round(My09-Msy*l[i]),10);
end;
Close (F1);
End;
{-------Определение используемых значений----------}
procedure Opredelenie;
Begin
Mx := GetMaxX;
Mx01 := Round (0.1* Mx);
Mx09 := Round (0.9* Mx);
My := GetMaxY;
My09 := Round (0.9*My);
My005 := Round (0.05* My);
SetColor (12);
end;
{-------Вывод осей координат----------}
procedure osikoord;
begin
Line (20, My09, Mx-10, My09);
Line (Mx01, My005, Mx01, My-9);

{Risovanie strelok}
Line (Mx-20, My09-3, Mx-10, My09);
Line (Mx-20, My09+3, Mx-10, My09);
Line (Mx01, My005, Mx01-3, My005+10);
Line (Mx01, My005, Mx01+3, My005+10);

{Nadpisi po osam X u Y}
SetTextStyle (0, 0, 2);
SetColor(14);
OutTextXY (Mx01-40, My005, ' Y ');
OutTextXY (Mx-40, My09-25, ' X ');
SetTextStyle (0, 0, 1);
SetColor(12);
End;
{-------Разметка осей----------}
procedure Razmetka;
begin
{Разметка оси Y}
Msy := Round (My09 / 40);
y := 1;
While y<=35 Do
Begin
Str (Y, St);
A := Round (My09 - Msy * y);
Line (Mx01+2, A, Mx01-2, A);
OutTextXY (Mx01-40, A-2, St);
y := y+1;
End;

{Разметка оси x}
Msx := Round (Mx09 / 20);
x := 1;
While x<=n Do
Begin
Str (x+1, St);
A := Round (Mx01 + Msx * x);
Line (A, My09+3, A, My09-3 );
OutTextXY (A, My09+5, St);
x := x + 1;
end;
SetColor(2);
end;
{-------Вывод графика----------}
Procedure VivodGraph;
Begin
Opredelenie;
osikoord;
Razmetka;
Vivod(b,c,d,k,e,l);
readln;
End;
{-------Основная программа----------}
BEGIN
grafika_on;
VivodGraph;
grafika_off;
END.

Автор: volvo 13.06.2007 18:26

Файл данных присоедини (именно присоедини, а не скопируй как текст - важно видеть ИМЕННО твой файл, до последнего байта!), пока его не будет - это все "испорченные телефоны", можно улучшать и улучшать то, что ты привела, но одна лишняя строка в файле уничтожат всю работу...

Автор: Рэнэ 13.06.2007 18:27

Нужна помощь...
До сдачи один день, помогите доделать программу... give_rose.gif give_rose.gif

Как сделать так чтобы вместо того чтобы проводить линии из начала координат до каждой точки, он проводил линию от точки до точки...

Цитата
{-------Вывод данных из файла----------}
Procedure Vivod(var b: MasData;c: MasMax;d: MasData;k:MasMin;e: MasData;l: MasSred);
Begin
Assign (F1, 'c:\Vivod.txt');
Reset (F1);
While Not EOF (F1) do
begin
If i:=1 to n do
begin
Read(F1,b[i],c[i]);
MoveTo(Mx01,My09);
LineTo(round(Mx01+Msx*b[i]), round(My09-Msy*c[i]));
SetColor (7);
Read(F1,d[i],k[i]);
LineTo(round(Mx01+Msx*d[i]), round(My09-Msy*k[i]));
SetColor (4);
Read(F1,e[i],l[i]);
LineTo(round(Mx01+Msx*e[i]), round(My09-Msy*l[i]));
SetColor (1);
end;
end;
Close (F1);
End;

Автор: Рэнэ 14.06.2007 12:27

Выдает ошибку: Нужен идентефикатор поля, в чем проблема?

Цитата
{-------Вывод данных из файла----------}
Procedure Vivod(var b: MasData;c: MasMax);
var i:byte;
p:array[1..6] of PointType;
Begin
Assign (F1, 'c:\Vivod.txt');
Reset (F1);
While Not EOF (F1) do
begin
for i:=1 to n do
begin
Read(F1,b[i],c[i]);
MoveTo(Mx01,My09);
for i:=1 to 6 do begin
b[i]:=(b[i]-Msx+20)*Mx;
c[i]:=getmaxy - (c[i]-Msy+40)*My;
end;
for i:=1 to 6 do begin
p[i].b:=trunc(b[i]);
p[i].c:=trunc(c[i]);

end;
drawpoly(6,p);
readln;
end;
end;
Close (F1);
End;
End;

procedure Opredelenie;
Begin
Mx := GetMaxX;
Mx01 := Round (0.1* Mx);
Mx09 := Round (0.9* Mx);
My := GetMaxY;
My09 := Round (0.9*My);
My005 := Round (0.05* My);
SetColor (12);
end;

Автор: Ozzя 14.06.2007 12:41

p[i].x:=trunc(b[i]); 
p[i].y:=trunc(c[i]);


Ибо тип описан как

type
PointType = record
х, у : Word
end;

Автор: Рэнэ 14.06.2007 13:07

выдает: Недопустимая операция с плавающей запятой... dry.gif

Цитата
{-------Вывод данных из файла----------}
Procedure Vivod(var b: MasData;c: MasMax);
var i:byte;
p:array[1..6] of PointType;
Begin
Assign (F1, 'c:\Vivod.txt');
Reset (F1);
While Not EOF (F1) do
begin
for i:=1 to n do
begin
Read(F1,b[i],c[i]);
MoveTo(Mx01,My09);
for i:=1 to 6 do begin
b[i]:=(b[i]-Msx+20)*Mx;
c[i]:=getmaxy - (c[i]-Msy+40)*My;
end;
for i:=1 to 6 do begin
p[i].f:=round(b[i]);
p[i].j:=round(c[i]);

end;
drawpoly(6,p);
readln;
end;
end;
Close (F1);
End;

Автор: volvo 14.06.2007 13:20

А тебе говорили уже, что это - "испорченные телефоны"? Говорили... Ты КАЖДЫЙ раз что-то меняешь, что-то химичишь, а сделать самое простое: присоединить файл данных и ПОСЛЕДНЮЮ версию программы в аттач (чтобы можно было проверить, пойми, если я сейчас начну делать то же самое - ошибок никаких не будет, ты что же думаешь, тебя просто так просят что-то сделать? Больше дел других нет? Ошибку надо ЛОКАЛИЗОВАТЬ, для этого мне надо создать абсолютно те же условия, что и у тебя, без данных этого не будет) не желаешь... Так разбирайся сама... dry.gif

Автор: Рэнэ 14.06.2007 13:28

Извините, пожалуйста unsure.gif


Прикрепленные файлы
Прикрепленный файл  Vivod.txt ( 68 байт ) Кол-во скачиваний: 161
Прикрепленный файл  prog.pas ( 2.67 килобайт ) Кол-во скачиваний: 161

Автор: Ozzя 14.06.2007 14:06

round выдает значение типа real, и ты пытаешься присвоить типу integer

Автор: мисс_граффити 14.06.2007 14:55

Цитата
round выдает значение типа real

blink.gif
да? а в хелпе пишут:
function Round(X: Real): LongInt;

что-то ты в Vivod сильно намудрила с циклами.
Procedure Vivod(var b: MasData;c: MasMax);
var i:byte;
p:array[1..6] of PointType;
Begin
Assign (F1, 'c:\Vivod.txt');
Reset (F1);
While Not EOF (F1) do //пока не конец файла
begin
for i:=1 to n do //еще один цикл. то есть на каждую проверку на законченность файла...
begin
Read(F1,b[i],c[i]); //делаем n считываний b[i] и c[i]. не многовато?
MoveTo(Mx01,My09); //и каждый раз перемещаемся в одну точку
for i:=1 to 6 do //дальше - интереснее. вложенный цикл по той же переменной
begin
b[i]:=(b[i]-Msx+20)*Mx; //мы могли считать только b[1], а ты уже с b[6] пытаешься работать
c[i]:=getmaxy - (c[i]-Msy+40)*My;
end;
for i:=1 to 6 do //опять по i цикл.
begin
p[i].f:=round(b[i]);
p[i].j:=round(c[i]);
end;
drawpoly(6,p);
readln;
end;
end;
Close (F1);
End;

Автор: Ozzя 14.06.2007 15:08

А , с int'ом перепутал
Бывает

Седина в бороду, мозги наружу dry.gif

Автор: volvo 14.06.2007 15:12

Оззя, правда? С каких пор? wink.gif

Рэнэ,
проблема совсем не в этом... Ты некорректно производишь масштабирование, у тебя значения после масштабирования получаются запредельные... Смотри, как я сделал (это отображает график):

Procedure Vivod(var b: MasData;c: MasMax);
var
i, n: byte;
p: array[1..6] of PointType;
Begin
Assign (F1, 'Vivod.txt'); Reset (F1);
n := 0;
{ сначала - читаем ВСЕ данные из файла, сколько есть }
while not seekeof(F1) do begin
inc(n);
Read(F1,b[n],c[n]);
end;

{ Потом - масштабируем их: }
for i:=1 to n do begin
b[i] := pred(b[i]) * msx + mx01;
c[i] := getmaxy - (c[i] * msy + my005);
end;

{ и заносим координаты точек в полигон (хотя это вполне можно сделать в предыдущем цикле) }
for i:=1 to n do begin
p[i].f:=b[i]; { <--- здесь round не нужен, число и так целое }
p[i].j:=round(c[i]); { <--- а вот тут - нужен }
end;

{ и рисуем график }
drawpoly(n,p);

Close (F1);
End;


Автор: Ozzя 14.06.2007 15:18

Цитата
Оззя, правда? С каких пор?

Дык, как модератора в разделе поменяли dry.gif
Загляжусь, бывало на профиль нового модератора give_rose.gif
И забуду, кто я, что я wub.gif unsure.gif rolleyes.gif

И всё-таки,
Почему упорно пишет тут так
      p[i].f:=b[i]; { <--- здесь round не нужен, число и так целое }
p[i].j:=
а не так

      p[i].x=b[i]; { <--- здесь round не нужен, число и так целое }
p[i].y:=


?

Автор: volvo 14.06.2007 15:22

Потому, что сначала делалось так:

PointType = record
f,j : Word
end;

(мотоцикл надо свой обязательно, нельзя же пользоваться стандартной PointType) smile.gif

Автор: мисс_граффити 14.06.2007 15:32

вот так вроде работает:

Procedure Vivod(var b: MasData;var c: MasMax);
var i,days:byte;
p:array[1..50] of PointType;
Begin
Assign (F1, 'Vivod.txt');
Reset (F1);
i:=1;
While Not EOF (F1) do
begin
read(F1,b[i],c[i]);
inc(i);
end;
Close(F1);
days:=i-2;

MoveTo(Mx01,My09);

for i:=1 to days do
begin
b[i]:=b[i]*Msx+60;
c[i]:=getmaxy - c[i]*Msy-50;
p[i].f:=round(b[i]);
p[i].j:=round(c[i]);
end;

drawpoly(days,p);
End;


хотя я бы подсчет дней и заполнение массивов b и c вынесла отдельной процедурой. да и заданию это соответствовало бы точнее.

Добавлено через 2 мин.
как всегда увлеклась отладкой и не заметила, что все уже сделано smile.gif