• Как редактировать XML файл при помощи Python?

    sergey-gornostaev
    @sergey-gornostaev Куратор тега Python
    Седой и строгий
    Не понимаю, как вы искали. Официальная документация "The ElementTree XML API", раздел "Modifying an XML File".
    Ответ написан
    Комментировать
  • В чем смысл запускать на Х-ядерном процессоре более Х потоков?

    @Neyury
    Самый простой пример в котором используется несколько потоков, это работа с сетью.

    Если есть всего один поток, и он запрашивает данные из сети, то он остановит свое выполнения до момента, когда эти данные придут. Если же будет несколько потоков, то пока один ждет данные из сети, другой может спокойно продолжать работу. Помимо работы с сетью, есть еще операции чтения и записи, которые в некоторых случаях могут быть медленными.
    Ответ написан
    2 комментария
  • А нельзя этот аргумент присвоить переменной?

    В питоне в методы и функции именовые переменные можно передовать через словарь
    d = {'a':1, 'b':2}
    
    def test(a,b):
        print('a:{}, b:{}'.format(a,b))
        
    test(**d)
    a:1, b:2
    Ответ написан
    Комментировать
  • Как узнать число запущенных потоков?

    leahch
    @leahch
    3D специалист. Dолго, Dорого, Dерьмово.
    Нет, это не очень хорошо. Вам желательно использовать легкие (green) треды и/или event pool. Иначе, при большом количестве клиентов уткнетесь в ограничения по количеству тредов.
    Посмотрите на асинхронные библиотеки типа aiohttp или twisted cyclone.io.
    Ответ написан
    4 комментария
  • Чем SVN лучше Git?

    @miksir
    IT
    Основные отличия - гита от svn - распределенность и хорошая поддержка ветвлений в разработке (ветки).

    SVN, конечно же, поддерживает ветки, но при сложных ветвлениях (ветки мержатся между собой) случаются неожиданные конфликты и т.п. Хотя, если у вас классическая схема - фича-ветка от мастера (транка) и обратный мердж в мастер (транк) - разница почти незаметна.

    Про распределенность: у SVN центральный сервер, у гита - граф серверов, хотя 99% процентов разработчиков используют локальный репо + один удаленный, т.е. по сути - тот же центральный сервер. Зато, так как репа локальная, гит очень быстр в переключении веток.

    Есть еще куча различий и, как плюсов, так и минусов у каждого ПО. Хотя сегодня SVN все реже и реже можно встретить, но в общем для многих рабочих групп его вполне достаточно для полноценной работы. С другой стороны - знать git тоже обязательно сегодня, ибо почти стандарт ;)

    Если вот так на первый взгляд поискать "чем svn лучше"...
    • работа с бинарными файлами, и быстрее и есть централизованные локи по репозиторию (что важно, ибо мердж бинарного файла обычно не очень эффективен);
    • есть система управления доступом вплоть до веток;
    • комит определенного юзера этим юзером и подписан, тогда как в гите аутентификация и поле автора не связаны никак (впрочем, последние две проблемы можно пофиксить хуками);
    • порядок комитов явный, т.е. есть глобальный счетчик с номером у каждого комита, хотя, конечно, не так принципиально;
    • частичный чекаут, т.е. начиная с любого узла SVN, удобно, если много мелких проектов - не нужно несколько репозиториев, просто один с папками проектов в корне


    Но я бы не стал говорить, что svn нормальный, а git нет. Просто он другой и со своими тараканами. Сам долгое время работал на SVN, потом потихоньку перебрались на git в основном из-за подводных камней сложного ветвления.
    Ответ написан
    Комментировать
  • Существуют ли правила подключения include-файлов в С++?

    @Mercury13
    Программист на «си с крестами» и не только
    Незыблемых правил два.
    1. В CPP первым — свой хедер. Это даёт уверенность, что в хедере нет недостающих включений.
    2. Избегать циклической зависимости по интерфейсам. Делить программу на слои и не включать ничего из верхних слоёв.

    Если уж второе не получилось — есть три решения, каждое из которых решает свою задачу.
    1. Forward declaration, полумера против сильной связанности классов.
    // Хедер 1
    class Master;
    
    class Slave {
      Master* master;
    }
    
    // Хедер 2
    class Master {
      Slave slave;
    }


    2. Разорвать порочный круг интерфейсом.
    // Хедер 1
    class Master {  // interface
    public:
      virtual void enumSlaves(const EnumSlavesCallback& v) = 0;
      virtual ~Master() = default; 
    }
    
    class Slave {
      Master* master;
    }
    
    // Хедер 2
    class MyMaster :  public Master {
    public:
      Slave slave;
      void enumSlaves(const EnumSlavesCallback& v) override {}
    }


    3. Вынести общие типы/функции в отдельный хедер под названием someDefines.h или someUtils.h.
    Ответ написан
    Комментировать
  • Как организовать обработку большого файла?

    @res2001
    Developer, ex-admin
    Проще всего использовать файлы отображаемые в память, там уже за вас обо всем подумали.
    Ответ написан
    Комментировать
  • Кто-нибудь знает толковый/любой обозреватель исходных файлов?

    TrueBers
    @TrueBers
    Гуглю за еду
    В плюсах не так всё просто, как в дотнете. Стандартных возможностей для этого не существует в природе. Си и С++ по сути являются высокоуровневым ассемблером без какой-либо метаинформации. Здесь всё зависит от наличия отладочной информации в файле. Если её нет, то вы увидите только ассемблерный код. Максимум сможете только найти строки, которые использует программа. Но даже с отладочной инфой вы не получите ни имён, ни переменных, ни классов. Будут абстрактные наборы процедур, которые, при наличии опыта реверсинга можно будет определять на глаз.

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

    А вообще, после перехода с дотнета просто смиритесь, что вы пишете, по сути, на ассемблере с синтаксическим сахаром, и что в плюсах разработка гораздо дольше, затратнее и сложнее с непривычки.
    Ответ написан
    2 комментария
  • Как в C++ распределяется память?

    pi314
    @pi314
    Президент Солнечной системы и окрестностей
    Смотря что именно подразумевается под "создать массив" )) Вот хорошая шпаргалка на тему, что это может означать и где он в результате окажется:

    int arr1[100000]; // BSS
    vector<int> arr2; // HEAP
     
    struct DumbStruct {
        int someArr[10000];
    };
     
    int main () {
        int arr3[100000]; // STACK
        vector<int> arr4; // HEAP
        int* arr5 = new int[100000]; // HEAP
        int* arr6 = (int*) malloc(100000 * sizeof(int)); // HEAP
        static int arr7[100000]; // BSS
        DumbStruct struct; // STACK
        DumbStruct* struct2 = new DumbStruct(); // HEAP
        vector<DumbStruct> structarr; // HEAP
        int n;
        scanf("%d", &n);
        int arr8[n]; // STACK (assuming C99 -- this does not compile in C++)
    }


    Если речь именно о динамическом выделении памяти и именно о С++, то есть два варианта: malloc()/free() и new[]/delete[]. Теоретически в случае фрагментации памяти (когда ее, в принципе, достаточно, но не "одним куском") ни тот, ни другой не "заполнит" никаких "свободных" ячеек. malloc() вернет NULL, a new[] кинет std::bad_alloc.

    А практически, конечно, возможно, что угодно... т.к. 1. new - это оператор, и значит, его можно переопределить, 2. с помошью std::set_new_handler ему можно подсунуть свой аллокатор, а также 3. полезет ли new[] вообще к malloc(), строго говоря, не гарантируется и, наконец 4. реализация malloc(), вообще-то, зависит от ОС, а они нынче умные и могут прореагировать как угодно - вплоть до убийства затребовавшего память процесса OOM менеджером.

    Так что, наиболее точный ответ на вопрос: возможны варианты (хорошие и разные)... Однако, если суть вопроса в том, а не получится ли при этом случайно массив, который не массив, то ответ - нет, не получится. Массив, это семантическая конструкция языка. В С++ программист может полагаться на то, что память в массиве непрерывна.
    Ответ написан
    5 комментариев
  • Как автоматически создавать документацию к программному коду?

    eduardtibet
    @eduardtibet
    Technical Writer / Documentation Engineer
    добавлю к предыдущему комментарию

    "... и никакого ворда" :)
    Ответ написан
    1 комментарий
  • Почему лучше не использовать статические конструкторы?

    AtomKrieg
    @AtomKrieg
    Давай я поищу в Google за тебя
    Cтатические конструкции (например," static const Foo & F = * new Foo ( ) ; " ) могут иметь утечки памяти. Если LLVM сбилдили в виде динамической библиотеки , он может перезагружается неограниченное число раз , и в каждой итераций загрузки будет создаваться один экземпляр 'Foo ' .
    Кроме того, если LLVM построен на Windows, MSVC 2013 ( который поддерживает LLVM ) , то функция статического создания уровня потоконебезопасна (безопасна начиная с MSVC 2015 ) . Некоторые варианты LTO будут создавать поток для каждого объекта.

    Ну и вот здесь еще пишут, про скорость запуска приложения
    llvm.org/docs/CodingStandards.html#do-not-use-stat...
    Если вкратце, то пользователь будут ждать много времени прежде чем покажутся окошки и можно будет нажимать кнопочки. Лучше создавать синглтоны в фоне пока интерфейс делает вид, что приложение полностью загружено и готово к работе.
    Ответ написан
    Комментировать
  • Как подставить массив в функцию?

    winordie
    @winordie
    Лучшая документация -- исходники
    По просьбам в дополнение к @nirvimel
    Добавляем сахарок
    x = [f(*z) for z in zip(a, omega, phi, t)]
    И еще
    x = map(f, a, omega, phi, t)
    Для простых функций
    x = map(lambda a, omega, phi, t: a * sin(omega * t + phi), a, omega, phi, t)
    Ответ написан
    Комментировать
  • Как использовать pip для разных версий Python?

    При установке python, в корневую директорию windows копируется py.exe. Запуская его с разными параметрами запускаются разные интерпретаторы:
    Запуск python 2 идет по умолчанию:
    py ваш_скрипт.py
    или явно:
    py -2 ваш_скрипт.py
    Запуск python 3:
    py -3 ваш_скрипт.py
    Документация

    Установка модулей:
    py -2   -m pip install SomePackage  # default Python 2
    py -2.7 -m pip install SomePackage  # specifically Python 2.7
    py -3   -m pip install SomePackage  # default Python 3
    py -3.4 -m pip install SomePackage  # specifically Python 3.4
    Ответ написан
    1 комментарий