- •Национальный исследовательский университет Высшая школа экономики
- •Управления разработкой программного обеспечения Контрольное домашнее задание по дисциплине «Программирование»
- •Условие задачи
- •Функции разрабатываемого приложения
- •Варианты использования
- •Описание интерфейса пользователя
- •Структура приложения
- •Диаграмма классов
- •Описание классов, их полей и методов
- •Распределение исходного кода по файлам проекта
- •Проект Main
- •Проект AddStudent
- •Проект Students
- •Контрольный пример и описание результатов
- •Исходный код программы
- •Код библиотеки классов Students
- •Список литературы:
Проект Students
Библиотека классов приложения, организующая взаимоотношения между классами, их иерархию наследования, методы, конструкторы и свойств.
Контрольный пример и описание результатов
Запустим приложение
Создадим новый файл (Создать)
Добавим несколько учащихся (Добавить), задав им параметры
Отредактируем параметры (Редактировать)
Удалим какого-либо учащегося (Удалить)
Сохраним результат в файл (Сохранить)
После выхода из программы (Файл-выход) откроем сохранённый нами файл (Открыть)
Отсортируем учащихся по типу (Сортировать)
С помощью поиска найдём какого-либо учащегося
В данном примере продемонстрированы основные возможности приложения.
Исходный код программы
Код библиотеки классов Students
namespace MyLib
{
public class Учащийся //базовый класс
{
string фамилия,вуз,факультет;
public string Фамилия { get { return фамилия; } set { фамилия = value; } }
public string Вуз { get { return вуз; } set { вуз = value; } }
public string Факультет { get { return факультет; } set { факультет = value; } }
virtual public string display()
{ return string.Format("{0,-50} {1,-30} {2,-30}", "Учащийся: " + Фамилия, "Вуз: " + Вуз, "Факультет: " + Факультет); }
}
public class СтудентБакалавриата : Учащийся //производный класс СтудентБакалавриата
{
uint курс,рейтинг;
public СтудентБакалавриата(string фамилия1, string вуз1, string факультет1, uint курс1, uint рейтинг1) : base()
{
Фамилия = фамилия1; Вуз = вуз1; Факультет = факультет1; курс = курс1; рейтинг = рейтинг1;
}
public uint Курс { get { return курс; } set { курс = value; } }
public uint Рейтинг { get { return рейтинг; } set { рейтинг = value; } }
override public string display()
{
return string.Format("{0,-50} {1,-30} {2,-30} {3,-30} {4,-30}", "Студент бакалавриата: " + Фамилия, "Вуз: " + Вуз, "Факультет: " + Факультет, "Курс: " + Курс, "Рейтинг: " + Рейтинг);
}
}
public class СтудентМагистратуры : Учащийся //производный класс СтудентМагистратуры
{
uint курс;
string темаДиссертации;
public СтудентМагистратуры(string фамилия1, string вуз1, string факультет1, uint курс1, string темаДиссертации1) : base()
{
Фамилия = фамилия1; Вуз = вуз1; Факультет = факультет1; курс = курс1; темаДиссертации = темаДиссертации1;
}
public uint Курс { get { return курс; } set { курс = value; } }
public string ТемаДиссертации { get { return темаДиссертации; } set { темаДиссертации = value; } }
override public string display()
{
return string.Format("{0,-50} {1,-30} {2,-30} {3,-30} {4,-30}", "Студент магистратуры: " + Фамилия, "Вуз: " + Вуз, "Факультет: " + Факультет, "Курс: " + Курс, "Тема диссертации: " + ТемаДиссертации);
}
}
public class Аспирант : Учащийся //производный класс Аспирант
{
string темаДиссертации, научныйРуководитель;
public Аспирант(string фамилия1, string вуз1, string факультет1, string темаДиссертации1, string научныйРуководитель1) : base()
{
Фамилия = фамилия1; Вуз = вуз1; Факультет = факультет1; темаДиссертации = темаДиссертации1; научныйРуководитель = научныйРуководитель1;
}
public string ТемаДиссертации { get { return темаДиссертации; } set { темаДиссертации = value; } }
public string НаучныйРуководитель { get { return научныйРуководитель; } set { научныйРуководитель = value; } }
override public string display()
{
return string.Format("{0,-50} {1,-30} {2,-30} {3,-30} {4,-30}", "Аспирант: " + Фамилия, "Вуз: " + Вуз, "Факультет: " + Факультет, "Тема диссертации: " + ТемаДиссертации, "Научный руководитель: " + НаучныйРуководитель);
}
}
}
Код Form1(Main)
using AddStudent;
using Students;
using System.IO;
namespace Main
{
public partial class Form1 : Form
{
string FileName = "Список учащихся"; //Запоминание имени файла для начального значения имени SaveAs
bool b = false; //проверка существования файла текущего документа
Учащийся[] Mas = new Учащийся[0];//массив списка
//метод добавления учащегося в список
void Add()
{
Form2 newform = new Form2("", "", "", true); //"","","" bool определяет текст кнопки и формы(true-добавление,добавить; false-редактирование,сохранить изменения)
newform.ShowDialog();
if (newform.DialogResult == DialogResult.OK)
{
listBox1.Items.Add(newform.ReturnData());//добавляем данные в список
Array.Resize(ref Mas, Mas.Length + 1);
Mas[Mas.Length - 1] = newform.ReturnMas();//добавляем данные в массив
}
Count();//пересчитываем статистику
}
//метод редактирования данных об учащемся
void Edit()
{
int a = listBox1.SelectedIndex;
if (a < 0) return;//если объект не выделен
else
{
Form2 newform = new Form2(Mas[a].Фамилия, Mas[a].Вуз, Mas[a].Факультет, false);//открываем форму 2 с параметром false
newform.ShowDialog();
if (newform.DialogResult == DialogResult.OK)
{
Mas[a] = newform.ReturnMas();//изменяем данные массива
listBox1.Items[a] = newform.ReturnData();//изменяем данные списка
}
Count();//пересчитываем статистику
}
}
//метод удаления учащегося из списка
void Del()
{
if (listBox1.SelectedIndex >= 0) listBox1.Items.RemoveAt(listBox1.SelectedIndex); else return;//удаление с проверкой на существования выделения
Array.Resize(ref Mas, 0);//обнуляем массив
for (int i = 0; i < listBox1.Items.Count; i++) Read(listBox1.Items[i].ToString());//заполняем
Count();//пересчитываем статистику
}
//метод считающий статистику (количество учащихся, средний рейтинг курсов бакалавриата)
void Count()
{
toolStripStatusLabel1.Text = "Количество учащихся в списке: " + listBox1.Items.Count;
//подсчёт среднего рейтинга студентов бакалавриата каждого курса
uint[] K = new uint[4]; //массив количества студентов курсов
uint[] S = new uint[4]; //массив суммы рейтингов студентов курсов
for (int i = 0; i < Mas.Length; i++) if (Mas[i] is СтудентБакалавриата)
{
S[((СтудентБакалавриата)Mas[i]).Курс - 1] += ((СтудентБакалавриата)Mas[i]).Рейтинг;
K[((СтудентБакалавриата)Mas[i]).Курс - 1]++;
}
string str = ""; //строка результата среднего рейтинга
bool e = false;//проверка - есть ли хотя бы один студент бакалавра
for (int i = 0; i < 4; i++) if (S[i] > 0) { e = true; str += string.Format(" " + (i + 1) + " курс: {0:f1} ", S[i] / K[i]); }
if (e == true) toolStripStatusLabel2.Text = "Средний рейтинг бакалавров: " + str; else toolStripStatusLabel2.Text = "";//вывод
}
//метод "Сохранить"
void Save()
{
try
{
if (b == false) { SaveAs(); return; }//если файл не создан используем "Сохранить как"
StreamWriter sw = new StreamWriter(FileName);
for (int i = 0; i < listBox1.Items.Count; i++) { sw.WriteLine(listBox1.Items[i].ToString()); }
sw.Flush();
}
catch { }
}
//метод "Сохранить как"
void SaveAs()
{
SaveFileDialog dlg = new SaveFileDialog();
dlg.FileName = Path.GetFileName(FileName);//начальному значению в поле имени файла присваивается имя текущего файла
dlg.Filter = "Text Files | *.txt";
dlg.DefaultExt = "txt";
var result = dlg.ShowDialog();
if (result == System.Windows.Forms.DialogResult.OK)
{
FileName = dlg.FileName;//присваиваем текущему имени файла значение из диалога
StreamWriter sw = new StreamWriter(dlg.FileName);
for (int i = 0; i < listBox1.Items.Count; i++) { sw.WriteLine(listBox1.Items[i].ToString()); }
sw.Flush();
b = true;//текущий файл существует
this.Text = Path.GetFileName(dlg.FileName) + " - Список учащихся";//обновление текста формы
}
}
//метод для чтения строки и преобразования её в объект массива
void Read(string line)
{
string[] s = line.Split(' '); //разбиваем на массив подстрок
int z = 0; //идентификатор элемента массива разделённой строки
for (int i = 0; i < s.Length; i++) //форматируем массив, удаляем пустые строки
{
s[i] = s[i].Trim();
if (s[i] != "") { s[z] = s[i]; z++; }
}
Array.Resize(ref s, z); //обрезаем лишние строки
try
{
//в зависимости от класса читаем строку нужным способом
switch (s[1])
{
//студент бакалавриата
case "бакалавриата:":
string sb1 = "", sb2 = "", sb3 = ""; uint ub1, ub2, jb = 2;
while (s[jb] != "Вуз:") { sb1 += s[jb] + " "; ++jb; } jb++;
while (s[jb] != "Факультет:") { sb2 += s[jb] + " "; ++jb; } jb++;
while (s[jb] != "Курс:") { sb3 += s[jb] + " "; ++jb; } jb++;
uint.TryParse(s[jb], out ub1);
uint.TryParse(s[jb + 2], out ub2);
Array.Resize(ref Mas, Mas.Length + 1);
Mas[Mas.Length - 1] = new СтудентБакалавриата(sb1, sb2, sb3, ub1, ub2);
break;
//студент магистратуры
case "магистратуры:":
string sm1 = "", sm2 = "", sm3 = "", sm4 = ""; uint um1, jm = 2;
while (s[jm] != "Вуз:") { sm1 += s[jm] + " "; ++jm; } jm++;
while (s[jm] != "Факультет:") { sm2 += s[jm] + " "; ++jm; } jm++;
while (s[jm] != "Курс:") { sm3 += s[jm] + " "; ++jm; } jm++;
uint.TryParse(s[jm], out um1); jm += 3;
while (jm < s.Length) { sm4 += s[jm] + " "; ++jm; }
Array.Resize(ref Mas, Mas.Length + 1);
Mas[Mas.Length - 1] = new СтудентМагистратуры(sm1, sm2, sm3, um1, sm4);
break;
//аспирант
default:
string sa1 = "", sa2 = "", sa3 = "", sa4 = "", sa5 = ""; uint ja = 1;
while (s[ja] != "Вуз:") { sa1 += s[ja] + " "; ++ja; } ja++;
while (s[ja] != "Факультет:") { sa2 += s[ja] + " "; ++ja; } ja++;
while (s[ja] != "Тема") { sa3 += s[ja] + " "; ++ja; } ja += 2;
while (s[ja] != "Научный") { sa4 += s[ja] + " "; ++ja; } ja += 2;
while (ja < s.Length) { sa5 += s[ja] + " "; ++ja; }
Array.Resize(ref Mas, Mas.Length + 1);
Mas[Mas.Length - 1] = new Аспирант(sa1, sa2, sa3, sa4, sa5);
break;
}
}
catch { MessageBox.Show("Не удаётся прочитать файл! Проверьте корректность данных.", "Ошибка!"); New(); return; }
}
//метод "Открыть файл"
void Open()
{
try
{
OpenFileDialog dlg = new OpenFileDialog();
dlg.Filter = "Text Files | *.txt";
dlg.DefaultExt = "txt";
var result = dlg.ShowDialog();
if (result == DialogResult.OK)
{
FileName = dlg.FileName;
listBox1.Items.Clear(); //очищаем список перед тем как его заполнить
StreamReader sr = new StreamReader(dlg.FileName);
Array.Resize(ref Mas, 0); //обнуляем массив перед чтением файла
while (true)
{
string line = sr.ReadLine();
if (line == null) break;
Read(line);//заполняем массив
listBox1.Items.Add(Mas[Mas.Length - 1].display());//отображаем элементы в списке методом display
}
b = true;//текущий файл существует
this.Text = Path.GetFileName(dlg.FileName) + " - Список учащихся";//обновление текста формы
Count();//пересчитываем статистику
}
}
catch { }
}
//метод "Создать файл"
void New()
{
//обнуляем список и массив
listBox1.Items.Clear();
Array.Resize(ref Mas, 0);
Count(); //пересчитываем статистику
b = false; //текущего файла не существует. При сохранении будет выполняться "Сохранить как"
this.Text = "Список учащихся";//обновление текста формы
}
//метод для сортировки списка/массива
void Sort()
{
Array.Sort(Mas, SortType);
listBox1.Items.Clear();
for (int i = 0; i < Mas.Length; i++) listBox1.Items.Add(Mas[i].display());
}
//Вспомогательный метод для перегрузки Array.Sort. Сортировка по типу
static int SortType(Учащийся A, Учащийся B)
{
if (A is СтудентБакалавриата && B is СтудентБакалавриата) return 0;
if (A is СтудентМагистратуры && B is СтудентМагистратуры) return 0;
if (A is Аспирант && B is Аспирант) return 0;
if (A is Аспирант) return 1;
if (B is Аспирант) return -1;
if (A is СтудентБакалавриата) return -1;
if (B is СтудентБакалавриата) return 1;
return 0;
}
//метод поиска в списке(поиск по фамилии, вузу, факультету)
void Search()
{
if (SearchBox.Text.Trim() == "") { listBox1.ClearSelected(); return; }//если ничего не введено - снимаем выделение
for (int i = 0; i < Mas.Length; i++)
if (Mas[i].Фамилия.ToUpper().Contains(SearchBox.Text.Trim().ToUpper()) ||
Mas[i].Вуз.ToUpper().Contains(SearchBox.Text.Trim().ToUpper()) ||
Mas[i].Факультет.ToUpper().Contains(SearchBox.Text.Trim().ToUpper())) listBox1.SetSelected(i, true);//выделяем, если соответствует поиску
else listBox1.SetSelected(i, false);//снимаем выделение, если нет
}
public Form1()
{
InitializeComponent();
}
private void выходToolStripMenuItem_Click(object sender, EventArgs e)
{
this.Close(); //закрываем форму
}
private void toolStripButton4_Click(object sender, EventArgs e)
{
Add();
}
private void toolStripButton5_Click(object sender, EventArgs e)
{
Del();
}
private void добавитьToolStripMenuItem_Click(object sender, EventArgs e)
{
Add();
}
private void удалитьToolStripMenuItem_Click(object sender, EventArgs e)
{
Del();
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
Count();
}
private void создатьToolStripMenuItem_Click(object sender, EventArgs e)
{
New();
}
private void сохранитьToolStripMenuItem_Click(object sender, EventArgs e)
{
Save();
}
private void сохранитьКакToolStripMenuItem_Click(object sender, EventArgs e)
{
SaveAs();
}
private void открытьToolStripMenuItem_Click(object sender, EventArgs e)
{
Open();
}
private void toolStripButton1_Click(object sender, EventArgs e)
{
New();
}
private void toolStripButton2_Click(object sender, EventArgs e)
{
Open();
}
private void toolStripButton3_Click(object sender, EventArgs e)
{
Save();
}
private void сохранитьToolStripMenuItem1_Click(object sender, EventArgs e)
{
Save();
}
private void toolStripButton6_Click(object sender, EventArgs e)
{
Edit();
}
private void редактироватьToolStripMenuItem_Click(object sender, EventArgs e)
{
Edit();
}
private void сортироватьToolStripMenuItem_Click(object sender, EventArgs e)
{
Sort();
}
private void toolStripButton7_Click(object sender, EventArgs e)
{
Sort();
}
private void SearchBox_TextChanged(object sender, EventArgs e)
{
Search();//выполняем поиск при изменении текста в поиске
}
//заново показать результаты поиска при клике
private void SearchBox_Click(object sender, EventArgs e)
{
Search();
}
//очищаем поле поиска и выделение при нажатии кнопки "Очистить"
private void toolStripButton8_Click(object sender, EventArgs e)
{
SearchBox.Text = "";
listBox1.ClearSelected();
}
}
}
Код Form2(AddStudent)
using Students;
namespace AddStudent
{
public partial class Form2 : Form
{
public Form2(string s1, string s2, string s3, bool b)//зависимость формы от параметров
{
InitializeComponent();
this.ClientSize = new Size(219, 190);
textBox1.Text = s1;
textBox2.Text = s2;
textBox3.Text = s3;
if (b == false) { this.Text = "Редактирование"; Add.Text = "Сохранить изменения"; }//если форма вызвана кнопкой "Редактировать"
}
private void comboBox1_TextChanged(object sender, EventArgs e)
{
//зависимость данных формы от выбраннаго статуса студента
inf1.Text = "";
inf2.Text = "";
if (comboBox1.Text == "Студент бакалавриата") { i1.Text = "Курс:"; i2.Text = "Рейтинг в баллах:"; inf1.MaxLength = 1; inf2.MaxLength = 5; }
if (comboBox1.Text == "Студент магистратуры") { i1.Text = "Курс:"; i2.Text = "Тема диссертации:"; inf1.MaxLength = 1; inf2.MaxLength = 255; }
if (comboBox1.Text == "Аспирант") { i1.Text = "Тема диссертации:"; i2.Text = "Научный руководитель:"; inf1.MaxLength = 255; inf2.MaxLength = 255; }
this.ClientSize = new Size(219, 330); //расширяем форму до появления кнопки добавления/сохранения изменений
}
//кнопка Добавить/Сохранить изменения
private void Add_Click(object sender, EventArgs e)
{
uint temp, temp1;
bool b = false;//проверка корректности введённых данных
if (textBox1.Text != "" && textBox2.Text != "" && textBox3.Text != "")
{
switch (comboBox1.Text)
{
case "Студент бакалавриата": if (uint.TryParse(inf1.Text, out temp) && temp > 0 && temp <= 4 && uint.TryParse(inf2.Text, out temp1)) b = true; break;
case "Студент магистратуры": if (uint.TryParse(inf1.Text, out temp) && temp > 0 && temp <= 2 && inf2.Text != "") b = true; break;
case "Аспирант": if (inf1.Text != "" && inf2.Text != "") b = true; break;
}
}
if (b == false) { MessageBox.Show("Некорректно введены данные!", "Ошибка!"); return; }
this.DialogResult = DialogResult.OK;
}
//метод, возвращающий строку данных о студенте, соответствующий данным формы
public string ReturnData()
{
switch (comboBox1.Text)
{
case "Студент бакалавриата":
Учащийся A = new СтудентБакалавриата(textBox1.Text, textBox2.Text, textBox3.Text, uint.Parse(inf1.Text), uint.Parse(inf2.Text));
return A.display();
case "Студент магистратуры":
Учащийся B = new СтудентМагистратуры(textBox1.Text, textBox2.Text, textBox3.Text, uint.Parse(inf1.Text), inf2.Text);
return B.display();
case "Аспирант":
Учащийся C = new Аспирант(textBox1.Text, textBox2.Text, textBox3.Text, inf1.Text, inf2.Text);
return C.display();
}
return "";
}
//метод, возвращающий элемент массива, соответствующий данным формы
public Учащийся ReturnMas()
{
switch (comboBox1.Text)
{
case "Студент бакалавриата":
Учащийся A = new СтудентБакалавриата(textBox1.Text, textBox2.Text, textBox3.Text, uint.Parse(inf1.Text), uint.Parse(inf2.Text));
return A;
case "Студент магистратуры":
Учащийся B = new СтудентМагистратуры(textBox1.Text, textBox2.Text, textBox3.Text, uint.Parse(inf1.Text), inf2.Text);
return B;
case "Аспирант":
Учащийся C = new Аспирант(textBox1.Text, textBox2.Text, textBox3.Text, inf1.Text, inf2.Text);
return C;
}
Учащийся D = new СтудентБакалавриата("", "", "", 0, 0);
return D;
}
}
}