• Как заменить switch case паттерном стратегия?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    Switch
    public enum DamageType { Melee, Range, Magic }
    public class Monster
    {
        public double Health { get; private set; }
        public double MeleeDamage { get; private set; }
        public double RangeDamage { get; private set; }
        public double MagicDamage { get; private set; }
        public DamageType FavoriteDamageType { get; private set; }
    
        public Monster(double health, double meleeDamage, double rangeDamage, double magicDamage, DamageType favoriteDamageType)
        {
            Health = health;
            MeleeDamage = meleeDamage;
            RangeDamage = rangeDamage;
            MagicDamage = magicDamage;
            FavoriteDamageType = favoriteDamageType;
        }
    
        public void AttackTo(Monster monster, DamageType damageType)
        {
            switch (damageType) // используется switch
            {
                case MonsterType.Melee: monster.Health -= MeleeDamage; break;
                case MonsterType.Range: monster.Health -= RangeDamage; break;
                case MonsterType.Magic: monster.Health -= MagicDamage; break;
            }
        }
    
        public void AttackTo(Monster monster)
        {
            AttackTo(monster, FavoriteDamageType);
        }
    }


    То же самое, но со стратегией
    public class Monster
    {
        public double Health { get; set; }
        public double MeleeDamage { get; private set; }
        public double RangeDamage { get; private set; }
        public double MagicDamage { get; private set; }
        public IDamageStrategy FavoriteDamageStrategy { get; private set; }
    
        public Monster(double health, double meleeDamage, double rangeDamage, double magicDamage, IDamageStrategy favoriteDamageStrategy)
        {
            Health = health;
            MeleeDamage = meleeDamage;
            RangeDamage = rangeDamage;
            MagicDamage = magicDamage;
            FavoriteDamageStrategy = favoriteDamageStrategy;
        }
    
        public void AttackTo(Monster monster, IDamageStrategy damageStrategy)
        {
            damageStrategy.Attack(this, monster); // не используется switch
        }
    
        public void AttackTo(Monster monster)
        {
            AttackTo(monster, FavoriteDamageStrategy);
        }
    }
    
    
    public interface IDamageStrategy
    {
        void Attack(Monster attacker, Monster defender);
    }
    public class MeleeDamageStrategy : IDamageStrategy 
    {
        public void Attack(Monster attacker, Monster defender)
        {
            defender.Health -= attacker.MeleeDamage;
        }
    }
    public class RangeDamageStrategy : IDamageStrategy 
    {
        public void Attack(Monster attacker, Monster defender)
        {
            defender.Health -= attacker.RangeDamage;
        }
    }
    public class MagicDamageStrategy : IDamageStrategy 
    {
        public void Attack(Monster attacker, Monster defender)
        {
            defender.Health -= attacker.MagicDamage;
        }
    }

    Отличие класса Monster только в коде первого метода AttackTo. Ну и свойства FavoriteDamageType или FavoriteDamageStrategy.

    Стратегия может быть полезна, если код атаки, в зависимости от типа, сильно отличается, используя внешние данные (не из класса монстра), например, день или ночь, ясно/дождь и пр. Использование стратегии переносит часть кода из класса монстра (и так сложного класса) в несколько простых классов.
    Ответ написан
    1 комментарий
  • Замена фотошопа верстальщику?

    Это зависит от того как построен процесс в компании. Надо было у них а и спросить, если бы собеседующий не смог ответить, то просто хотел вас опустить.
    Фотошоп актуален, но не все его используют(и .psd макеты).
    Кто то рисует макеты в векторе. Кто то проcто в других программах. Кто то в figma, где все онлайн.
    Кто то считает что дизайн должен рождаться не на картинке, а в среде той где будет работать, где сразу можно тестить адаптив и разные экраны, т.е прямо в браузере.
    Но все это слишком специфично, и если в компании это есть, то это их проблемы по адаптации новых сотрудников.
    Ответ написан
    Комментировать
  • Когда имеет смысл делать несколько таблиц с комментариями?

    longclaps
    @longclaps
    О, набежали подписанты )
    Идея дурацкая и вредная, всем коментам место в одной таблице, и быстрее будет, и сохраннее.
    Почитать про индексы даже не советую - бесполезно.
    Ответ написан
    Комментировать
  • И все-таки PHP 7 быстрее Python 3?

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега PHP
    Бенчмарки - это бесполезные писькомерки.

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

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

    Но вот есть ли смысл в удобстве, если это удобство не дает нужных результатов?
    Нам надо вас уговорить вернуться на php? Вы благословения испрашиваете? Вы уже столкнулись с реальными проблемами производительности?
    Ответ написан
    6 комментариев
  • Загадочное межбуквенное расстояние. Куда копать, как чинить?

    JRK_DV
    @JRK_DV
    Рецепты https://codepen.io/jrkdv/full/LKLXdq
    Без ссылки на сайт, на первый взгляд:
    Периодически читатели жалуются вот на такую странную штуку:

    Шрифт "PT Sans Narrow" не доступен для браузера и браузер пытается использовать следующий шрифт по цепочке в порядке следования это будут "'雅黑', '文泉驿微米黑', '黑体', sans-serif;"
    На русских версиях ОС начертания русских глифов в китайских шрифтах может и не быть, как пример:
    d9fb26e3439e4d28804abb599ceb0d0f.png
    на скрине в одном текстовое поле, две строки текста
    Русские символы отрендерились с паддингом, а английские нет - разность начертания шрифта

    Из-за чего шрифт может быть не доступен?
    Браузер пытается найти исходник шрифта, например, смотрит на:
    1. local('PT Sans Narrow') - Но такого локального шрифта нет
    2. local('PTSans-Narrow') - Такого локально тоже нет
    Локальных копий нет, пытается найти на сервере:
    url('../fonts/google-fonts/UyYrYy3ltEffJV9QueSi4RdbPw3QSf9R-kE0EsQUn2A.woff') format('woff');
    И тут может быть ошибка:
    Сервер не отдаёт шрифт - По урл пути нет шрифта, шрифт не поддерживается браузером и т.д.
    Смотрите почему шрифт не доступен шрифт для браузера

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

    Дополню ответ на вопрос "Почему не у всех?":
    Шрифт доступен в интернете "PT Sans Narrow" и браузер пользователя на другом сайте уже когда то загружал этот шрифт к себе в локальный кеш. Поэтому может его использовать брать локальную копию (см. блок как браузер будет искать этот шрифт)
    Ответ написан
    1 комментарий
  • Как сделать линию HR вертикальной?

    Astrohas
    @Astrohas
    Python/Django Developer
    Есть два ваианта:
    1. <hr width="1" size="700">
    2. border
    Ответ написан
    Комментировать
  • Как сделать линию HR вертикальной?

    Расположить поверх большой <div> с border-left:1px solid #CCC?
    Ответ написан
    Комментировать
  • Какой алгоритм подойдет для описания полета насекомого?

    sergiks
    @sergiks Куратор тега Алгоритмы
    ♬♬
    Можно сделать цепочку преследования: к случайной точке тянется одна, к ней другая, и т.д., а последняя – муха.

    Очередную точку ставить на плоскости случайно, в любом месте внутри допустимой области. Эта точка – цель, к которой стремится следующая, невидимая точка: каждый следующий кадр её координаты изменяются на k * векторИзТекущегоПоложения-в-Цель:
    x = x + k * (xTarget - x);
    y = y + k * (yTarget - y);

    Так «преследователь» замедляется, по мере приближения к цели, никогда её не достигая.

    Эта невидимая точка – не одна. К ней, как к цели, стремится следующая. К той ещё одна. Наконец, сама муха по этому закону стремится к хвосту этой цепи - очередной точке.

    Чем больше звеньев в такой цепи, тем плавнее получается кривая. При приближении мухи к цели ближе, чем на D, генерится следующая случайная цель.

    Сделал рабочий пример.

    Можно поменять алгоритм и сделать, скажем, линейную скорость постоянной. Или случайно варьировать параметры k и D – от этого поменяется скорость и траектория от плавной ближе к ломаной.
    Ответ написан
    Комментировать
  • Как вы втягиваетесь в новый проект?

    xmoonlight
    @xmoonlight
    https://sitecoder.blogspot.com
    Для быстрого начала работы над задачей, только что влившемуся в проект сотруднику, нужны следующие вещи:

    1. Централизованная структурированная проектная документация всего разрабатываемого решения.
    2. Архитектурная схема решения и помеченный блок, в котором нужно будет выполнять задание.
    3. Краткое описание задания и методика проверки его полного выполнения.
    4. Краткая архитектура кода этого блока и указание места с пояснением для начала выполнения работы.
    5. Ориентировочный перечень наиболее вероятных названий классов/методов/смежных API для использования при выполнении задания с кратким описанием и со ссылками в централизованную документацию (п.1).
    6. Ориентировочный перечень классов/методов/смежных API, которые возможно могут понадобиться (также, как и в п.4 со ссылками в п.1).
    7. Рекомендуемая среда разработки для выполнения задания и её настройки для исполнения данной задачи
    8. Планируемое время выполнения задания
    9. Контакты с другими разработчиками (с указанием их зон ответственности в проекте и времени доступности) для возникающих вопросов, касательно этого задания.

    Попросите дать задачу в таком формате: у того, кто давно работает в проекте, это займёт не более часа, а сэкономит - недели проектной разработки!
    Ответ написан
    2 комментария
  • Что делать когда коллеги уровнем ниже?

    @amambaru
    Кто сказал что они ниже уровнем?
    Эффект Даннинга — Крюгера
    Программеру всегда трудно вникнуть в чужой код - это не зависит от квалификации того, кто кодировал.
    Возможно что даже и они более квалифицированы - просто давным-давно забили на перфекционизм, а из вас он еще прет из за юнешеского максимализма.
    А может и вы правы.

    Тут дело не в квалификации, а в мотивации и организации процесса.
    Скажем, мне доводилось работать в команде, где в git пропускали всего по 200 строчек изменений за раз. И эти строчки обязательно должны были пройти через стандартизованное форматирование и линтеры (статические анализаторы) - иначе их git выплевывал. Это вынуждало программистов писать более менее приемлимо - коллег код меньше раздражал.
    Ответ написан
    19 комментариев
  • К нашей программе создали и выложили кряк - что делать?

    @McBernar
    1. Порадоваться :)
    2. Обновить алгоритм покупки
    3. Написать досудебное письмо сайтам с кряком или их хостерам
    Ответ написан
    5 комментариев
  • К нашей программе создали и выложили кряк - что делать?

    Host-Eiweb
    @Host-Eiweb
    Хостинг VPS серверов в Европе и США
    Мы - разработчики программы, на рынке с 2010 года.

    Неужели за 7 лет, не научились работать.

    Пофиксить и выпустив обновление.
    В противном случае Ваш код - гроша ломаного не стоит.
    Ответ написан
    1 комментарий
  • Как научиться понимать как работает память на низком уровне?

    Griboks
    @Griboks
    Прочитайте про процессоры, их архитектуры, доступ к памяти, почему возникли кэши вместо оперативки и т.д.
    Стек и куча - это всего лишь абстракция.
    Ответ написан
    1 комментарий
  • Почему не так работают условая?

    fornit1917
    @fornit1917
    пхп разбирает выражение следующим образом:

    (true ? 1 : false) ? 2 : 3;

    Если то что в скобках истинно, то будет 2, иначе 3.

    Разбираемся с тем что в скобках: true ? 1 : false. Очевидно, что это 1. 1 в пхп трактуется как истина. Поэтому получаем 2. Что же тут непонятного?

    В яваскрипте приоритет операций выставляется иначе:
    true ? 1 : (false ? 2 : 3);

    Во избежание таких недоразумений всегда расставляйте скобки явно, а еще лучше - не пишите вложенные тернарные операторы вообще.
    Ответ написан
    1 комментарий
  • MySQL грузит все ядра проца. Глюк?

    @asd111
    Поскольку у вас 24 ядра и 11.000 запросов в секунду query_cache лучше отключить.
    [mysqld]
    query_cache_size = 0
    query_cache_type = 0   # важно ! отключает mutex, которым оперирует query_cache

    Потому что в таких условиях он больше мешает чем помогает. Особенно если у вас мало таблиц и есть изменение таблиц, из которых чаще всего происходит чтение. Всё дело в том что ядра борятся за доступ к кэшу и если есть insert, update, delete в таблицу, для которой есть записи в кэше, то кэш всей этой таблицы обнуляется и снова ядра борятся кто будет обнулять, кто будет читать, писать и вся вот эта многопоточная борьба за мьютекс query_cache грузит CPU. И ещё кучу времени занимает очистка кэша если размер кэша большой(гигабайты).
    Если интересно что происходит с кэшем гляньте SHOW STATUS LIKE "qcache%";
    Там стоит обратить внимание на Qcache_lowmem_prunes. Чем эта переменная меньше тем лучше (в идеале 0 )- эта переменная показывает сколько раз обнулялся кэш для таблиц.
    Ответ написан
    1 комментарий
  • Использование нелицензированного ПО в организации, кто несёт ответственность?

    sergey-gornostaev
    @sergey-gornostaev
    Седой и строгий
    А теперь от теории к практике, я сам несколько раз попадал под проверки, а также несколько лет "работал" независимым специалистом по киберпреступлениям, в том числе на проверках лицензионной чистоты. Руководство всегда показывает пальцем на админа и говорит "Мы не знали, вот ответственный специалист!" Заканчивается это тем, что компанию штрафуют, а админу прилетает срок. Наличие бумажки о том, что директор знал об установке пиратского софта трактуется судом как преступный сговор. Позиция админа "я не обязан разбираться в тонкостях лицензирования" - это как позиция бухгалтера "я не обязан разбираться в тонкостях налогообложения". Правильных решений может быть только два - либо заставить компанию перейти на лицензионное ПО, либо уволиться.
    Ответ написан
    39 комментариев
  • Как закруглить строку таблицы при наведении?

    @L1ar
    .net / php
    Попробуйте background задавать не для строки, а для ячейки
    Отредактированный вариант из ответа выше - https://jsfiddle.net/3zozuzgr/
    Ответ написан
    1 комментарий
  • Почему не стоит мешать html c php?

    usdglander
    @usdglander Куратор тега PHP
    Yipee-ki-yay
    Почему нельзя? Можно! Просто получится сложночитаемая и малоподдерживаемая хрень.
    Ответ написан
    Комментировать
  • Как перевести широту и долготу в пиксели?

    fedorez
    @fedorez
    Хатуль мадан
    в общем да.
    а если точность нужна то всё посложнее будет.
    земля не круглая, она геоид, на практике юзают эллипсоид. от поставщика данных зависит какой.
    географические координаты переводят в плоские по довольно громоздким формулам согласно ГОСТ Р 51794-2008

    ну а потом согласуете эти плоские координаты со своими пикселями в зависимости от разрешения и окна просмотра

    я когда-то плотно сидел на этой теме и написал библиотеку на C# которая расчёт по этим формулам обеспечивала.
    вот вам оттуда кусок
    простите за столь неряшливое оформление, валяюсь болею, не имею доступа к нормальному коду, выдрал из старого архива, пишу через утюг.
    но думаю разберётесь

    spoiler
    /// <summary>
    		/// Возвращает плоскую координату X для пары угловых координат (зона проекции определена константой)
    		/// </summary>
    		/// <param name="Bd">Широта, град</param>
    		/// <param name="Ld">Долгота, град</param>
    		/// <returns></returns>
    		static public double flat_x(double Bd, double Ld)
    		{
                int N = 6;
                //int N = GetProjectionZone(Ld);
    
    			return flat_x(Bd, Ld, N);
    		}
    
    		/// <summary>
    		/// Возвращает плоскую координату X для пары угловых координат в заданной зоне проекции
    		/// </summary>
    		/// <param name="Bd">Широта, град</param>
    		/// <param name="Ld">Долгота, град</param>
            /// <param name="N">Зона проекции</param>
    		/// <returns></returns>
    		static public double flat_x(double Bd, double Ld, int N)
    		{
    			double b, L, l_rad;
    			b = Bd * Math.PI / 180;
    			L = Ld * Math.PI / 180;
    			l_rad = (Ld - (3 + 6 * (N - 1))) / 57.29577951;
    			double Result, R1, R2, R3, R4, M1, M2;
    			R1 = 1594561.25 + 5336.535 * Math.Pow((Math.Sin(b)), 2) + 26.79 * Math.Pow((Math.Sin(b)), 4) + 0.149 * Math.Pow((Math.Sin(b)), 6);
    			R2 = 672483.4 - 811219.9 * Math.Pow((Math.Sin(b)), 2) + 5420.0 * Math.Pow((Math.Sin(b)), 4) - 10.6 * Math.Pow((Math.Sin(b)), 6);
    			R3 = 278194 - 830174 * Math.Pow((Math.Sin(b)), 2) + 572434 * Math.Pow((Math.Sin(b)), 4) - 16010 * Math.Pow((Math.Sin(b)), 6);
    			R4 = 109500 - 574700 * Math.Pow((Math.Sin(b)), 2) + 863700 * Math.Pow((Math.Sin(b)), 4) - 398600 * Math.Pow((Math.Sin(b)), 6);
    			M2 = (R2 + (Math.Pow(l_rad, 2)) * (R3 + (Math.Pow(l_rad, 2)) * (R4)));
    			M1 = (R1 + (Math.Pow(l_rad, 2)) * M2);
    			Result = 6367558.4698 * b - Math.Sin(2 * b) * (16002.89 + 66.9607 * Math.Pow((Math.Sin(b)), 2) + 0.3515 * Math.Pow((Math.Sin(b)), 4) - Math.Pow(l_rad, 2) * M1);
    			return Result;
    		}
    
    		/// <summary>
            /// Возвращает плоскую координату Y для пары угловых координат (зона проекции определена константой)
            /// </summary>
    		/// <param name="Bd">Широта, град</param>
    		/// <param name="Ld">Долгота, град</param>		
    		/// <returns></returns>
    		static public double flat_y(double Bd, double Ld)
    		{
                int N = 6;
                //int N = GetProjectionZone(Ld);
    			return flat_y(Bd, Ld, N);
    		}
    
    		/// <summary>
            /// Возвращает плоскую координату Y для пары угловых координат в заданной зоне проекции
            /// </summary>
    		/// <param name="Bd">Широта, град</param>
    		/// <param name="Ld">Долгота, град</param>
    		/// <param name="N">Зона проекции</param>
    		/// <returns></returns>
    		static public double flat_y(double Bd, double Ld, int N)
    		{
    			double b, L, l_rad;
    			b = Bd * Math.PI / 180;
    			L = Ld * Math.PI / 180;
    			l_rad = (Ld - (3 + 6 * (N - 1))) / 57.29577951;
    			double Result, R1, R2, R3, R4, M1;
    			R1 = 6378245 + 21346.1415 * Math.Pow((Math.Sin(b)), 2) + 107.159 * Math.Pow((Math.Sin(b)), 4) + 0.5977 * Math.Pow((Math.Sin(b)), 6);
    			R2 = 1070204.16 - 2136826.66 * Math.Pow((Math.Sin(b)), 2) + 17.98 * Math.Pow((Math.Sin(b)), 4) - 11.99 * Math.Pow((Math.Sin(b)), 6);
    			R3 = 270806 - 1523417 * Math.Pow((Math.Sin(b)), 2) + 1327645 * Math.Pow((Math.Sin(b)), 4) - 21701 * Math.Pow((Math.Sin(b)), 6);
    			R4 = 79690 - 866190 * Math.Pow((Math.Sin(b)), 2) + 1730360 * Math.Pow((Math.Sin(b)), 4) - 945460 * Math.Pow((Math.Sin(b)), 6);
    
    			M1 = Math.Pow(l_rad, 2) * (R2 + Math.Pow(l_rad, 2) * (R3 + Math.Pow(l_rad, 2) * (R4)));
    			Result = (5 + 10 * N) * Math.Pow(10, 5) + l_rad * Math.Cos(b) * (R1 + M1);
    			return Result;
    		}
    
            /// <summary>
            /// Возвращает значение зоны проекции для заданного значения долготы
            /// </summary>
            /// <param name="Ld">Долгота, град</param>
            /// <returns>Значение зоны</returns>
            static public int GetProjectionZone(double Ld)
            {
                return Convert.ToInt32(Microsoft.VisualBasic.Conversion.Fix((6 + Ld) / 6));
            }
    
            /// <summary>
            /// Возвращает значение зоны проекции, пригодное для проецирования большинства из массива долгот
            /// </summary>
            /// <param name="longitudes">Массив долгот, град</param>
            /// <returns></returns>
            static public int GetProjectionZone(double[] longitudes)
            {
                // Значения зон
                List<int> lst_values = new List<int>();
                // Количество вхождений
                List<int> lst_valueCounts = new List<int>();
    
                foreach (double longitude in longitudes)
                {
                    // Зона для текущей долготы
                    int currentN = GetProjectionZone(longitude);
    
                    // Если значение новое, то занесем его в список и создадим нулевой счетчик этого значения
                    if (!lst_values.Exists(p => p == currentN))
                    {
                        lst_values.Add(currentN);
                        lst_valueCounts.Add(0);
                    }
    
                    int index = lst_values.IndexOf(currentN);   // Иднекс этого значения
                    lst_valueCounts[index] += 1;                // Увеличим счетчик этого значения
                }
    
                // Индекс значения с максимальным вхождением
                int maxIndex = lst_valueCounts.IndexOf(lst_valueCounts.Max());
    
                return lst_values[maxIndex];
            }
    
    		static public double DegreesMinutesToDouble(int degrees, double minutes)
    		{
    			return DegreesMinutesSecondsToDouble((double)degrees, minutes, 0);
    		}
    
    		static public double DegreesMinutesSecondsToDouble(int degrees, int minutes, double seconds)
    		{
                return DegreesMinutesSecondsToDouble((double)degrees, minutes, seconds);
    		}
    
            static public double DegreesMinutesSecondsToDouble(double degrees, double minutes, double seconds)
            {
                minutes += seconds / 60;
    
                degrees += minutes / 60;
    
                return degrees;
            }
    }

    Ответ написан
    Комментировать
  • Как перевести широту и долготу в пиксели?

    longclaps
    @longclaps
    При изменении широты ты движешься по дуге большого круга - по меридиану. Соответственно 1град==1/57радиана<~>1/57радиуса_Земли
    При изменении долготы ты движешься по параллели - кругу с радиусом, пропорциональным косинусу широты.
    Вот и вся формула.
    Ответ написан
    2 комментария