Re[3]: Таблица из двух параметров - как лучше записать?
От: Mihas  
Дата: 15.11.21 13:23
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Так нужно же 2 значения — state1 и state 2. Делать одним длинным списком?

Dictionary<State,Dictionary<State,Action>>
Re[3]: Таблица из двух параметров - как лучше записать?
От: kov_serg Россия  
Дата: 15.11.21 13:45
Оценка: +1
Здравствуйте, Shmj, Вы писали:

S>Так нужно же 2 значения — state1 и state 2. Делать одним длинным списком?

Вы точно знакомы с языками программирования? Хеш таблицы, типы данных?
State = {state1,state2,...}
Re[4]: Таблица из двух параметров - как лучше записать?
От: Shmj Ниоткуда  
Дата: 15.11.21 14:00
Оценка: :)
Здравствуйте, kov_serg, Вы писали:

S>>Так нужно же 2 значения — state1 и state 2. Делать одним длинным списком?

_>Вы точно знакомы с языками программирования? Хеш таблицы, типы данных?
_>State = {state1,state2,...}

По условиям задачи каждый из state (и state1 и state2) имеет 3 варианта значений.
Re[5]: Таблица из двух параметров - как лучше записать?
От: Ночной Смотрящий Россия  
Дата: 15.11.21 14:35
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Самое наглядное — это таблица.


Таблицу тебе тоже уже предложили в виде Dictionary<State, Action>, но и она тебе тоже не мила.

S> Вот представьте таблицу — разве будет удобно, если ее представить в виде плоского теста и каждый раз дублировать названия столбцов и строк?


Зачем в PM дублировать названия столбцов? Кортежи никто пока не отменял.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[5]: Таблица из двух параметров - как лучше записать?
От: kov_serg Россия  
Дата: 15.11.21 15:01
Оценка:
Здравствуйте, Shmj, Вы писали:

S>По условиям задачи каждый из state (и state1 и state2) имеет 3 варианта значений.

struct State { 
  Type1 x; Type2 y; Type3 z;
  uint getHashCode();
  int compare(const State &rv) const;
};
Re[3]: Таблица из двух параметров - как лучше записать?
От: Sinclair Россия https://github.com/evilguest/
Дата: 15.11.21 16:04
Оценка: +1
Здравствуйте, Shmj, Вы писали:
S>А если не просто значение нужно вернуть — а вызвать некие методы?
Омг.
https://sharplab.io/#v2:CYLg1APgAgTAjAWAFBQMwAJboMLoN7LpGYZRwBsmArADwCWAdgC4A06AykwE6MDmAfAG0WAXXQB9ABYBDBsAA2AUy4BndAF50DRQHdq9Zm048GA4SIJJi1m3gCCcNgCFHOOAF8WhGz/sxn/jgwnt4+1vaozpE4qO6hNu4A3PFomAAs6ACyABSMTOgqTNJMiq55BUUlgeUAbtLyAK6KAJT48dZkAJzZUrIKyiqChcWlbMNVItl1jS3NyVbEcQtEKaQUmHAADOgOuczo0q3q/AcAdAAqAPbGfNlzqxuUZNsue/mHGifZMABUhxfXbi3e7LEiPDbbbBwN4HI5fVB/ZoAm6mO7zB5kJ5bHYwGEfY7obLSMBwJFXFG8NEY9bPdBOXHlfFfX7E0nIoGokEdNZYyEM/ZMwkI1lkwEmSkg6m8naoPFwwnSAC0bPJHIl8254NpTlljPl3z+ytFFKpoNSmIhMTlnyFhpVYuB6KQ7iAA===

public class C {
    public static Func<int, String>[,] _handlers = new Func<int, String>[,]{
            {A1, B1, C1},
            {A2, B2, C2},
            {A3, B3, C3}
        };
    public void M(int state1, int state2, int value) {
        Console.WriteLine(_handlers[state1, state2](value));
    }
    
    public static string A1(int a) => a.ToString();
    public static string B1(int a) => (2*a).ToString();
    public static string C1(int a) => (3*a).ToString();

    public static string A2(int a) => (a+1).ToString();
    public static string B2(int a) => (2*a+1).ToString();
    public static string C2(int a) => (3*a+1).ToString();

    public static string A3(int a) => (a-1).ToString();
    public static string B3(int a) => (2*a-1).ToString();
    public static string C3(int a) => (3*a-1).ToString();

}
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Отредактировано 15.11.2021 16:21 Sinclair . Предыдущая версия .
Re[4]: Таблица из двух параметров - как лучше записать?
От: Shmj Ниоткуда  
Дата: 15.11.21 18:21
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, Shmj, Вы писали:

S>>А если не просто значение нужно вернуть — а вызвать некие методы?
S>Омг.

Наверное нужно было сразу пример привести. Примрено такой пример:

  Скрытый текст
using System;

namespace ConsoleApp36
{
    class Program
    {
        enum GradeOfMen
        {
            Black,
            Mandarin,
            Aryan
        }

        static void Main(string[] args)
        {
            TransformAMan(GradeOfMen.Mandarin, GradeOfMen.Black);
        }

        static void TransformAMan(GradeOfMen fromMan, GradeOfMen toMan)
        {
            switch (fromMan)
            {
                case GradeOfMen.Black:

                    switch (toMan)
                    {
                        case GradeOfMen.Black:

                            // do nothing

                            break;
                        case GradeOfMen.Mandarin:

                            Wash();
                            GlueEyes();

                            break;
                        case GradeOfMen.Aryan:

                            throw new InvalidOperationException(); // impossible

                        default:
                            throw new ArgumentOutOfRangeException(nameof(toMan), toMan, null);
                    }

                    break;
                case GradeOfMen.Mandarin:

                    switch (toMan)
                    {
                        case GradeOfMen.Black:

                            Soot();
                            Scare();

                            break;
                        case GradeOfMen.Mandarin:

                            // do nothing

                            break;
                        case GradeOfMen.Aryan:

                            throw new InvalidOperationException(); // impossible

                        default:
                            throw new ArgumentOutOfRangeException(nameof(toMan), toMan, null);
                    }

                    break;
                case GradeOfMen.Aryan:

                    switch (toMan)
                    {
                        case GradeOfMen.Black:
                            
                            Soot();

                            break;

                        case GradeOfMen.Mandarin:

                            GlueEyes();

                            break;

                        case GradeOfMen.Aryan:

                            // do nothing

                            break;
                        default:
                            throw new ArgumentOutOfRangeException(nameof(toMan), toMan, null);
                    }

                    break;
                default:
                    throw new ArgumentOutOfRangeException(nameof(fromMan), fromMan, null);
            }
        }

        static void Scare() => Console.WriteLine("Пугаем (глаза увеличиваются)");
        static void Wash() => Console.WriteLine("Отмываем");
        static void Soot() => Console.WriteLine("Посыпаем сажей");
        static void GlueEyes() => Console.WriteLine("Клеим глаза");
    }
}
Re: [Updated]Таблица из двух параметров - как лучше записать?
От: Danchik Украина  
Дата: 15.11.21 18:33
Оценка: 16 (3) +2
Здравствуйте, Shmj, Вы писали:

S>Есть 2 параметра (или даже больше) state1 и state2. В зависимости от значений state1 и state2 — нужно выполнять определенные действия или бездействия (а так же генерить исключения — если такая комбинация не возможна).


S>Можно использовать вложенные друг в друга switch/case. Если в каждом из state 3 возможных значения — то получится 3 switch и внутри каждого — еще по 3 штуки switch. Есть ли что более красивое?


[Skip]

Я так понял вы пишете FSM (Finite State Machine).
Ну выбирайте, что посвежее https://stackoverflow.com/questions/632391/state-machine-frameworks-for-net
Re[2]: [Updated]Таблица из двух параметров - как лучше записать?
От: Shmj Ниоткуда  
Дата: 15.11.21 20:11
Оценка:
Здравствуйте, Danchik, Вы писали:

D>Я так понял вы пишете FSM (Finite State Machine).

D>Ну выбирайте, что посвежее https://stackoverflow.com/questions/632391/state-machine-frameworks-for-net

Да, оно таки. Вот помню что что-то какое встречал, но даже забыл как называется.

Но ничего годного так и не нашлось, к сожалению Самые популярные Automatonymous и stateless. Последнее толком не поддерживается. Для первого толком нет документации и нормальных примеров.

Оно же еще и умеет сохранять свое состояние.

Как часто все это дело используют вообще?
Re[3]: [Updated]Таблица из двух параметров - как лучше записать?
От: Danchik Украина  
Дата: 15.11.21 21:04
Оценка: 3 (1)
Здравствуйте, Shmj, Вы писали:

S>Здравствуйте, Danchik, Вы писали:


D>>Я так понял вы пишете FSM (Finite State Machine).

D>>Ну выбирайте, что посвежее https://stackoverflow.com/questions/632391/state-machine-frameworks-for-net

S>Да, оно таки. Вот помню что что-то какое встречал, но даже забыл как называется.


S>Но ничего годного так и не нашлось, к сожалению Самые популярные Automatonymous и stateless. Последнее толком не поддерживается. Для первого толком нет документации и нормальных примеров.


S>Оно же еще и умеет сохранять свое состояние.


S>Как часто все это дело используют вообще?


Ну вот когда надо такое трекать, например протокол обмена данными, состояние конекта, авторизации, пересылки. Если приходит ивент который никак не обрабатывается текущим состоянием — сбрасываем на реконект состояние и тд. Есть еще куча, просто гуглите. Сам себе такие клепал.
Re[5]: Таблица из двух параметров - как лучше записать?
От: Sinclair Россия https://github.com/evilguest/
Дата: 16.11.21 05:35
Оценка: +1
Здравствуйте, Shmj, Вы писали:

S>Наверное нужно было сразу пример привести. Примрено такой пример:


S>
  Скрытый текст
S>
S>using System;

S>namespace ConsoleApp36
S>{
S>    class Program
S>    {
S>        enum GradeOfMen
S>        {
S>            Black,
S>            Mandarin,
S>            Aryan
S>        }

S>        static void Main(string[] args)
S>        {
S>            TransformAMan(GradeOfMen.Mandarin, GradeOfMen.Black);
S>        }

S>        static void TransformAMan(GradeOfMen fromMan, GradeOfMen toMan)
S>        {
S>            switch (fromMan)
S>            {
S>                case GradeOfMen.Black:

S>                    switch (toMan)
S>                    {
S>                        case GradeOfMen.Black:

S>                            // do nothing

S>                            break;
S>                        case GradeOfMen.Mandarin:

S>                            Wash();
S>                            GlueEyes();

S>                            break;
S>                        case GradeOfMen.Aryan:

S>                            throw new InvalidOperationException(); // impossible

S>                        default:
S>                            throw new ArgumentOutOfRangeException(nameof(toMan), toMan, null);
S>                    }

S>                    break;
S>                case GradeOfMen.Mandarin:

S>                    switch (toMan)
S>                    {
S>                        case GradeOfMen.Black:

S>                            Soot();
S>                            Scare();

S>                            break;
S>                        case GradeOfMen.Mandarin:

S>                            // do nothing

S>                            break;
S>                        case GradeOfMen.Aryan:

S>                            throw new InvalidOperationException(); // impossible

S>                        default:
S>                            throw new ArgumentOutOfRangeException(nameof(toMan), toMan, null);
S>                    }

S>                    break;
S>                case GradeOfMen.Aryan:

S>                    switch (toMan)
S>                    {
S>                        case GradeOfMen.Black:
                            
S>                            Soot();

S>                            break;

S>                        case GradeOfMen.Mandarin:

S>                            GlueEyes();

S>                            break;

S>                        case GradeOfMen.Aryan:

S>                            // do nothing

S>                            break;
S>                        default:
S>                            throw new ArgumentOutOfRangeException(nameof(toMan), toMan, null);
S>                    }

S>                    break;
S>                default:
S>                    throw new ArgumentOutOfRangeException(nameof(fromMan), fromMan, null);
S>            }
S>        }

S>        static void Scare() => Console.WriteLine("Пугаем (глаза увеличиваются)");
S>        static void Wash() => Console.WriteLine("Отмываем");
S>        static void Soot() => Console.WriteLine("Посыпаем сажей");
S>        static void GlueEyes() => Console.WriteLine("Клеим глаза");
S>    }
S>}
S>


Ну, и в чём проблема?
using System;
public class C 
{
    public static Action[,] _handlers = new Action[,]{
            {null,                   ()=>{Wash(); GlueEyes();}, Invalid},
            {()=>{Soot(); Scare();}, null,                      Invalid},
            {Soot,                   GlueEyes,                     null},
        };
    
        enum GradeOfMen
        {
            Black,
            Mandarin,
            Aryan
        }
    
        private static int ToInt(GradeOfMen man, string expression)
        {
           if(man < GradeOfMen.Black || man > GradeOfMen.Aryan)
               throw new ArgumentOutOfRangeException(expression, man, null);
            return (int)man;
        }

        public static void Main(string[] args)
        {
            TransformAMan(GradeOfMen.Mandarin, GradeOfMen.Black);
        }
    
      

        static void TransformAMan(GradeOfMen fromMan, GradeOfMen toMan) =>
            _handlers[ToInt(fromMan, nameof(fromMan)), ToInt(toMan, nameof(toMan))]?.Invoke();

        static void Scare() => Console.WriteLine("Пугаем (глаза увеличиваются)");
        static void Wash() => Console.WriteLine("Отмываем");
        static void Soot() => Console.WriteLine("Посыпаем сажей");
        static void GlueEyes() => Console.WriteLine("Клеим глаза");
        static void Invalid() => throw new InvalidOperationException();
}
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[6]: Таблица из двух параметров - как лучше записать?
От: Shmj Ниоткуда  
Дата: 16.11.21 05:42
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Ну, и в чём проблема?


А если еще и контекст нужно захватить и методов сильно больше двух, так что "верстка" таблицы посыпется? Это явно решение имеет наглядность только для простых случаев.
Re[5]: Таблица из двух параметров - как лучше записать?
От: dmitry_npi Россия  
Дата: 16.11.21 05:59
Оценка: +1
Здравствуйте, Shmj, Вы писали:
S>По условиям задачи каждый из state (и state1 и state2) имеет 3 варианта значений.
[Flags]
enum State1 { // пользуемся первыми тремя битами
  S1 = 0x00000001,
  S2 = 0x00000002,
  S3 = 0x00000004
}

[Flags]
enum State2 { // пользуемся следующими тремя битами - не пересекаются с первыми
  S1 = 0x00000008,
  S2 = 0x00000010,
  S3 = 0x00000020
}

Dictionary<Int32, Action> actions = new();

// заполняем:
actions[State1.S1 | State1.S3] = () => { /*do smth when S1 & S2*/ };
actions[State2.S2]             = () => { /*do smth when S2 from State2 */ };
actions[State2.S2 | State2.S3] = () => { /*do smth when S2 & S3 of State2*/ };
...
// profit :)


Писал без компилятора, возможно, типы придется приводить к Int.
Атмосферная музыка — www.aventuel.net
Re[7]: Таблица из двух параметров - как лучше записать?
От: Sinclair Россия https://github.com/evilguest/
Дата: 16.11.21 06:26
Оценка: +2
Здравствуйте, Shmj, Вы писали:

S>А если еще и контекст нужно захватить и методов сильно больше двух, так что "верстка" таблицы посыпется?

Если вёрстка таблицы "посыпется", то надо просто пойти по стандартному пути — дать анонимным методам имена.
S>Это явно решение имеет наглядность только для простых случаев.
Ну так случаи-то все разные. Конкретно ваш делается так.
Будет другой случай — будет другое решение. Например — полиморфизм.
Или вот такое тоже вполне себе прилично будет смотреться:
using System;
public class C 
{
        enum GradeOfMen
        {
            Black,
            Mandarin,
            Aryan
        }
    
        public static void Main(string[] args)
        {
            TransformAMan(GradeOfMen.Mandarin, GradeOfMen.Black);
        }
    
      

        static void TransformAMan(GradeOfMen fromMan, GradeOfMen toMan)
        {
            switch ((fromMan, toMan))
            {
                case (GradeOfMen.Black, GradeOfMen.Mandarin): 
                    Wash(); GlueEyes(); break;
                case (GradeOfMen.Mandarin, GradeOfMen.Black):
                    Soot(); Scare(); break;
                case (GradeOfMen.Aryan, GradeOfMen.Black): 
                    Soot(); break;
                case(GradeOfMen.Aryan, GradeOfMen.Mandarin):
                    GlueEyes(); break;
                case (var x, var y) when x==y: 
                    break;
                default: throw new InvalidOperationException();
            }
        }
        static void Scare() => Console.WriteLine("Пугаем (глаза увеличиваются)");
        static void Wash() => Console.WriteLine("Отмываем");
        static void Soot() => Console.WriteLine("Посыпаем сажей");
        static void GlueEyes() => Console.WriteLine("Клеим глаза");
}
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[8]: Таблица из двух параметров - как лучше записать?
От: Shmj Ниоткуда  
Дата: 16.11.21 08:03
Оценка: :))
Здравствуйте, Sinclair, Вы писали:

S>Или вот такое тоже вполне себе прилично будет смотреться:


Все же на первый взгляд не ясно — все ли случаи перебраны, ничего ли не упустили.

Наверное более подходящее решение — применить https://rsdn.org/forum/dotnet/8133614.flat
Автор: Shmj
Дата: 16.11.21
Re[9]: Таблица из двух параметров - как лучше записать?
От: Jack128  
Дата: 16.11.21 09:25
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Здравствуйте, Sinclair, Вы писали:


S>>Или вот такое тоже вполне себе прилично будет смотреться:


S>Все же на первый взгляд не ясно — все ли случаи перебраны, ничего ли не упустили.


S>Наверное более подходящее решение — применить https://rsdn.org/forum/dotnet/8133614.flat
Автор: Shmj
Дата: 16.11.21


А что, там яснее будет?
Re[10]: Таблица из двух параметров - как лучше записать?
От: Sharov Россия  
Дата: 16.11.21 09:52
Оценка:
Здравствуйте, Jack128, Вы писали:

S>>Наверное более подходящее решение — применить https://rsdn.org/forum/dotnet/8133614.flat
Автор: Shmj
Дата: 16.11.21

J>А что, там яснее будет?

Правила(переходов) компактнее описать. Хотя и с матрицей можно просто на null проверять
для запрещенных (не описанных) правил.
Кодом людям нужно помогать!
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.