<?xml version="1.0" encoding="utf-8" ?><rss version="2.0" xmlns:tt="http://teletype.in/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>@snakeblog</title><generator>teletype.in</generator><description><![CDATA[@snakeblog]]></description><image><url>https://teletype.in/files/92/924affcf-c715-466e-bf68-5c2bd9180b73.jpeg</url><title>@snakeblog</title><link>https://teletype.in/@snakeblog</link></image><link>https://teletype.in/@snakeblog?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=snakeblog</link><atom:link rel="self" type="application/rss+xml" href="https://teletype.in/rss/snakeblog?offset=0"></atom:link><atom:link rel="next" type="application/rss+xml" href="https://teletype.in/rss/snakeblog?offset=10"></atom:link><atom:link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></atom:link><pubDate>Fri, 17 Apr 2026 22:07:25 GMT</pubDate><lastBuildDate>Fri, 17 Apr 2026 22:07:25 GMT</lastBuildDate><item><guid isPermaLink="true">https://teletype.in/@snakeblog/rJZFxHmE7</guid><link>https://teletype.in/@snakeblog/rJZFxHmE7?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=snakeblog</link><comments>https://teletype.in/@snakeblog/rJZFxHmE7?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=snakeblog#comments</comments><dc:creator>snakeblog</dc:creator><title>Зачем нужны or и and в Python?</title><pubDate>Tue, 21 Aug 2018 14:37:36 GMT</pubDate><description><![CDATA[Сначала может показаться, что вопрос в заголовке, как минимум, странный и в чём-то даже глупый, но не всё так просто. Как известно, в языке Python есть побитовые операции &amp;(и), |(или), а также ^(строгое или). Однако есть ещё &quot;словесные&quot; братья and и or, которые используются в условиях. Однако зачем они нужны, если можно использовать &amp; и | вместо них и всё будет работать? На этот вопрос мы и попытаемся ответить в данной статье. Для начала лучше вникнем в суть происходящего:]]></description><content:encoded><![CDATA[
  <p>Сначала может показаться, что вопрос в заголовке, как минимум, странный и в чём-то даже глупый, но не всё так просто. Как известно, в языке Python есть побитовые операции &amp;(и), |(или), а также ^(строгое или). Однако есть ещё &quot;словесные&quot; братья and и or, которые используются в условиях. Однако зачем они нужны, если можно использовать &amp; и | вместо них и всё будет работать? На этот вопрос мы и попытаемся ответить в данной статье. Для начала лучше вникнем в суть происходящего:</p>
  <pre>print(True or False) # True
print(True | False)  # True
print(True and False)  # False
print(True &amp; False)  # False
</pre>
  <p>Как можно заметить, результат они выдают одинаковый. Так в чём же разница? Ответить можно одним словом - <em>оптимизация</em>. Наглядно это проиллюстрирует следующий пример:</p>
  <pre>def print_and_return(boolean):
	print(boolean)
	return boolean

print(&quot;Обычный |&quot;)
res1 = print_and_return(True) | print_and_return(False)
print(&quot;Словесный or&quot;)
res2 = print_and_return(True) or print_and_return(False)
</pre>
  <p>В первом случае, выведутся все 2 значения: результат первой функции, результат второй. А вот во втором случае, нас ждёт сюрприз: второго вызова функции не произойдёт. Почему? Потому что or умеет оптимизировать обработку условий: результат будет истинным независимо от второго условия: ведь первое истинно - так зачем нужно считать второе?</p>
  <p>То же самое с and:</p>
  <pre>  def print_and_return(boolean):
  	print(boolean)
  	return boolean
  
  print(&quot;Обычный &amp;&quot;)
  res1 = print_and_return(False) &amp; print_and_return(True)
  print(&quot;Словесный and&quot;)
  res2 = print_and_return(False) and print_and_return(True)
</pre>
  <p>Понятно, что условие ложно после вычисления первого выражения и and пропускает второе, сразу выдавая результат.</p>
  <p>Теперь должно стать ясно, что для условий &quot;выгоднее&quot; использовать or и and вместо | и &amp;, кроме тех случаев, когда необходимо выполнение всех частей условия. Например :</p>
  <pre>(a != 0) and (1 / a)
</pre>
  <p>никогда не выкинет ошибку деления на ноль. Думаю, таких применений можно придумать массу, но это занятие я оставляю вам, а сам расскажу про ещё одну интересную особенность or и and.</p>
  <p>Их можно использовать для inline выражений не только с bool, но и с любыми другими типами, которые приводятся к логическому. Рассмотрим следующие выражения:</p>
  <pre>print(3 or 10) # 3
print(&quot;&quot; or 5) # 5
print(&quot;&quot; and 20) # Выведет пустую строку
print(3 and 10) # 10
</pre>
  <p>То есть оператор or работает по принципу: если первое выражение - истина, то возвращаем его, иначе возвращаем второе.</p>
  <p>And работает по-другому: если первое - ложь, то возвращаем его, иначе вернём второе.</p>
  <p>Думаю, теперь вы разобрались, как работают эти 2 оператора и сможете эффективно использовать их особенности в своих программах.</p>
  <p>На этом всё.</p>
  <p>До новых встреч в группе <a href="https://vk.com/snakeblog" target="_blank">SnakeBlog</a></p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@snakeblog/S1evxIgrX</guid><link>https://teletype.in/@snakeblog/S1evxIgrX?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=snakeblog</link><comments>https://teletype.in/@snakeblog/S1evxIgrX?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=snakeblog#comments</comments><dc:creator>snakeblog</dc:creator><title>Разница между __str__ и __repr__</title><pubDate>Thu, 02 Aug 2018 09:35:20 GMT</pubDate><description><![CDATA[Во многих курсах по Python упоминают только один из этих двух &quot;магических&quot; методов и применяют их для одной цели: превращение объекта в строку. Считаю такой подход неправильным и поэтому расскажу, когда какой метод стоит применять.]]></description><content:encoded><![CDATA[
  <p>Во многих курсах по Python упоминают только один из этих двух &quot;магических&quot; методов и применяют их для одной цели: превращение объекта в строку. Считаю такой подход неправильным и поэтому расскажу, когда какой метод стоит применять.</p>
  <p>Примером для дальнейшего описания послужит простенький класс точки на плоскости:</p>
  <pre>class Point:                                   
  def __init__(self, x, y):                          
    self.x = x                                
    self.y = y 
</pre>
  <p>Давайте, для начала, определим метод __str__ у нашего класса и посмотрим, что выйдет</p>
  <pre>class Point:                                   
  def __init__(self, x, y):                          
    self.x = x                                
    self.y = y                                
                                         
  def __str__(self, x, y):                           
    return &quot;Point, x={}, y={}&quot;.format(x, y)

point = Point(1, 2)
print(point) 
</pre>
  <p>Как мы и ожидаем увидеть, вывод будет следующим:</p>
  <pre>Point, x=1, y=2
</pre>
  <p>Загвоздка в том, что если мы переименуем __str__ в __repr__, то в выводе изменится... ровно ничего. А теперь давайте определим и тот и другой, но немного по-разному.</p>
  <pre>class Point:                                   
  def __init__(self, x, y):                          
    self.x = x                                
    self.y = y                                
                                         
  def __repr__(self):                             
    return &quot;repr: Point, x={}, y={}&quot;.format(self.x, self.y)         
                                         
  def __str__(self):                              
    return &quot;str: Point, x={}, y={}&quot;.format(self.x, self.y)          
                                         
point = Point(5, 6)                               
print(point) 
</pre>
  <p>Вывод будет следующим:</p>
  <pre>str: Point, x=5, y=6
</pre>
  <p>Значит, при превращении объекта в строку, преимущество имеет __str__, да и его название говорит о том, что это и есть его назначение. Но зачем тогда нужен точно такой же __repr__? Суть в том, что не такой же. Откройте интерпретатор и вставьте туда наш класс. А теперь введите</p>
  <pre>point = Point(1, 2)
point
</pre>
  <p>Выводом послужит следующая строка:</p>
  <pre>repr: Point, x=1, y=2
</pre>
  <p>То есть для того, чтобы выводить объект в интерпретаторе, преимущество имеет repr.</p>
  <p>Вывод: используйте __str__ для превращения объекта в строку, а __repr__, когда хотите получать какую-то информацию в интерпретаторе при дебаге. Да, они взаимозаменяемы, но созданы они для разных целей.</p>
  <p>Тем временем наше маленькое расследование подошло к концу.</p>
  <p>Буду рад, если вы подпишетесь на мою группу <a href="https://vk.com/snakeblog" target="_blank">SnakeBlog</a></p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@snakeblog/Skc4E26Em</guid><link>https://teletype.in/@snakeblog/Skc4E26Em?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=snakeblog</link><comments>https://teletype.in/@snakeblog/Skc4E26Em?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=snakeblog#comments</comments><dc:creator>snakeblog</dc:creator><title>Python: ссылки или значения?</title><pubDate>Tue, 31 Jul 2018 10:04:34 GMT</pubDate><media:content medium="image" url="https://teletype.in/files/fc/fcd8945c-782e-47e6-98af-54a80d829e97.png"></media:content><description><![CDATA[<img src="https://i.ytimg.com/vi/NVzUGZxeNH4/maxresdefault.jpg"></img>Как вы думаете, что происходит, когда вы пишете следующее выражение?]]></description><content:encoded><![CDATA[
  <figure class="m_column">
    <img src="https://i.ytimg.com/vi/NVzUGZxeNH4/maxresdefault.jpg" width="1280" />
  </figure>
  <p>Как вы думаете, что происходит, когда вы пишете следующее выражение?</p>
  <pre>a = b
</pre>
  <p>Логичным, однако не совсем корректным ответом, будет &quot;переменной a присваивается значение b&quot;. Простой пример:</p>
  <pre>first = [1, 2, 3]
second = first
second[0] = 5
# first = [5, 2, 3]
</pre>
  <p>Если бы second просто присваивалось значение first, то при изменении second first не менялась бы. Однако это произошло. Cуть в том, что в python все объекты передаются по ссылке(а это объекты класса list). То есть для python всё равно, что вы напишете - first или second - они указывают на одну область в памяти и изменения, сделанные в значении одной переменной, отобразятся и во второй. Однако надо понимать разницу между <em>изменением</em> и <em>присвоением</em> ей нового значения:</p>
  <pre>first = [1, 2, 3]
second = first
second = [2, 3, 4]
# first не изменился
</pre>
  <p>После присвоения second значения [2, 3, 4] эта переменная теперь указывает на новую область памяти и уже никак не связана с first.</p>
  <p>Абсолютно тот же механизм использует передача аргументов в функцию:</p>
  <pre>def change_value(value):
    value[0] = 10
    value = [3, 4, 5]

a = [1, 2, 3]
change_value(a)
# a = [10, 2, 3]
</pre>
  <p>Первая строчка в функции изменяет значение в памяти, а вторая создаёт ссылку на новую область памяти, а значит связь value с a теряется.</p>
  <p>Понимание этого механизма может облегчить вам жизнь при работе с данными в Python.</p>
  <p>Например может показаться, что следующий код создаёт двумерный список 3 на 3, заполненный нулями</p>
  <pre>a = [[0] * 3] * 3  # a = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
</pre>
  <p>Однако это не совсем тот список, который мы ожидаем увидеть: список [0, 0, 0] передаётся по ссылке, а значит все три вложенных списка указывают на одну область памяти.</p>
  <pre>a[0][0] = 1  # [[1, 0, 0], [1, 0, 0], [1, 0, 0]]
</pre>
  <p>Нетрудно заметить, что изменились все 3 списка, то есть толку от них мало. &quot;Правильным&quot; созданием такого списка было бы</p>
  <pre>a = [[0] * 3 for _ in range(3)]
</pre>
  <p>В этом выражении, каждый новый элемент - новая область в памяти, а значит вложенные списки независимы:</p>
  <pre>a[0][0] = 1  # [[1, 0, 0], [0, 0, 0], [0, 0, 0]]
</pre>
  <p>Надеюсь, теперь вы разобрались в этой теме и не будете совершать ошибок, как в примере с массивом.</p>
  <p>Подписывайтесь на группу <a href="https://vk.com/snakeblog" target="_blank">SnakeBlog</a></p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@snakeblog/ByI5SQ54X</guid><link>https://teletype.in/@snakeblog/ByI5SQ54X?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=snakeblog</link><comments>https://teletype.in/@snakeblog/ByI5SQ54X?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=snakeblog#comments</comments><dc:creator>snakeblog</dc:creator><title>Тестируем код в Python: unittest</title><pubDate>Sat, 28 Jul 2018 17:19:09 GMT</pubDate><description><![CDATA[Вспомните, когда вы в последний раз писали программу и она запускалась с первого раза, и в ней потом не было найдено багов. Тоже вспомнили &quot;Hello world!&quot;?;) Написание кода, а особенно длинного, требует огромной внимательности, однако даже если вы ей обладаете, то не факт, что в вашем коде не будет проблем. Бывает так, что о них вы узнаёте через продолжительное время, в самый неподходящий момент. Так как же предупредить эти самые проблемы? Очевидно, надо тестировать свою программу. Однако как? Не вручную же вбивать много разных данных в функции и смотреть, тот ли результат. Постойте, мы же с вами написали какую-то программу, а что нам мешает написать другую программу, которая будет тестировать первую? Специально для таких программ...]]></description><content:encoded><![CDATA[
  <p>Вспомните, когда вы в последний раз писали программу и она запускалась с первого раза, и в ней потом не было найдено багов. Тоже вспомнили &quot;Hello world!&quot;?;) Написание кода, а особенно длинного, требует огромной внимательности, однако даже если вы ей обладаете, то не факт, что в вашем коде не будет проблем. Бывает так, что о них вы узнаёте через продолжительное время, в самый неподходящий момент. Так как же предупредить эти самые проблемы? Очевидно, надо тестировать свою программу. Однако как? Не вручную же вбивать много разных данных в функции и смотреть, тот ли результат. Постойте, мы же с вами написали какую-то программу, а что нам мешает написать другую программу, которая будет тестировать первую? Специально для таких программ в стандартной библиотеке python есть модуль unittest.</p>
  <blockquote>Код с подсветкой можете найти на Pastebin:</blockquote>
  <blockquote>Файл с функцией: <a href="https://pastebin.com/NH5FmLSc" target="_blank">https://pastebin.com/NH5FmLSc</a></blockquote>
  <blockquote>Файл с тестами: <a href="https://pastebin.com/BtqXuNiK" target="_blank">https://pastebin.com/BtqXuNiK</a></blockquote>
  <p>Давайте напишем функцию для получения чисел Фибоначчи в файле, который назовём <code>fibonacci.py</code></p>
  <pre>def get_fibonacci_numbers(amount):                        
  if amount == 1:                               
    return [1]                                
  result = [1, 1]                               
  for i in range(amount-2):                          
    result.append(result[-1] + result[-2])                  
  return result
</pre>
  <p>Теперь напишем программу, которая будет тестировать эту функцию. Для этого в модуле unittest есть класс TestCase, от которого можно наследоваться и создавать тестирующей класс. У объекта этого класса есть специальные методы вида assert&lt;что-то ещё&gt;, которые сравнивают разные значения с ожидаемыми. Самым распространённым является метод assertEqual, который сравнивает 2 значения и, в случае различия, выдаёт ошибку. Давайте напишем самый простой тест для одного числа в файле <code>fibtest.py</code></p>
  <pre>from unittest import TestCase                          
from fibonacci import get_fibonacci_numbers                   
                                         
                                         
class FibonacciTest(TestCase):                        
  def test_single(self):                            
    self.assertEqual(1, get_fibonacci_numbers(1)[0]) 
</pre>
  <p>Мы создаём у этого класса тестирующий метод, название которого обязательно должно начинаться со слова test(требование программы-тестера). Давайте напишем ещё один тест посложнее, который будет проверять всю последовательность на каком-нибудь числе</p>
  <pre>from unittest import TestCase                          
from fibonacci import get_fibonacci_numbers                   
                                         
                                         
class FibonacciTest(TestCase):                          
  def test_single(self):                            
    self.assertEqual(1, get_fibonacci_numbers(1)[0])             
                                         
  def test_big_number(self):                          
    big_number = 1337                            
    sequence = get_fibonacci_numbers(big_number)               
    self.assertEqual(1, sequence[0])                     
    self.assertEqual(1, sequence[1])                     
    for i in range(2, big_number):                      
      self.assertEqual(sequence[i-1] + sequence[i-2], sequence[i])  
</pre>
  <p>Тесты есть, осталось их запустить. Для этого надо выполнить команду test из модуля unittest на нашем файле:</p>
  <pre>python -m unittest test fibtest.py
</pre>
  <p>Вывод у команды будет следующего вида:</p>
  <pre>----------------------------------------------------------------------
Ran 2 tests in 0.003s

OK
</pre>
  <p>Статус OK говорит, что все тесты пройдены успешно. Если бы были ошибки, то там была бы информация о них. Вот так вот можно стандартными средствами тестировать программы.</p>
  <p>Надеюсь, статья была вам полезной.</p>
  <p>Буду рад видеть вас в группе <a href="https://vk.com/snakeblog" target="_blank">SnakeBlog</a></p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@snakeblog/rJnA9jwEX</guid><link>https://teletype.in/@snakeblog/rJnA9jwEX?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=snakeblog</link><comments>https://teletype.in/@snakeblog/rJnA9jwEX?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=snakeblog#comments</comments><dc:creator>snakeblog</dc:creator><title>Получаем число с Random.org API на Python</title><pubDate>Thu, 26 Jul 2018 20:10:59 GMT</pubDate><description><![CDATA[У многих веб-сервисов есть свой HTTP API - интерфейс, позволяющий обмениваться с их серверами данными. В этой статье разберёмся, как делать запросы из Python без сторонних библиотек. Рассматривать мы это будем на примере небезызвестного Random.org - теперь никто нас не упрекнёт, что рандом в нашей программе &quot;нечестный&quot;)]]></description><content:encoded><![CDATA[
  <p>У многих веб-сервисов есть свой HTTP API - интерфейс, позволяющий обмениваться с их серверами данными. В этой статье разберёмся, как делать запросы из Python без сторонних библиотек. Рассматривать мы это будем на примере небезызвестного Random.org - теперь никто нас не упрекнёт, что рандом в нашей программе &quot;нечестный&quot;)</p>
  <p>Необходимая информация об API представлена по ссылке <a href="https://api.random.org/json-rpc/1/" target="_blank">api.random.org</a></p>
  <p>Вот на <a href="https://api.random.org/api-keys/beta" target="_blank">этой странице</a> вы сможете получить токен для API - просто введите свой email и он придёт в письме.</p>
  <p>Мы будем пользоваться самым базовым API методом - <a href="https://api.random.org/json-rpc/1/basic" target="_blank">generateIntegers</a>, который возвращает случайные числа от min до max.</p>
  <blockquote>Полный код с подсветкой можете найти на <a href="https://pastebin.com/1Y3F76HK" target="_blank">Pastebin</a></blockquote>
  <p>Для начала, импортируем всё необходимое. А нужно нам немного: HTTPSConnection из http.client для того, чтобы отсылать запросы; dumps и loads из json чтобы кодировать и декодировать данные в JSON, который используется этим API.</p>
  <pre>from http.client import HTTPSConnection                     
from json import dumps, loads                          
                                         
API_TOKEN = &#x27;xxx&#x27;# Ваш токен
</pre>
  <p>Теперь давайте создадим словарь с данными для запроса и заголовками. Эти 2 словаря мы запакуем в JSON: теперь они готовы для отправки на сервер.</p>
  <pre>&quot;&quot;&quot;
Больше о формате запроса 
https://api.random.org/json-rpc/1/introduction
&quot;&quot;&quot;
request_data = {  # Тело запроса                      
  &#x27;jsonrpc&#x27;: &#x27;2.0&#x27;,                              
  &#x27;method&#x27;: &#x27;generateIntegers&#x27;,                        
  &#x27;params&#x27;: {                                  
    &#x27;apiKey&#x27;: API_TOKEN,                           
    &#x27;min&#x27;: 1,  # Нижняя граница рандома                       
    &#x27;max&#x27;: 100,  # Верхняя граница        
    &#x27;n&#x27;: 1,  # Количество запрашиваемых чисел          
  },                                      
  &#x27;id&#x27;: 1,                                   
}                                        
encoded_data = dumps(request_data)                        
                                         
headers = {                                
  &#x27;Content-Type&#x27;: &#x27;application/json-rpc&#x27;,  # Тип запроса              
}                                        
encoded_headers = dumps(headers)  
</pre>
  <p>Теперь непосредственно к обмену данными. Установим соединение и отправим данные:</p>
  <pre>connection = HTTPSConnection(&#x27;api.random.org&#x27;)                  
connection.request(&#x27;GET&#x27;, &#x27;/json-rpc/1/invoke&#x27;, encoded_data, headers)  
</pre>
  <p>Получим ответ и распакуем его из JSON:</p>
  <pre>response = connection.getresponse()                       
response_data = loads(response.read().decode()) 
</pre>
  <p>Если запрос прошёл успешно, то в response_data[&#x27;result&#x27;][&#x27;random&#x27;][&#x27;data&#x27;] будет лежать массив запрошенных чисел. Запрашивали мы одно число, его и выведем на экран.</p>
  <pre>print(response_data[&#x27;result&#x27;][&#x27;random&#x27;][&#x27;data&#x27;][0])  
</pre>
  <p>Вот так вот просто можно обмениваться данными с любым HTTP API, просто надо внимательно читать описания методов и формата, который требуется.</p>
  <p>Жду вас в группе <a href="https://vk.com/snakeblog" target="_blank">SnakeBlog</a></p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@snakeblog/rJt5hKEVm</guid><link>https://teletype.in/@snakeblog/rJt5hKEVm?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=snakeblog</link><comments>https://teletype.in/@snakeblog/rJt5hKEVm?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=snakeblog#comments</comments><dc:creator>snakeblog</dc:creator><title>lambda, map и filter в Python</title><pubDate>Tue, 24 Jul 2018 11:25:04 GMT</pubDate><description><![CDATA[<img src="https://imageog.flaticon.com/icons/png/512/43/43146.png?size=1200x630f&amp;pad=10,10,10,10&amp;ext=png&amp;bg=FFFFFFFF"></img>Разберёмся с этими тремя элементами Python, которые очень часто применяются вместе, потому и были объединены мной в одну статью.]]></description><content:encoded><![CDATA[
  <p>Разберёмся с этими тремя элементами Python, которые очень часто применяются вместе, потому и были объединены мной в одну статью.</p>
  <figure class="m_column">
    <img src="https://imageog.flaticon.com/icons/png/512/43/43146.png?size=1200x630f&pad=10,10,10,10&ext=png&bg=FFFFFFFF" width="1200" />
  </figure>
  <p>Первой я хочу рассмотреть конструкцию <strong>lambda</strong>. Это способ определения анонимной функции(&quot;лямбды&quot;, как их ещё называют). Тут слово &quot;анонимный&quot; никак не связано с Роскомнадзором и сетью Tor, просто у таких функций нет имени. Постойте, а как к ним обращаться? А нам это и не нужно, мы хотим просто передать простенькую функцию как аргумент куда-нибудь и забыть про неё.</p>
  <p>Объявляются такие функции следующим образом:</p>
  <pre>lambda &lt;аргументы&gt;: &lt;выражение&gt;
</pre>
  <p>Например вот функция, которая возвращает куб данного числа:</p>
  <pre>lambda x: x**3
</pre>
  <p>Красиво, просто, пока непонятно зачем. Для примера обратимся к методу sort и сделаем сортировку по обратному значению(даже не спрашивайте зачем).</p>
  <pre>a = [1, -2, 4, 5, 228, -322]
a.sort(key=lambda x: 1/x)  # [-2, -322, 228, 5, 4, 1]
</pre>
  <p>Теперь перейдём к двум похожим, но разным функциям <strong>map</strong> и <strong>filter</strong>, в которые очень часто передают лямбда функции.</p>
  <p>map принимает 2 аргумента: функцию и массив, и возвращает список(на самом деле специальный map объект), в котором ко всем элементам массива применили нашу функцию. Так как с map объектом мы ничего интересного сделать не можем, то его мы превратим обратно в список.</p>
  <pre>a = [1, -2, 4, 5, 228, -322]
mapped = list(map(lambda x: x**2, a))  # Список квадратов чисел
</pre>
  <p>filter принимает всё те же 2 аргумента и возвращает filter объект(который опять же мы превратим в список), в котором остались только те элементы, на которых функция истинна. Например:</p>
  <pre>a = [1, -2, 4, 5, 228, -322]
filtered = list(filter(lambda x: x &lt; 10, a))  # Список чисел меньше 10
</pre>
  <p>Благодаря этим двум функциям и конструкции lambda можно сократить рутинный код до однострочника. Однако сильно увлекаться этим не стоит, а то рискуете сделать свою программу нечитаемой.</p>
  <p>Больше статей в группе <a href="https://vk.com/snakeblog" target="_blank">SnakeBlog</a></p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@snakeblog/rJidaa-Nm</guid><link>https://teletype.in/@snakeblog/rJidaa-Nm?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=snakeblog</link><comments>https://teletype.in/@snakeblog/rJidaa-Nm?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=snakeblog#comments</comments><dc:creator>snakeblog</dc:creator><title>Пишем веб-сервер на Flask</title><pubDate>Sun, 22 Jul 2018 09:25:07 GMT</pubDate><media:content medium="image" url="https://teletype.in/files/d5/d5e8b976-f2ee-4c00-a3db-73476fd8efd6.png"></media:content><description><![CDATA[<img src="https://cdn.scotch.io/scotchy-uploads/2016/12/6bOQ3QNDTISElwCsEL0f_getting-started-with-flask.jpg"></img>В наше время, мало таких приложений, которые обходятся без обмена данными со своим сервером. Давайте разберём на пальцах, что представляет из себя этот самый &quot;сервер&quot; и даже напишем серверную программу на фреймворке Flask.]]></description><content:encoded><![CDATA[
  <p>В наше время, мало таких приложений, которые обходятся без обмена данными со своим сервером. Давайте разберём на пальцах, что представляет из себя этот самый &quot;сервер&quot; и даже напишем серверную программу на фреймворке Flask.</p>
  <figure class="m_column">
    <img src="https://cdn.scotch.io/scotchy-uploads/2016/12/6bOQ3QNDTISElwCsEL0f_getting-started-with-flask.jpg" width="1200" />
  </figure>
  <h2>Немного теории</h2>
  <p>&quot;Общение&quot; с сервером представляет из себя цепочку <strong>запрос</strong>-<strong>ответ</strong>. Мы формируем запрос в специальном HTTP формате, потом отсылаем его на нужный адрес и получаем(или не получаем) ответ от сервера. У адреса есть 2 важные составляющие: <strong>домен</strong> и <strong>метод</strong>. Пример: <code>https://api.vk.com/method/messages.send</code></p>
  <p>Домен - https://api.vk.com - это то место в Сети, где располагается наш сервер. Всё, что обращается к нашему домену, будет обрабатываться нашим веб-сервером.</p>
  <p>Метод - /method/messages.send - это &quot;функция&quot; нашего сервера, которую мы хотим использовать.</p>
  <h2>Теперь к делу</h2>
  <blockquote>Замечание: я пишу команды в консоли в предположении, что ваш интерпретатор называется python , если он называется иначе, то соответственно заменяйте это слово своим названием</blockquote>
  <p>Нам понадобится Python и библиотека flask. Её можно установить следующим образом:</p>
  <pre>python -m pip install flask
</pre>
  <p>Теперь создадим файл <em>app.py </em>, в котором и будет наша программа.</p>
  <p>Для начала импортируем в нём модуль Flask из библиотеки flask и создадим объект нашего приложения:</p>
  <pre>from flask import Flask

app = Flask(&#x27;hello_world&#x27;)
</pre>
  <p>Теперь давайте допишем функцию, которая будет отвечать &quot;Hello world!&quot; на запрос к методу /hello_world</p>
  <pre>from flask import Flask

app = Flask(&#x27;hello_world&#x27;)


@app.route(&#x27;/hello_world&#x27;)
def hello():
	return &quot;Hello world!&quot;
</pre>
  <p>Вы можете мне не поверить, но это всё. Теперь давайте запустим нашу программу у себя на компьютере(используя его как сервер).</p>
  <pre>python -m flask run --port 8000
</pre>
  <p>Зайдите теперь в браузер по адресу <a href="http://127.0.0.1:8000/hello_world" target="_blank">http://127.0.0.1:8000/hello_world</a> и увидите ту самую строчку. 127.0.0.1 - специальный домен, который отображает наш с вами компьютер, а 8000 - порт нашего подключения.</p>
  <p>Эта статья была написана чтобы показать, что веб-сервер - не что-то &quot;волшебное&quot; и очень сложное, а самая обычная программа, к которой мы обращаемся специальным образом. Возможно вы заинтересуетесь темой, тогда вам стоит начать изучать Backend разработку.</p>
  <p>До встреч в группе <a href="https://vk.com/snakeblog" target="_blank">SnakeBlog</a></p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@snakeblog/rJ5kiJA7m</guid><link>https://teletype.in/@snakeblog/rJ5kiJA7m?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=snakeblog</link><comments>https://teletype.in/@snakeblog/rJ5kiJA7m?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=snakeblog#comments</comments><dc:creator>snakeblog</dc:creator><title>Форматирование строк в Python</title><pubDate>Thu, 19 Jul 2018 10:42:31 GMT</pubDate><description><![CDATA[Очень часто, вывод программы представляет из себя некую строку, в которой содержатся данные из вашей программы. Здесь мы рассмотрим способы форматирования строк, то есть подстановки ваших переменных в строки в языке программирования Python.]]></description><content:encoded><![CDATA[
  <p>Очень часто, вывод программы представляет из себя некую строку, в которой содержатся данные из вашей программы. Здесь мы рассмотрим способы форматирования строк, то есть подстановки ваших переменных в строки в языке программирования Python.</p>
  <h2>C-форматирование</h2>
  <p>Наверное все, кто программировал на языке C или C++ знают о такой функции, как printf, которая выводит строку, подставляя туда переменные в нужном формате. Чтобы понять о чём я говорю, рассмотрим примеры:</p>
  <pre>printf(&quot;Целое число %d&quot;, 5);
printf(&quot;Дробное число %f&quot;, 2.1);
printf(&quot;Строка %s&quot;, &quot;какая-то строка&quot;);
</pre>
  <p>Для каждого типа данных есть собственная последовательность + есть всякие модификаторы. Побольше о них можно узнать например <a href="https://ru.wikipedia.org/wiki/Printf" target="_blank">здесь</a>. Для того, чтобы таким образом отформатировать строку, используется следующий синтаксис:</p>
  <p>&lt;строка с параметрами&gt;%(&lt;переменные для подстановки&gt;)</p>
  <p>Например:</p>
  <pre>print(&quot;%d %f %s&quot;%(1, 2.5, &quot;string&quot;)) # Вывод: 1 2.500000 string
</pre>
  <p>Можно записать строку в переменную и потом подставить параметры:</p>
  <pre>pattern = &quot;%d %f %s&quot;
print(pattern%(2, 3.3, &quot;abc&quot;))  # Вывод: 2 3.300000 abc
</pre>
  <p>Этот способ хорош тем, что можно очень гибко настраивать параметры вывода при помощи модификаторов. Например вот так можно вывести число с точностью 3 знака после запятой:</p>
  <pre>print(&quot;%.3f&quot;%(2.12345))  
</pre>
  <h2>Метод format</h2>
  <p>У строк есть специальный метод format, который выполняет ту же задачу, но немного элегантнее. Он ищет в строке фигурные скобки и подставляет вместо них аргумент. В фигурных скобках можно указать номер аргумента(нумеруются с 0), а можно ничего не указывать и format подставит аргументы по порядку.</p>
  <p>Пример:</p>
  <pre>pattern = &quot;{}:{}:{}&quot;
print(pattern.format(1, 2, 3))  # 1 2 3
another_pattern = &quot;{2}:{1}:{0}&quot;
print(another_pattern.format(1, 2, 3))  # 3 2 1
</pre>
  <p>Этот способ хорош тем, что ему не важен тип аргумента, лишь их порядок.</p>
  <h2>f-строки</h2>
  <p>С версии 3.6 существует ещё один способ форматирования. Он очень удобен, однако не без недостатков: подставляет аргументы в строку сразу при объявлении. Рассмотрим пример:</p>
  <pre>a = 3
b = 2
print(f&quot;{a*b} {a+b} {3*3}&quot;)  # 6 5 9
</pre>
  <p>Перед строкой ставится префикс f, который обозначает f-строку.Внутри могут быть любые выражения в фигурных скобках: они вычисляются сразу же.</p>
  <p>Какой из этих способов использовать зависит от вас и от ситуации. В любом случае, один из них точно подойдёт. А эта статья подошла к концу, до встреч в группе <a href="https://vk.com/snakeblog" target="_blank">SnakeBlog</a>.</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@snakeblog/r1K3mtnmm</guid><link>https://teletype.in/@snakeblog/r1K3mtnmm?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=snakeblog</link><comments>https://teletype.in/@snakeblog/r1K3mtnmm?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=snakeblog#comments</comments><dc:creator>snakeblog</dc:creator><title>Декораторы</title><pubDate>Wed, 18 Jul 2018 09:26:52 GMT</pubDate><media:content medium="image" url="https://teletype.in/files/d0/d0f78feb-53fc-4245-bfc4-b84d6bdd45bd.png"></media:content><description><![CDATA[<img src="http://udc-razvitie.com/wp-content/uploads/2015/09/%D0%B4%D0%B8.jpg"></img>Давайте предположим, что у нас есть несколько функций, которые что-то выводят, скажем, логи нашей программы.]]></description><content:encoded><![CDATA[
  <figure class="m_custom">
    <img src="http://udc-razvitie.com/wp-content/uploads/2015/09/%D0%B4%D0%B8.jpg" width="720" />
  </figure>
  <p>Давайте предположим, что у нас есть несколько функций, которые что-то выводят, скажем, логи нашей программы.</p>
  <pre>from datetime import datetime                          
                                         
                                         
def date_logger(): # Выводит текущую дату и время                
  print(datetime.now().strftime(&quot;%Y-%m-%d %H:%M:%S&quot;))             
                                         
                                         
def connection_logger(connected): # Выводит статус соединения          
  if connected:                                
    print(&quot;Connected&quot;)                            
  else:                                    
    print(&quot;Not connected&quot;)
</pre>
  <p>Мы где-то используем их в коде. Всё хорошо, но тут заказчик говорит, что перед каждым логом надо выводить &quot;Log:&quot;. Зачем? А кто знает, надо и надо.</p>
  <p>Конечно можно в начале каждой функции выводить это слово. Однако функций может быть много, а завтра заказчик захочет выводить другое слово. Хочется чего-то более универсального. Тут кто-то предложит глобальную переменную, но это не всегда лучший способ. Сегодня я вам расскажу про другой метод решения этой проблемы и имя ему декоратор.</p>
  <p>Давайте рассмотрим следующую функцию - декоратор, которая &quot;оборачивает&quot; другую функцию:</p>
  <pre>def log_decorator(function):
    def wrapped(*args):  # Вложенная функция-обёртка
        print(&quot;Log:&quot;, end=&#x27; &#x27;)
        function(*args)  # Вызываем нашу функцию с параметрами
    return wrapped 
</pre>
  <p>А теперь давайте заменим наши функции на обёрнутые этой.</p>
  <pre>date_logger = log_decorator(date_logger)
connection_logger = log_decorator(connection_logger)
</pre>
  <p>Действительно, теперь, при вызове будет выводиться &quot;Log: &quot;. Казалось бы, проблема решена. Но как-то не эстетично это выглядит. Поэтому в питоне есть специальный синтаксис для декорации:</p>
  <pre>@&lt;имя декоратора&gt;
def &lt;декорируемая функция&gt;(...):
	...
</pre>
  <p>То есть наши функции будут выглядеть следующим образом:</p>
  <pre>@log_decorator
def date_logger():  # Выводит текущую дату и время
	print(datetime.now().strftime(&quot;%Y-%m-%d %H:%M:%S&quot;))

@log_decorator
def connection_logger(connected): # Выводит статус соединения
	if connected:
		print(&quot;Connected&quot;)
	else:
		print(&quot;Not connected&quot;)
</pre>
  <p>Отлично, но что, если я хочу сделать декоратор с параметром? Здесь надо создать функцию с параметром, которая будет возвращать декоратор. Например так:</p>
  <pre>def word_log_decorator(word):
   def decorator(function):
       def wrapped(*args):
           print(word, end=&#x27;: &#x27;)
           function(*args)
       return wrapped
   return decorator
</pre>
  <p>Вызывать эту функцию мы будем при декорации следующим образом:</p>
  <pre>@word_log_decorator(&quot;Log&quot;)
def date_logger():  # Выводит текущую дату и время
    print(datetime.now().strftime(&quot;%Y-%m-%d %H:%M:%S&quot;))
</pre>
  <p>При помощи декораторов ваш код может стать более понятным, однако стоит различать, когда имеет смысл поменять саму функцию, а когда написать декоратор.</p>
  <p>Надеюсь, статья была вам полезной.</p>
  <p>Надеюсь увидеть вас в моей группе <a href="https://vk.com/snakeblog" target="_blank">SnakeBlog</a></p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@snakeblog/S1a9As_7Q</guid><link>https://teletype.in/@snakeblog/S1a9As_7Q?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=snakeblog</link><comments>https://teletype.in/@snakeblog/S1a9As_7Q?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=snakeblog#comments</comments><dc:creator>snakeblog</dc:creator><title>Генераторы</title><pubDate>Sun, 15 Jul 2018 11:45:07 GMT</pubDate><description><![CDATA[В этой статье я хочу рассказать о такой интересной особенности Python, которой нет во многих других языках, и которая носит название &quot;генераторы&quot;. Что, если я вам скажу, что вот такой код, при некоторых условиях, может выполняться до бесконечности?]]></description><content:encoded><![CDATA[
  <p>В этой статье я хочу рассказать о такой интересной особенности Python, которой нет во многих других языках, и которая носит название &quot;генераторы&quot;. Что, если я вам скажу, что вот такой код, при некоторых условиях, может выполняться до бесконечности?</p>
  <pre>for number in fibonacci_numbers:
	print(number)
</pre>
  <p>Наверное у вас появится закономерный вопрос: &quot;Как же так, ведь fibonacci_numbers должен быть ограничен по длине и когда-нибудь цикл закончится?&quot;. И вы были бы правы, будь эта переменная списком или чем-то подобным, но в примере выше, она - генератор и не имеет конца. Заинтересовались? Тогда давайте разберёмся, как работает эта сущность в Python.</p>
  <p>Для начала, поймём, как работает цикл <strong>for</strong>. На самом деле, всё, что он делает:</p>
  <ol>
    <li>Вызывает на нашем объекте &quot;магический&quot; метод<strong> __iter__</strong> и получает специальный объект-итератор, у которого есть метод <strong>__next__</strong></li>
    <li>При каждой итерации, этот метод вызывается и значение переменной, указанной нами в цикле обновляется.</li>
    <li>Итерация прекращается, когда метод<strong> __next__</strong> вызывает исключение StopIteration.</li>
  </ol>
  <p>То есть, мы можем сделать генератор своими руками. Прикрепляю ссылку на Pastebin потому что там есть подсветка синтаксиса и копировать код оттуда проще.</p>
  <p><a href="https://pastebin.com/sFd0CT3a" target="_blank">Код на Pastebin</a></p>
  <pre>class FibonacciGenerator:                            
  &quot;&quot;&quot;                                     
  Класс, объект которого мы будем создавать                  
  &quot;&quot;&quot;                                     
  class FibonacciIterator:                           
    &quot;&quot;&quot;                                   
    Вспомогательный класс, который реализует метод __next__         
    Этот метод вызывается на каждой итерации for               
    &quot;&quot;&quot;                                   
    def __init__(self):                           
      &quot;&quot;&quot;                                 
      Начинаем нашу последовательность с двух единиц            
      &quot;&quot;&quot;                                 
      self.first_number = 1                        
      self.second_number = 1                        
      self.iterations = 0                         
                                         
    def __next__(self):                           
      self.iterations += 1                         
      if self.iterations &lt;= 2: # Первые 2 раза мы возвращаем единицу     
        return 1                             
      self.first_number, self.second_number = self.second_number, self.first_number + self.second_number
      return self.second_number                      
                                         
  def __iter__(self):                             
    return self.FibonacciIterator()                     
                                         
fib_gen = FibonacciGenerator()                          
for i in fib_gen:                                
  print(i)
</pre>
  <p>Если вы запустите у себя этот код, то увидите бесконечно выводящиеся числа Фибоначи. Теперь о том, как это работает: for, когда начинает свою работу, вызывает метод <strong>__iter__</strong> и получает объект класса FibonacciIterator. На нём, перед каждой итерацией, он запускает метод <strong>__next__</strong> и получает следующее число, которое записывается в переменную i. Согласитесь, выглядит не очень красиво.Наверное поэтому в Python существует специальный синтаксис, призванный упростить создание генераторов. Главным средством для этого, является ключевое слово <strong>yield</strong>. Это как <strong>return</strong>, но функция не заканчивается, а её состояние запоминается и при вызове <strong>__next__</strong> продолжается с того же места. Пример с числами Фибоначи:</p>
  <p><a href="https://pastebin.com/h920Ji4M" target="_blank">Код на Pastebin</a></p>
  <pre>def fibonacci_generator():                            
  &quot;&quot;&quot;                                     
  Эта функция возвращает специальный объект-генератор               
  &quot;&quot;&quot;                                     
  yield 1                                   
  yield 1                                   
  first, second = 1, 1                             
  while True:                                 
    first, second = second, first + second                  
    yield second                               
                                         
test_generator = fibonacci_generator()                      
for i in test_generator:                             
  print(i)
</pre>
  <p>Эта программа делает всё то же самое. test_generator - объект специального класса generator, который реализует то, что мы описали. Кроме <strong>yield</strong> есть ещё конструкция <strong>yield from</strong> &lt;collection&gt;, которая делает yield последовательно каждого элемента &lt;collection&gt;. Выглядит это так:</p>
  <pre>def yield_from_generator():
	yield from (1,2,3)
</pre>
  <p>Объект, созданный этой функцией вернёт 1, потом 2, потом 3.</p>
  <p>Бонус:</p>
  <p>У генераторов есть сокращённый синтаксис, как в list comprehensions, но вместо квадратных скобок надо поставить круглые. Например вот генератор квадратов чисел от 1 до 100:</p>
  <pre>(i**2 for i in range(1, 101))
</pre>
  <p>Генераторы - очень мощный инструмент, который может, при правильном применении, сильно упростить код. Используйте с умом и наслаждайтесь красотой и мощью Python!</p>
  <p>До новых встреч в группе <a href="https://vk.com/snakeblog" target="_blank">SnakeBlog</a></p>

]]></content:encoded></item></channel></rss>