Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: 1 2 [3] 4  Все   Вниз
  Печать  
Автор Тема: Написание программы  (Прочитано 62636 раз)
0 Пользователей и 25 Гостей смотрят эту тему.
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #60 : 15-10-2019 21:33 » 

Отлично

Теперь к последнему оставшемуся методу.

Ваш метод OutputResult выполняет двойную функцию
 - определяет данные для вывода
 - и делает непосредственно вывод

Не есть гут. Каждый метод должен отвечать только за своё одно задание. Проблема заключается в наглядности, Вы экономите на буферных переменных, что на данном этапе обучения контропродуктивно.

Например

Console.WriteLine("Toyota " + "Nissan " + "Mazda");

можно представить как

string buffer = "Toyota " + "Nissan " + "Mazda";
Console.WriteLine(buffer);

если определить переменную для результата, то тело метода можно записать след. образом
Код: (C#)
        private static void OutputResult(string key)
        {
                // >>>>> начиная отсюда

                string result = ""; // это пока пустая строка, которая будет заполнена позднее

                string b = "русские";
                string c = "российские";
                string d = "рассийские";
                string e = "росийские";

               if(key == b || key == c || key == d || key == e)
               {
                    result = "Ваз " + "Газ";
               }
               else
               {
                   result = "Toyota " + "Nissan " + "Mazda";
               }
               // >>>>> и до сюда, не имеет к выводу никакого отношения, скорее к поиску результата/данных.              

               Console.WriteLine(result); // отвечает 100% названию метода, а что делают строчки до этого места? не лучше ли их вынести в отдельный метод?
        }
« Последнее редактирование: 16-10-2019 01:55 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #61 : 16-10-2019 01:46 » 

По итогу программа делает то же самое, что и ранее

И это замечательно, значит всё делается правильно. Так и должно быть.
Код стал компактным, а значит удобочитаемы и "удоборазбираемым".
Вы получили навыки и теперь можете самостоятельно кодировать логику.

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

Как-то так.

зы

Наткнулся в интернете на такой код

Это ещё повезло, что на такой, а ведь могли бы наткнуться и на что-нить типа такого:

Код: (C#)
            var result = from x in dict
                         where x.Value == "Сюда что ищем"
                         select x;

            result.ToList().ForEach(s => Console.WriteLine(s.Value));

А что Вы поняли из этого кода? Что есть dict? Что такое lambda-выражение, LINQ Вы уже знаете? Так чего же Вы тогда мне голову морочите?
Если нет, то Вы сейчас примерно учитесь даже не летать, а ещё только подпрыгивать. А найденный Вами код можно сравнить с пилотированием космического корабля.

Я немного в замешательстве. Цель всего это начинания? Научиться самостояльно создавать программы?

Или найти в инете хоть какой-нить код, который бы что-то сделал?

Если второе, то смею Вас уверить, такого в инете нет, не бывает. А иначе бы все подобное тестирование, да и сама работа программистов, были бы чистейшим очковтирательством. Нафига платить кучу бабла? Зашёл в инет, скачал готовое решение, компильнул и готово, пользуйся.
« Последнее редактирование: 16-10-2019 01:50 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
KOzh1r
Участник

ru
Offline Offline

« Ответ #62 : 16-10-2019 07:39 » 

Код: (C#)
using System;

public class MainClass
{
        public static void Main()
        {
                string request = GetRequest(); // получаем запрос

                string key = FindKey(request); // передаём запрос в метод поиска ключа в этом запросе

                string data = FindData(key);

                OutputResult(data);
               
        }

       private static string GetRequest()
       {
           Console.WriteLine("Введите запрос"); // показывам приглашение
           string a = Console.ReadLine(); // получаем из консоли ввод пользователя
           return a; // возвращаем его как результат метода
       }

        private static string FindKey(string request)
        {
            string result = request.ToLower();
            return result;
        }
        private static string FindData(string key)
        {
                string result = ""; // это пока пустая строка, которая будет заполнена позднее

                string b = "русские";
                string c = "российские";
                string d = "рассийские";
                string e = "росийские";

               if(key == b || key == c || key == d || key == e)
               {
                    result = "Ваз " + "Газ";
               }
               else
               {
                    result = "Nissan " + "Toyota " + "Mazda";
               }
               return result;
        }
        private static void OutputResult(string data)
        {
                Console.WriteLine(data);
        }
}
Исправил код, добавив метод. Но мне кажется, где-то в коде какая-то ошибка...  Здесь была моя ладья...
Записан
KOzh1r
Участник

ru
Offline Offline

« Ответ #63 : 16-10-2019 07:54 » 

Наткнулся в интернете на такой код
 
Код: (C#)
var result = dict.Where(x => x.Value == "Сюда что ищем");
foreach(string data in result)
Console.WriteLine(data);

Поясню, это не поиск готового решения или волшебной части кода, который послужит Панацеей в данной ситуации. Я отлично понимаю, что готового решения нет. Хотя бы потому, что запрос может измениться и бОльшая часть этого "готового решения" станет ошибкой в коде.

В моей ситуации - это лишь попытка найти хоть что-то, что поможет мне реализовать поиск этого самого ключа. Какой-то намёк, тонкая нить, по которой Я смогу выйти на нужный результат.

Но Вы правильно заметили, что найденный мною код для меня - китайские иероглифы. Однако такими же иероглифами, на прошлой неделе было и это:
Код: (C#)
public class MainClass
{
        public static void Main()
        {
            string request = GetRequest(); // получаем запрос
            string key = FindKey(request); // передаём запрос в анализатор
            string result = ""; // создаём буфер для результата
            if (!string.IsNullOrEmpty(key)) // так осуществляется проверка пустой строки, её можно будет перенести в метод FindData
            {
                // предположим анализатор возвращает непустую строку, если он распознал ключ
                result = FindData(key); // передаём ключ в метод поиска данных
            }
            OutputResult(result); // выводим результат
      }
}
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #64 : 16-10-2019 09:08 » 

Улыбаюсь

Но мне кажется, где-то в коде какая-то ошибка...  Здесь была моя ладья...

Хм... я ничего такого на первый взгляд не увидел... А что говорит компилятор? Прога должна работать как в версии кода 0.1

Да это по большому счёту и не важно.

Важно
1. Код стал обозримым и более понятным, теперь мы можем с ним работать
2. Вы приобрели необходимые навыки
3. Он уже для Вас не "китайские иероглифы" (с)

Это самое главное. Ещё раз, для проверки: всё понятно в последней версии? Нет никаких сложностей? Иначе мы не сможем двигаться дальше.
На этом этапе не стесняйтесь ошибаться и пороть чепуху, Вы имеете на это право. Гороаздо хуже отмалчивание непоняток. Это приведёт к большим проблемам в будущем.

Насчёт поиска кода в инете.

Это помогает только когда Вы чётко представляете себе задачу, алгоритм. Код это только способ объяснить компьютеру каким должно быть решение. Если сам этого не представляешь, то никакой код не поможет.

Собственно решение, даже разные варианты, были озвучены уже в первых сообщениях. Конечно, тогда никто не представлял Вашего уровня подготовки.

Ладно. Лирику в сторону.

До сих пор по сути код не изменился, алгоритм остался прежним. Мы просто "разбросали" отдельные куски кода по методам.

Оффтоп, просто для удовольствия или прикола. Такая организация кода позволит нам записать программу в одну строчку.
Если внимательно посмотреть, то каждое возвращённое одним методом значение передаётся в след. метод. Поэтому можно поозорничать

Код: (C#)
        public static void Main()
        {
                OutputResult(FindData(FindKey(GetRequest())));
        }

Улыбаюсь

В реальности этого конечно же лучше не делать. Ибо ТАКОЙ код просто неудобно читать.

Итак, добавляем новинки, о которых я уже упоминал. Сначала я напишу это в коде, а потом объясню.
И ещё одно я теперь не буду приводить весь код, а только необходимые методы, просто чтобы место сэкономить.
По сути методы GetRequest и OutputResult нас ваще не интересуют. Правильно? А после след. добавлений не будет
интересовать и метод Main. Эти методы до самого конца останутся неизменными.

Итак, недостаток существующего кода:
 - ключ по сути определяется в методе поиска данных
 - в качестве ключа используется строка, её надо сравнивать и тд и тп

Исправим эти недостатки
Код: (C#)
using System;
using System.Text; // <<<< это новое, необходимо для "видимости" объекта  StringBuilder

public class MainClass
{
        enum ManufactureCountryKey // <<<<  это новое, эти значения мы будем использовать в качестве ключа
        {
            Undefined,
            Russia,
            Japan
        };

        public static void Main()
        {
                string request = GetRequest();
                ManufactureCountryKey key = FindKey(request); // метод больше не возвращает строковый тип
                string data = FindData(key);  // метод больше не получает строковый тип
                OutputResult(data);
        }

        private static ManufactureCountryKey FindKey(string request)  // изменён тип возвращаемого значения
        {
            if (!string.IsNullOrEmpty(request))
            {
                string key = request.ToLower();

                string b = "русские";
                string c = "российские";
                string d = "рассийские";
                string e = "росийские";

                if (key == b || key == c || key == d || key == e)
                {
                    return ManufactureCountryKey.Russia;
                }
                else
                {
                    return ManufactureCountryKey.Japan;
                }
            }

            return ManufactureCountryKey.Undefined;
        }

        private static string FindData(ManufactureCountryKey key) // тип параметра изменён
        {
            StringBuilder sb = new StringBuilder();

            switch(key)
            {
                case ManufactureCountryKey.Russia:
                    {
                        sb.Append("Ваз");
                        sb.Append(" ");
                        sb.Append("Газ");
                    }
                    break;
                case ManufactureCountryKey.Japan:
                    {
                        sb.Append("Mazda");
                        sb.Append(" ");
                        sb.Append("Toyota");
                        sb.Append(" ");
                        sb.Append("Nissan");
                    }
                    break;
                default:
                    {
                        sb.Append("По Вашему запросу данных нет");
                    }
                    break;
            }

            string result = sb.ToString();
            return result;
        }

}
« Последнее редактирование: 16-10-2019 09:10 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #65 : 16-10-2019 09:21 » 

Не очень большие изменения. Прога ещё работает как до этого.

1. Определён тип данных ManufactureCountryKey, значения этого типа мы будем использовать в качестве ключа (дом. задание: почитать в учебнике про enum)
2. Код для поиска ключа наконец-то находится в методе FindKey, там где он и должен находится.
3. Метод FindData адаптирован под новый тип ключа (раньше это была строка)

О последнем немного подробней в последний раз. В дальнейшем он нас не будет интересовать с точки зрения обучения.
1. Объект StringBuilder  "складывает" строки гораздо эффективней, чем оператор + (оставляем это на домашнее задание)
2. Введён оператор выбора switch, который позволяет выбрать соответствующий ключу код гораздо быстрее чем цепочка if ... else if
3. Очевидно, что такая организация метода позволит, при необходимости расширить его, например, добавить марки машин других стран производителей.

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

Есть проблемы с пониманием этих нововведений?

Если нет, то перейдём к последнему и главному методу - нашей цели - FindKey.
« Последнее редактирование: 16-10-2019 09:42 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
KOzh1r
Участник

ru
Offline Offline

« Ответ #66 : 16-10-2019 12:22 » 

Он уже для Вас не "китайские иероглифы" (с)
Исключительно благодаря Вам, за что огромное спасибо!

Есть проблемы с пониманием этих нововведений?
С пониманием алгоритма проблем нет. Но, тем не менее, новые типы данных и новые объекты немного путают, сбивают с мысли. Приходится перечитывать код чтобы понять что к чему.  Считаю это скорее плюсом, чем минусом.
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #67 : 16-10-2019 13:28 » 

Ну тогда вкратце.

Ключ.

Во-первых тип string хоть и является стандартным, но всё-таки это БОЛЬШОЙ объект, с кучей методов и тд. Понятно, что сравнение строки это нетривиальная операция. Необходимо учитывать длину, сравнивать каждый символ (кстати, следущим шагом мы будем практически этим заниматься).
Куда гораздо проще сравнивать целочисленный тип.
Другими словами, если мы скажем, что российские марки получат ключ целочисленного типа 1, японские 2, а неопределённые 0, то все операции с ключом будут производиться с максимальным быстродействием.
С другой стороны, если мы видим в коде 0, 1, 2, что это такое? Тут на помощь приходит enum, который позволяет определить целочисленый тип, но со смысловым именем.

Код: (C#)
        enum ManufactureCountryKey
        {
            Undefined,
            Russia,
            Japan
        };

В данном случае enum это ключевое слово, после которого следует описание = ИмяТипа. В фигурных скобках - возможные элементы, которые имеют целочисленный тип. Называть их можно как угодно, но лучше конечно, вкладывать в имя смысл.

По идее, его можно было бы представить в виде трёх переменных

Код: (C#)
            int Undefined = 0;
            int Russia = 1;
            int Japan = 2;

И пользоваться этими переменными. Тогда бы тип возвращаемого значения метода FindKey и тип параметра метода FindData был бы int. Но в таком случае можно было бы передавать скажем в FindData(9), а девятка у нас не определена. Таким образом enum позволяет избежать случайных ошибок программирования и отлавливать их уже на этапе компиляции. Это повышает надёжность кода и, ессно, программы.

Сложение строк.

Как уже упоминалось выше, строка это сложный объект. Слоожение двух таких объектов может происходить только по одному сценарию. Нам необходимо выделить память размером равным или больше размеров обоих слагаемых. Скопировать поочерёдно содержимое слагаемых в этот буфер и освободить память занимаемую исходными объектами. Если это делать многократно с оператором +, то каждый раз будет выполняться эта цепочка операций.
Если же мы сначала соберём все слагаемые в один список, то перед тем как сделать из них результирующую строку операцию выделения памяти нужно будет сделать только один раз, ведь все размеры в этот момент времени нам известны.

Для этот в .NET есть объект StringBuilder - построитель строк. Сначала мы добавляем в него строки, которые хотим сложить, вызывая метод Append, а для результата вызваем метод ToString.

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

Оператор выбора switch

Можно заменить на
Код: (C#)
                    if(ManufactureCountryKey.Russia == key)
                    {
                        sb.Append("Ваз");
                        sb.Append(" ");
                        sb.Append("Газ");
                    }
                    else if(ManufactureCountryKey.Japan == key)
                    {
                        sb.Append("Mazda");
                        sb.Append(" ");
                        sb.Append("Toyota");
                        sb.Append(" ");
                        sb.Append("Nissan");
                    }
                    else
                    {
                        sb.Append("По Вашему запросу данных нет");
                    }

Так понятней? switch делает тоже самое, только гораздо эффективней. Ну и является одним из стандарных операторов практически каждого языка программирования высокого уровня. Так что это относится к части обучения "расширяем словарный запас". Ага

Вот так выглядит метод FindData без нововведений

Код: (C#)
        private static string FindData(ManufactureCountryKey key)
        {
            string result = "";

            if (ManufactureCountryKey.Russia == key)
            {
                result = "Ваз " + "Газ";
            }
            else if (ManufactureCountryKey.Japan == key)
            {
                result = "Mazda " + "Toyota " + "Nissan";
            }
            else
            {
                result = "По Вашему запросу данных нет";
            }

            return result;
        }

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

зы да, ну и конечно же, без учебника по C# Вам ну никак не обойтись. Ага
« Последнее редактирование: 16-10-2019 14:49 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
KOzh1r
Участник

ru
Offline Offline

« Ответ #68 : 16-10-2019 22:25 » 

Я думаю, что на данном этапе лучше использовать знакомые выражения. В противном случае Я боюсь окончательно запутаться _)) Поэтому, думаю, пока лучше использовать этот вариант:
Код: (C#)
if(ManufactureCountryKey.Russia == key)
                    {
                        sb.Append("Ваз");
                        sb.Append(" ");
                        sb.Append("Газ");
                    }
                    else if(ManufactureCountryKey.Japan == key)
                    {
                        sb.Append("Mazda");
                        sb.Append(" ");
                        sb.Append("Toyota");
                        sb.Append(" ");
                        sb.Append("Nissan");
                    }
                    else
                    {
                        sb.Append("По Вашему запросу данных нет");
                    }

Данный тест необходимо сдать в понедельник, потом он завершится и состоится подведение итогов. Этот этап Я пока пропустил, но хочу успеть его сдать. Как считаете, успею понять и реализовать? Отлично
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #69 : 17-10-2019 01:25 » 

Ну в принципе осталась мелочь. Вам максимум часа на два кодирования.

Забываем про все остальные методы, кроме FindKey. Они выполнют свои ф-ции и что-то в них менять нет необходимости.
С этого момента мы будет работать только с FindKey.

Итак, оригинальная логика проверяет только на "русские" и... остальные. Это неправильно. Она должна выяснить, есть ли в запросе "русские", "японские" и остальные (неопределённые). Это мы уже подготовили. У нас есть три ключа для, соответственно, каждого из вариантов.

Теперь осталось только проанализировать запрос и вернуть нужный ключ. Поскольку запрос задаётся человеком, нам надо "очеловечить" программу. Те анализировать так, как это делает человек.
Предложение состоит из слов, разделённых символами разделения, например пробелом. Слова в свою очередь состоят из букв, которые также являются символами. Мы, человеки, ищем в этом массиве символов нужную нам комбинацию, например мы отличаем "рус" от "япо". С учётом ошибок, таких комбинаций будет несколько, для каждого варианта/страны.

Зададим размер комбинации равный трём. Те исходим из того, что определённая комбинация из трёх букв даст нам однозначный ответ: "русский", "японский", или "неопределён".
Если на каком-то этапе, или в процессе тестирования мы выясним, что трёх недостаточно, мы увеличим их до четырёх, пяти и тд. Или наоборот уменьшим до двух. Принципиального значения это не имеет. Всё ограничивается только нашей фантазией и фантазией пользователя.
По идее можно начать и с одной, но очевидно что одной буквы не хватит, чтобы найти нужную нам информацию.

Для начала нам надо получить доступ к этим отдельным символам запроса.
После этого останется только найти нужную комбинацию в запросе и вернуть соответствующий ключ. Всё.

Тип данных для отдельных символов называется char, а string представляет собой ни что иное, как массив этих самых символов.
Для доступа к элементам массива существует оператор индекса, который записыватся в коде в виде квадратных скобок [], внутри которых записывается индекс (позиция) символа.

ВАЖНО!!! Индекс в квадратных скобках не должен превышать длину массива (в нашем случае строки).
Индексация массивов начинаются с нуля (индекс первого элемента 0), а не с единицы, поэтому условие проверки должно быть строгим. Другими словами, индекс последнего элемента всегда на единицу меньше длины массива.

Пример

в строке string str = "ABC"; три символа
  символ A находится в позиции 0, доступ к нему str[0]
  символ B находится в позиции 1, доступ к нему str[1]
  символ C находится в позиции 2, доступ к нему str[2]

попытка доступа к четвёртому, несуществующему, элементу str[3] приведёт к сбою в работе программы.

Объекты типа char можно добавлять в объекты типа string
Код: (C#)
            char ch = 'C';
            string str = "AB";
            str += ch; // после этого в строке str находится "АВС"

Ну и ещё нам нужен оператор цикла, чтобы "пробегать" по элементам строки (массива). Мы будем использовать for.

Вот как это выглядит в коде
Код: (C#)
            string str = "ABC";
            for (int i = 0; i < str.Length; i++)  // этот оператор увеличивает содержимое переменной i на единицу после каждого выполнения тела цикла, до тех пор, пока не выполнится условие
            {
                // тело цикла
                char ch = str[i]; // здесь в переменную ch будет помещён символ из позиции текущего значения i
                // дальше можно делать с этим символом всё что угодно
            }

int i = 0; -> инициаллизация начального значения
i < str.Length; -> условие работы цикла
        * пока i строго меньше длины массива (она находится в свойстве Length объекта string), выражение истинно и цикл работает
i++ -> увеличение i на единицу, по сути это  i=i+1

Строка str содержит 3 символа, значит длина массива равна 3, следовательно тело цикла будет выполнено...
1-ый раз: i=0, i<3 -> ОК - в переменной ch находится элемент массива (строки) с индексом 0, "A"
2-ой раз: i=1, i<3 -> ОК - в переменной ch находится элемент массива (строки) с индексом 1, "B"
3-ий раз: i=2, i<3 -> ОК - в переменной ch находится элемент массива (строки) с индексом 2, "C"
4-ый раз: i=3, i<3 -> условие ложно, цикл остановлен после третьего раза.


Чтобы Вы поняли как это работает добавим такой код в метод FindKey

Код: (C#)
        private static ManufactureCountryKey FindKey(string request)
        {
            if (!string.IsNullOrEmpty(request))
            {
                // след. код выведет в консоль запрос посимвольно "в столбик"
                for (int i = 0; i < request.Length; i++)
                {
                      char ch = request[i];
                      Console.WriteLine(ch);
                }

                // остальное нас сейчас не интересует
            }

            return ManufactureCountryKey.Undefined;
        }

Ну вот и всё, больше код я писать не буду. Теперь у Вас есть все "инструменты", чтобы максимум за два часа закодировать задание.

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

Например, Ъ в любой позиции комбинации не подходит ни для одной из стран.

Лучше сделать два метода, каждый из которых будет отвечать за свою "страну", но можно сделать и один метод, и передавать в него необходимые для "страны" параметры.
Второй способ предпочтительней, но я думаю Вам пока не стоит экономить, а сделать два метода. По функциональности они будут идентичными.
Refactoring мы сделаем потом, если время останется.

Говоря "простым языком", метод FindKey должен выглядеть как-то так

Код: (C#)
        private static ManufactureCountryKey FindKey(string request)  // изменён тип возвращаемого значения
        {
            if (!string.IsNullOrEmpty(request))
            {
                if (HasRUS(request))
                {
                    return ManufactureCountryKey.Russia;
                }
                else if (HasJAP(request))
                {
                    return ManufactureCountryKey.Japan;
                }
            }
            return ManufactureCountryKey.Undefined;
        }

где
 * private static bool HasRUS(string request)
 * private static bool HasJAP(string request)


Разбивать ли запрос сначала на отдельные слова? Это как Вам нравится, с этого момента Вы - программист. Я - только консультант. Ага

Я думаю, что в создании алгоритма бОльшую помощь Вам окажет Ваш сынишка, в силу
Цитата
Он тоже понимает что такое буквы, но что такое слова - для него загадка.
Попросите его найти нужную комбинацию букв в запросе, а потом запишите в виде кода, как он это сделал. Ага

Ну и ещё я - подсказчик.

Подсказки
 * добавить в код вспомогательный метод выделения из строки-источника определённого количества символов в строку начиная с определённой позиции
   * private static string GetSubString(string source, int startPosition, int length)
   * не забудьте про проверку индекса
 * добавить в код вспомогательный метод для проверки нахождения символа в массиве других смволов
    * private static bool IsCharInArray(char ch, string allowedChars)

« Последнее редактирование: 17-10-2019 02:03 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #70 : 18-10-2019 10:01 » 

Проблемы? Или всё готово?

ps
Меня завтра не будет, и до форума смогу "добраться" только в воскр. в лучшем случае после обеда, в худшем, только к вечеру.
« Последнее редактирование: 18-10-2019 15:55 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
KOzh1r
Участник

ru
Offline Offline

« Ответ #71 : 19-10-2019 09:45 » 

Теперь у Вас есть все "инструменты", чтобы максимум за два часа закодировать задание.

Два дня колупаюсь, но так и не пойму как реализовать это:


После этого останется только найти нужную комбинацию в запросе и вернуть соответствующий ключ.
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #72 : 19-10-2019 09:48 » 

Ок, есть полчаса. В чём именно проблема? Как цикл работает понятно?

Добавлено через 2 минуты и 14 секунд:
Вы GetSubString уже реализовали?

Добавлено через 13 минут и 43 секунды:
Покажите, что уже сделано. Какие методы реализованы. Начиная с кода FindKey, все остальные нас не интересуют.

Добавлено через 7 минут и 13 секунд:
Два дня колупаюсь, но так и не пойму как реализовать это:
После этого останется только найти нужную комбинацию в запросе и вернуть соответствующий ключ.

Это ВСЁ оставшееся задание.

Делайте постепенно. Методом последовательных приближений. Забудьте на полчаса о ВСЁМ задании, и сконцентрируйтесь на одном методе.

Для начала "вытаскивание" последовательности трёх символов из запроса. Кстати понятно почему и для чего это надо делать? Вы прдеставляете себе алгоритм?

После этого забываем на полчаса обо всём кроме метода проверки наличия символа в массиве.

После этого у Вас остаётся целый час чтобы соединить три вызова этого метода, уже знакомыми Вам if-ами.

Ну это из моей прикидки, что Вам потребуется 2 часа для завершения задания.
« Последнее редактирование: 19-10-2019 10:24 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
KOzh1r
Участник

ru
Offline Offline

« Ответ #73 : 19-10-2019 10:29 » 

Код: (C#)
string rus = "";
            string b = "рус";
            for (int i = 0; i < b.Length; i++)
            {
                char ch = request[i];
                rus = rus + ch;
            }
            string key = request.ToLower();

так реализован метод внесения в переменную rus первых введённых трех символов в request.

Я пока концентрирую внимание на том, как найти одно значение - "рус". После этого уже займусь добавлением "япо".

GetSubString - вообще не понял зачем нужен, если начальная позиция мне не известна?
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #74 : 19-10-2019 10:38 » 

Вы понимаете, что Вы делаете? Этот код просто копирует переменную b в rus, можете просто записать rus = b;
Но зачем? Что Вам это даёт?

Добавлено через 3 минуты и 33 секунды:
Я так понимаю у Вас проблемы не с кодом, а с алгоритмом.

Забудьте про код, опишите просто словами последовательность действий нахождения в запросе нужной инфы.

На входе "Покажи руския".

Ваши действия?


« Последнее редактирование: 19-10-2019 10:42 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #75 : 19-10-2019 10:43 » 

Я пока "подправлю" Ваш метод. Как цикл работает Вы поняли, это уже хорошо.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
KOzh1r
Участник

ru
Offline Offline

« Ответ #76 : 19-10-2019 10:52 » new

1. Вход - "покажи руския"
2. Разбиваем запрос на слова - "покажи" и "руския"
3. Ищем, записанный в переменную, ключ "рус", в этих словах
4. Находим - "руския"
4. Возвращаем слово целиком
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #77 : 19-10-2019 10:59 » 

Итак

В Вашем коде Вы "вытаскиваете" последовательно символы и сохраняете их в буфер - это то что нам нужно. Только
1. Вытаскивать надо из request, который передаётся в метод в качестве параметра source
2. Сколько? 3 символа, значит цикл должен рабоать только 3 раза

дальше коменты в коде

Код: (C#)
private static string GetSubString(string source, int startPosition, int length)
{
            string rus = ""; // а для вытаскивания японских этот метод разве не подойдёт? ну ладно пусть будет rus
            // string b = "рус"; // это к чему? выкидываем нафик
            for (int i = 0; i < b.Length; i++) // почему с 0? стартовая позиция передаётся в метод в качестве параметра -> startPosition
            // конечное условие? длина последовательности -> length, но нам нужен индекс символа, совершенно очевидно, что если мы начнём "вытаскивать" с 5-ой позиции, то условие 5 < 3 будет изначально ложно, и цикл не выполнится ни разу
            // что надо сделать? пересчитать индекс символа с учётом стартовой позици. Логика: получить 3 символа, начиная с пятой позиции, значит какие индексы нам нужны? 5,6,7 или?
            {
                char ch = request[i];
                rus = rus + ch;
            }

        return rus;
}
Вот и всё... Уже можно работат, НО опасно. А что если метод будет вызван со стартовым индексом 134? Я уже говорил, что доступ к не существующим индексам приведёт к обрушению программы. Значит, перед тем как его запускать
надо проверить стартовое и... конечное значение. Ведь если в метод будет передан индекс последнего символа, то на втором шаге индек будет больше количества элементов в строке.
Это делается простыми известными Вам if-ами
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #78 : 19-10-2019 11:04 » 

1. Вход - "покажи руския"
2. Разбиваем запрос на слова - "покажи" и "руския"
3. Ищем, записанный в переменную, ключ "рус", в этих словах
4. Находим - "руския"
4. Возвращаем слово целиком

Ок, понятно. Вы всё-таки хотите разбивать на слова. Можно конечно и так. Я так понимаю метод из п.2 готов?
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
KOzh1r
Участник

ru
Offline Offline

« Ответ #79 : 19-10-2019 11:20 » 

Дело не в том, как Я хочу, но в том, как Я понимаю реализацию. Вот в этом методе Я вообще запутался.

Вытаскиваю Я символы и сую их в буфер. Отлично. Хм, хотя.. А для чего Я это делаю? Допустим Я перебрал и записал три символа с восьмой позиции в запросе "покажи руския ... " и получил "рус". Прога отработала, всё ок. А если запрос будет "какие руския ..."? Тогда Я выдерну уже "уск" и прога не отработает.

Предположим, есть какие-то методы, для поиска нужных символов в запросе. Они сами определят где начинается" руския" и начнут отсчёт именно с этого символа. Но тогда зачем весь этот изначальный перебор? Если программа уже знает, где начинается "руския", то зачем искать это слово заново? В общем Я окончательно запутался..
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #80 : 19-10-2019 11:26 » 

Всё, мне надо убегать. Посему.

Это даже хорошо, что у Вас "свой" алгоритм. Тогда я могу показать "свой". На его основе, Вы можете реализовать свой. И это не будет "плагиатом".

У Вас в любом случае будут проблемы с п.3. Те необходимо будет рализиовать более простой алгоритм, котороый я предлагал. С тем исключением, что "мой" метод работает дольше, конечно в зависимости от того, как Вы реализуете метод "вытаскивания" слов.

Как дети складывают буквы в слова?

М--А МА  М--А МА... а МАМА

Те это самый простой, "примитивный" способ. Но он работает.

Те нам надо найти определённую последовательность символов, которую мы "узнаем",
точнее предположим, что "узнали"

Допустим есть запрос

"Покажи руския"

Предполагаем, что комбинация из трёх символов может дать нам достаточно инфы, для распознавания.

Те первым шагом из запроса надо получить эти три символа и проанализировать их.
Поскольку мы не знаем, в каком месте они находятся, необходимо "пробежать" по всей строке

0 Пок
1 ока
2 каж
3 ажи
4 жи
5 и р
6  ру
7 рус
8 уск
и тд

Эту ф-ю будет выполнять метод GetSubString. Те "вытаскивать" из "Покажи руския" поочерёдно по три символа

Определим правила распознавания последовательности.

Какие символы допустимы на первом месте комбинации?
Очевидно, что для "русских" это "Рр"(простой идеальный вариант, а какие могут быть ещё?)
На втором "Уу"(простой идеальный вариант, а какие могут быть ещё?)
На третьем "Сс" (простой идеальный вариант, а какие могут быть ещё?)

Те нам надо проверить наличие символа в каком-то массиве заданных символов.
Эту ф-ю выполняет метод IsCharInArray.
Сначала мы проверяем первый символ, если тест проходит успешно, возрастает вероятность, что это "знакомая" комбинация.
Проверяем второй символ.
Аналогично третий.
Когда все три теста будут успешными, мы с большой долей вероятности, можем сказать, что пользователь хочет посмотреть "русские" марки машин.
Если хотя бы один из тестов выдаёт false, переходим к след. последовательности.
Продолжаем пока не найдём "знакомую" или не переберём все символы ввода.

В примере выше, мы находим нужную комбинацию на восьмом шаге.

Если же мы когда-нибудь решим, что последовательности из 3-х символов недостаточно, мы расширим её до 4-х, 5-ти и тд.
Но на для теста такого уровня достаточно и 3-х.

Абсолютно любой ввод распознать невозможно (пользователь уснул на клавиже Ж).

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

Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #81 : 19-10-2019 11:31 » 

Предположим, есть какие-то методы, для поиска нужных символов в запросе. Они сами определят где начинается" руския" и начнут отсчёт именно с этого символа. Но тогда зачем весь этот изначальный перебор? Если программа уже знает, где начинается "руския", то зачем искать это слово заново? В общем Я окончательно запутался..

Хе? Программа не знает НИЧЕГО!!! Точнее, она знает только то, чему мы её научим. Что значит "предположим"? Методы есть только те, которые мы САМИ СОЗДАЁМ. Никакой другой манны небесной нет.

Итак, код

(click to show)
Код: (C#)
        private static bool HasRUS(string request)
        {
            for (int i = 0; i < request.Length; i++)
            {
                string keySequence = GetSubString(request, i, 3);
                if(VerifyRUS(keySequence))
                {
                    return true;
                }
            }
            return false;
        }

        private static bool HasJAP(string request)
        {
            for (int i = 0; i < request.Length; i++)
            {
                string keySequence = GetSubString(request, i, 3);
                if (VerifyJAP(keySequence))
                {
                    return true;
                }
            }
            return false;
        }

        private static bool VerifyRUS(string keySequence)
        {
            if (!string.IsNullOrEmpty(keySequence) && (keySequence.Length == 3))
            {
                string allowedInFirstPos = "Рр";
                string allowedInSecondPos = "УуОоАа";
                string allowedInThirdPos = "Сс";

                if (IsCharInArray(keySequence[0], allowedInFirstPos))
                {
                    if (IsCharInArray(keySequence[1], allowedInSecondPos))
                    {
                        if (IsCharInArray(keySequence[2], allowedInThirdPos))
                        {
                            return true;
                        }
                    }
                }
            }
            return false;
        }

        private static bool VerifyJAP(string keySequence)
        {
            if (!string.IsNullOrEmpty(keySequence) && (keySequence.Length == 3))
            {
                string allowedInFirstPos = "ЯяИи";
                string allowedInSecondPos = "Пп";
                string allowedInThirdPos = "Оо";

                if (IsCharInArray(keySequence[0], allowedInFirstPos))
                {
                    if (IsCharInArray(keySequence[1], allowedInSecondPos))
                    {
                        if (IsCharInArray(keySequence[2], allowedInThirdPos))
                        {
                            return true;
                        }
                    }
                }
            }
            return false;
        }
« Последнее редактирование: 19-10-2019 11:37 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #82 : 19-10-2019 11:46 » 

До завтра Вам необходимо рализовать метод разбивания запроса на слова и метод поиска нужной последовательности в слове.
За основу можете взять методы Has* и Veirfy*, как Вы заметили они функционально идентичны для стран.

Я думаю, что буду завтра в онлайне где-то часов с 12-13 (GMT+1)
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
KOzh1r
Участник

ru
Offline Offline

« Ответ #83 : 19-10-2019 19:19 » 

В общем, буду откровенен. В последних Ваших сообщениях Я понимаю только то, что написано русским языком. То, что написано в коде С# до меня не доходит. Равно как и то, что необходимо сделать для того, чтобы всё работало. После того, как Я с Вашей помощью, стал разбирать метод "FindKey", Я вообще перестал понимать код. Может Я настолько глуп, но вот эти фразы типа "IsCharInArray", "!string.IsNullOrEmpty" и "ManufactureCountryKey" вообще не ясны. Вернее, Я понимаю(или думаю что понимаю) что они значат в конкретном участке кода, но их влияние на программу в целом остаётся загадкой. Ранее Я понимал как работает программа по информации, которая выводится. По результату. Теперь Я вообще не контролирую код. Компилятор постоянно выдает ошибки, которые Я допускаю пытаясь собрать код в одно целое. Кроме того, какое-то из этих слов нужно внести наверх кода, в метод Main... Какие? Да черт его знает.

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

Джон, спасибо Вам большое за помощь и за усердные попытки научить меня понимать и работать с С#. Вы какой-то исключительный человек, чесслово. Не надоело же возиться со мной, с нубом_)) Похоже Я дойду до решения самостоятельно через пару-тройку месяцев. Жаль что тест провалю, столько заданий выполнял и все зря_)) Спасибо Вам ещё раз и уважение!  Класс!
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #84 : 20-10-2019 11:16 » 

Да ладно Вам, насколько я понимаю тест надо сдать завтра? Так ещё не всё потеряно.

В общем, буду откровенен.
Иного я и не жду, в противном случае ничего не получится.

столько заданий выполнял
А какого типа были ЭТИ задания? Те они не были связаны с кодированием?

Компилятор постоянно выдает ошибки, которые Я допускаю пытаясь собрать код в одно целое.
Так покажите Ваш код, на ошибках же учатся.

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

Ок, ещё раз и по полочкам.

1. Программа не есть код.
Посему сначала пишем программу на понятном нам языке, вместо сигнатур (так называются страшные строчки типа private static bool HasRUS(string request)) я буду писать что происходит в этом месте
Я не буду вдаваться в объяснения, как происходит объявление переменных, или что у них должет быть определён тип. С этим, как и синтаксисом, судя по первому коду, у Вас проблем нет.

Итак

Изначальная точка входа в Программу, здесь всё начинается, а заканчивается после закрывающей скобки, см внизу
{
      буфер запроса, в котором будет храниться введённое значение = Получить введённое пользователем предложение/запрос

      ключ (ключевая информация), который, либо однозначно определяет данные для вывода (рус или яп), либо содержит инфу и нераспознанном запросе = Получить ключ из буфера запроса

      буфер результата = Получить данные по ключу

      Показать буфер результата пользователю

} // когда выполнение дойдёт до этой скобки программа завершится

Всё, это и есть вся программа. Логика, алогоритм и тд и тп. Это то, что мы хотим сделать. Необходимая последовательность действий, выполнив которые мы получим результат.
Такая запись понятна нам, но непонятна компьютеру. Здесь на помощь приходит язык программирования (ЯП). Какой? По сути не важно. Каждый ЯП, так же как и в человеческих языках, имеет свои преимущества и недостатки.
По большому счёту можно выбирать любой. Поэтому в задании Вашего теста не конкретизируется, на каком именно ЯП надо выполнить задание.

Вы выбрали C#. Очевидно, что какие-то вещи из тех, которые нам нужны для "объяснения" нашей задумки компьютеру, уже присутствуют в ЯП. С чего-то надо начинать. А вот остальные нам придётся "добавить" самим.

Запишем нашу программу на языке C#.
К сожалению, большинство компиляторов (это те штуки, которые переводят код ЯП в код понятный процессору) не понимают русский язык. Поэтому будем использовать английские буквы и слова.
Синим цветом выделены уже известные в C# слова.
Коричневым - слова определённые программистом по правилам языка C# и понятные компилятору
Красным -  слова определённые программистом по правилам языка C#, но ещё пока непонятные компилятору

// Изначальная точка входа в Программу, здесь всё начинается, а заканчивается после закрывающей скобки, см внизу
public static void Main()
{
      // буфер запроса, в котором будет храниться введённое значение = Получить введённое пользователем предложение/запрос
      string request = GetRequest();

      // ключ (ключевая информация), который, либо однозначно определяет данные для вывода (рус или яп), либо содержит инфу и нераспознанном запросе = Получить ключ из буфера запроса
       /*тип этой переменной не содержится в стандартном наборе C# и нами тоже пока ещё не определён*/ key = FindKey(request);

      // буфер результата = Получить данные по ключу
      string data = FindData(key);

      // Показать буфер результата пользователю
      OutputResult(data);

} // когда выполнение дойдёт до этой скобки программа завершится

public static void Main() -> известно компилятору изначально, нам это даже зачастую предоставляется средой разработки. Так же как и, например, string.
А вот
 *  GetRequest
 *  FindKey
 *  FindData
 *  OutputResult
неопределены в С#, поэтому нам надо создать их самим. Мы уже сообщили компилятору желаемую последовательность действий. Теперь надо "расшифровать" для него, что же
мы конкретно имеем ввиду под тем или иным действием, до сих пор неизвестным компилятору.

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

Каждое из наших нововедённых "словечек" является по сути маленькой программкой, с завершённой логикой. Каждая из этих программок выполняет какие-то действия и может, если это необходимо, возвращать результат.

Небольшой оффтоп, простенькая аллегория:
(click to show)
Представьте себе, что мы создаём неких искусственых собачек, каждая из которых может выполнять определённое задание:
 *  GetRequest: сбегай, принеси, что там пользователь ввёл
 *  FindKey: найди в том, что принёс GetRequest, ключ и принеси его
 *  FindData: понюхай ключ и принеси все данные с таким же запахом
 *  OutputResult: отнеси данные пользователю

Такие программки называются методы.

Как определять в коде методы я уже подробно описал тут.

Если есть непонятки, тогда вернёмся к этому моменту.

Так же я не буду останавливаться на реализации методов GetRequest,  FindData,  OutputResult.

Опять же, если есть непонятки, тогда вернёмся и к этому моменту.

Пока всё ОК?
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
KOzh1r
Участник

ru
Offline Offline

« Ответ #85 : 20-10-2019 12:12 » 

А какого типа были ЭТИ задания? Те они не были связаны с кодированием?
Задания наподобие
"Напишите программу, которая выводит "Hello, World!" 10 раз, каждый на своей строке"
или
"По данному трехзначному числу, определите образуют ли цифры данного числа возрастающую последовательность"

Пока всё ОК?
Сложности лишь по той причине, что много новой информации. Я не знаю как именно написать (какие слова, методы, переменные или названия использовать) чтобы компьютер понял чего Я хочу. Для какого-то метода есть обязательные условия, один должен что-то возвращать, другой наоборот не должен. Следующий возвращает один тип данных и не возвращает другой. Значит надо как-то изменить этот тип. В общем моих знаний на уровне неофита явно мало.
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #86 : 20-10-2019 12:17 » 

Делам паузу

Сложности лишь по той причине, что много новой информации. Я не знаю как именно написать (какие слова, методы, переменные или названия использовать) чтобы компьютер понял чего Я хочу. Для какого-то метода есть обязательные условия, один должен что-то возвращать, другой наоборот не должен. Следующий возвращает один тип данных и не возвращает другой. Значит надо как-то изменить этот тип.

Так, стоп, это я всё понял. На этом этапе, Вашего "словарного" запаса достаточно, чтобы СЕГОДНЯ завершить это задание.

А остальное... Вы прочитали предыдущий пост? Моя цель, как раз и объяснить Вам, что МЫ САМИ определяем методы, МЫ САМИ решаем как и что они делают, и что возвращают.
Для этого Вам не нужно знать ничего "нового", мы оперируем только тем, что Вам уже известно. От switch мы (Вы) отказались, как работает for Вы разобрались. Больше нам ничего не надо.
Кстати, какой цикл Вы использовали здесь:
которая выводит "Hello, World!" 10 раз, каждый на своей строке
?

Если уж будет совсем "напряжно", то откажемся и от enum.

Но я пока не потерял надежду, посему...

Продолжаем

Концентрируемся на FindKey.

Начнём с типа ключа, да и вообще с ключа.

В Вашем первом коде различие в марках делалось след. образом

Код: (C#)
               if(key == b || key == c || key == d || key == e)
               {
                    result = "Ваз " + "Газ";
               }
               else
               {
                    result = "Nissan " + "Toyota " + "Mazda";
               }

Те Вы различали определённо русские марки и... все остальные были японскими. Достаточно пользователю было ввести какую-нить чушь (уснуть на кнопке Ж), как он тут же получал японские модели машин. А чтобы Вы делали, если бы в задании требовалось показать российские, японские и немецкие? А ещё французкие? А ещё корейские? И тд.
Как Вы, как человек, различаете, что есть российские, а что японские? (вопрос риторический)
Так а откуда же это ВСЁ должен знать компилятор?

По-хорошему, если бы у нас была некая база данных, то тогда таблица с данными о марках машин содержала бы две, примерно такие, колонки:

Страна-производительМарка
РоссияГаз
ЯпонияNissan
ЯпонияToyota
ЯпонияMazda
РоссияВаз

Очевидно, что в левой колонке находится информация, позволяющая однозначно определить принадлежность марки машики к стране-производителю. Назовём эту инфу "ключ".
Таким образом наш "ключ" может принимать два значения "Россия" и "Япония", но всегда остаётся и третья возможность "ни то, ни то", или "все остальные". Поскольку,
в нашем случае, эта третья возможность получится только тогда, когда мы не распознаем в запросе ни Россию, ни Японию, установим это третье состояние как "Неопределённое".

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

Страна-производительМарка
1Газ
2Nissan
2Toyota
2Mazda
1Ваз

Но теперь нам непонятно, а что же такое 1, 2 и... помним про "Неопределённое", присвоим ему  0.
Те нужна некая "легенда"

Смысл ключаКод ключа
Неопределён0
Россия1
Япония2

« Последнее редактирование: 20-10-2019 14:07 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #87 : 20-10-2019 13:21 » 

Продолжу здесь, чтобы сохранить очерёдность постов.

Собственно мы уже подошли к enum.

Он позволяет нам объединить простоту понимания как для человека (мы будем читать в коде понятные нам слова, а не 0 1 2 ), так и для компьютера, который будет работать с 0 1 2.

Внешне конструкция enum выглядит как определения типа. Ну Вы ведь уже пользуетесь такими типами данных как int, string, bool, которые уже находятся в словаре C# и известны компилятору. enum в данном случае позволяет нам определить свой собственный тип и дать ему ЛЮБОЕ имя, которое мы захотим. Я решил дать ему имя ManufactureCountryKey, те это 3 соединёных вместе слова Manufacture Country Key (Производитель Страна Ключ), каждое из которых начинается с большой буквы для удобства прочтения (manufacturecountrykey читать гораздо неудобней). Да, по этой же причине, имена методов состоящие из более чем одного слова
записываются таким же образом (Get Request, Find Key и тд). Такой способ записи имеет своё название CamelCase, но об этом Вы почитаете, когда мы расправимся с заданием.

Итак, первые два "слова" в определении enum понятны? Первое, собственно enum - ключевое слово языка C#, которое сообщает компилятору, что за ним последует определение нового типа данных в общем и непосредственно за ним Именем этого нового типа, которое выбрал программист.

Далее следует "тело" этого нового типа. Как мы уже знаем, "тело" принято брать в фигурные скобки.

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

        enum ManufactureCountryKey
        {
            Undefined = 0,
            Russia = 1,
            Japan = 2
        };

Чтобы долго не заморачиваться, я внёс в этот тип слова, которые соответствуют занчениям нашего ключа. Undefined - Неопределённый, Russia - Россия, Japan - Япония.
Для пущей наглядности, я ввёл целочисленные значения для этих "слов" ( =0, =1, =2), такая запись не является синтаксической ошибкой, но компилятор делает это из без такой записи.
Те и без  =0, =1, =2 реальные значения равны соответствено 0 1 2


Я бы мог кончено определить этот тип и так

        enum KljutchStranyProizvoditelja
        {
            Neopredeljonnyj,
            Rossija,
            Japonija
        };

Но всё-таки лучше использовать английские слова, те слова языка, который худо бедно понимает каждый программис, и следовательно поймёт и Ваш код.
В данном случае, для Вашего теста, Вы можете использовать русский транслитеративно. Может это даже будет полезно, если вы все определённые нами методы, переименуете таким образом.
Ну типа FindKey -> NajtiKljutch.

Всё, после определения такого типа в классе, мы можем им пользоваться везде в коде как и любым другим типом данных (для сравнения я привожу пример использования типа int в аналогичных ситуациях).

Возвращать его как результат метода
Код: (C#)
int FindKey()
ManufactureCountryKey FindKey()

Передавать в качестве параметра в метод
Код: (C#)
string GetData(int key)
string GetData(ManufactureCountryKey key)

Определять переменные этого типа:
Код: (C#)
int keyInt; // переменная типа int
ManufactureCountryKey keyEnum; // переменная типа ManufactureCountryKey

Разница заключается только в том, что переменной типа ManufactureCountryKey может быть присвоено значение ТОЛЬКО из тех, которые перечислены в теле этого типа.
Код: (C#)
int i = 3;

ManufactureCountryKey keyEnum = 0; // ошибка, 0 не находится в списке разрешённых величин
ManufactureCountryKey keyEnum = ManufactureCountryKey.Undefined; // всё ОК

Запись ManufactureCountryKey.Undefined означет, что имеется ввиду величина Undefined именно типа ManufactureCountryKey, а не какого-то другого типа, у которого тоже есть величина с таким именем. Например у меня может быть и другой тип

        enum MyColorEnumType
        {
            Undefined,
            red,
            green,
            blue
        };
тогда
            MyColorEnumType my_color = ManufactureCountryKey.Undefined; // ошибка
            ManufactureCountryKey key = MyColorEnumType.Undefined; // ошибка

аналогично если Вы попробуете сделать след.
Код: (C#)
            string st1 = "";
            int n234 = st1; // ошибка
А так всё в порядке
Код: (C#)
            MyColorEnumType my_color = MyColorEnumType.Undefined;
            ManufactureCountryKey key = ManufactureCountryKey.Undefined;

Ну вроде всё.

Переходим к реализации FindKey? Или есть непонятки?
« Последнее редактирование: 20-10-2019 13:29 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #88 : 20-10-2019 13:52 » 

Итак метод FindKey

Мы помним, что в нашей ПРОГРАММЕ (где всё написано человеческим языком) вторым заданием явлется нахождение ключа

Цитата
ключ (ключевая информация), который, либо однозначно определяет данные для вывода (рус или яп), либо содержит инфу и нераспознанном запросе = Получить ключ из буфера запроса

Тип ключа мы уже определили, далее в русскоязычном тексте я будут называть его Тип Ключа, в коде C# использовать имя введённого типа ManufactureCountryKey, только цвет у него будет не коричневый, а синий, как и у других типов int, string. Нууу это всё-таки тип, как-никак.

Сначала определяем, что должна делать эта программка-собачка. Совершенно очевидно, что это один из самых простых методов, и по идее можно обойтись и без него, а записать тело метода напрямую в метод Main, но мы учимся создавать хорошо читабельный код, а самое главное - разбивать СЛОЖНЫЕ ЗАДАНИЯ на ПРОСТЫЕ и распределять их по методам-собачкам.

вернуть Тип Ключа после поиска его в буфере запроса
{
      если в буфере запроса содержится хоть какая-нибудь информация (буфер не пуст)
      {
            если проверка наличия ключа для России пройдена успешно
            {
                  возвращаем ключ Россия
            }

            иначе если проверка наличия ключа для Японии пройдена успешно
            {
                  возвращаем ключ Япония
            }
       }
       во всех остальных случаях возвращаем ключ Неопределено
}

Записываем задание на языка C#

Код: (C#)
// вернуть Тип Ключа после поиска его в буфере запроса
private static ManufactureCountryKey FindKey(string request)
{
    // если в буфере запроса содержится хоть какая-нибудь информация (буфер не пуст)
    if (!string.IsNullOrEmpty(request))
    {
        // если проверка наличия ключа для России пройдена успешно
        if (HasRUS(request))
        {
            // возвращаем ключ Россия
            return ManufactureCountryKey.Russia;
        }
        // иначе если проверка наличия ключа для Японии пройдена успешно
        else if (HasJAP(request))
        {
            // возвращаем ключ Япония
            return ManufactureCountryKey.Japan;
        }
    }
    // во всех остальных случаях возвращаем ключ Неопределено
    return ManufactureCountryKey.Undefined;
}

Это понятно?

Компилятору тоже пока всё понятно, или почти всё... Конечно же, он сразу спросит, а что такое HasRUS и HasJAP?
« Последнее редактирование: 20-10-2019 13:57 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #89 : 20-10-2019 14:37 » 

И можно было бы сделать только одну "собачку" и посылать её выполнять задание сначала для "русского" ключа, а потом для "японского". Но мы решили пока не экономить на понятности.

Совершенно очевидно, что подпрограммки HasRUS и HasJAP выполняют одну и ту же функциональную задачу, только одна ищет "русский" ключ, вторая "японский".

Поэтому рассмотрим детально только одну из них -> HasRUS.

Итак мы помним, что она должна искать "русский" ключ во введённом пользователм запросе и вернуть истину, если таковой в нём будет найден

вернуть результат проверки наличия "русского" ключа во введённом пользователм запросе
{
    перебираем все позиции в запросе начиная с нулевого
    {
        последовательность для проверки = Получить из запроса последовательность длиной 3 символа, начиная с текущей позиции
        если последовательность соответствует "русскому" ключу
        {
            останавливаем выполнение программки (метода, собачки) и возвращаем результат истина
        }
    }
    "русский" ключ в запросе не найден, возвращем результат ложь
}

Ну и на C#

Код: (C#)
private static bool HasRUS(string request)
// вернуть результат проверки наличия "русского" ключа во введённом пользователм запросе
{
    // перебираем все позиции в запросе начиная с нулевого
    for (int i = 0; i < request.Length; i++)
    {
        // последовательность для проверки = Получить из запроса последовательность длиной 3 символа, начиная с текущей позиции
        string keySequence = GetSubString(request, i, 3);
        // если последовательность соответствует "русскому" ключу
        if(VerifyRUS(keySequence))
        {
            // останавливаем выполнение программки (метода, собачки) и возвращаем результат истина
            return true;
        }
    }
    // "русский" ключ в запросе не найден, возвращем результат ложь
    return false;
}

Совершенно очевидно, что отличие "японской" версии метода (HasJAP) заключается в вызове метода VerifyJAP вместо VerifyRUS.

Поскольку метод VerifyRUS на данном этапе не известен компилятору, необходимо описать и его.

вернуть результат проверки последовательности 3-х символов на соответствие "русскому" ключу
{
    проверку разрешается производить только в том случае, если последовательность состоит из 3-х символов
    {
        определим разрешённые для русского ключа символы на первом месте "Рр"
        определим разрешённые для русского ключа символы на втором месте "УуОоАа"
        определим разрешённые для русского ключа символы на втором месте "Сс"

        если первый символ находится в массиве (списке) разрешённых для первой позиции символов
        {
            проверяем второй символ
            если второй символ находится в массиве (списке) разрешённых для второй позиции символов
            {
                проверяем третий символ
                если третий символ находится в массиве (списке) разрешённых для третьеё позиции символов
                {
                    возвращаем результат истина
                }
            }
        }
    }
    тест как минимум одного символа не пройден, возвращаем результат ложь
}

Теперь всё тоже самое на языке C#

Код: (C#)
// вернуть результат проверки последовательности 3-х символов на соответствие "русскому" ключу
private static bool VerifyRUS(string keySequence)
{
    // проверку разрешается производить только в том случае, если последовательность состоит из 3-х символов
    if (!string.IsNullOrEmpty(keySequence) && (keySequence.Length == 3))
    {
        // определим разрешённые для русского ключа символы на первом месте "Рр"
        string allowedInFirstPos = "Рр";
        // определим разрешённые для русского ключа символы на втором месте "УуОоАа"
        string allowedInSecondPos = "УуОоАа";
        // определим разрешённые для русского ключа символы на втором месте "Сс"
        string allowedInThirdPos = "Сс";

        // если первый символ находится в массиве (списке) разрешённых для первой позиции символов
        if (IsCharInArray(keySequence[0], allowedInFirstPos))
        {
            // проверяем второй символ
            // если второй символ находится в массиве (списке) разрешённых для второй позиции символов
            if (IsCharInArray(keySequence[1], allowedInSecondPos))
            {
                // проверяем третий символ
                // если третий символ находится в массиве (списке) разрешённых для третьеё позиции символов
                if (IsCharInArray(keySequence[2], allowedInThirdPos))
                {
                    // возвращаем результат истина
                    return true;
                }
            }
        }
    }
    // тест как минимум одного символа не пройден, возвращаем результат ложь
    return false;
}

Совершенно очевидно, что отличие "японской" версии метода (VerifyJAP) заключается в другом наборе символов разрешённых в позиции 0, 1, 2.
Пока... но возможно его придётся расширить до последовательности 4-х символов, если учесть, что пользователь может написать "йапонские".
Или даже учитывать оба варианта.
Но это уже дело техники, чётко сформулированного задания и очень сильного желания заказчика непомерно увеличить бюджет проекта. Ага

Вот собственно и всё, все шаги нашей ПРОГРАММЫ объяснены компилятору на его "родном" языке. Собачек можно спускать.

Что непонятно?
« Последнее редактирование: 20-10-2019 15:12 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Страниц: 1 2 [3] 4  Все   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines