50381 (Разработка программы при помощи языка программирования языка Delphi), страница 3

2016-07-30СтудИзба

Описание файла

Документ из архива "Разработка программы при помощи языка программирования языка Delphi", который расположен в категории "". Всё это находится в предмете "информатика" из 1 семестр, которые можно найти в файловом архиве . Не смотря на прямую связь этого архива с , его также можно найти и в других разделах. Архив можно найти в разделе "курсовые/домашние работы", в предмете "информатика, программирование" в общих файлах.

Онлайн просмотр документа "50381"

Текст 3 страницы из документа "50381"

Процедура ShowAComp предназначена для вывода информации о всех компьютерах из массива AComp в поля таблицы. Синтаксис:

ShowAComp(AComp:ATComp;Sgr:TStringGrid).

где AComp – массив записей, хранящий информацию о компьютерах,

SGr – таблица, в которую производится вывод.

Алгоритм процедуры приведен на рисунке А.4.

3.3 Описание процедуры BOpenClick

Эта процедура является обработчиком события onClick для объектa NOpen, то есть запускается при щелчке на указанном объекте. В теле этого вызывается стандартный диалог открытия файла, в случае, если диалог был завершен успешно, имя файла сохраняется в переменной FName, производится чтение содержимого исходного файла в массив AComp, а затем его содержимое выводится на форму при помощи процедуры ShowAComp. Алгоритм процедуры приведен на рисунке А.2.

Процедура NShowClick является обработчиком события onClick для объектa NShow. В ней тоже происходит чтение файла в массив AComp и вывод содержимого на форму. Однако в этой процедуре не выполняется запуск диалога открытия файла, а производится чтение текущего файла, имя которого занесено в FName.



3.4 Описание процедуры BSaveAsClick

Эта процедура является обработчиком события onClick для объектa NSaveAs, то есть запускается при щелчке на указанном объекте. В теле этого вызывается стандартный диалог сохранения файла, в случае, если диалог был завершен успешно, имя файла сохраняется в переменной FName, производится сохранение содержимого массива AComp в файл с указанным именем. Алгоритм процедуры приведен на рисунке А.3.

Процедура NSaveClick является обработчиком события onClick для объектa NSave. В ней тоже происходит сохранение содержимого массива AComp в файл на жестком диске, однако в этой процедуре не выполняется запуск диалога сохранения файла, а производится сохранение в текущий файл, имя которого занесено в FName.

3.5 Процедуры навигации и редактирования

Процедура BBPrevClick является обработчиком события onClick для объектa BBPrev. Предназначена для перехода не предыдущую запись, для чего номер текущей записи CurK уменьшается на 1 и выводится на форму запись AComp[CurK] при помощи ShowComp. Следует заметить, что если текущая запись первая, то нажатие на кнопку переводит указатель на последнюю запись массива.

Процедура BBNextClick является обработчиком события onClick для объектa BBNext. Предназначена для перехода не следующую запись, для чего номер текущей записи CurK увеличивается на 1, а на форму выводится запись AComp[CurK] при помощи ShowComp. Следует заметить, что если текущая запись последняя, то нажатие на кнопку переводит указатель на первую запись массива.

Процедура BBDeleteClick является обработчиком события onClick для объектa BBDelete. Предназначена для удаления записи, для чего все записи после позиции CurK сдвигаются на одну позицию влево, а размерность массива уменьшается на 1.

Процедура BBUpdateClick является обработчиком события onClick для объектa BBUpdate. Предназначена для изменения данных о компьютере. В процедуре содержимое из полей ввода формы переносится в соответствующие поля текущего компьютера под номером CurK.

Процедура BBAddClick является обработчиком события onClick для объектa BBAdd. Предназначена для добавления данных о новом компьютере. В процедуре содержимое из полей ввода формы переносится в соответствующие поля компьютера, размер массива AComp увеличивается на 1 и новая запись добавляется в конец массива.

Процедура BBSearchClick является обработчиком события onClick для объектa BBSearch. Предназначена для поиска компьютеров по какому либо критерию. В процедуре анализируется содержимое из полей ввода формы, если содержимое пустое, то в поиске это поле не учитывается, если же нет, то происходит поиск записей с указанным значением соответствующего поля. Условия по всем полям объединяются условием И. Содержимое выборки заносится в массив Ares и выводится на форму. Следует заметить, что по текстовым полям «Наименование компьютера», «Тип монитора» выполняется сравнение не на полное соответствие строк, а на наличие указанной подстроки. То есть, если поле содержит искомый фрагмент и еще какую-то информацию, то такой компьютер тоже будет выведен.



4 ИНСТРУКЦИЯ ОПЕРАТОРУ

Разработанная программа представляет собой исполняемый файл Computers.exe размером 493 568 байт. В программе выполняется обработка типизированных файлов.

После запуска программы появляется окно, изображенное на рисунке 4.1.

Рисунок 4.1 – Главное окно программы

Главное меню содержит пункты:

- «Информация» (при нажатии запускается диалог с информацией о задании и разработчике, изображенный на рисунке 4.2);

- «Открыть файл» (при нажатии запускается диалог открытия файла, изображенный на рисунке 4.3)

- «Перенос» (при нажатии выполняются действия согласно заданию)

- «Сохранить результат» (при нажатии запускается диалог сохранения файла, изображенный на рисунке 4.4);

- «Выход» (закрывает программу)

Рисунок 4.2 – Информационное окно «Задание»

Рисунок 4.3 – Диалог открытия файла

Рисунок 4.4 – Диалог сохранения файла

В качестве примера введем некоторые данные о нескольких компьютерах и сохраним в файле, нажав на пункт меню «Сохранить как».

При помощи кнопок «Предыдущая запись» и «Следующая запись» можно перемещаться между записями о компьютерах. Если необходимо изменить данные о каком то компьютере, то необходимо перейти на запись о нем, изменить соответствующие данные в индивидуальных полях, а потом нажать на кнопку «Обновить». Запись этого компьютера в массиве будет изменена.

Для удаления записи следует нажать на кнопку «Удалить».

Для поиска нужно в требуемые поля написать данные запроса и нажать на кнопку «Поиск». Если записи по заданным критериям найдены, то информация об этих компьютерах будет выведена на форму.

Например, пусть критерием поиска будет имя ‘USER1 ’, а остальные поля оставим незаполненными. В результате будет выполнен поиск, выведены результаты, изображенные на рисунке 4.5. По результатам видно, что выводится компьютер с указанным именем.

Если мы хотим вновь отобразить содержимое обо всех введенных компьютерах, необходимо нажать на пункт главного меню Файл-> Показать. (см рисунок 4.6).

Рисунок 4.5 – Пример поиска

Рисунок 4.6 - Содержимое файла

Можно осуществить поиск по нескольким полям, например: выведем все компьютеры с объемом оперативной памяти 256 Мб и имеющих подключение к интернет. Пример запроса и результат приведен на рисунке 4.7.

Рисунок 4.7 – Результат поиска по нескольким полям


ВЫВОДЫ

Данный курсовой проект был выполнен в полном соответствии поставленному заданию и отлажен в среде DELPHI 7.0. В ходе выполнения курсовой работы была разработана программа для обработки типизированных файлов, а также создан визуальный интерфейс для создания и ведения базы о компьютерах предприятия.

В результате выполнения данной курсовой работы, я убедилась в широких возможностях языка программирования Object Pascal и среды проектирования Delphi 7.


Перечень ссылок

  1. Валентин Озеров «Советы по Delphi», 1999

  2. Зуев Е.А. Программирование на языке Turbo Pascal 6.0,7.0. – М.: Радио и связь, Веста, 1993.

  3. Фаронов В.В. Turbo Pascal 7.0. Начальный курс. - М.: Нолидж, 2000.

  4. Фаронов В.В. «DELPHI. Программирование на языке высокого уровня». – Питер, 2005.

  5. Дятченко Д.А. Методические указания к выполнению курсовой работы по дисциплине «Программирование и алгоритмические языки»– Северодонецк, 2005.



ПРИЛОЖЕНИЕ А


Алгоритм программы

Рисунок А.1 – Обработка событий главной формы программы

Рисунок А.2 – Открытие файла

типизированный файл программирование delphi

Рисунок А.3 – Алгоритм процедуры сохранения в файл

Рисунок А.4 – Алгоритм вывода содержимого массива AComp на форму


ПРИЛОЖЕНИЕ Б


Листинг программы

  1. unit Unit1;

  2. interface

  3. uses

  4. Windows, Messages, SysUtils, Variants, Classes, Graphics,

  5. Controls, Forms,Dialogs, Menus, StdCtrls, Buttons, ExtCtrls,

  6. Grids;

  7. type

  8. TForm1 = class(TForm)

  9. MainMenu1: TMainMenu;

  10. N1: TMenuItem;

  11. NOpen: TMenuItem;

  12. NSave: TMenuItem;

  13. NSaveAs: TMenuItem;

  14. NCreate: TMenuItem;

  15. N6: TMenuItem;

  16. NExit: TMenuItem;

  17. NInfo: TMenuItem;

  18. NShow: TMenuItem;

  19. SaveDlg: TSaveDialog;

  20. OpenDlg: TOpenDialog;

  21. Label1: TLabel;

  22. Label2: TLabel;

  23. Label3: TLabel;

  24. Label4: TLabel;

  25. Label9: TLabel;

  26. EHDD: TEdit;

  27. ERAM: TEdit;

  28. EMonitor: TEdit;

  29. RGrInet: TRadioGroup;

  30. EName: TEdit;

  31. SGrid1: TStringGrid;

  32. BBPrev: TBitBtn;

  33. BBNext: TBitBtn;

  34. BBDelete: TBitBtn;

  35. BBAdd: TBitBtn;

  36. BBUpdate: TBitBtn;

  37. BBSearch: TBitBtn;

  38. procedure FormCreate(Sender: TObject);

  39. procedure NCreateClick(Sender: TObject);

  40. procedure NOpenClick(Sender: TObject);

  41. procedure NShowClick(Sender: TObject);

  42. procedure NSaveClick(Sender: TObject);

  43. procedure NSaveAsClick(Sender: TObject);

  44. procedure NExitClick(Sender: TObject);

  45. procedure NInfoClick(Sender: TObject);

  46. procedure BBPrevClick(Sender: TObject);

  47. procedure BBNextClick(Sender: TObject);

  48. procedure BBUpdateClick(Sender: TObject);

  49. procedure BBAddClick(Sender: TObject);

  50. procedure BBDeleteClick(Sender: TObject);

  51. procedure BBSearchClick(Sender: TObject);

  52. private

  53. { Private declarations }

  54. public

  55. { Public declarations }

  56. end;

  57. TComp = record

  58. Name:string[20];

  59. HDD:real;

  60. RAM:integer;

  61. Monitor:string[20];

  62. Inet:boolean; {true - есть, false - нет}

  63. end;

  64. ATComp = array of TComp;

  65. var

  66. Form1: TForm1;

  67. F:file of TComp;

  68. Comp:TComp;

  69. AComp:ATComp;

  70. CurK:integer;

  71. Fname:string;

  72. implementation

  73. uses Unit2;

  74. {$R *.dfm}

  75. // поиск компьютера по имени

  76. Function GetComp(name:string;AComp:ATComp;var Comp:TComp):boolean;

  77. var i:integer;

  78. begin

  79. for i:=0 to Length(AComp)-1 do

  80. if AComp[i].Name = Name then

  81. begin

  82. Comp:=AComp[i];

  83. GetComp:=true;

  84. exit;

  85. end;

  86. GetComp:=false;

  87. end;

  88. // вывод информации об одном компьютерера из типизированного файла на экранную форму

  89. Procedure ShowComp(Comp:TComp);

  90. begin

  91. Form1.EName.Text:=Comp.Name;

  92. Form1.EHDD.Text:=FloatToStr(Comp.HDD);

  93. Form1.ERAM.Text:=IntToStr(Comp.RAM);

  94. if Comp.Inet then

  95. Form1.RgrInet.ItemIndex := 1

  96. else

  97. Form1.RgrInet.ItemIndex:=0;

  98. Form1.EMonitor.Text:=Comp.Monitor;

  99. end;

  100. // вывод информации о компьютере из типизированного файла в таблицу

  101. Procedure ShowCompInGrid(Comp:TComp;Sgr:TStringGrid;Row:integer);

  102. begin

  103. Sgr.Cells[0,Row]:=IntToStr(Row);

  104. Sgr.Cells[1,Row]:=Comp.Name;

  105. Sgr.Cells[2,Row]:=FloatToStr(Comp.HDD);

  106. Sgr.Cells[3,Row]:=IntToStr(Comp.RAM);

  107. Sgr.Cells[4,Row]:=Comp.Monitor;

  108. if Comp.Inet then

  109. Sgr.Cells[5,Row]:='есть'

  110. else

  111. Sgr.Cells[5,Row]:='нет';

  112. end;

  113. // вывод содержимого массива FComp в таблицу

  114. Procedure ShowAComp(AComp:ATComp;Sgr:TStringGrid);

  115. var i,ln:integer;

  116. begin

  117. ln:=Length(AComp);

  118. if ln = 0 then

  119. Sgr.RowCount:=2

  120. else

  121. Sgr.RowCount:=ln+1;

  122. SGr.FixedRows:=1;

  123. for i:=0 to LN-1 do

  124. ShowCompInGrid(AComp[i],Sgr,i+1);

  125. end;

  126. // добавление новой записи в массив

  127. procedure TForm1.BBAddClick(Sender: TObject);

  128. var

  129. k:integer;

  130. begin

  131. Comp.Name:=EName.Text;

  132. Comp.HDD:=StrToFloat(EHDD.Text);

  133. Comp.RAM:=StrToInt(ERAM.Text);

  134. Comp.Monitor:=EMonitor.Text;

  135. Comp.Inet:=RgrInet.ItemIndex = 1;

  136. //

  137. if GetComp(Comp.Name,AComp,Comp) then

  138. begin

  139. MessageBox(0,PAnsiChar(String('Ошибка! Запись компьютера с именем '+Comp.Name+' уже существует!')),'Ошибка',0);

  140. exit;

  141. end;

  142. k:=Length(AComp);

  143. SetLength(AComp,k+1);

  144. AComp[k]:=Comp;

  145. CurK:=k;

  146. ShowAComp(AComp,SGrid1);

  147. end;

  148. // переход на предыдущую запись массива

  149. procedure TForm1.BBPrevClick(Sender: TObject);

  150. begin

  151. curK:=CurK-1;

  152. if CurK<0 then CurK:=Length(AComp)-1;

  153. if CurK < Length(AComp) then

  154. ShowComp(AComp[CurK]);

  155. end;

  156. // переход на последующую запись массива

  157. procedure TForm1.BBNextClick(Sender: TObject);

  158. begin

  159. curK:=CurK+1;

  160. if CurK>=Length(AComp) then CurK:=0;

  161. if CurK < Length(AComp) then

  162. ShowComp(AComp[CurK]);

  163. end;

  164. // сохранение содержимого массива в типизированном файле

  165. procedure TForm1.NSaveClick(Sender: TObject);

  166. var i:integer;

  167. begin

  168. if Fname = '' then

  169. MessageBox(0,'Имя файла не задано!','Ошибка',0)

  170. else begin

  171. AssignFile(F,Fname);

  172. Rewrite(f);

  173. for i:=0 to Length(AComp)-1 do

  174. write(f,AComp[i]);

  175. CloseFile(F);

  176. end;

  177. end;

  178. // сохранение в содержимого массива в типизированном файле

  179. // с возможностью указания имени файла

  180. procedure TForm1.NSaveAsClick(Sender: TObject);

  181. var i:integer;

  182. begin

  183. if SaveDlg.Execute then

  184. begin

  185. Fname:=SaveDlg.FileName;

  186. AssignFile(F,Fname);

  187. Rewrite(f);

  188. for i:=0 to Length(AComp)-1 do

  189. write(f,AComp[i]);

  190. CloseFile(F);

  191. end;

  192. end;

  193. // открытие типизированного файла и вывод его содержимого на форму

  194. procedure TForm1.NOpenClick(Sender: TObject);

  195. var K:integer;

  196. begin

  197. if OpenDlg.Execute then

  198. begin

  199. Fname:=OpenDlg.FileName;

  200. AssignFile(F,Fname);

  201. ReSet(f);

  202. k:=0;

  203. SetLength(AComp,0);

  204. while not eof(f) do

  205. begin

  206. read(f,Comp);

  207. SetLength(AComp,k+1);

  208. AComp[k]:=Comp;

  209. k:=k+1;

  210. end;

  211. CloseFile(F);

  212. ShowAComp(AComp,SGRid1);

  213. end;

  214. end;

  215. // удаление текущей записи из массива записей AComp

  216. procedure TForm1.BBDeleteClick(Sender: TObject);

  217. var i,Ln:integer;

  218. begin

  219. Ln:=Length(AComp);

  220. for i:=CurK to Ln-2 do

  221. AComp[i]:=AComp[i+1];

  222. if Ln>0 then

  223. SetLength(AComp,Ln-1);

  224. if CurK

  225. ShowComp(AComp[CurK]);

  226. ShowAComp(AComp,SGrid1);

  227. end;

  228. // Создание нового массива записей

  229. procedure TForm1.NCreateClick(Sender: TObject);

  230. begin

  231. CurK:=0;

  232. SetLength(AComp,0);

  233. Fname:='';

  234. ShowAComp(AComp,SGrid1);

  235. end;

  236. // созание формы - формирование шапки таблицы

  237. procedure TForm1.FormCreate(Sender: TObject);

  238. begin

  239. SGrid1.Cells[0,0]:='№ п/п';

  240. SGrid1.Cells[1,0]:='Имя ПК';

  241. SGrid1.Cells[2,0]:='Объём памяти';

  242. SGrid1.Cells[3,0]:='Объём ОП';

  243. SGrid1.Cells[4,0]:='Тип монитора';

  244. SGrid1.Cells[5,0]:='Подключение к Internet';

  245. end;

  246. // чтение инофрмации из полей ввода и обновление

  247. // данных текцщей записи в массиве AComp

  248. procedure TForm1.BBUpdateClick(Sender: TObject);

  249. begin

  250. Comp.Name:=EName.Text;

  251. Comp.HDD:=StrToFloat(EHDD.Text);

  252. Comp.RAM:=StrToInt(ERAM.Text);

  253. Comp.Monitor:=EMonitor.Text;

  254. Comp.Inet:=RgrInet.ItemIndex = 1;

  255. //

  256. AComp[CurK]:=Comp;

  257. ShowCompInGrid(Comp,SGrid1,CurK+1);

  258. end;

  259. // ввод информации типизированного файла на форму

  260. procedure TForm1.NShowClick(Sender: TObject);

  261. var k:integer;

  262. begin

  263. AssignFile(F,Fname);

  264. ReSet(f);

  265. k:=0;

  266. SetLength(AComp,0);

  267. while not eof(f) do

  268. begin

  269. read(f,Comp);

  270. SetLength(AComp,k+1);

  271. AComp[k]:=Comp;

  272. k:=k+1;

  273. end;

  274. CloseFile(F);

  275. ShowAComp(AComp,SGRid1);

  276. end;

  277. // поиск записей, удовлетворяющих условию поиска

  278. procedure TForm1.BBSearchClick(Sender: TObject);

  279. var i,k:integer;

  280. Ares:ATComp;

  281. begin

  282. Comp.Name := EName.Text;

  283. if EHDD.Text = '' then

  284. Comp.HDD:=0

  285. else

  286. Comp.HDD:=StrtoFloat(EHDD.Text);

  287. if ERAM.Text = '' then

  288. Comp.RAM:=0

  289. else

  290. Comp.RAM:=StrtoInt(ERAM.Text);

  291. Comp.Monitor:=EMonitor.Text;

  292. Comp.Inet:=RgrInet.ItemIndex = 1;

  293. //

  294. k:=0;

  295. for i:=0 to Length(AComp) do

  296. if ((Comp.Name='')or(Pos(Comp.Name,AComp[i].Name)<>0))and

  297. ((Comp.HDD=0)or(Comp.HDD = AComp[i].HDD))and

  298. ((Comp.RAM=0)or(Comp.RAM = AComp[i].RAM))and

  299. ((Comp.Monitor='')or

  300. (Pos(Comp.Monitor,AComp[i].Monitor)<>0))and

  301. (Comp.Inet = AComp[i].Inet) then

  302. begin

  303. SetLength(Ares,k+1);

  304. Ares[k]:=AComp[i];

  305. k:=k+1;

  306. end;

  307. ShowAComp(Ares,SGrid1);

  308. end;

  309. // вывод информации о программе

  310. procedure TForm1.NInfoClick(Sender: TObject);

  311. begin

  312. AboutBox.ShowModal;

  313. end;

  314. // завершение работы приложения

  315. procedure TForm1.NExitClick(Sender: TObject);

  316. begin

  317. close;

  318. end;

  319. end.


ПРИЛОЖЕНИЕ В

Протокол выполнения программы

  1. Созданная программа позволяет добавлять, редактировать и удалять записи, так же позволяет осуществлять поиск по нескольким полям.

  2. При редактировании или удалении данных

  3. Размещено на Allbest.ru

Свежие статьи
Популярно сейчас
А знаете ли Вы, что из года в год задания практически не меняются? Математика, преподаваемая в учебных заведениях, никак не менялась минимум 30 лет. Найдите нужный учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Нашёл ошибку?
Или хочешь предложить что-то улучшить на этой странице? Напиши об этом и получи бонус!
Бонус рассчитывается индивидуально в каждом случае и может быть в виде баллов или бесплатной услуги от студизбы.
Предложить исправление
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
5057
Авторов
на СтудИзбе
456
Средний доход
с одного платного файла
Обучение Подробнее