Архив автора: admin

Красивые заколки на скорую руку

Вам нужно выйти «в свет» и обязательно блеснуть? А тут как назло нет ни времени, ни денег на покупку нового ошеломительного наряда. Знакомая ситуация? Не отчаивайтесь! Свой обрез можно изменить не только при помощи нового платья. Порой аксессуары играют более важную роль, поскольку в первую очередь притягивают к себе внимание. К примеру, если вы наденете шикарное колье с крупными камнями, то вряд ли кто-то уже обратит внимание на то, что в этом платье вы уже появлялись раньше. Изменить образ можно при помощи обуви, пояса, сумочки и даже броши. Мы же предлагаем сделать украшение для волос – красивую заколку за 5 минут.

Как украсить заколки

Как украсить заколки

Читать

Удаление объектов сборщиком мусора

На Хабре появилась толковая статьяо неприятностях, которые может доставить Garbage Collector.

Отмечу актуальность описания проблемы и полную корректность решения для tornado.

Однако не могу не обратить внимание на слабое освещение того, как именно работает сборщик мусора в CPython.

Почему при работающем garbage collector появляется так много неудаляемых объектов?

Немного теории.

Сборщик мусора имеет три поколения (счёт начинается с нуля). При создании объекта он попадает в нулевое поколение.

У каждого поколения есть счётчик и порог. Работает эта пара так:

  • При добавлении объекта в поколение счётчик увеличивается.
  • При выбывании из поколения счётчик уменьшается.
  • Когда счётчик превысит пороговое значение — по всем объектам из поколения пройдётся сборщик мусора. Кого найдёт — удалит.
  • Все выжившие в поколении объекты перемещаются в следующее (из нулевого в первое, из первого во второе). Из второго поколения объекты никуда не попадают и остаются там навечно.
  • Перемещённые в следующее поколение объекты меняют соответствующий счетчик, и операция может повториться уже для следующего поколения.
  • Счётчик текущего поколения сбрасывается.

Объекты, подлежащие уничтожению но имеющие переопределённый метод __del__ не могут быть собраны. Причина проста: эти объекты могут ссылаться друг на друга.

Python не способен определить безопасный порядок вызова __del__. Если вызывать деструкторы в произвольном порядке, то можно получить ситуацию вида:

  • Деструктор объекта a для работы требует объект b.
  • Последний в своём деструкторе обращается к объекту a.
  • Если вызовем __del__ у a, то деструктор b не сможет отработать нормально. Ссылка на a будет иметь значение None.

Чтобы не заставлять программиста корректно разрешать такие ситуации было принято решение не уничтожать подобные объекты а просто перемещать их в gc.garbage — и дальше программист пусть сам разбирается что делать с этим мусором.

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

Перейдём к практической части.

Пример

Для иллюстрации рассмотрим немного изменённый пример из приведенной в самом начале статьи.

Имеем классическую древовидную структуру:

class Node(object):
parent = None

def __init__(self, *children):
self.children = list(children)
for node in self.children:
node.parent = self

@classmethod
def tree(cls, depth=1, numchildren=1):
if depth == 0:
return []
return [cls(*cls.tree(depth-1, numchildren))
for _ in range(numchildren)]

Родитель и потомки напрямую связаны друг с другом циклической связью. Метод tree создает дерево нужной глубины.

Добавляем garbage collection hook для того чтобы увидеть когда срабатывает сборщик мусора и сколько объектов он уничтожает:

import gc

def gc_cb(phase, info):
if not info['collected'] and not info['uncollectable']:
return
print("{0}:t{1[generation]}t{1[collected]}t{1[uncollectable]}".format(
phase, info))

gc.callbacks.append(gc_cb)

Наконец, делаем много-много наших деревьев и смотрим как они разрушаются:

for n in range(20):
for _ in range(n):
Node.tree(depth=5, numchildren=6)

Пороги стоят стандартные:

>>> gc.get_threshold()
(700, 10, 10)

700 объектов в нулевом поколении и по 10 в первом и во втором.

Анализ

Теперь о том, почему образуется столько мусора.

Пример напечатает что-то вроде такого (вырезка из очень длинного результата):

...
stop: 1, 4665, 0
stop: 2, 79305, 0
stop: 1, 4665, 0
stop: 2, 79305, 0
stop: 1, 4665, 0
stop: 1, 4665, 0
stop: 1, 4665, 0
stop: 2, 97965, 0
stop: 1, 4665, 0
stop: 2, 79305, 0
stop: 1, 4665, 0
...

За один вызов Node.tree(depth=5, numchildren=6) создается 9330 тесно связанных объектов, которые нельзя разрушить в 0 поколении (помним, что порог 700). Значит они попадают в первое, а большая часть даже во второе поколение (9330>700*10). Наконец все 9330 объекта созданы, можно разрушать.

На уменьшении счётчиков ссылок на объекты ничего убрать не получится. Поэтому ждём, когда опять превысим порог в 700 (на следующем вызове Node.tree, конечно).

Собираем нулевое поколение (оно оказывается заполнено свежими данными и поживиться почти ничем не удаётся).

А сборщик мусора для поколения 1 вызовется только если туда попадут как минимум 10 объектов из поколения 0.

Хорошо, мы добрались до сбора в 1 поколении. Часть циклов мож
но уничтожить сразу (два поколения для анализа лучше одного), некоторые переправляются в поколение 2. В котором сборщик запускается тоже если в свою очередь превысили порог.

Что случается ещё реже и таким образом наши объекты накапливаются во втором поколении. Когда сборщик мусора доходит до него, то всё чистит.

Проблема в том, что до последнего поколения дело доходит относительно редко.

В результате имеем не слишком типичный для сборщика мусора случай.

Чиним

Конечно, лучше всего не доводить дело до сборщика мусора вообще в случаях подобным нашему синтетическому примеру.

Разрушать ссылки вручную через вызов del или присваивания Noneочень неудобно, но есть и другой способ.

Воспользуемся слабыми ссылками на родителя:

import weakref

class Node(object):
parent = None

def __init__(self, *children):
self.children = list(children)
for node in self.children:
node.parent = weakref.proxy(self)

Я предпочитаю weakref.ref как дающий больший контроль (всегда можно добавить свойство):

class Node(object):
_parent = None

def __init__(self, *children):
self.children = list(children)
for node in self.children:
node._parent = weakref.ref(self)

@property
def parent(self):
if self._parent is None:
return None
else:
return self._parent()

В любом варианте дело до сборщика мусора не дойдёт и объекты будут уничтожены сразу как только перестанут быть нужны.

Если вариант со слабыми ссылками почему-то не проходит можно просто увеличить пороги. У нас создаётся за раз 9330 объектов? Поставим порог для первого поколения в 10000.

gc.set_threshold(10000, 100, 100)

Результат выглядит куда лучше:

...
stop: 0, 4665, 0
stop: 0, 4665, 0
stop: 0, 4665, 0
stop: 0, 4665, 0
stop: 0, 4665, 0
stop: 1, 919005, 0
stop: 0, 4665, 0
stop: 0, 4665, 0
stop: 0, 4665, 0
stop: 0, 4665, 0
...

Как видим сборщик мусора уничтожает почти всё на первом проходе, и лишь иногда требуется второй. Правда, смущает цифра 919005.

Именно потому что не всё прибивается на первом проходе, а второй наступает нескоро.

Уменьшаем второй порог:

gc.set_threshold(10000, 10, 10)

Ага, теперь всё красиво:

...
stop: 1, 83970, 0
stop: 0, 9330, 0
stop: 0, 4665, 0
stop: 0, 4665, 0
stop: 1, 74640, 0
stop: 0, 4665, 0
stop: 0, 4665, 0
stop: 1, 102630, 0
stop: 0, 4665, 0
stop: 0, 4665, 0
...

Выводы

В результате всё просто. Используем слабые ссылки. Если это по каким-то причинам невозможно — поднимаем пороги.

Но при этом нужно помнить, что сборщик мусора будет запускаться реже.

Установка порогов в слишком большое значение способно в нашем случае съесть память не менее успешно, чем если бы эти значения оставались установленными по умолчанию.

Автор: Andrew Svetlov

Украшение детской игрушками хэндмэйд

Чем украшают и дополняют интерьер детской комнаты? Конечно же, игрушками! Здорово, когда игрушки сшиты  или сделаны своими руками. Особенно, если ваше чадо станет непосредственным участником процесса создания игрушки. И не нужно ждать лучших времен! Берите в руки ткань и швейные принадлежности и беритесь за дело. Как украсить детскую игрушками хэндмэйд – тема сегодняшней статьи.

Украшение детской игрушками

Украшение детской игрушками

Читать

RetroShare. Обмен файлами

Продолжаем серию статей про RetroShare. Сегодня научимся расшаривать папки и файлы и качать чужие. Естественно, если Ваши друзья дали общий доступ к своим данным.
Вкладка «File Sharing» содержит в себе пять вкладок. Каждая из них отвечает за какую-либо операцию. Рассмотрим каждую из них по-отдельности.


Первая вкладка «Downloads«, на которой мы сможем наблюдать процесс скачивания файлов, а также выполнять определенные действия над скачанными и скачивающимися файлами.
Описывать колонки вкладки смысла нет. Все и так понятно. Части файлов и скачанные файлы хранятся в папках, которые Вы указывали в настройках программы.
Нажав правую кнопку мыши на любом из скачиваемых файлов — мы увидим контекстное меню, позволяющее управлять файлами и некоторыми функциями загрузки.
С закачанным файлом, а также файлом, находящимся в процессе закачки, можно делать следующие операции:
1. Воспроизвести — без комментариев)))
2. Priority (Speed)… — выставляем необходимую скорость закачки: Slower (низкая), Awerage (обычная), Faster (высокая).
3. Chunk strategy — выставляем размер качающихся блоков: Streaming (потоковая передача), Progressive (прогрессивный) и Random (случайный).
4. Rename file… — переименовать файл.
5. Set destination directory — выбираем папку по умолчанию.
6. Open file — открыть файл (если текстовый, либо еще какой).
7. Preview File — предпросмотр файла.
8. Open Folder — открыть папку, куда скачался файл.
9. Details — детали файла. При нажатии открывается следующее окно:

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

 
10. Clear Completed — очистить выполненные. Убираем записи о выполненных закачках с экрана.
11. Скопировать (вставить) ссылку RetroShare — следующие два пункта меню. Копируем либо вставляем ссылку.
12. Show cache transfers — ставим галочку для показа передачи кеша файла.
13. Download from collection file… — загрузка файла коллекции.
Вкладка «Uploads«, в которой отображаются файлы и прогресс-бар их выгрузки .
У меня пустой экран, ибо никто не качает))
 
 
Вкладка «Поиск«. В ней мы имеем возможность произвести поиск файлов по ключевым словам.
Сложного тут ничего нет. Соответственно расписывать не буду. Разберетесь сами.
 
Вкладка «Friends files» (файлы друзей). В этой вкладке отображаются расшаренные папки и файлы Ваших друзей, которые можно просматривать и скачивать себе. Эта вкладка — то, ради чего создавалась эта программа.
При нажатии правой кнопки мыши на файле либо папке мы видим контекстное меню как на картинке выше. При выборе пункта меню «Скачать» — выбранный файл переносится во вкладку «Downloads», где можно отслеживать процесс закачки.
 
Вкладка «My files» (мои файлы). Тут мы сможем добавить свои папки и файлы для общего использования. А также видим те данные, которые мы выложили.
Теперь будем добавлять свои файлы для своих друзей. Для этого нажимаем на пиктограмму желтой папки с зеленым крестиком. Видим вот такое вот окно:
 
В этом окне Вы увидите все папки, которые были расшарены и права доступа к ним. Эти папки можно редактировать и удалять. Мы же будем добавлять. Для этого нажимаем кнопку «Добавить«. Появится следующее окно:
 
Указываем «Local path» (локальный путь). Это местонахождение папки, которую Вы ходите добавить, на Вашем винте. Либо прописываем ручками путь до папки (если знаем наизусть), либо нажимаем кнопку «Выбор файла» и выбираем в стандартном окне необходимую папку. 
Затем в «Virtual Folder» (виртуальная папка) указываем название расшариваемой папки. Оно может быть любым.
Теперь выставим права доступа к этой папке. Это делается в блоке «Share Flags and groups«. Это три картинки. При выборе первой Ваши друзья, добавленные в какую-либо группу, будут иметь анонимный тоннель до данной директории. Видима для всех друзей в группе друзей. При выборе второй — папка будет не видна для всех остальных друзей, не входящих списки групп друзей. Третья картинка — папка видима и доступна для всех друзей, не вошедших в какую-либо группу.
Теперь о группах друзей. В правом углу окна отмечаем крестиком группы друзей, которым будет доступна и видна папка. Это группы: Друзья, Family (Семья), Co-workers (сослуживцы), Other Contacts (прочие контакты), Favorites (фавориты).
 
Теперь некоторые нюансы расшаривания. При расшаривании какой-либо папки программа сканирует каждый файл этой папки. Это может занять определенное время. Так что сразу же Ваши друзья не увидят этих папок. Процесс сканирования добавляется в нижней части программы, в котором видны следующие параметры: 
 
— количество кешированных файлов (3 из 9), 
— общий размер файла и процент кеширования, 
— название файла. 
 
Наблюдается некоторое зависание при множестве мелких файлов в папке. Имеется ввиду хеширование. До 25000 файлов кеширование еще проходит, а выше — зависает, только не определил на какой период. Терпежа не хватило. Еще одна фишка — разделы размером 500 ГБ, но с видеофайлами пережевывает нормально, а кучу мелких из раздела, размером до 100 ГБ ни в какую не хочет нормально вставлять. Так что учтите это при добавлении папок.
 
 
В этой статье мы разобрали действия по добавлению и скачиванию файлов друг у друга. В следующей статье будем разбираться со встроенными чатами.

Автор: Роман Дмитриевич

Паровоз из памперсов

Коляска и грузовик из подгузников

Что подарить новоиспеченным родителям в честь рождения их малыша? Хочется презентовать что-нибудь особенно милое и одновременно полезное. Коляска или грузовик из подгузников на первый взгляд кажется просто произведением искусства, которое под силу повторить только искусным мастерам. Однако, не боги же горшки обжигают! И для наших рукодельниц нет непосильных задач. Все окажется очень просто, если разобрать общий процесс на пошаговые этапы работы. А мы вам в этом поможем!

Машина из памперсов

Машина из памперсов

Читать

Хронический гастрит — лечение распространенной болезни

В наше время довольно сложно найти человека, не страдающего острой или хронической формой гастрита. Причины проявления данного заболевания различны. Это нарушение обменов веществ, вредные привычки (курение и выпивка), влияющие на работу желудочно-кишечного тракта, и работа на вредном производстве, а также при различных хронических болезнях других систем. Хроническая форма встречается, однако, чаще, да и ведет себя более коварно. Нужно отметить, что у больных-хроников довольно редко наблюдаются выраженные симптомы, что же касается болей, то они могут отсутствовать вообще. Здесь необходима серьезная диагностика с применением современного оборудования. В этом плане лучше всего обращаться в клиники Германии — их медицина давно уже занимается изучением данного вопроса. Указать пациенту на необходимость пройти диагностику такого характера должна хроническая отрыжка, а также вздутие живота и тошнота по утрам. Тревожным симптомом может быть также кисловатый привкус во рту. Диагностика данной болезни направлена прежде всего на установление ее причин. Если имеются сопутствующие хронические заболевания, к примеру, сердечная недостаточность, то на ряду с гастритом необходимо лечить пациента и по этой части. Для диагностики кроме общих анализов также применимо зондирование. По результатам исследования больному назначают диету и медикаментозное лечение. Стоит отметить, что пациенту совсем не обязательно все время находится в стационаре. Исключение составляют только сложные случаи, сопровождаемые болями. Необходим постоянный врачебный контроль также больным со сложными сопутствующими заболеваниями. Самое важное для эффективного лечения — соблюдать рекомендации по питанию, а также принимать пищу строго по режиму. Это наиболее эффективный способ наладить нормальную работу желудка. Подбор пищи врач производит исходя из формы заболевания. Терапия предполагает также применение препаратов группы В внутримышечно, так как у больных этой группы полезные вещества на самом деле усваиваются слабо. Лечение хронического гастрита предусматривает повторную диагностику после прохождения полного курса. Кроме того, больной в дальнейшем должен раз в полгода посещать врача и сдавать необходимые анализы, поскольку данная болезнь может давать рецидивы.