Главная страница
Навигация по странице:

  • Контрольные вопросы

  • 24.1. Текст и график функции в форме

  • 24.2. Компонент Chart Создать программу отображения диаграммы двух функций с использованием компонента Chart. Проект – WindowsForm приложение. 130 Пример

  • Задание

  • Задание.

  • Лабораторная работа циклы. Поволжский государственный университет телекоммуникаций и информатики


    Скачать 3.57 Mb.
    НазваниеПоволжский государственный университет телекоммуникаций и информатики
    АнкорЛабораторная работа циклы
    Дата08.10.2022
    Размер3.57 Mb.
    Формат файлаpdf
    Имя файлаLR_CSharp_Akchurin_2010.pdf
    ТипДокументы
    #721430
    страница6 из 7
    1   2   3   4   5   6   7
    23.
    Таблицы
    Предмет исследований

    Cвойства компонентов label, button, textBox, dataGridView.

    События onClick, onChange, onCreate.

    Как создать код обработчика события.
    Контрольные вопросы
    События onClick, onCreate.
    1.
    Назначение и свойства компонента кнопка button.
    2.
    Назначение и свойства компонент метка label.
    3.
    Назначение и свойства компонента однострочный редактор textBox.
    4.
    Назначение и свойства компонента dataGridView.
    5.
    Как иници таблицу при старте приложения.
    6.
    Как создать обработчик события onClick.
    7.
    Как использовать строковые данные для вычислений.
    8.
    Задание. Создать проект “Таблица конвертации” для конвертации рублей Рос- сии в разные валюты с учетом комиссии. В таблице предусмотреть возмож- ность редактирования содержимого ячеек, добавления и удаления строк и столбцов.
    Пример.

    Запустить ИСР.

    Создать в ней новое WindowsForm приложение.

    Сохранить проект под именем WindowsFormTablitsa.

    122

    Свойству формы text присвить значение Таблица конвертации

    Установить на форме компоненты: однострочные редакторы textBox1 и textBox1, метки label1 и label2, кнопку button1, таблицу строк dataGridView1

    В окне свойств метки label1 свойство text = Комиссия % ==>.

    В окне свойств метки label1 свойство text = Ваши руб. ==>.

    В окне свойств кнопки button1 свойство text = Рассчитать.
    Правой кнопкой мыши вызвать для объекта dataGridView1 команду «Правка столбцов». Вызывается диалоговое окно
    В нем задаем заголовки столбцов. После установок интерфейс проекта примет вид

    123
    Двойным щелчком по кнопке в форме создать шаблоны обработчика нажатия на кнопку.
    Написать коды процедуры обработчика. В ней задаются 3 строки таблицы, задается комиссионный сбор, выбираются 3 валюты, для которых заносятся текущие курсы
    Листинг программы using
    System; using
    System.Windows.Forms; namespace
    WindowsFormsTablitsa
    { public partial class
    Form1
    :
    Form
    { public
    Form1()
    {
    InitializeComponent();

    124 dataGridView1.Rows.Add(3);
    } private void button1_Click(
    object sender,
    EventArgs e)
    { dataGridView1.Rows[0].Cells[0].Value =
    "Доллар США"
    ; dataGridView1.Rows[1].Cells[0].Value =
    "Евро"
    ; dataGridView1.Rows[2].Cells[0].Value =
    "Фунт UK"
    ; dataGridView1.Rows[0].Cells[1].Value =
    "30"
    ; double vd =
    System.
    Convert
    .ToDouble(dataGridView1.Rows[0].Cells[1].Value); dataGridView1.Rows[1].Cells[1].Value =
    "45"
    ; double ve =
    System.
    Convert
    .ToDouble(dataGridView1.Rows[1].Cells[1].Value); dataGridView1.Rows[2].Cells[1].Value =
    "50"
    ; double vf =
    System.
    Convert
    .ToDouble(dataGridView1.Rows[2].Cells[1].Value); string s = textBox1.Text; double k = System.
    Convert
    .ToDouble(s); s = textBox2.Text; double r = System.
    Convert
    .ToDouble(s); dataGridView1.Rows[0].Cells[2].Value = s; dataGridView1.Rows[1].Cells[2].Value = s; dataGridView1.Rows[2].Cells[2].Value = s; double kr = r*k/100; s = System.
    Convert
    .ToString(kr); dataGridView1.Rows[0].Cells[3].Value = s; dataGridView1.Rows[1].Cells[3].Value = s; dataGridView1.Rows[2].Cells[3].Value = s; double v = (r-kr)/vd; s = System.
    Convert
    .ToString(v); dataGridView1.Rows[0].Cells[4].Value = s; v = (r - kr) / ve; s = System.
    Convert
    .ToString(v); dataGridView1.Rows[1].Cells[4].Value = s; v = (r - kr) / vf; s = System.
    Convert
    .ToString(v); dataGridView1.Rows[2].Cells[4].Value = s;
    } private void dataGridView1_CellContentClick(
    object sender,

    125
    DataGridViewCellEventArgs e)
    {
    }
    }
    }
    Окно формы перед завершением программы:

    126
    24.
    Графика. Рисуем функции
    Предмет исследований

    Графические средства C#.

    Компонент Chart
    Контрольные вопросы
    Класс Graphics (графический объект).
    1.
    Класс Font - шрифт.
    2.
    Класс Pen - перо.
    3.
    Класс Brush - кисть.
    4.
    Вывод текста. Метод DrawString.
    5.
    Вывод линии. Метод DrawLine.
    6.
    Компонент Chart – средство отбражения диаграмм.
    7.
    ChartAreas – области диаграммы.
    8.
    Series – ряды диаграммы.
    9.
    Сколько рядов надо для рисования N графиков в одной области.
    10.
    Legendes – лененды диаграммы..
    11.
    Задание функции для отображения в компоненте Chart.
    12.
    Стили отображения диаграмм.
    13.
    Использование легенды в компоненте Chart.
    14.
    24.1.
    Текст и график функции в форме
    Создать программу вывода текста и рисования в форме графиков функций.
    Проект – WindowsForm приложение.

    127
    Пример. Создать программу рисования в форме графика функции с поясняю- щим текстом. Проект – WindowsForms приложение. Функция - синус. Програм- ма предусматривает рисование графика в форме Form1 линиями с помощью метода DrawLine. Над графиком с помощью метода DrawString выводится по- ясняющий текст. Кнопка Старт вызывает построение графиков в окне.
    Листинг программы

    128 using
    System; using
    System.Drawing; using
    System.Windows.Forms; namespace
    GraphicFunction
    { public partial class
    Form1
    :
    Form
    { public
    Form1()
    {
    InitializeComponent();
    } private void button1_Click(
    object sender,
    EventArgs e)
    { int imax =100;
    //число точек в периоде int t=2;
    //число периодов int amp=70;
    //амплитуда int h = 40;
    //отступ для текста int x0=20;
    //начала координат int y0 = h+amp; double
    [] f = new double
    [imax*t+10];
    // Функция for
    (
    int i = 0; i < imax * t; i++)
    { f[i] =
    Math
    .Round(amp *
    Math
    .Sin(2 *
    Math
    .PI / imax * i));
    }
    // Инструменты рисования
    Graphics g =
    Graphics
    .FromHwnd(
    this
    .Handle);
    // Где рисуем
    Pen pen =
    Pens
    .Black;
    // Чем рисуем
    // Текст заголовка g.DrawString(
    "График синусоиды"
    , new
    Font
    (
    "Arial"
    , 14),
    Brushes
    .Red, 0, 0);
    //Вывод текста
    //textBox1.Text = "График синусоиды";
    //Рисуем график g.DrawLine(pen , x0, y0, x0+imax*t, y0);
    //Рисуем ось X
    g.DrawLine(pen, x0, y0-amp, x0, y0+amp);
    //Рисуем ось Y for
    (
    int i = 0; i < imax * t; i++)
    //Рисуем график
    { int f1 = y0 - (
    int
    )f[i];
    //Координата Y[i]
    int f2 = y0 - (
    int
    )f[i + 1];
    //Координата Y[i+1]
    g.DrawLine(pen, x0+i, f1, x0+i+1, f2);

    129
    }
    } private void
    Form1_Load(
    object sender,
    EventArgs e)
    {
    }
    }
    }
    При прогоне программы получается результат:
    24.2.
    Компонент Chart
    Создать программу отображения диаграммы двух функций с использованием компонента Chart. Проект – WindowsForm приложение.

    130
    Пример. Создать программу отображения диаграммы двух функций sin(x) и cos(x) с использованием компонента Chart. Проект – WindowsForm приложе- ние. Стиль линий Spline.
    Создаем – WindowsForm приложение. В форму заносим компоненты chart1 для отображения диаграммыи button1 для создания стартового обработчика собы- тий.
    В окне свойств Button1 задаем его свойству Text значение Старт.
    В окне компонента Chart1 в раэделе Seies определяем две серии:

    Для функции sin(x) с именем Синус.

    Для функции cos(x) с именем Косинус.
    Двойным щелчком по кнопке создаем в окне кода шаблон обработчика собыия нажатия кнопки. Функциоинальная часть обработчика включает задание в цик- ле наборов данных для серий.
    Листинг программы using
    System; using
    System.Windows.Forms; namespace
    Chart
    { public partial class
    Form1
    :
    Form
    { public
    Form1()

    131
    {
    InitializeComponent();
    } private void chart1_Click(
    object sender,
    EventArgs e)
    {
    } private void button1_Click(
    object sender,
    EventArgs e)
    { double y = 0; for
    (
    int x = 0; (x <= 19); x++)
    { y =
    Math
    .Sin(
    Math
    .PI / 5 * x); chart1.Series[
    "Синус"
    ].Points.AddXY(x, y); y =
    Math
    .Cos(
    Math
    .PI / 5 * x); chart1.Series[
    "Косинус"
    ].Points.AddXY(x, y);
    }
    } private void
    Form1_Load(
    object sender,
    EventArgs e)
    {
    }
    }
    }
    При запуске программы отображается форма, в которой .прорисовываются диаграмма с двумя поименованными сериями и кнопка старта. Самаих графи- ков пока нет, так как данные для них формирует обработчик.

    132
    Кнопка button1 (Старт). Она вызывает построение графиков в окне.

    133
    25.
    Графика, рисование фигур
    Предмет исследований

    Методы работы с графическими фигурами.

    Методы работы с залитыми графическими фигурами.
    Контрольные вопросы
    Назначение графических примитивов.
    1.
    Кривая Безье и метод DrawBezier.
    2.
    Кривая и метод DrawCurve.
    3.
    Замкнутая кривая и метод DrawClosedCurve.
    4.
    Прямоугольник и метод DrawRectangle.
    5.
    Полигон и метод DrawPolygon.
    6.
    Эллипс и метод DrawEllipse.
    7.
    Дуга эллипса и метод DrawArc.
    8.
    Торт и метод DrawPie.
    9.
    Метод заполнения замкнутых фигур (заполнить область),
    10.
    Стили линий.
    11.
    Стили заливки.
    12.
    Задание. Создать программу рисования в форме графических фигур без за- ливки и с заливкой.
    Пример. Создать программу рисования в форме графических фигур без за- ливки и с заливкой.
    В левом верхнем углу формы будут рисоваться два графика: верхний – фигура без заливки, нижний – фигура с заливкой.

    134
    В форме размещаем 4 выпадающих списка Combobox и метки Label для заго- ловков списков:

    Фигура - Combobox1 и Label1.

    Стиль линии – Combobox2 и Labe2.

    Фигура с заливкой – Combobox3 и Label3.

    Стиль заливки – Combobox4 и Label4.
    Кнопка button1 с надписью старт для запуска обработчика события.
    В окне свойств Combobox1 определим фигуры рисования:

    DrawBezier – кривая Безье.

    DrawCurve – кривая.

    DrawClosedCurve – замкнутая кривая.

    DrawRectangle – прямоугольник.

    DrawPolygon – многоугольник.

    DrawEllipse – эллипс.

    DrawArc – дуга эллипса.

    DrawPie – торт.
    В окне свойств Combobox2 определим стили линий фигур:

    Dash – тире.

    DashDot – тире + точки.

    DashDotDot - тире + 2 точки.

    Dot - точки.
    В окне свойств Combobox3 определим фигуры с заливкой:

    FillClosedCurve - замкнутая кривая.

    FillRectangle - прямоугольник.

    FillPolygon - многоугольник.

    FillEllipse - эллипс.

    FillPie - торт.
    В окне свойств Combobox4 определим стили заливки фигур:

    Cross – сетка.

    DiagonalCross – диагональная сетка.

    ForwardDiagonal – диагональ прямая.

    BackwardDiagonal – диагональ обратная.

    135
    В листинге программы дополнительно задаются размеры рисуемых фигур.
    Листинг прогаммы using
    System; using
    System.Drawing; using
    System.Drawing.Drawing2D; using
    System.Windows.Forms; namespace
    Figures
    { public partial class
    Form1
    :
    Form
    { public
    Form1()
    {
    InitializeComponent();
    } private void button1_Click(
    object sender,
    EventArgs e)
    {
    Graphics g =
    Graphics
    .FromHwnd(
    this
    .Handle);
    // Где рисуем
    Pen pen = new
    Pen
    (
    Color
    .Black);
    // Чем рисуем
    Brush brush =
    Brushes
    .White;
    Brush brush1 =
    Brushes
    .Blue;

    136
    //stem.Drawing.Drawing2D.FillMode;
    HatchBrush brush2 = new
    HatchBrush
    (
    HatchStyle
    .Cross,
    ForeColor, BackColor);
    HatchBrush brush3 = new
    HatchBrush
    (
    HatchStyle
    .DiagonalCross,
    ForeColor, BackColor);
    HatchBrush brush4 = new
    HatchBrush
    (
    HatchStyle
    .ForwardDiagonal,
    ForeColor, BackColor);
    HatchBrush brush5 = new
    HatchBrush
    (
    HatchStyle
    .BackwardDiagonal,
    ForeColor, BackColor);
    Point
    [] p =
    { new
    Point
    (10, 0), new
    Point
    (80,70), new
    Point
    (90,50), new
    Point
    (50,90),
    };
    Point
    [] p1 =
    { new
    Point
    (0,110), new
    Point
    (80,180), new
    Point
    (90,160), new
    Point
    (50,200),
    };
    Rectangle rect = new
    Rectangle
    (0,0, 110, 220);
    Rectangle rect1 = new
    Rectangle
    (10,0, 100, 100);
    Rectangle rect2= new
    Rectangle
    (10,110, 100, 100); g.FillRectangle(brush, rect); if
    (comboBox3.SelectedItem ==
    "Dash"
    )
    { pen.DashStyle =
    DashStyle
    .Dash;
    } if
    (comboBox3.SelectedItem ==
    "DashDot"
    )
    { pen.DashStyle =
    DashStyle
    .DashDot;
    } if
    (comboBox3.SelectedItem ==
    "DashDotDot"
    )
    { pen.DashStyle =
    DashStyle
    .DashDotDot;
    }

    137 if
    (comboBox3.SelectedItem ==
    "Dot"
    )
    { pen.DashStyle =
    DashStyle
    .Dot;
    } if
    (comboBox4.SelectedItem ==
    "Cross"
    )
    { brush1 = brush2;
    } if
    (comboBox4.SelectedItem ==
    "DiagonalCross"
    )
    { brush1 = brush3;
    } if
    (comboBox4.SelectedItem ==
    "ForwardDiagonal"
    )
    { brush1 = brush4;
    } if
    (comboBox4.SelectedItem ==
    "BackwardDiagonal"
    )
    { brush1 = brush5;
    } if
    (comboBox1.SelectedItem ==
    "DrawRectangle"
    )
    { g.DrawRectangle(pen, rect1);
    } if
    (comboBox2.SelectedItem ==
    "FillRectangle"
    )
    { g.FillRectangle(brush1,10, 110, 100, 100);
    } if
    (comboBox1.SelectedItem ==
    "DrawPolygon"
    )
    { g.DrawPolygon(pen, p);
    } if
    (comboBox2.SelectedItem ==
    "FillPolygon"
    )
    { g.FillPolygon(brush1, p1);
    } if
    (comboBox1.SelectedItem ==
    "DrawEllipse"
    )
    { g.DrawEllipse(pen, rect1);
    } if
    (comboBox2.SelectedItem ==
    "FillEllipse"
    )

    138
    { g.FillEllipse(brush1,10, 110, 100, 100);
    } if
    (comboBox1.SelectedItem ==
    "DrawPie"
    )
    { g.DrawPie(pen, rect1, 50, 250);
    } if
    (comboBox2.SelectedItem ==
    "FillPie"
    )
    { g.FillPie(brush1, rect2, 50, 250);
    } if
    (comboBox1.SelectedItem ==
    "DrawCurve"
    )
    { g.DrawCurve(pen, p);
    } if
    (comboBox1.SelectedItem ==
    "DrawClosedCurve"
    )
    { g.DrawClosedCurve(pen, p);
    } if
    (comboBox2.SelectedItem ==
    "FillClosedCurve"
    )
    { g.FillClosedCurve(brush1, p1);
    } if
    (comboBox1.SelectedItem ==
    "DrawArc"
    )
    { g.DrawArc(pen, rect1,50,250);
    } if
    (comboBox1.SelectedItem ==
    "DrawBezier"
    )
    { g.DrawBezier(pen, p[0], p[1], p[2], p[3]);
    }
    } private void comboBox1_SelectedIndexChanged(
    object sender,
    EventArgs e)
    {
    }
    }
    }
    Пример запуска.

    139
    А это результат:

    140
    26.
    Графика, растровые изображения
    Предмет исследований

    Графические средства C#.

    Форматы графики.
    Контрольные вопросы
    BitMap изображение.
    1.
    TIFF изображение
    2.
    GiF изображение.
    3.
    PNG изображение.
    4.
    JPEG изображение.
    5.
    Компонент PictureBox.
    6.
    Принцип создания анимации.
    7.
    Использование в анимационной программе фоновой картинки.
    8.
    Использование в анимационной программе картинки образа.
    9.
    Использование в анимационной программе буфера.
    10.
    Задание. Создать программу работы с графическими файлами. Проект – Win- dowsForm приложение. В проекте растровая картинка *.bmp преобразуется в другие форматы графики.
    Пример. Создать программу работы с графическими файлами. Проект – Win- dowsForm приложение. В программе используется файл растровой картинки
    Кувшинка.bmp, который надо загрузить в ту же папку, где находится проект приложения. Этот файл находится в папке УМД к ЛР.
    В проекте растровая картинка Кувшинка.bmp преобразуется в другие форматы графики. Картинки отображаются в компонентах PictureBox1 (с заголовком
    BitMap в компоненте Label1) для исходника и PictureBox2 (с заголовком Ре- зультат в компоненте Label2).
    Тип результата (TIFF, GIF, PNG, JPEG), выбирается из выпадающего списка combobox1 с заголовком «Выбор формата» в компоненте Label3.
    При выборе JPEG дополнительно выбирается желаемое качество результата от 5 до 100 из выпадающего списка-диапазона NumericUpDown с заголовком
    «Качество» в компоненте Label4.
    При выборе TIFF дополнительно из выпадающего списка combobox2 с заголов- ком «Сжатие TIFF» в компоненте Label5 выбирается алгоритм сжатия:

    None – сжатия нет.

    Default – по умолчанию.

    141

    Lzw – сжатие без потерь качества.

    Rle – с анализом повторов пикселей

    Zip – для архивирования.
    Кнопка с надписью «Старт» запускает процесс преобразования.
    Форма проекта задания 1. В окне свойств формы задаем свойство text = Раст- ровая графика.
    Листинг программы using
    System; using
    System.Drawing; using
    System.Windows.Media.Imaging;

    142 using
    System.IO; using
    System.Windows.Forms; namespace
    RastrGraphic
    { public partial class
    Form1
    :
    Form
    { public
    Form1()
    {
    InitializeComponent();
    // Загрузка bitmap
    FileStream fin = new
    FileStream
    (
    @"e:\Kuvshinka.bmp"
    ,
    FileMode
    .Open); pictureBox1.Image =
    Image
    .FromStream(fin); long
    Bytes = fin.Length; fin.Close(); label1.Text =
    "BitMap "
    + Bytes.ToString() +
    " байт"
    ;
    } private void button1_Click(
    object sender,
    EventArgs e)
    { if
    ( comboBox1.SelectedItem ==
    "TIFF"
    )
    {
    FileStream fin = new
    FileStream
    (
    @"e:\Kuvshinka.bmp"
    ,
    FileMode
    .Open);
    FileStream fout = new
    FileStream
    (
    @"e:\Kuvshinka.tiff"
    ,
    FileMode
    .Create);
    TiffBitmapEncoder encTiff = new
    TiffBitmapEncoder
    (); if
    (comboBox2.SelectedItem ==
    "Default"
    )
    { encTiff.Compression =
    TiffCompressOption
    .Default;
    } if
    (comboBox2.SelectedItem ==
    "None"
    )
    { encTiff.Compression =
    TiffCompressOption
    .None;
    } if
    (comboBox2.SelectedItem ==
    "Rle"
    )
    { encTiff.Compression =
    TiffCompressOption
    .Rle;
    } if
    (comboBox2.SelectedItem ==
    "Lzw"
    )
    { encTiff.Compression =
    TiffCompressOption
    .Lzw;
    } if
    (comboBox2.SelectedItem ==
    "Ccitt3"
    )

    143
    { encTiff.Compression =
    TiffCompressOption
    .Ccitt3;
    } if
    (comboBox2.SelectedItem ==
    "Ccitt4"
    )
    { encTiff.Compression =
    TiffCompressOption
    .Ccitt4;
    } if
    (comboBox2.SelectedItem ==
    "Zip"
    )
    { encTiff.Compression =
    TiffCompressOption
    .Zip;
    } encTiff.Frames.Add(
    BitmapFrame
    .Create(fin)); encTiff.Save(fout); fin.Close(); long
    Bytes = fout.Length; pictureBox2.Image =
    Image
    .FromStream(fout); fout.Close(); label2.Text =
    "TIFF "
    + Bytes.ToString() +
    " байт"
    ;
    } if
    (comboBox1.SelectedItem ==
    "GIF"
    )
    {
    FileStream fin = new
    FileStream
    (
    @"e:\Kuvshinka.bmp"
    ,
    FileMode
    .Open);
    FileStream fout = new
    FileStream
    (
    @"e:\Kuvshinka.gif"
    ,
    FileMode
    .Create);
    GifBitmapEncoder encGif = new
    GifBitmapEncoder
    (); encGif.Frames.Add(
    BitmapFrame
    .Create(fin)); encGif.Save(fout); fin.Close(); long
    Bytes = fout.Length; pictureBox2.Image =
    Image
    .FromStream(fout); fout.Close(); label2.Text =
    "GIF "
    + Bytes.ToString() +
    " байт"
    ;
    } if
    (comboBox1.SelectedItem ==
    "PNG"
    )
    {
    FileStream fin = new
    FileStream
    (
    @"e:\Kuvshinka.bmp"
    ,
    FileMode
    .Open);
    FileStream fout = new
    FileStream
    (
    @"e:\Kuvshinka.png"
    ,
    FileMode
    .Create);
    PngBitmapEncoder encPng = new
    PngBitmapEncoder
    (); encPng.Frames.Add(
    BitmapFrame
    .Create(fin)); encPng.Save(fout); fin.Close();

    144 long
    Bytes = fout.Length; pictureBox2.Image =
    Image
    .FromStream(fout); fout.Close(); label2.Text =
    "PNG "
    + Bytes.ToString() +
    " байт"
    ;
    } if
    (comboBox1.SelectedItem ==
    "JPEG"
    )
    {
    FileStream fin = new
    FileStream
    (
    @"e:\Kuvshinka.bmp"
    ,
    FileMode
    .Open);
    FileStream fout = new
    FileStream
    (
    @"e:\Kuvshinka.jpeg"
    ,
    FileMode
    .Create);
    JpegBitmapEncoder encJpeg = new
    JpegBitmapEncoder
    (); encJpeg.QualityLevel = (
    int
    )numericUpDown1.Value; encJpeg.Frames.Add(
    BitmapFrame
    .Create(fin)); encJpeg.Save(fout); fin.Close(); long
    Bytes = fout.Length; pictureBox2.Image =
    Image
    .FromStream(fout); fout.Close(); label2.Text =
    "JPEG "
    + Bytes.ToString() +
    " байт"
    ;
    }
    }
    }
    }
    При запуске проекта на выполнение появляется окно, в котором преобразо- ванной картики нет, а для исходника отображается тип и размер файла.

    145
    Пусть выбран тип JPEG с качество 5. При нажатии на кнопку Старт формиру- ется результат – выводится картинка, а в поле результата прописывается тип картинки и размер файла.

    146
    Картинка получилась со сжатием почти в 100 раз, но с плохим качеством. Из- меним качество на 30 и повторим преобразование. Результат с хорошим каче- ством, но сжатие стало меньше, около 30 раз.

    147

    148
    1   2   3   4   5   6   7


    написать администратору сайта