Очки своими руками

Как украсить солнечные очки

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

Украсить очки

Читать

Как правильно питаться, чтобы похудеть (без диет) женщине?

В современном обществе стал особо актуальным вопрос о правильном питании. Диеты остались в прошлом, уже собрано много доказанных фактов об их вреде и последствиях.

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

К тому же некоторые болезни можно вылечить, если начать правильно питаться.

Придерживаться правильного питания совсем несложно. Чуть ниже описаны пункты, как правильно составить рацион питания. Частое и дробное питание. Вам необходимо начать часто употреблять пищу, но маленькими порциями. Таким образом, у вас будет нормализована работа желудка и кишечника, а ещё вы не успеете почувствовать голод. Читать

Диета

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

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

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

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

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