среда, 27 апреля 2011 г.

Python. Пишем простенький сканер портов

Всем доброе время суток. Сегодня мы будем писать очень простенький сканер портов. Итак приступим.
# -*-coding: cp1251

#Импортируем модуль для работы с сокетами
import socket

#определяем хост, который мы будем сканировать
HOST = 'localhost'

# Создаем список портов, которые мы хотим просканирвать
ports = [21, 22, 23, 25, 38, 43, 80, 109, 110, 115, 118, 119, 143,
194, 220, 443, 540, 585, 591, 1112, 1433, 1443, 3128, 3197,
3306, 4000, 4333, 5100, 5432, 6669, 8000, 8080, 9014, 9200]
#Теперь в цикле перебераем все указаные порты
for port in ports:
    #Создаем новый сокет
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # Устанавливаем таймаут, чтоб скрипт не зависал если попал
    # на открытый порт
    sock.settimeout(1)
    try:
        # Пробуем подключится
        sock.connect((HOST, port))
    except:
        # Если возникло исключение -- порт закрыт
        print ("Port %s closed" % port)
        continue
    try:
        #Если порт открыт - пробуем прочитать с него порцию информации
        result = sock.recv(1024)
        # если что-то удалось прочитать, выводим это
        print ("Received: %s port: %s" %port,result)
    except:
        # Если ничего прочитать не удалось -- просто выводим
        # информацию что порт открыт
        print ("Порт %s открыт." % port)
# закрываем сокет.
sock.close()

понедельник, 11 апреля 2011 г.

Pygame. Загрузка изображений.

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

Итак, загрузка изображений в pygame неимоверно проста:
our_image = pygame.image.load( filename ).convert()

Единственный вопрос, который может возникнуть -- это на счет метода convert(). Документация гласит, что этот метод меняет формат пикселей изображения, благодаря чему оно будет рисоваться на экране гораздо быстрее. Для файлов, содержащих альфа-канал ( png например) нужно использовать convert_alpha()

Pygame. Использование мышки и клавиатуры.

В сегодняшнем примере мы рассмотрим принципы работы pygame с устройствами ввода, то есть мышкой и клавиатурой.

Чтоб считать состояние клавиатуры мы пробегаемся по событиям и смотрим не появилось ли событие KEYDOWN или KEYUP. Если они появились, то мы смотрим из этого события какие кнопки были нажаты и обновляем положения прямоугольничка на экране.

Чтобы узнать координаты мышки нужно вызвать метод pygame.mouse.get_pos(), который возвращает координаты курсора.

pygame_input.py:
import pygame

# Определяем несколько цветов
black    = (   0,   0,   0)
white    = ( 255, 255, 255)
green    = (   0, 255,   0)
red      = ( 255,   0,   0)

# Функция для очистки экрана
def draw_background(screen):
screen.fill(white)

# Функция для отрисовки нашего персонажа
def draw_item(screen, color, x, y):
pygame.draw.rect(screen, color, [0+x, 0+y, 30, 10], 0)
pygame.draw.circle(screen, black, [15+x, 5+y], 7, 0)

# Инициализируем pygame
pygame.init()

screen = pygame.display.set_mode([640, 480])

# Скорость в пикселях за кадр
x_speed = 0
y_speed = 0

# Текущие координаты
x_coord = 10
y_coord = 10

clock = pygame.time.Clock()

done=False
while done == False:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True # Если игрок закрыл окно -- прерываем цикл.

# Обрабатываем клавиатуру
# Если игрок нажал каку-нибудь кнопку -- начинаем движение
if event.type == pygame.KEYDOWN:
# Выясняем какая именно кнопка была нажата
if event.key == pygame.K_LEFT:
x_speed =-3
if event.key == pygame.K_RIGHT:
x_speed = 3
if event.key == pygame.K_UP:
y_speed = -3
if event.key == pygame.K_DOWN:
y_speed = 3

# Если кнопка была отпущена, то и движение надо прекратить
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
x_speed = 0
if event.key == pygame.K_RIGHT:
x_speed = 0
if event.key == pygame.K_UP:
y_speed = 0
if event.key == pygame.K_DOWN:
y_speed = 0

# Обрабатываем движение мышки
pos = pygame.mouse.get_pos()
mouse_x, mouse_y = pos[0], pos[1]

# Двигаем нашего игрока в соответствии
# нажатым кнопкам.
x_coord += x_speed;
y_coord += y_speed;

draw_background(screen)

# Рисуем двух игроков -- зеленый управляется клавиатурой,
# а красный -- мышкой
draw_item(screen, green, x_coord, y_coord)
draw_item(screen, red, mouse_x, mouse_y)

#Теперь выводим все что мы нарисовали из буффера на экран
pygame.display.flip()
clock.tick(60)
pygame.quit()

Pygame. Анимация звездного неба.

В этом примере я покажу как использовать массивы для анимации и слежения за несколькими объектами, в нашем случае -- звездами. Ну звездами их конечно можно назвать с натяжкой, но для vertical scroll shooter`а самое оно. Это отличный фон для какой-нибудь космической стрелялки.

animation_star.py:
import pygame
import random

# Инициализируем pygame
pygame.init()

black = [0, 0, 0]
white = [255, 255, 255]

# Задаем размеры окна
size = [400, 400]
screen = pygame.display.set_mode(size)

# Устанавливаем заголовок
pygame.display.set_caption("Star Animation")

# Создаем пустой массив
star_list = []

# Добавляем 50 звезд со случайными координатами
for i in range(50):
x = random.randrange(0, 400)
y = random.randrange(0, 400)
speed = random.randint(1,3)
star_list.append([x,y, speed])

clock = pygame.time.Clock()

# Повторяем цикл, пока пользователь не закроет окно
done = False
while done == False:

for event in pygame.event.get(): # Проходим по всем событиям
if event.type == pygame.QUIT: # Если пользователь закрыд окно
done = True # Помечаем что пора заканчивать

# Очищаем окно
screen.fill(black)

# Обрабатываем каждую звезду в списке
for star in star_list:
# Рисуем звезду
pygame.draw.circle(screen, white, star[0:2], 2)

# Смещаем звезду вниз
star[1] += star[2]

# Если звезда упала за низ окна
if star[1] > 400:
# Устанавливаем для нее новые случайные координаты (конечноже выше экрана)
star[0] = random.randrange(0,400)
star[1] = random.randrange(-50, -10)
# Выводим на экран все что нарисовали
pygame.display.flip()
clock.tick(20)

pygame.quit()

Pygame. Рисование простых фигур и текста.

В этом примере показывается как в pygame рисовать прямоугольники, линии, текст и другие простые формы.

sample_graphics_demo.py:
# Импорт библиотеки pygame
import pygame

# Инициализируем движок pygame
pygame.init()

# Определяем несколько цветов, которые мы будем
# использовать (RGB)
black = [0, 0, 0]
white = [255, 255, 255]
red = [255, 0, 0]
green = [0, 255, 0]
blue = [0, 0, 255]

pi = 3.141592653

# Устанавливаем размеры окна
size = [400, 500]
screen = pygame.display.set_mode(size)

# Устанавливаем заголовок окна
pygame.display.set_caption("Крутая игра")

# Цикл работает пока пользователь не закроет окно
done = False
clock = pygame.time.Clock()

while done == False:
# Следующяя строка ограничивает наш цикл 10 кадрами в секунду.
# Если этого не сделать, то игра будет использовать
# максимальное колличество ресурсов.
clock.tick(10)

for event in pygame.event.get(): # Проходимся по событиям
if event.type == pygame.QUIT: # Если пользователь закрыл окно
done = True # Сигнализируем что цикл пора завершать

# Все рислвание происходит после нашего for-цикла,
# но внутри главного цикла ( while done==False ).

# Очищаем экран
screen.fill(white)

# Рисуем на экране зеленую линию из левого верхнего угла (0, 0)
# в точку (100, 100) шириной 5 пикселей
pygame.draw.line(screen, green, [0,0], [100,100], 5)

# Рисуем несколько красных линий из точки (0,10) в точку (100, 110)
# используя цикл
y_offset = 0
while y_offset < 100 :
pygame.draw.line(screen, red, [0, 10+y_offset], [100, 110+y_offset], 5)
y_offset += 10

# Выбираем шрифт, который мы будем использовать.
# Стандартный шрифт, 25 точек.
font = pygame.font.Font(None, 25)

# Рисуем текст. "True" означает использовать сглаживание
# Black -- цвет текста. Следующая строка создает образ текста
# но не рисует его на экране.
text = font.render("My text", True, black)

#Рисуем изображение текста на экран в точке (250, 250)
screen.blit(text, [250, 250] )

# Рисуем прямоугольник
pygame.draw.rect(screen, black, [20,20, 250,100], 2)

# Рисуем эллипс. При рисовании эллипса используется
# прямоугольник, в который этот эллипс вписывается
pygame.draw.ellipse(screen, black, [20,20, 250, 100], 2)

# Рисуем дугу как часть эллипса. Координаты угла
# задаются в радианах
pygame.draw.arc(screen,black,[20,220,250,200], 0, pi/2, 2)
pygame.draw.arc(screen,green,[20,220,250,200], pi/2, pi, 2)
pygame.draw.arc(screen,blue, [20,220,250,200], pi,3*pi/2, 2)
pygame.draw.arc(screen,red, [20,220,250,200],3*pi/2, 2*pi, 2)

# Эта строчка рисует треугольник используя функцию "polygon"
pygame.draw.polygon(screen,black,[[100,100],[0,200],[200,200]],5)

# Теперь обновляем окно чтобы все наше рисование
# отбразилось на экране. Это надо делать ПОСЛЕ ТОГО
# как все нарисовали
pygame.display.flip()

pygame.quit()

Pygame. Каркас приложения.

Это приложение создает пустое pygame окно. Ничего особенного, но его можно использовать как каркас, когда создаете новое приложение.

pygame_base_template.py:
import pygame


#Определяем несколько цветов
black = (0, 0, 0)
white = (255, 255, 255)
green = (0, 255, 0)
red = (255, 0, 0)


#Инициализируем pygame
pygame.init()


#Задаем ширину и высоту окна
size = [700, 500]
screen = pygame.display.set_mode(size)


#Устанавливаем заголовок окна
pygame.display.set_caption("My game")


#Повторяем цикл, пока пользователь не закроет окно
done = False


#Эта переменная используется для управления частотой обновления окна
clock = pygame.time.Clock()


#-------------- Главный цикл --------------
while done==False:
for event in pygame.event.get(): #проверяем все события
if event.type == pygame.QUIT:
done = True
#Устанавливаем фон
screen.fill(black)

#Устанавливаем частоту обновления
clock.tick(60)

#Обновляем наше окно
pygame.display.flip()

# Будем дружественны к IDLE. Если забыть эту строчку то программа зависнеть
# при закрытии окна
pygame.quit()

Django шаблоны. Разбиение списка.

Я недавно начал изучать Django и столкнулся с такой проблемой -- в шаблон передается список, а там то уже его надо разбить на две колонки. Представляю вам решение -- расширить набор тегов с помощью сниппетов (Django snippets).

Представленный сниппет разбивает список на n подсписков.

Тэг: {% list_to_columns ваш_список as новый_список колличество_колонок %}

Вам необязательно знать точное колличество эллементов в списке, а тлолько колличество коллонок на которые надо его разбить. Например у вас есть список:

monty = ['Eric', 'Graham', 'John', 'Michael', 'Terry', 'Terry']

Чтоб разбить его на три подсписка надо прописать:

{% list_to_columns monty as full_monty 3 %}

В результате получится новый список full_monty, содержащий три элемента:

['Eric', 'Graham']
['John', 'Michael']
['Terry', 'Terry']

Пример использования в шаблоне:

{% load list_to_columns %}
{% list_to_columns people as list 3 %}
{% for l in list %}
    (cycle through your div and ul code)
    {%for p in l %}
        (cycle through your list items)
    {% endfor %}
(end ul and div tags)
{% endfor %}

Чтобы заставить сниппет работать нужно сохранить файл list_to_columns.py  в директории templatetags вашего приложения. Т.е. если ваш проект называется mysite, а внутри него вы создали приложение myapp код сниппета надо разместить в папке mysite/myapp/templatetags/ . Также в этой папке должен находится пустой файл __init__.py .

Файл list_to_columns.py:

"""Splits query results list into multiple sublists for template display."""


from django.template import Library, Node


register = Library()


class SplitListNode(Node):
    def __init__(self, results, cols, new_results):
        self.results, self.cols, self.new_results = results, cols, new_results


    def split_seq(self, results, cols=2):
        start = 0
        for i in xrange(cols):
            stop = start + len(results[i::cols])
            yield results[start:stop]
            start = stop


    def render(self, context):
        context[self.new_results] = self.split_seq(context[self.results], int(self.cols))
        return ''


def list_to_columns(parser, token):
    """Parse template tag: {% list_to_colums results as new_results 2 %}"""
    bits = token.contents.split()
    if len(bits) != 5:
        raise TemplateSyntaxError, "list_to_columns results as new_results 2"
    if bits[2] != 'as':
        raise TemplateSyntaxError, "second argument to the list_to_columns tag must be 'as'"
    return SplitListNode(bits[1], bits[4], bits[3])


list_to_columns = register.tag(list_to_columns)