Deutsch
Germany.ruФорумы → Архив Досок→ Программирование

Задачи для начинающих

5160   9 10 11 12 13 14 15 16 17 18 19 все
AlexNek патриот14.02.21 21:41
AlexNek
NEW 14.02.21 21:41 
в ответ anly 14.02.21 19:25
а всякий тупой стёб без малейшей аргументации мне не интересен.

Ожидалось, что аргументы додумаются смущ

Тогда конкретно, самый минимум:

  • Как Вы относитесь к глобальный переменным?
  • Как Вы относитесь к case 1,2,3,х ? Насколько "понимабельно"
  • Как мне сделать два/три/х светофоров исключительно через кодогенератор?
  • Это ничего, что код не рабочий? Сколько интересно понадобится времени "новому программисту", что бы это понять чисто смотря в код?
anly патриот14.02.21 22:27
anly
NEW 14.02.21 22:27 
в ответ AlexNek 14.02.21 21:41, Последний раз изменено 14.02.21 22:33 (anly)
Как Вы относитесь к глобальный переменным? Как Вы относитесь к case 1,2,3,х ? Насколько "понимабельно" Как мне сделать два/три/х светофоров исключительно через кодогенератор? Это ничего, что код не рабочий? Сколько интересно понадобится времени "новому программисту", что бы это понять чисто смотря в код?

ответьте сперва на мои вопросы, а потом я отвечу на Ваши если еще понадобится.

- Вы считаете что нужно понимать именно результат компиляции, а не исходный код?

- если да, то это относится только к сгенерированному в C# для исполнения в симуляторе, или же и к сгенерированному в машинный код какого либо конкретного процессора, для выполнения на реальном контроллере?

- вы часто оцениваете код глядя на его шестнадцатeричный дамп ?

- вы знаете чем в памяти контроллера отличаются ячейки где хранятся переменные, объявленные в исходниках как публичные от ячеек с объявленными как приватные , и какие из них лучше?

Проклят нарушающий межи ближнего своего (Втор.27:17)
Программист коренной житель15.02.21 09:59
NEW 15.02.21 09:59 
в ответ anly 14.02.21 18:46

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

Прости конечно, но это самое ужасное режение из всех возможных.

Его минусы:

1) оно не масштабируемое.

2) оно сложно тестируемо.


Предлагаю подойти к решению задачи с другой стороны:

1) надо признать, что мы тут говорим о состояниях, а не о каких-то алгоритмах. Состояний у светофора не так много:

+----+----------------+---------------+----------------+------------------+------------------+
| Nr | машины Красный | машины Желтый | машины Зеленый | пешеходы Красный | пешеходы Зеленый |
+----+----------------+---------------+----------------+------------------+------------------+
| 1  |      1         |      0        |       0        |         0        |         1        |
| 2  |      1         |      0        |       0        |         1        |         0        |
| 3  |      0         |      1        |       0        |         1        |         0        |
| 4  |      0         |      0        |       1        |         1        |         0        |
+----+----------------+---------------+----------------+------------------+------------------+

Если я какое-то состояние упустил, то его можно добавить :)

Итак, делаем интерфейс описывающий состояния светофора:

public enum CarLight
{
  Red,
  Yellow,
  Green
}
public enum PedestrianLight
{
  Red,
  Green
}
public interface ITrafficLight
{
  CarLight CarLight { get; }
  PedestrianLight PedestrianLight { get; }
}
public class TrafficLight : ITrafficLight
{
  public CarLight CarLight { get; set: }
  public PedestrianLight PedestrianLight { get; set; }
}


2) Вспоминаем, что у нас есть кнопка и описываем ее интерфейсом:

public interface ITrafficLightButton
{
   bool IsPressed { get; }
   void Reset ();
}


3) Теперь можем описать состояния:

public interface ITrafficLightState
{
  ITrafficLight TrafficLight { get; }
  void Wait ();
}
public class TrafficLightState : ITrafficLightState
{
  private int _delay;
  public ITrafficLight TrafficLight { get; private set; }
  public <span class="redactor-invisible-space"></span>TrafficLightState (ITrafficLight trafficLight, int delay)
  {
     // тут проверить параметры
     TrafficLight = trafficLight;
     _delay = delay;
  }
  public virtual void Wait ()
  {
    Thread.Sleep (_delay);
  }
}
public class TrafficLightWaitForPedestrianState : TrafficLightState
{
  private ITrafficLightButton _button;
  public TrafficLightWaitForPedestrian (ITrafficLightButton button, ITrafficLight trafficLight, int delay)
    : base (trafficLight, delay)
  {
    if (button == null)
      throw new ArgumentNullException ("button must be initialized");<span class="redactor-invisible-space"></span>
    _button = button;
  }
  public override void Wait ()
  {
    while (_button.IsPressed == false)
      Thread.Sleep (1000);
    base.Wait ();
  }
}
public class TrafficLightResetButtonState : TrafficLightState
{
  private ITrafficLightButton _button;
  public TrafficLightWaitForPedestrian (ITrafficLightButton button, ITrafficLight trafficLight, int delay)
    : base (trafficLight, delay)
  {
    if (button == null)
      throw new ArgumentNullException ("button must be initialized");<span class="redactor-invisible-space"></span>
    _button = button;
  }
  public override void Wait ()
  {
    _button.Reset ();
    base.Wait ();
  }
}


4) Теперь нам нужен зацикленный контейнер:

public class CircularList<T> : IEnumerable<T>, IEnumerator<T>
{
  private List<T> _list = new List<T>();
...
  public void Add (T item)
  {
    _list.Add(item);
  }
...
  #region имплементация IEnumerable<T>
...
  #endregion
  #region имплементация IEnumerator<T>
...
  #endregion
}


5) Ну и теперь самое интересное - код светофора:


В конструкторе светофора инициализуруем состояния:

ITrafficLightButton button = new TrafficLightButton();
CircularList<ITrafficLightState> states = new CircularList<ITrafficLightState>();
states.Add (new TrafficLightWaitForPedestrianState(button, new TrafficLight() { CarLight = CarLight.Green, PedestrianLight = PedestrianLight.Red }, 5000 );
states.Add (new TrafficLightState(new TrafficLight() { CarLight = CarLight.Yellow, PedestrianLight = PedestrianLight.Red }, 3000 );
states.Add (new TrafficLightState(new TrafficLight() { CarLight = CarLight.Red, PedestrianLight = PedestrianLight.Red }, 2000 );
states.Add (new TrafficLightResetButtonState(button, new TrafficLight() { CarLight = CarLight.Red, PedestrianLight = PedestrianLight.Green}, 15000 );
states.Add (new TrafficLightState(new TrafficLight() { CarLight = CarLight.Red, PedestrianLight = PedestrianLight.Red }, 1000 );


А вот и так этот светофор работает:

foreach (ITrafficLightState trafficLightState in states)
{
  TurnTrafficLights(trafficLightState.TrafficLight);
  trafficLightState.Wait ();
}

Вот собственно говоря и все :)


AlexNek патриот15.02.21 13:05
AlexNek
NEW 15.02.21 13:05 
в ответ anly 14.02.21 22:27
ответьте сперва на мои вопросы, а потом я отвечу на Ваши

Вообще то даже детишки дома этого себе не позволяют. смущ

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

нужно понимать именно результат компиляции, а не исходный код

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


если да

тут нужен nullable boolean, но его у вас скорее всего нет.

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


вы часто оцениваете код глядя на его шестнадцатeричный дамп

Исходя из того что это кодогенератор можно оценить модель лежащую в его основе.


вы знаете чем в памяти контроллера отличаются ячейки

Как то совершенно не волнует где будет исполнятся моя прога, как и то что там насували эти затейники в Сименс или Куку.

Интересен прежде всего код. А всё что вижу - это есть одна баальшая функция.

AlexNek патриот15.02.21 13:07
AlexNek
NEW 15.02.21 13:07 
в ответ Программист 15.02.21 09:59

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

koder патриот15.02.21 13:24
koder
NEW 15.02.21 13:24 
в ответ AlexNek 15.02.21 13:07
соответственно хотелось бы иметь что попроще.

А проще некуда. Да, в ответе многа букаффф. Но есть 2 вещи.
1. это состояние. Мы не меняем желтый на красный. Мы меняем состояние на состояние. Можно в тестовом примере выкинуть пешеходный светофор. Можно выкинуть кнопку. Но принцип останется
2. Это описание реальных обьектов классами. Что бы выкинуть пешеходный светофор, не нужно вылавливать его из огромного метода. Достаточно удалить или замочить класс. И само описание состояния соответствует реальным обьектам - в каждом классе инкапсулировано ровно то, что нужно.



Кроме того есть интересные вещи типа масштабируемости. Можно добавлять или удалять обьекты. Имхо на таком коде нужно учить новичков - что бы привыкали думать обьектами.


P.S.

респект Программисту. Я не пишу на С-шарп, но код абсолютно понятен и легко читаем.

Программист коренной житель15.02.21 13:40
15.02.21 13:40 
в ответ AlexNek 15.02.21 13:07
хотелось бы иметь что попроще.

Что может быть проще, чем один бесконечный цикл? :) Ни ветвлений, ни каких-то алгоритмов.


Из "сложного" тут только циклический контейнер. Но, если человек не знает как работает foreach, то его можно заменить на простой бесконечный цикл:

List<ITrafficLightState> _list = new List<ITrafficLightState>();
....
int index = 0;
while(true)
{
  ITrafficLightState state = _list[index];

  TurnTrafficLights(trafficLightState.TrafficLight);
  trafficLightState.Wait ();

  index = index + 1;
  index = index % _list.Count;
}


Murr патриот15.02.21 13:59
Murr
NEW 15.02.21 13:59 
в ответ anly 14.02.21 22:27

Местное глюкало вчера сожрало ответ, а сегодня откуда-то нашло.


- Вы находите приведённый в файле код хорошим или плохим?

-----

Ничего если Я отвечу?

В файле лежит генерированный говнокод. Он не может быть хорошим или плохим в том плане в каком программисты считают код хорошим или плохим. Оценивать его можно только с точки зрения реализации автомата описанного СФЦ. С этой точки зрения это именно говнокод...


Вы считаете что нужно понимать именно результат компиляции, а не исходный код?

-----

Понимать нужно весь процесс и в деталях.

Т.е. надо понимать язык описания, синтезируемый автомат и иметь возможность модифицировать как описание, так и продуцированный код.


или же и к сгенерированному в машинный код

-----

Часто крайне желательно понимать не только машинный код, но и то как его выполняет процессор.

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

koder патриот15.02.21 14:08
koder
NEW 15.02.21 14:08 
в ответ Murr 15.02.21 13:59
Местное глюкало вчера сожрало ответ, а сегодня откуда-то нашло.

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

Murr патриот15.02.21 14:19
Murr
NEW 15.02.21 14:19 
в ответ Программист 15.02.21 09:59
Если я какое-то состояние упустил, то его можно добавить

-----

Ты начал - правильно.

Даже привел таблицу состояний.

Что требовалось сделать - построить... автомат, который берет одно состояние как текущее и возвращает каким должно быть следующее. Можно по состоянию ламп, можно - по номерам состояний - это не важно, лишь бы различались. Существенно - без привязки к самому светофору.

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

Т.е. у тебя будет один автомат и любое количество любых светофоров - код автомата останется без изменений.

Murr патриот15.02.21 14:36
Murr
NEW 15.02.21 14:36 
в ответ koder 15.02.21 13:24

Мы меняем состояние на состояние.

-----

Нее, нету этого... не реализовалось... Надо, но нету... хммм

koder патриот15.02.21 14:43
koder
NEW 15.02.21 14:43 
в ответ Murr 15.02.21 14:36
Нее, нету этого... не реализовалось...
foreach (ITrafficLightState trafficLightState in states)
{
  TurnTrafficLights(trafficLightState.TrafficLight);
  trafficLightState.Wait ();
}
Murr патриот15.02.21 14:45
Murr
NEW 15.02.21 14:45 
в ответ koder 15.02.21 14:08

Если ты не нажимаешь кнопку "отправить",

-----

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


у меня так

-----

Глюкало так глюкнуло, что "так" ночью не было, но сейчас - стало.

Программист коренной житель15.02.21 15:07
NEW 15.02.21 15:07 
в ответ koder 15.02.21 14:43

Murr хочет сказать, что интерфейс ITrafficLightState должен быть таким:

public interface ITrafficLightState
{
  ITrafficLight TrafficLight { get; }
  void Wait ();
  ITrafficLightState Next { get; }
}


и тогда работа светофора будет такой:

ITrafficLightState trafficLightState = startState;
do
{
  TurnTrafficLights(trafficLightState.TrafficLight);
  trafficLightState.Wait ();
  trafficLightState = trafficLightState.Next;
}
while (trafficLightState != null);


Но в данном случае, я не вижу необходимости в таком подходе.

Murr патриот15.02.21 15:07
Murr
NEW 15.02.21 15:07 
в ответ koder 15.02.21 14:43

ITraficLight traficLight = TTraficLightFactory.Crete("MyTraficLight");
TButton button = traficLight.Button;

TTraficLightController controller = new TTraficLightController("MyTraficLight");
ITrafficLightState state = controller.Init();

foreach (;true;)
{ 
  trafficLight.Set(state);
  state = controller.Next(state,{button,timmer}); // S = F(S,U)
  // Wait (); // не нужно - state будет управлять через отсутствие изменений
}
Программист коренной житель15.02.21 15:14
NEW 15.02.21 15:14 
в ответ Murr 15.02.21 15:07

Ну в моем первоначальном варианте роль контроллера исполняет зацикленный лист ;)


Ну и ты забыл написать самое интересно - код контроллера ;) Напишешь? ;)

Murr патриот15.02.21 15:14
Murr
NEW 15.02.21 15:14 
в ответ Программист 15.02.21 15:07

ITrafficLightState Next { get; }

-----

ITrafficLightState Next(ITrafficLightState,ITraficLightResponse);

И он должен быть отделен от светофора.

Murr патриот15.02.21 15:25
Murr
NEW 15.02.21 15:25 
в ответ Программист 15.02.21 15:14

Напишешь? ;)

-----

Опять - лениво.

Бо, всем понятно что там будет - табличка: текущее состояние, управляющие сигналы, новое состояние.

Ищется совпадение первых двух и возвращается третье. Все по теории.

Табличку - проверяем отдельным инструментом (не руками/головой) на отсутствие потерянных и подвисших строк и дополняем автомат если нужно.

koder патриот15.02.21 15:29
koder
NEW 15.02.21 15:29 
в ответ Murr 15.02.21 15:14, Последний раз изменено 15.02.21 15:31 (koder)
controller.Next

Теоретически да. Внешний контроллер.

Но в данном конкретном УЧЕБНОМ случае это неважно, в роле контроллера выступает обычный цикл. Главное - состояния переключаются и переключение вынесено из светофора.imho


P.S. Ааа, Программист уже написал....

koder патриот15.02.21 15:34
koder
NEW 15.02.21 15:34 
в ответ Программист 15.02.21 15:07
ITrafficLightState Next { get; }

Здесь я не понял. Состояние должно знать следующее состояние?