среда, 12 марта 2014 г.

Заметки по Python

Заметка №1

Порой требуется, найти минимальные и максимальные значения списка вот такого списка:
>>> a[[5, 6], [7, 8], [-3, -10], [6, 12], [-4, 10]]
 Предположим, что это список координат точек, и требуется найти Xmax, Ymax, Xmin, Ymin. К сожалению, я не нашел более удобного способа сделать это в 1 строку, но вот способ в 2 строки.
>>> [X, Y] = zip(*a)>>> (Xmax, Ymax, Xmin, Ymin) = (max(X), max(Y), min(X), min(Y))
 Здесь я использовал распаковку списка, что позволит, нам посмотреть по отдельности максимальные и минимальные значения X и Y.
Теперь проверим правильность результатов:
>>> Xmax
7
>>> Ymax
12
>>> Xmin
-4
>>> Ymin
-10
Как видим результат соответствует желаемому.

вторник, 4 марта 2014 г.

unittest'ы в Python примеры использования на будущее

Не люблю долго описывать, то чем пользуюсь, ибо мне понятнее примеры, и поэтому зачастую пользуюсь старыми исходниками. Но так как были инциденты потери данных решил сохранить, важные разделы здесь.
Файл geometry.py
#coding=utf-8
# -*- coding: utf-8 -*-

from math import *
import sys

class point:
  def __init__(self, x, y):
    self.x = float(x)
    self.y = float(y)
    
  def __str__(self):
    return '({0}, {1})'.format(self.x, self.y)
  
  def __eq__(self, other):
    return True if ((self.x == other.x) and (self.y == other.y)) else False
  
  def __ne__(self, other):
    return True if ((self.x != other.x) or (self.y != other.y)) else False

Файл тестирования test_geometry.py:
#coding=utf-8
# -*- coding: utf-8 -*-

from geometry import *
import unittest

class testGeometry(unittest.TestCase):
  # Создадим 4 точки, которые будем использовать для тестирования
  def setUp(self):
    self.A = point(5, 6)
    self.B = point(6, 10)
    self.C = point(5.0, 6.0)
    self.D = point(-5, -6)

  # Тестируем создание точки
  def test_init(self):
    # Проверим правильность получения координат
    self.assertEqual((self.A.x, self.A.y), (float(5), float(6)), "Полученные значения не являются вещественными!!!")
    self.assertEqual((self.B.x, self.B.y), (float(6), float(10)), "Полученные значения не являются вещественными!!!")
    self.assertEqual((self.C.x, self.C.y), (float(5), float(6)), "Полученные значения не являются вещественными!!!")
    self.assertEqual((self.D.x, self.D.y), (float(-5), float(-6)), "Полученные значения не являются вещественными!!!")

  # Тестируем правильность формата печати
  def test_str(self):
    self.assertTrue(str(self.A) == "(5.0, 6.0)", "Неправильный вывод на экран!!!")
    self.assertTrue(str(self.B) == "(6.0, 10.0)", "Неправильный вывод на экран!!!")
    self.assertTrue(str(self.C) == "(5.0, 6.0)", "Неправильный вывод на экран!!!")
    self.assertTrue(str(self.D) == "(-5.0, -6.0)", "Неправильный вывод на экран!!!")

  # Тестируем операцию равенства
  def test_eq(self):
    self.assertTrue(self.A == self.C, "Данные две точки равны, а в результате тестирования, они оказались неравными!!!")
    self.assertFalse(self.A == self.B, "Данные две точки неравны, а в результате тестирования, они оказались равными!!!")
    self.assertFalse(self.A == self.D, "Данные две точки неравны, а в результате тестирования, они оказались равными!!!")
  
  def test_ne(self):
    self.assertFalse(self.A != self.C, "Данные две точки равны, а в результате тестирования, они оказались неравными!!!")
    self.assertTrue(self.A != self.B, "Данные две точки неравны, а в результате тестирования, они оказались равными!!!")
    self.assertTrue(self.A != self.D, "Данные две точки неравны, а в результате тестирования, они оказались равными!!!")

# Запускаем тестирование, если файл запущен без аргументов
if __name__ == '__main__':
    unittest.main()
Данных примеров лично мне хватит для большинства целей, если честно я даже понять не могу зачем нужны функции assertEqual и assertNotEqual, если есть  accertTrue и assertFalse, хотя на вкус и цвет фломастеров нет.
******************
Наткнулся на еще один интересный момент, если хочется проверить, отработку, какого-либо исключения, придется повыеживаться. Приведу пример.
Тестируемый код:
class segment:
  def __init__(self, point0, point1):
    if point0 == point1:
      raise(NameError("Это не отрезок, это точка!!!"))
    else:
      self.begin = point0
      self.end = point1
Тестирование:
# Проверим инициализацию отрезков
    try:
      self.AC = segment(self.A, self.C)
    except:
      self.assertTrue(True, "Не возникает ошибки при задании точки вместо отрезка!")
Далее, если наткнусь на интересные аспекты, дополню раздел.