Ответы пользователя по тегу Программирование
  • Как быстро изменить оформление кода всего проекта?

    @abcd0x00
    Может есть какие то средства? Или программы?

    Есть sed, но его нужно знать.
    Ответ написан
    Комментировать
  • Как правильно организовать структуру в классе?

    @abcd0x00
    Нужно создать программу, которая будет служить эмулятором кассового аппарата.

    Ты должен сначала описать наружнюю составляющую этого аппарата.

    Типа
    начать работу
    нажать кнопку один
    нажать кнопку два
    повернуть ручку такую-то
    повернуть ручку другую-то
    показать на экране текущее состояние
    кончить работу

    Это внешнее описание аппарата.

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

    Введённые продукты добавляются в список продуктов, который скрыт от наружнего наблюдателя, но который виден внутри аппарата. Всё управление аппаратом происходит через его внешние методы (через интерфейс).
    Ответ написан
    Комментировать
  • Какую книгу можно использовать по языку C, чтобы получить базовые познания в CS?

    @abcd0x00
    Язык программирования C (K&R2)
    www.ozon.ru/context/detail/id/2480925

    Язык программирования C. Лекции и упражнения. (Стивен Прата)
    www.ozon.ru/context/detail/id/31649671
    Ответ написан
    Комментировать
  • Используете ли Вы онлайн площадки, как например "coding ground", есть похожие?

    @abcd0x00
    Попробуй https://ideone.com , для демонстраций кому-нибудь чего-нибудь годится.
    Ответ написан
    Комментировать
  • Как разбить большую функцию на несколько мелких?

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

    У тебя не должно быть так, что сначала появляется функция, а потом ты думаешь, что ею можно сделать. Должно быть наоборот. Сначала должна появляться задача, которую нужно сделать, а вот уже под эту задачу должна появляться функция, которая её выполняет. И таких функций может быть много, и все они могут быть разными.

    Например, ты хочешь вывести строку "hello" в C.
    Код
    #include <stdio.h>
    
    int main(void)
    {
        printf("hello\n");
        puts("hello");
        fputs("hello\n", stdout);
        fprintf(stdout, "hello\n");
        fwrite("hello\n", 1, 6, stdout);
        return 0;
    }

    Вывод
    [guest@localhost c]$ .ansi t.c -o t
    [guest@localhost c]$ ./t
    hello
    hello
    hello
    hello
    hello
    [guest@localhost c]$


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

    А вот та же задача, но перечисленные функции использовать запрещено. Что делать?
    Можно написать функцию вместо них.
    Код
    #include <stdio.h>
    
    void f1(void)
    {
        putchar('h');
        putchar('e');
        putchar('l');
        putchar('l');
        putchar('o');
        putchar('\n');
    }
    
    void f2(char c)
    {
        putchar(c);
        putchar('e');
        putchar('l');
        putchar('l');
        putchar('o');
        putchar('\n');
    }
    
    void f3(char c)
    {
        int i;
        
        putchar('h');
        putchar('e');
        for (i = 0; i < 2; i++)
            putchar(c);
        putchar('o');
        putchar('\n');
    }
    
    int main(void)
    {
        f1();
        f2('h');
        f3('l');
        return 0;
    }

    Вывод
    [guest@localhost c]$ .ansi t.c -o t
    [guest@localhost c]$ ./t
    hello
    hello
    hello
    [guest@localhost c]$


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

    А вот теперь давай подумаем, как так получилось, что функция printf(), написанная десятки лет назад, решила нашу задачу и тысячи других задач, а свои функции f1(), f2() и f3() могут решить только нашу задачу, но кроме неё не могут решить и десятка других задач?

    В чём разница между printf() и f1()? В том, что в printf() строка "hello" передаётся через параметр (то есть выводимый текст параметризован), тогда как в f1() строки вообще нет, она образуется из символов, которые даже не параметризованы. А что у нас с f2(), ведь там есть параметр? А в f2() выводимый текст параметризован недостаточно, так же как и в f3().

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

    Вот таким образом и пишется функция: ты должен ставить задачу и решать её вызовом какой-то функции. А если функции не существует, то ты всё равно должен её вызывать, но потом дописывать её содержимое. И вот дописывая функцию, внутри неё ты делаешь то же самое - ставишь задачу и решаешь её вызовом какой-то функции.

    В примере выше ты решаешь задачу вывода строки "hello" функцией f1(), а внутри функции f1() ты решаешь задачу вывода символа на экран функцией putchar(). (Благо putchar() готова уже и хорошо параметризована. Но если не готова, то ты так же её вызываешь, а потом дописываешь её внутренность, в которой всё повторяется - задача и вызов.)
    Ответ написан
    Комментировать
  • Чем извлечь информацию из .png?

    @abcd0x00
    Ну, ты берёшь этот файл, разделяешь его на части, потом меняешь нужную часть и сохраняешь всё в новый файл. Если он сохранился, то заменяешь им исходный файл.

    Как разделить на части? По длине в байтах или по маркеру (признаку).
    Ответ написан
    Комментировать
  • Должен ли программист знать ассемблер?

    @abcd0x00
    Если тебе нужно что-то переделать в какой-то программе, то ты никак это не переделаешь, не зная ассемблера. Например, сидишь ты в винде, тут раз она начала куда-то подключаться и что-то качать. Ты ищешь, а где это отключается, и обнаруживаешь, что нигде, что так задумано. Вот тогда ты лезешь в то место, где она включает эту закачку, и переключаешь там байты на то место, где она думает, что уже всё закачала.
    Ответ написан
    Комментировать
  • Большой проект на С. Как строить работу чтобы не завалило кодом?

    @abcd0x00
    По самому проекту тебе ответил уже Владимир Дубровин, а вот по малой части надо стремиться к декомпозиции (разложению) на исполнители.

    В одном .h файле описываешь интерфейс объекта, например, стека
    void stack_start();
    int stack_push(int value);
    int stack_pop();
    int stack_isempty();
    int stack_topr();
    int stack_topw(int value);
    void stack_del();
    void stack_end();

    Дальше в .c файле пишешь реализации этих методов (сами функции и статические (закрытые в файле) переменные, которые им нужны для внутренней работы). И потом, чтобы подключить стек, ты просто подключаешь его .h файл и используешь эти методы.
    (Это пример; на самом деле, делается набор методов, который можно применять к разным стекам, где соответствующий стек (структура) просто передаётся в метод первым аргументом.)

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

    Тогда всё будет чисто, это всё можно будет тестировать ясными unit-тестами, можно будет легко выделять такую часть и заменять на другую и, самое главное, можно будет сами эти методы также декомпозировать дальше, так как не всегда они просто устроены, как в примере со стеком.
    Ответ написан
    Комментировать
  • Клиент хочет автоматизировать загрузку каталога на сайт через CSV, как это сделать если есть сложные описания?

    @abcd0x00
    Надо просто использовать готовые средства для преобразования данных в csv, потому что они знают, как правильно экранировать (соотвествуют rfc4180).
    На питоне пример
    >>> import csv
    >>> import sys
    >>> 
    >>> lst = [['a a1', 'b,b1', '<c>"text"</c>1', 'd d1'],
    ...        ['a a2', 'b,b2', '<c>"text"</c>2', 'd d2'],
    ...        ['a a3', 'b,b3', '<c>"text"</c>3', 'd d3']]
    >>> 
    >>> writer = csv.writer(sys.stdout)
    >>> 
    >>> writer.writerows(lst)
    a a1,"b,b1","<c>""text""</c>1",d d1
    a a2,"b,b2","<c>""text""</c>2",d d2
    a a3,"b,b3","<c>""text""</c>3",d d3
    >>>

    Ответ написан
  • Как работает данный код?

    @abcd0x00
    Почему в данном фрагменте требуется создать доп. метод Count ?

    Когда ты его вызываешь, создаётся замыкание, в котором в переменной sum накапливается значение при каждом вызове. И таких замыканий можно сделать несколько независимых друг от друга.
    CountIt c1 = Counter();
    CountIt c2 = Counter();
    CountIt c3 = Counter();

    Для того они и используются. Между вызовами что-то сохраняется в переменную и для каждого замыкания эта переменная своя собственная.
    Ответ написан
    Комментировать
  • Как исправить цикл "while", чтобы выводилось одно значение игнорируя перенос строки?

    @abcd0x00
    Когда ты вводишь символ, тебе нужно нажать <return> (Enter). Так вот этот приводит к тому, что за введённым символом сразу посылается символ перевода строки \n. На следующем шаге цикла он считывается и обрабатывается как обычный символ, поэтому получается проскок.

    Как это решается: нужно сделать функцию input_char().
    Нужно считать строку до конца, а потом из считанной строки выбрать первый символ. Для считывания строки можно использовать fgets(), а для считывания символа из полученного символьного массива можно использовать sscanf(). Это способ fgets() + sscanf().
    Ответ написан
  • Как научиться программировать на Delphi?

    @abcd0x00
    К примеру, хотел написать парсер текста и приплыл.

    Для этого нужно изучить конечные автоматы и формальные грамматики.
    wiki. конечный автомат
    wiki. формальная грамматика
    Пособия от МГУ: пособие по грамматикам

    Это, конечно, ещё не всё, так как надо ещё много чего изучать, чтобы просто разрабатывать программы (система контроля версий, юнит-тестирование, автоматическая сборка проекта, UML).

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

    @abcd0x00
    Сделать можно, но делать так не надо
    >>> def foo():
    ...     print('in foo')
    ...     def foo_in_foo():
    ...         print('in foo_in_foo')
    ...     foo.foo_in_foo = foo_in_foo
    ... 
    >>> foo()
    in foo
    >>> foo.foo_in_foo()
    in foo_in_foo
    >>>
    Ответ написан
    Комментировать
  • В чем разница между & и &&?

    @abcd0x00
    Операции && || ! :
    используются для проверки истинности своих операндов.

    Операции & | ^ ~ << >> :
    используются для управления битами в своих операндах.

    Если у тебя есть переменные flag1, flag2, flag3, ты можешь проверить их на истинность:
    if ((flag1 && flag2) || !flag3) {
        something;
    }

    А если у тебя есть переменная states, ты можешь проверить в ней какие-то определённые биты:
    if (states & (0x1 | 0x4)) {
        something;
    }

    0x1 - в битовом представлении выглядит как
    00000000 00000000 00000000 00000001

    0x4 - в битовом представлении выглядит как
    00000000 00000000 00000000 00000100

    0x1 | 0x4 - в битовом представлении выглядит как
    00000000 00000000 00000000 00000101

    Пример1:
    Если states равно 0x123 - в битовом представлении это выглядит как
    00000000 00000000 00000001 00100011

    Выражение states & (0x1 | 0x4) - в битовом представлении будет выглядеть как
    00000000 00000000 00000001 00100011 &
    00000000 00000000 00000000 00000101
    =
    00000000 00000000 00000000 00000001

    Получилось, что всё выражение равно 0x1 или просто 1.
    if (0x1) {
        something;
    }


    Пример2:
    Если states равно 0x122 - в битовом представлении это выглядит как
    00000000 00000000 00000001 00100010

    Выражение states & (0x1 | 0x4) - в битовом представлении будет выглядеть как
    00000000 00000000 00000001 00100010 &
    00000000 00000000 00000000 00000101
    =
    00000000 00000000 00000000 00000000

    Получилось, что всё выражение равно 0x0 или просто 0.
    if (0x0) {
        something;
    }
    Ответ написан
    Комментировать
  • Как понять рекурсию в Python?

    @abcd0x00
    Как понять рекурсию в Python?

    Нужно смотреть на функцию как на множество разных функций, похожих друг на друга. Поэтому когда функция вызывает саму себя, надо на это смотреть как на функцию, вызывающую очень похожую, но другую функцию. А когда функция вызывает другую функцию, они передают друг другу значения: вызывающая вызываемой подаёт параметры, а вызываемая вызывающей подаёт возвращаемое значение.
    Ответ написан
    1 комментарий
  • Как создать списки с динамически изменяющимися именами?

    @abcd0x00
    >>> numbers = (1, 2, 3)
    >>> fnames = ('file{}.txt'.format(i) for i in numbers)
    >>> files = [open(i, 'w', encoding='utf-8') for i in fnames]
    >>> files
    [<_io.TextIOWrapper name='file1.txt' mode='w' encoding='utf-8'>, <_io.TextIOWrapper name='file2.txt' mode='w' encoding='utf-8'>, <_io.TextIOWrapper name='file3.txt' mode='w' encoding='utf-8'>]
    >>> [i.close() for i in files]
    [None, None, None]
    >>>


    [guest@localhost t]$ ls
    file1.txt  file2.txt  file3.txt
    [guest@localhost t]$


    Вообще, файлы принято открывать через with. Если особой необходимости нет для ручного открытия и закрытия, то надо использовать with.
    Ответ написан
    Комментировать
  • Как считать данные из файла и записать их в список?

    @abcd0x00
    [guest@localhost py]$ cat file.txt 
    1.5
    2.6
    3.123
    4.56
    [guest@localhost py]$


    >>> with open('file.txt') as fin:
    ...   lst = list(map(float, fin))
    ... 
    >>> lst
    [1.5, 2.6, 3.123, 4.56]
    >>>
    Ответ написан
    Комментировать
  • Как определить суммы левой и правой частей больших чисел?

    @abcd0x00
    >>> import operator
    >>> 
    >>> def split3(x):
    ...     return (x // 100, x // 10 % 10, x % 10)
    ... 
    >>> def split6(x):
    ...     return (x // 1000, x % 1000)
    ... 
    >>> pred = lambda x: operator.eq(*map(sum, map(split3, split6(x))))
    >>> 
    >>> out = list(filter(pred, range(100000, 1000000)))
    >>> out[:10]
    [100001, 100010, 100100, 101002, 101011, 101020, 101101, 101110, 101200, 102003]
    >>>
    Ответ написан
    Комментировать
  • Зачем писать такой большой код?

    @abcd0x00
    Изучи метод разработки "сверху вниз". Если его не освоишь, ничего длиннее ста строк писать не будешь.
    wiki. структурное программирование
    Ответ написан
    Комментировать
  • Что нужно изучать, чтобы стать программистом C++?

    @abcd0x00
    Что нужно изучать, чтобы стать системным программистом на С++?

    Нет системных программистов на C++, есть просто системные программисты, и они используют сразу много языков. Для начала тебе нужно понять, при чём тут математика. Вот смотри, есть файловая система на диске. Чтобы эти файлы экономно распределять и работать с ними быстро, алгоритмы работы с файлами оптимизируются. А оптимизируются они как? Правильно, оптимизируют они математически. То есть берётся какая-то математическая теория и из неё делаются выводы, как можно написать программу покороче, как можно сложить данные покомпактнее. Так придумали всякие математические деревья для файловых систем.

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

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

    Если хочешь быть программистом, готовься к тому, что придётся изучать самую обычную математику и самую обычную физику.
    Ответ написан
    Комментировать