Задать вопрос
Пользователь пока ничего не рассказал о себе

Достижения

Все достижения (4)

Наибольший вклад в теги

Все теги (28)

Лучшие ответы пользователя

Все ответы (49)
  • Вычисления на звуковой карте?

    Tanner
    @Tanner
    Огромный человекоподобный боевой робот
    Большая часть звуковых карт содержит только DAC/ADC. Есть, однако, карты с чипом DSP, которые действительно что-то как-то вычисляют.

    Карточки Creative с процессором EMU10xxx и выше — вот первое, что приходит в голову. Но архитектура процессора закрытая, трудно понять, что он на самом деле может. Реверсивную разработку этих чипов вроде бы производят ребята из kX, но насчёт команд и структуры DSP… В общем, попробуйте глянуть на их сайте какие-нибудь доки или спросить на форуме драйверов kX.

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

    Tanner
    @Tanner
    Огромный человекоподобный боевой робот
    Жёсткие диски ненадёжны. Точка. Регулярно бэкапьте данные на другой диск, желательно — на другой компьютер; если важно всё содержимое диска — RAID1. Также учитывайте, что причиной большинства случаев потери данных является сбои питания. Появились бэдблоки — проверяйте БП!

    Перебирать модели и бренды бессмысленно. Во-первых, потому что к тому моменту, когда соберётся хорошая статистика по вылетам конкретной модели, эта модель морально устареет. Во-вторых, попасть в 1% «счастливчиков» так же обидно, как и в 40%.
    Ответ написан
    1 комментарий
  • Программирование микроконтроллера в USB флешке

    Tanner
    @Tanner
    Огромный человекоподобный боевой робот
    В общем случае можно. Есть, например, сайт flashboot.ru, там собрана база данных по типу «PnP ID флэшки — марка контроллера». Можно поискать даташиты на эти контроллеры. Если даташитов нет, то там же народ выкладывает подпольные тулзы для перепрошивки этих самых контроллеров. Можно и фирмварь реверснуть. Понятно, что пользы от этого никакой, для самоделок лучше купить что-то типа Arduino. А как экзотический хак — возможно, прокатит.
    Ответ написан
    1 комментарий
  • Прошу помощи. В каком направлении мне двигаться?

    Tanner
    @Tanner
    Огромный человекоподобный боевой робот
    Для начала, мне непонятно, почему все части вашей программы, которые вполне могут выполняться синхронно, работают в потоках. Есть часть программы, которая выиграла бы от многопоточности − сканирование портов, где логично было бы создать по потоку на каждый порт (если портов слишком много, то создать пул потоков, определить стратегию переиспользования потоков, в общем, тут большой простор для творчества), но у вас порты сканируются в одном потоке, последовательно.

    Но давайте притворимся, что так и надо, и поговорим о других проблемах вашего кода.
    • Не стоит использовать глобальные переменные в программах длиннее одного экрана. Вместо global лучше объявить глобальный объект и спрятать flag в него:
      class PortScanner:
          
          def __init__(self):
              self.flag = 0
              
          def animate_menu_up(self):
              print("\n")
              ...
              self.flag = 1


    • Код инициализации программы тоже лучше перенести в __init__() глобального объекта. И основной цикл вынести в отдельный метод, например, run(). Тогда на нижнем уровне у нас останется что-то вроде:
      import ...
      
      class PortScanner:
          ...
      
      if __name__ == '__main__':
          main_obj = PortScanner()
          main_obj.run()

      этот идиоматичный код позволит импортировать класс PortScanner в другой скрипт, а также обеспечит плюсик на собеседовании/ревью,
    • приучайтесь использовать докстринги вместо комментариев:
      def animate_menu_up():
          """ Создание красивого меню (вверх). """

    • лишний цикл while True: в select_mode(),
    • слишком много магии. По мере роста программы становится всё тяжелее держать и сопоставлять в голове всякие абстрактные значения. Вот литералы, которые, по моему мнению, стоило бы определить как константы − или в «шапке» скрипта, или как атрибуты класса:
      MF_INITIAL = 0
      MF_MENU_CENTER = 1
      MF_MENU_DOWN = 2
      MF_SELECT = 3
      
      SCREEN_WIDTH = 50
      ALL_PORTS = [22, 80, 7777, 2516]
      SOCK_TIMEOUT = 0.5
      ANIM_SYMBOL = '~'
      ANIM_DELAY = 0.02

    • такие вещи очень больно стреляют в ногу и почти гарантированно проваливают собеседования:
      except RuntimeError:
          continue
      если вы действительно хотите продолжить выполнение программы после такой ошибки (что в обычных обстоятельствах бессмысленно и опасно), то позаботьтесь хотя бы о правильной индикации:
      import traceback
      ...
      except RuntimeError:
          traceback.print_exc(file=sys.stdout)
          continue

    • раз уж мы задержались здесь, давайте сделаем диспетчер более идиоматичным:
      while True:
          try:
              {
                  MF_MENU_CENTER: th_three.start,
                  MF_MENU_DOWN: th_two.start,
                  MF_SELECT: select_mode,
              }[flag]()
          except RuntimeError:
              traceback.print_exc(file=sys.stdout)
              continue
      Такой наивный подход выводит много шелухи на экран, но это не важно. Важно то, что такой код проще читать и дорабатывать, чем цепочку if...elif...else.

    • Работа со строками тоже напрашивается на улучшения:
      1. нет смысла разбивать строки на списки, к символам в строке можно обращаться так же, как к элементам списка − по индексу и с помощью срезов,
      2. не нужно копировать строки,
      3. не нужно печатать всю строку с начала, это делает анимацию неровной − конец строки печатается медленнее, чем начало. Достаточно допечатать один символ в строке.
      Например:
      def animate_menu_center():
          """ Создание анимации центрального меню. """
          # настройки для анимации
          output_strings = [
              '[1] scan all ports',
              '[2] scan enter port',
              '[3] exit',
              'SCANNER V1.0',
          ]
      
          # анимация названия
          for output_string in output_strings:
              print('\r\t\t', end='')
              for ch in output_string:
                  print(ch, end='')
                  time.sleep(ANIM_DELAY)
              # last string?
              if output_string != output_strings[-1]:
                  # new line
                  print()
      
          print('', flush=True)
          flag = MF_MENU_DOWN
      (Я убрал цвета для простоты.)
    • юзабилити сильно страдает из-за отсутствия нормальной функции выхода из приложения,
    • не оставляйте закомментированный код в файле, который отдаёте на ревью, это минус. Вместо этого напишите комментарий с пометкой “TODO”, например:
      # TODO: реализовать режим '2' (скан произвольного списка портов)
      Это однозначно плюс − показывает, что вы умеете работать в команде и пользоваться системами контроля версий.

    Вроде бы наиболее серьёзные проблемы я перечислил. Выложу более полный вариант кода в комментариях.
    Ответ написан
    1 комментарий
  • Motorola L7e DIY

    Tanner
    @Tanner
    Огромный человекоподобный боевой робот
    У Вас есть спеки на контроллер? Что там за проц? ARM6, Snapdragon, НЁХ? Как инициализировать периферию? Как вообще туда засунуть Вашу программу? Есть ли бутблок? Как отлаживать?
    Ответ написан
    Комментировать

Лучшие вопросы пользователя

Все вопросы (1)