Ответы пользователя по тегу Программирование
  • Как избежать ошибки Необработанное исключение типа "System.IO.IOException" в mscorlib.dll?

    @mayorovp
    Ошибка возникает потому что вы пытаетесь открыть файл лога из нескольких потоков одновременно. Или вы просто одновременно открыли его в текстовом редакторе.

    PS
    Совет номер 1: откройте для себя NLog
    Совет номер 2: никогда не делайте вот так в цикле
    s_message = mass[i] + Environment.NewLine + s_message;
    - для таких вещей есть StringBuilder, который работает быстрее.
    Совет номер 3: А еще лучше - вместо таких циклов использовать удобный метод
    s_message  = string.Join(Environment.NewLine, mass)

    Совет номер 4: Еще лучше - использовать File.ReadAllText вместо File.ReadAllLines в таких случаях.
    Ответ написан
    1 комментарий
  • Какую базу данных лучше использовать в java?

    @mayorovp
    Популярные СУБД - это SQL Server, Oracle, Postgres и MySql.

    Но первая СУБД - не кроссплатформенная, вторая - платная, последняя - must die.
    Поэтому я бы советовал использовать Postgres.
    Ответ написан
    Комментировать
  • MySQL и Doubly-encoded to UTF-8 from CP1251, как считать данные?

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

    @mayorovp
    Если интересует рантайм-версия, то вот самый простой вариант: sizeof(void*) - может быть равен 4 или 8 :)

    Но, если не секрет, в чем именно отличие этих двух веток? Мне во всех моих проектах хватало исключительно правильной расстановки типов size_t и ptrdiff_t, и ни разу не пришлось прибегать к явному определению разрядности.
    Ответ написан
  • Как привести объект к типу выше в древе наследования?

    @mayorovp
    Grid - это контрол. Я решил его унаследовать, что-бы хранить пару методов. Но теперь в FileMember надо инфлейтить разметку. Я нашёл единственный вариант: XamlReader.Load(XmlReader.Create(new StringReader(rawXaml)));
    Если просто пытаться результат привести к FileMember - выпадает исключение.
    Если вы считываете Grid из потока XAML - то почему нельзя считать оттуда сам FileMember? Добавьте конструктор по умолчанию и замените тэг верхнего уровня в разметке.
    Ответ написан
    Комментировать
  • Как получить данные из стандартных команд cmd.exe в своем приложении на C#, не вызывая подпрограммы?

    @mayorovp
    У вас путаница в мыслях... Во-первых, "подпрограмма" - это в C# синоним метода. Если вы используете winforms - то вы уже используете кучу подпрограмм :) А то, чего вы хотите избежать, называется "внешняя программа" или "дочерний процесс".

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

    В-третьих, ping, tracert и netsh не являются командами cmd.exe. Команды cmd.exe - это echo, if, call, set, goto, for и т.д., а то, что вы перечислили - это системные утилиты.

    Теперь по вопросу.

    ping. Имеется вот этот класс: msdn.microsoft.com/en-us/library/system.net.networ... Ни разу с ним не работал, но выглядит удобным.

    tracert. Используйте тот же класс, указав Ttl в PingOptions.

    netsh. Тут все сложнее. Дело в том, что эта программа - обертка для кучи разных настроек, находящихся в совершенно разных местах. Если вам нужно получать данные - то попробуйте поискать их в msdn.microsoft.com/en-us/library/system.net.networ... Если их там нет - гуглите. Главное - гуглите без ключевого слова netsh.

    etc. А вот тут все не просто сложно, а невозможно. Невозможно взять неизвестную заранее утилиту, и сделать то же самое, что она делает, не запуская ее при этом. Поэтому вам надо определиться - либо ваша программа умеет выполнять фиксированный список действий - либо ей можно передать любую команду, но она будет запускать дочерние процессы. Возможен и промежуточный вариант - есть действия, которые программа может выполнять сама, а для выполнения других будут запускаться дочерние процессы.
    Ответ написан
    Комментировать
  • C# или ActionScript?

    @mayorovp
    Возможность доступа из сети. Открыл браузер, ввел адрес - и вот она программа. HTML5 + ASP.NET, думаю решают это запросто.
    Ни разу не аргумент: нельзя сравнивать серверный язык с клиентским. Если нужен именно C# - то надо смотреть в сторону Silverlight или Unity. Однако, Silverlight использует другую стандартную библиотеку - а Unity вообще другой компилятор.

    Возможность быстро считать (наши программы расчетные). Мне кажется, что ActionScript (а видимо Flash) тут проигрывает .NET. Не уверен, тесты сам лично не делал.
    Сделайте тесты, чтобы быть уверенным.

    Возможность "рисовать" интерфейс, делать его нестандартным. Думаю, XAML, HTML + CSS - отличный выбор.
    Здесь графический редактор, конечно, выигрывает у языка общего назначения :) Но стоит напомнить начальнику про разные размеры мониторов у разных пользователей. Flash умеет в лучшем случае масштабировать картинку, остальное - через боль.

    С недавнего времени заинтересовала кроссплатформенность. Чтобы программы запускались на Android, iOS. Чувствую, что с ActionScript это будут особенные грабли.
    Flash на андроидах не поддерживается ни дефолтным браузером, ни хромом - Action Script, соответственно, тоже. Про другие браузеры не знаю, но этих достаточно.
    Ответ написан
    Комментировать
  • Как запустить Task после его выполнения?

    @mayorovp
    Я немного не понял, вам надо запускать задачи последовательно или параллельно? А если параллельно - то обрабатывать результаты сразу или вместе?

    1. Последовательный запуск:
    private async void OnlyLike()
    {
        for (var i=0; i<5; i++)
            TextBox.Text += await VK.NakrytkaLike(KeyAntigateTextBox.Text);
    }


    2. Параллельный запуск, обработка всех результатов вместе
    private async void OnlyLike()
    {
        var tasks = Enumerable.Range(0, 5).Select(i => VK.NakrytkaLike(KeyAntigateTextBox.Text));
        foreach (var result in await Task.WhenAll(tasks))
            TextBox.Text += result;
    }


    3. Параллельный запуск, обработка результатов сразу же:
    private async void OnlyLike()
    {
        TextBox.Text += await VK.NakrytkaLike(KeyAntigateTextBox.Text);
    }
    
    private void StartButton_Click(object sender, RoutedEventArgs e)
    {
        for (var i=0; i<5; i++)
            OnlyLike();
    }


    Выбирайте что нравится. И не бойтесь использовать async/await - оно создано для упрощения кода, а не для усложнения :)

    UPD

    Последовательный запуск на фреймворке 4.0:
    public void OnlyLike()
    {
        var scheduler = TaskScheduler.Current ?? TaskScheduler.FromCurrentSynchronizationContext();
        Task task = TaskEx.FromResult(false);
        var text = KeyAntigateTextBox.Text;
        for (var i=0; i<5; i++) {
            task = task.ContinueWith(_ => {
                var LikeTurbo = VK.NakrytkaLike(text);
                LikeTurbo.ContinueWith(_ => {
                     TextBox.Text += LikeTurbo.Result;
                }, scheduler);
                return LikeTurbo;
            }, TaskContinuationOptions.ExecuteSynchronously).Unwrap();
        }
    }
    
    ...
    
    public static class TaskEx {
        public static Task<T> FromResult<T> (T result) {
            var tcs = new TaskCompletionSource<T>();
            tcs.SetResult(result);
            return tcs.Task;
        }
    
        public static Task<T> Unwrap<T>(this Task<Task<T>> task) {
            var tcs = new TaskCompletionSource<T>();
            task.ContinueWith(_ => {
                if (task.IsCanceled) tcs.SetCancelled();
                else if (task.IsFaulted) tcs.SetException(task.Exception);
                else task.Result.ContinueWith(innerTask => {
                    if (innerTask.IsCanceled) tcs.SetCancelled();
                    else if (innerTask.IsFaulted) tcs.SetException(task.Exception);
                    else tcs.SetResult(innerTask.Result);
                }, TaskContinuationOptions.ExecuteSynchronously);
            }, TaskContinuationOptions.ExecuteSynchronously);
            return tcs.Task;
        }
    }


    Выглядит многословно, но на самом деле - ничего сложного. В цикле задачи ставятся в очередь одна за другой при помощи конструкции task = task.ContinueWith(...).Unwrap(). Здесь Unwrap() - это функция, позволяющая дождаться выполнения дочерней задачи, фактически простой распаковщик монады Task Task T -> Task T.

    Внутри такого цикла находится, фактически, старый код метода OnlyLike() - за тем исключением, что теперь он еще и возвращает ту задачу, которую создал (это нужно, чтобы дождаться ее выполнения). Здесь я позволил себе небольшое ускорение - поскольку я написал return LikeTurbo - каждая следующая итерация цикла будет ждать лишь предыдущей задачи VK.NakrytkaLike - но не будет ждать вывода на экран предыдущих результатов. Если важно именно дождаться вывода результатов - то надо возвращать не LikeTurbo, а результат ContinueWith.

    Также тут очень важно расположение вызова TaskScheduler.FromCurrentSynchronizationContext(); Поскольку в момент исполнения прошлой задачи мы можем находиться в любом контексте - то ориентироваться на текущий контекст нельзя. Нужный нам планировщик задач следует сохранить при входе в метод (на будущее: его нужно _всегда_ сохранять _только_ при входе в метод!)
    Ответ написан
  • Как ограничить вызов метода владельцем объекта?

    @mayorovp
    Вариант первый — минимальная защита от индуса:
    class Event {
      public void subscribe(...) {}
    }
    
    class OwnedEvent extends Event {
      public void fire(...) {}
      public void addReaction(...) {}
    }
    

    Владелец события создает объект класса OwnedEvent, но перед передачей его другим объектам приводит к Event. При попытке приведения события обратно — больно бить по рукам.

    Вариант второй — максимальная защита от индуса, но с повышенным расходом памяти.
    class Event {
      public void subscribe(...) {}
    
      public static class Owner {
        private final Event event = new Event();
    
        public void fire(...) {}
        public void addReaction(...) {}
    
        public Event getEvent() { return event; }
      }
    }
    

    Смысл в том, что при таком подходе класс Event.Owner должен иметь доступ к приватным полям класса Event, чем и можно воспользоваться.

    PS на Java не писал ничего уже 4 года, могу накосячить с синтаксисом. Надеюсь, это не помешает пониманию написанного.
    Ответ написан
  • Стоит ли давать Haskell школьнику в качестве первого языка?

    @mayorovp
    Haskell — язык математиков. Уверены ли вы, что ваш девятиклассник достаточно хорошо знает математику?

    Если уверены — учите Хаскелю смело.
    Ответ написан
    Комментировать
  • Булевское свойство или функция

    @mayorovp
    Идеологически правильнее использовать наследование — ввести поле абстрактного класса «данные авторизации», и два производных класса — «авторизация по логину» и «авторизация по сертификату».
    Ответ написан
    1 комментарий
  • Что не так с реализацией алгоритма Хаффмана?

    @mayorovp
    Да, только что заметил: метод decompress теперь может распаковать несколько мусорных символов в конце файла (попробуйте упаковать файл, содержащий всего один символ). Надо бы записывать перед сжатым потоком длину исходного, или хотя бы ее последние три бита.
    Ответ написан
  • Что не так с реализацией алгоритма Хаффмана?

    @mayorovp
    Так, а какие файлы называются «большими»?
    Навскидку я вижу две проблемы — файлы более 2Гб (переполнение int) и нулевые символы (которым ошибочно не назначается код).

    Первая проблема лечится использованием большего типа данных, а вторая таким вот патчем:
    void Compressor::buildCodeTable(Node *root)
    {
        if (root->hasChild())
        {
            code.push_back(0);
            buildCodeTable(root->getChild(true));
            code.pop_back();
    
            code.push_back(1);
            buildCodeTable(root->getChild(false));
            code.pop_back();
        } else {
            codeTable[letter] = root->getLetter();
        }
    }
    Ответ написан
    Комментировать
  • Что не так с реализацией алгоритма Хаффмана?

    @mayorovp
    Еще две ошибки — вы не удаляете созданные сущности Node, что вызывает утечку памяти. Кроме того, выполнение tree.sort в цикле — ужасная идея. Правильная реализация алгоритма использует тот факт, что сущности Node в алгоритме создаются в порядке возрастания частот, благодаря чему можно обойтись одной сортировкой исходных нод в начале.
    Ответ написан
  • Что не так с реализацией алгоритма Хаффмана?

    @mayorovp
    Да, еще замечание по структуре: мне не кажется хорошей идеей объединение методов compress и decompress в одном классе, хранящем входной файл в виде поля. Как мне кажется, еще на этапе создания экземпляра пользователь библиотеки будет знать, что ему с этим файлом делать — упаковывать или распаковывать.

    ИМХО лучше выделить поля charMap, charTree и inputFile в базовый класс, а остальное разбросать по классам Compressor и Decompressor. Еще лучше ограничиться двумя глобальными функциями.

    Еще один вариант — убрать сущность «входной файл» из полей класса. Это позволит собирать статистику по одному потоку, а сжимать — другой, что может быть полезным для сжатия «на лету». Или можно хранить статистику отдельно от сжатых данных, чему тоже можно найти применение.
    Ответ написан
  • Что не так с реализацией алгоритма Хаффмана?

    @mayorovp
    Вот этот кусок надо добавить в функцию compress перед закрытием потока:
    if (count > 0)
        out << buf;
    

    Это связано с тем, что после цикла в buf могли оказаться значимые биты, не образующие полного байта и потому еще не записанные в поток.
    Ответ написан
    Комментировать
  • Как правильно принимать данные по LPT?

    @mayorovp
    Возможно, сейчас я скапинанствую, но надо писать драйвер виртуального порта.
    Ответ написан
  • Подскажите алгоритм

    @mayorovp
    Вот полное решение.

    Пусть исходные числа — a и b.
    1. Очевидно, если числа не являются взаимно простыми — ответом будет бесконечность.
    2. Известно, что любое число m может быть представлено как m = ka+lb при взаимно простых a и b.
    Для того, чтобы m не было разложимым, должно выполняться одно из двух условий: k<0 или l<0.

    Заметим, что (k+b)a+(l-a)b = ka+lb = (k-b)a+(l+a)b. Отсюда следует, что для неразложимом m должны существовать такие k и l, что k<0, l<a или k<b, l<0 (иначе можно будет найти разложение по одной из этих формул).
    Поскольку нам известны ограничения сверху как для k, так и для l, притом эти ограничения независимы,
    можно взять эти переменные по-максимуму.
    m = (-1)a+(a-1)b = (b-1)a+(-1)b = ab-a-b.

    Следовательно, для взаимно простых a и b ответом будет ab-a-b, а для имеющих общие делители — бесконечность.
    Ответ написан
    2 комментария
  • Какую книгу по программированию лучше всего подарить будущему программисту?

    @mayorovp
    image

    Мне вот эта в свое время очень помогла, правда тут не с нуля. В качестве первой книги по программированию я бы ее дарить поостерегся, но как вторая — вполне подходит.
    Ответ написан
    Комментировать