Глава №5. Итоговый тест

  Юрий  | 

  |

  Обновл. 15 Сен 2020  | 

 93128

 ǀ   104 

Поздравляю! Мы продвинулись еще на одну главу вперед. Чтобы закрепить пройденный материал, давайте быстренько повторим теорию и выполним 2 практических задания.

Теория

Операторы if позволяют выполнить код, основываясь на результате условия (истинно оно или нет). Если условие ложное, то выполняется оператор else. Можно связывать несколько операторов if и else вместе.

Оператор switch обеспечивает более удобный и быстрый способ использования условий/ветвлений в коде. Он отлично сочетается с перечислениями.

Оператор goto позволяет переносить точку выполнения в программе из одного места в другое. Использовать этот оператор не рекомендуется.

Цикл while выполняет определенный код до тех пор, пока условие истинно. Сначала обрабатывается условие, а затем выполняется код.

Цикл do while — это тот же цикл while, только сначала выполняется код, а затем уже проверяется условие. Он отлично подходит для вывода меню или других элементов, так как позволяет выполнить код хотя бы один раз.

Циклы for наиболее используемые циклы. Они идеальны, когда нужно выполнить код определенное количество раз.

Оператор break позволяет немедленно завершить выполнение оператора switch, циклов while, do while или for.

Оператор continue позволяет немедленно перейти к следующей итерации цикла. Будьте осторожны при использовании этого оператора в связке с циклами while или do while — не забывайте о возникновении проблемы с инкрементом счетчика цикла.

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

Тест


Задание №1

В итоговом тесте главы №2 мы написали программу имитации мячика, падающего с башни. Так как тогда мы еще ничего не знали о циклах и не умели их использовать, то время полета мячика составляло всего лишь 5 секунд.

Измените программу, приведенную ниже, таким образом, чтобы мячик падал ровно то количество секунд, которое необходимо ему для достижения земли.

constants.h:

Основной файл:

Ответ №1

constants.h:

Основной файл:

Задание №2

Напишите программу-игру типа Hi-Lo:

   Во-первых, ваша программа должна выбрать случайное целое число в диапазоне от 1 до 100.

   Пользователю дается 7 попыток, чтобы угадать это число.

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

   Если пользователь угадал число, то программа должна сообщить, что всё верно — вы выиграли.

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

   В конце игры программа должна спросить у пользователя, не хочет ли он сыграть еще раз. Если пользователь не введет ни y, ни n (а что-то другое), то программа должна спросить его еще раз.

Пример результата выполнения вашей программы:

Let's play a game. I'm thinking of a number. You have 7 tries to guess what it is.
Guess #1: 64
Your guess is too high.
Guess #2: 32
Your guess is too low.
Guess #3: 54
Your guess is too high.
Guess #4: 51
Correct! You win!
Would you like to play again (y/n)? y
Let's play a game. I'm thinking of a number. You have 7 tries to guess what it is.
Guess #1: 64
Your guess is too high.
Guess #2: 32
Your guess is too low.
Guess #3: 54
Your guess is too high.
Guess #4: 51
Your guess is too high.
Guess #5: 36
Your guess is too low.
Guess #6: 45
Your guess is too low.
Guess #7: 48
Your guess is too low.
Sorry, you lose. The correct number was 49.
Would you like to play again (y/n)? q
Would you like to play again (y/n)? f
Would you like to play again (y/n)? n
Thank you for playing.

Подсказки:

   Используйте в качестве стартового числа во время генерации случайных чисел вызов функции time(0).

   Пользователям Visual Studio: Из-за плохой реализации функции rand() (первое рандомное число не сильно отличается от стартового) — вызовите rand() сразу после установки стартового числа, чтобы сбросить первый результат.

   Используйте функцию getRandomNumber() из урока №71 для генерации случайного числа.

   В функции, которая будет спрашивать у пользователя, не хочет ли он сыграть еще раз, используйте механизм обработки некорректного пользовательского ввода.

Ответ №2

Оценить статью:

Звёзд: 1Звёзд: 2Звёзд: 3Звёзд: 4Звёзд: 5 (272 оценок, среднее: 4,89 из 5)
Загрузка...

Комментариев: 104

  1. Сашуня:

    Второе задание:

  2. Сашуня:

    Первое:

    constants.h

    main.cpp

  3. Valdemar:

    Написал программу заново, без образца.

    Решил через for.

    Загуглил, единственное, как извлекать корень в C++, для того, чтобы в конце сообщить, какое точное время потребовалось для достижения земли, использовав всё ту же формулу. Буду рад критике от пользователей и Юры)

    Constant.H:

    main.cpp:

  4. SOM:

    Завдання 1

    main

    constants.cpp

    constants.h

    myFunctions.h

    myFunctions.cpp

  5. Владимир:

    Второе задание можно было через for реализовать, но показалось что так проще(да и потом уже понял что через for можно делать). Спасибо предыдущим урокам , благодаря которым я понял как правильно отладку делать. «Шаг с заходом» решил все проблемы, благодаря проверке всех вариантов цикла.

    1. Владимир:

      В конце забыл написать ветвление на случай если пользователь с первого раза введёт нужный выбор.

  6. Ivan:

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

  7. Ivan:

    Подскажите пожалуйста, почему это работает

    ведь в условиях вроде (true && false) = false, разве нет? не понимаю как это работает

    1. Vladislava:

      Мы задаем условие: while (пока ch не ‘y’ И пока ch не ‘n’ ), то выполняется тело цикла (do). Если мы введем ‘y’  или ‘n’, то это не удовлетворит условие и тело цикла (do) прекратит выполнение.                                     

      Есть логический оператор И (&&). Он говорит: если оба условия верны, то возвращается true (1 && 1 = 1).       

      Также и в нашем случае: если оба условия верны, то это 1 и, следовательно, тело цикла выполнится (while (1 && 1) значит do тоже 1).

  8. Surprizze:

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

  9. Alex Road:

    В контексте первого задания так будет поизящней, наверно.
    Не знаю только, подобные стартеры циклов (double height = 1) допустимы ли.

  10. Артём:

    Все сделали на английском, а я решил на русском сделеать)
    Кстати, почему-то, когда используешь

    То русские символы сравниваются не правильно. странно.

  11. Vitalt1158:

    Вторая:

    Файл Main.cpp:

    Файл Function.h:

    Файл Function.cpp:

  12. Artem:

    Решил полностью переделать код из 1 задания\

  13. Ironsaid:

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

  14. Max:

    С do while кажется код был бы более понятным.

  15. Kayfor:

    Моё видение порвого задания:

  16. Андрей:

    Оставлю и я здесь свой стрёмный вариант второго задания.)

  17. Виталий:

    Второе задание:

  18. Виталий:

    Первое задание:

  19. Артурка:

    2-е задание:

    GuessNumberGame.h:

    GuessNumberGame.cpp:

  20. Ruslan:

    Задание № 2.

  21. Ангелина:

    Мой вариант второй задачи:

    Да, с goto, да, забыла про do while, так вышло 🙂 Хотя в лекциях даже писалось, что do while идеален для вызова меню.

  22. Ruslan:

    Задание № 1

    constants.h :

    основной файл:

  23. Ангелина:

    Ух, это было мозголомно, но круто) Целый день просидела.

    Первая задача (constants.h не меняется):
    main.cpp

    А еще сделала вариант, который выводит не просто секунды падения, а секунды и минуты) Тогда main() выглядит так:

    Можно было, конечно, еще запилить часы, тогда бы последнее else if в цикле for выглядело бы так:

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

  24. Никита:

    Второе задание с использование Вихря Мерсенна для рандомной генерации

  25. Павел:

    Всё работает, но в функции test(), которая должна выдавать разные ошибки на числа, которые меньше 1 или больше 100 и введение не чисел. Однако он всегда выдаёт только первую ошибку, т.е "Ваше число должно быть больше 1 и меньше 100". Если что, я пробовал поменять местами ошибки в ветвлении if, и тогда на все случаи прога выдаёт, что введённое мной число не является числом, даже если это просто число меньше или больше 100. Кто знает, с чем это связано?

    1. Сергей:

      Попробую внести ясность. Для этого рекомендую воспользоваться уроком 27. Отладка программ: стек вызовов и отслеживание переменных. https://ravesli.com/urok-27-otladka-stek-vyzovov-i-otslezhivanie-peremennyh/

      1. В строке 30 объявлена целочисленная переменная x (не инициализирована, а значит компилятор проинициализирует её: 0).

      2. В строке 33 используется cin >>. При вводе символов (например"asdf") происходит Ошибка №3: Извлечение не выполняется. Урок №72. Обработка некорректного пользовательского ввода https://ravesli.com/urok-72-obrabotka-nekorrektnogo-vvoda-cherez-std-cin/.
      А переменная x так и осталась с "мусором" (0), т. е. x=0.

      3. В строке 34 вызов функции проверки test(x), где x = 0, обрабатывается как "меньше 1 или больше 100" (строка 14: if(yourNumber < 1 || yourNumber > 100) ).

  26. Баринов Александр Сергеевич:

    Здравствуйте, сам написал программу к итоговому тесту 5 заданию 2 и столкнулся с проблемой: программа в первый раз работает, но после второго вызова функции test() 2 раза выдаёт текст с вводом, а потом закрывается(при этом не важно что вводишь). Кто понимает из-за чего это помогите.

    1. Сергей:

      Попробую внести ясность. Для этого рекомендую воспользоваться уроком 27. Отладка программ: стек вызовов и отслеживание переменных. https://ravesli.com/urok-27-otladka-stek-vyzovov-i-otslezhivanie-peremennyh/

      1. Строка 52: char result = test();. В случае ввода 'y' переменная result = 'y' (это КЛЮЧЕВОЙ момент).

      2. В цикле do (строка 54) будет обработан стейтмент (строка 58): bool result2 = game(guess, number);.
      После этого будет обработана либо строка 61-62, либо строка 66-67, где присутствует вызов функции test() (это Ваш первый раз). Но результат вызова теряется, поэтому переменная result сохраняет 'y'. (п.1).

      3. В строке 70 (if (result == 'n')) управление перейдет на строку 74 (else), а затем строка 76 (вызов функции test() (это Ваш второй раз), а результат вызова теряется). Внимание: значение result не меняется (='y').

      4. Строка 78: while (result != 'n' && result != 'y'); приводит к while (false) и прекращению цикла.

  27. Александр:

    Здравствуйте. Вот мой код. Если будут какие-либо предложения для улучшения кода — говорите, буду рад услышать чужое мнение.

    Код:

  28. Onium:

    Такой ответ на второе задание

    1. Сергей:

      Сделано очень интересно, с enum class, вообще здорово.
      Но в строке 78 функцию void choice() надо переписать.
      При некорректном вводе (например, "asd") выполнится else (строка 90 ) и по условию: exit(0), а желательно "Неккоректный ответ. Введите еще раз:".

  29. Onium:

    Такой ответ на первое задание

  30. Viktor:

    Ось мій варіант другого завдання. Дякую за ці чудові курси)))

  31. Pipka Jenskaya:

    Ну, мой вариант

  32. Nikita:

    Написал свой вариант с возможностью выбора диапазона значений. В процессе написания столкнулся с множеством проблем, оно и к лучшему, многое вспомнил и многому научился. Юрий, спасибо за уроки!

    Main.cpp

    add.h

    functions.cpp

  33. Павел:

    Не могу исправить ошибку. Если я ввожу вместо цифры любые символы программа уходит в вечные строчки.

    1. Дмитрий:

      Я сам далеко не спец и могу ошибаться, но мои замечания таковы:
      1. В цикле while (в функции main) обработай сначала случай cin.fail(), а затем все остальные случаи (так как это сейчас — cin принимает значение ошибки и никак не может сравнить эту ошибку со случаями, когда х=рандому, больше или меньше его).
      2. Кстати, еще одна моя придирка: нафиг делать сравнение ">=" и "<=", если случай "=" у тебя обрабатывается отдельно?

      1. Павел:

        Исправил код. Теперь обрабатывает как надо, онако 2 if в одном for выглядит как говнокод:

        1. Bampi:

          Замени на switch(x), если не нравится или чтоб main не нагружать кодом(читабельней становится), то в функцию передать х и там обработать.

        2. Дмитрий:

          А что тебе мешает в 80-й строке использовать "else if" (тем самым объединив все условия в один блок, как было в первоначальной версии)?

        3. Павел:

          Дмитрий, добрый день.
          Если я в 80-ой строке использую else if вместо if, тогда вместо 2-х (один делает проверку на корректность ввода, а второй на корректность выполнения условий) циклов у меня будет один. Проще говоря после ввода текста выполниться условие корректности ввода и на этом цикл будет завершаться, а следующий цикл сравнения условий не выполниться. Касательно оператора switch(x) можно было и через него, но я уже сделал)))

          Вот и всё решение.

        4. Дмитрий:

          Павел, доброго времени суток!
          Вот как это видится мне:

        5. Павел:

          Добрый день Дмитрий!
          Да примерно так как вы описали, только условие выполниться не последовательно, а примерно так(ну во всяком случае как понимаю я, может и ошибаюсь))))
          1)Проверка корректности ввода текста:
          если да, то выход из цикла
          если нет, то переходим к следующему шагу
          2)Проверка равенства значения x и random:
          если да, то выход из цикла
          если нет, то переходим к следующему шагу
          и т.д.

          (Эх жаль картинку добавить нельзя. Я бы блок схему нарисовал для наглядности)).
          То есть цикл при выполнении первого условия дальше не проверяет и тогда не выполняется сравнение значений. А если не выполниться первое условие то дальнейшее выполнение тоже бестолковое, т.к. само значение некорректно(знак или буква, а может слово). По этой причине я и сделал 2 цикла вместо 1.

        6. Дмитрий:

          Павел, вы чуть-чуть ошибаетесь. Первое условие (cin.fail) — это проверка на правильность ввода. Первое условие выполнится как раз только тогда, когда ввод будет НЕ корректным (т.е. в том случае, когда дальнейшие сравнения и не имеют никакого смысла). Если ввод будет правильным первое условие выполняться не будет и сравнение пойдет дальше!

        7. Павел:

          Тогда получается, что строчка "if (cin.fail())" предусловие к выполнению цикла. Так то код рабочий и смотрится грамотнее, но логика что то отлетает напрочь. Я думал, что If/else это линейный цикл, который при выполнении условия его завершает, а тут получается, что "if (cin.fail())" не совсем в цикле. Спасибо за науку.)))

  34. Виталий:

    В общем написал как мог, вроде работает (возможно с багами =))

    1. Bampi:

      Из доков про <random>:

      Дальше чтоб получить число из диапазона (1,100) с равномерным распределением dist(gen). Ну и завернуть в функция, где возвращается данное число.

  35. Юра:

    Второе задание

  36. Геннадий:

  37. Вадим:

  38. Михаил:

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

  39. Денис:

    Ребят, помогите!
    Голова взорвалась. Почему тут при true цикл останавливается, а у меня сколько бы ни делал, на какой бы попытке ни угадывал, все равно приходится доделывать остальные попытки.

    1. Денис:

      Необходимо предусмотреть условие выхода из цикла

      ->ввели верное число
      ->break;(вышли из цикла)

  40. Илья:

    Здравствуйте люди).
    Смотрю вы забыли про goto)
    С ним все намного легче (только если правильно использовать)
    Bот мой ответ на 2 задание с goto:

  41. Константин:

    ответ на первое задание

    заголовочный файл:

    программа:

  42. Константин:

    Ответ на второе задание.

  43. Анастасия Лузинсан:

    Сделала возможность определения диапазона значений и количества попыток. Рандомное число определяется по Вихрю Мерсенна. Всё проходит через проверку на ошибки (вроде). И, всё завязано на меню(так что можно добавить опции).

  44. Maksim:

    Хочу поблагодарить за данный материал. Очень много полезной информации. Контент действительно качественный !!! и инфа. очень легко заходит. Спасибо!

    1. Фото аватара Юрий:

      Пожалуйста)) Спасибо за отзыв)

  45. Maksim:

  46. Игорь:

    2-е задание. Долго колупал. Была одна проблема: с каждым нажатием на Enter выводил на экран 48-ю строку(Сыграем в игру Правила просты: я загадываю число от 1 до 100, а ты отгадываешь. У тебя 7 попыток!) и при этом переменная Attemp(попытка #) всегда была равна 1, т.е. Attemp #: 1. Хотя с каждой попыткой должен быть инкремент +1. И цикл отрабатывал только 7 раз как и положено. Но что самое странное — я удалил эту строку вообще, потом запустил программу и все равно программа выводит мне эту строку с каждым нажатием Enter.
    более 5 часов ушло на разборки, но теперь все работает!

  47. zashiki:

    как то так( с "продолжить игру" подсмотрела)

  48. Вячеслав:

    Вот что-то такое у меня получилось…
    Можете оценить, насколько хорошо/плохо он написан ( сразу оговорюсь, что проверку на ввод данных пользователем не делал, только для y / n ) .

  49. Александр:

    Мда, по этим решениям видно, на сколько моё решение далеко от идеала. Салага я ещё, раз у меня строк в коде более чем в два раза больше, чем в решении задачи №2.

  50. Алексей:

    Заморочился, но практика.

    Выбор сложности и тд и тп.

  51. Алексей:

    Да, простые, то простые, но как берешься.

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

  52. Kishmyak:

    сделал такой вот код, плюс в том, что прога спрашивает, в каких пределах чисел вы хотите поиграть

  53. Алексей:

    Задачи вроде-бы не сложные, простые.
    Только во втором случаи, функция то одни и те же номера генерирует.

  54. Владимир:

    Задание №1
    constants.h:

    Основной файл:

  55. Владимир:

    Задание №2

  56. Дмитрий:

    Поясните, пожалуйста, как в ответе на вторую задачу работает функция playAgain? Конкретно интересует:

    Выполнять цикл пока переменная ch не равна 'y' и 'n' одновременно? Разве здесь не должен быть оператор "ИЛИ"?

    1. Павел:

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

  57. Константин:

    Я не знал как делать (игру hi-lo), поэтому сделал просто:

  58. Денис:

    Решил сделать как мини-игру:) Лого, просто для полноты картины:)
    Можно совершать ставки на игру, вроде ошибок не заметил, перепроверял много раз.

    1. Денис:

      А при чем ставки? В этой игре гарантированно выигрываешь, если следовать простому медианному алгоритму. Достаточно ровно 7 попыток.

  59. Павел:

    Вторая задача с Вихрем Мерсенна:

  60. zvezdonom:

    Доброго времени суток. На первое задание почему-то никто не предложил варианта, когда выбирается шаг по времени вывода данных, а так же проверка пользовательского ввода. Допустим, я хочу бросить с высоты 1 метр и показать данные каждые 0.1 сек. Вот результат моей программы:

    Enter the height of the tower in meters:
    1
    Enter the step of the time in seconds:
    0.1
    All fall time is 0.451754 seconds.
    At 0 seconds, the ball is at hight: 1 meters;
    At 0.1 seconds, the ball is at hight: 0.951 meters;
    At 0.2 seconds, the ball is at hight: 0.804 meters;
    At 0.3 seconds, the ball is at hight: 0.559 meters;
    At 0.4 seconds, the ball is at hight: 0.216 meters;
    At 0.5 seconds, the ball is on the ground.

    И сама программа (4 файлика):

    1. calculate.h

    2. constants.h

    3. calculate.cpp

    4. main.cpp

  61. Юрий:

    Первое задание. Заглавочный файл не изменяется, поэтому:

  62. Вячеслав:

    Взял за основу код Алексея, немного доработал и вот что получилось:

  63. Игорь:

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

  64. Alexey:

  65. Диана:

    первое задание…

  66. Дмитрий:

    Задание №2

  67. Алексей:

    Ответ на Задание №2:

  68. Юрий:

    Привет. Вопрос такой — я обрабатываю некорректный ввод числа от 1 до 100. При этом если это будет число меньше нуля, больше ста, символ, дробь — некорректный ввод обрабатывается и программа работает как нужно. Но если пользователь вводит строку к примеру "55нгук78437" буфер cin принимает число 55 и никак на это моя программа не ругается. Как можно обработать такой ввод?

    1. Александр:

      Напиши после cin команду cin.ignore(32767, '\n')

  69. Игорь:

  70. Владислав:

    Привет. Решение второго задания хорошее, но стоило бы еще сделать проверку ввода числа от пользователя, ибо если будет введен символ, то будет бесконечный цикл. А также в правилах указывается, что загадывается число от 1 до 100, то стоило бы и сделать проверку числа на нахождение в этом диапазоне (т.к. можно и отрицательные числа вводить, никто не запрещает 🙂 )
    Ну и мой код:

  71. Alexey:

    Решил вторую задачу несколько другим путём. Пришлось добавить заголовочный файл, чтобы можно было объявлять одну функцию внутри другой, а также оператор goto, т.к. это было первое, что пришло на ум.

    Hi-lo.h:

    Hi-lo.cpp:

  72. artem:

  73. Денис:

    Мой вариант:

  74. Алибек:

    Вторая задача:

  75. Андрей:

    Фух, долго пришлось писать эту программу -))
    Пришлось сначала на листке рисовать блоки (кстати было бы неплохо сделать статью на эту тему для начинающих или в Телеграме как Вы делаете пакет ссылок на одну тему)

    От себя я решил немного усложить и добавил 2 условия:
    1 После озвучивания правил игры спрашиваю согласия пользователя
    2 В запросе числа от пользователя добавил проверку на корректность ввода числа.

    И саму игру решил не выносить в отдельную функцию — onlinegdb.com/HJcySZIRz.

    1. Фото аватара Юрий:

      У вас в программе если ввести неверное число первый раз, то выводится предупреждение и после него на все последующие значения также пишет, что не из диапазона, даже если вводить от 1 до 100. Проблема в этой строчке:

      Здесь нужно использоваться оператор И, вместо ИЛИ:

      1. Андрей:

        Если мы поставим оператор И вместо ИЛИ то у нас такое условие никогда не выполнится. Нет таких чисел одновременно меньше 0 и больше 100.
        Ошибка была в расположении циклов For и If относительно друг друга.
        Поменял местами и вроде все варианты работают.

        1. Фото аватара Юрий:

          Да, я что-то не досмотрел. Решение должно быть другое.

  76. Анатолий:

    srand(); и rand(); для сброса обязательно в main должны быть? Или можно в getRandomNumber вставить? А если getRandomNumber в отдельный файл вынести как тогда?

    1. Фото аватара Юрий:

      rand() можно вставить и в getRandomNumber. Чтобы вынести getRandomNumber в отдельный файл, вам нужно будет тогда просто подключать файл .cpp с этой функцией к файлу, где она будет использоваться — смотрите Урок 20. Многофайловые программы.

  77. Анатолий:

    Есть ограничение на размер комментария? Пробовал писать с кодом, получалось довольно длинное сообщение, и оно, как я понял не отправлялось.

    1. Фото аватара Юрий:

      Попробуйте тогда разбить ваш комментарий на части и отправить несколько комментариев.

  78. Анатолий:

    Как сюда код вставить, чтоб в как в статье выглядело?

    1. Фото аватара Юрий:

      Просто вставляйте код в форму комментария и отправляйте. Весь внешний вид кода я редактирую и тогда уже оно выглядит как в статье.

Добавить комментарий

Ваш E-mail не будет опубликован. Обязательные поля помечены *