Показаны сообщения с ярлыком python. Показать все сообщения
Показаны сообщения с ярлыком python. Показать все сообщения

воскресенье, 20 февраля 2011 г.

Pygame:учим Python рисовать

    Так уж получилось, что  у меня в универе начался предмет компьютерная геометрия, а на нем,естественно, нужно представлять программы, которые генерируют нужные изображения. У нас выбрали как инструмент представления результатов  Qbasiс. 
Мне это понравилось неслишком по той простой причине, что в Ubuntu он не идет да и в Windows он запускается с бубном.
Память подсказала мне  кроссплатформенную   библиотеку Pygame. Она базируется на С-библиотеке SDL. Гарантировано работает на Windows,Linux,FreeBSD,Mac.
Собственно, чтобы в Ubuntu установить данную библиотеку, можно воспользоваться либо Центром приложений, либо в консоли: 
sudo apt-get install python-pygame. Установится все должно быстро и без вашего участия. 
Проверить,  действительно ли, установилась pygame можно при помощи: 
import pygame  
Если команда отработала без сообщений, то все в порядке. 
   Нарисуем с вами круг, закрашенный и наоборот, а на этом примере увидим, как работать с Pygame.
Начать нужно с инициализации библиотеки: 
import pygame
pygame.init()
Это обязательный шаг: во время этой команды Pygame настраивает себя на работу с вашей системой. Дальше нам надо получить область рисования на экране. Для этого напишем следующее: 

resolution=(420,320)#ширина и высота области 
flag=0#никаких дополнительных условий и настроек 
depth=32#глубина
screen=pygame.display.set_mode(resolution, flag,depth)

Здесь мы обращаемся к той части pygame,которая отвечает за работу с вашим экраном. Мы производим начальную настройку области рисования. Стандартная область 420,320. В переменной flag мы например можем потребовать у pygame использовать полноэкранный режим (pygame.FULLSCREEN) , однако во время отладки вашего приложения лучше его не использовать, так как прибить ошибочно работающий скрипт будет много легче не в полноэкранном режиме. 
Дальше задаем глубину цвета. 
После всех подготовительных действий передаем это все в функцию настройки экрана set_mode()
Дальше закрасим нашу область белым цветом. Для этого вызовем у объекта screen метод fill, а перед этим занесем в переменную color тот цвет, который нам нужен.
 
color=(255, 255, 255)# задаем белый цвет модели RGB цветов   
screen.fill(color) #закрашиваем всю область, цветом color    

цвета в pygame определяются кортежем из трех элементов. Как уже написано  в комментариях цвет должен передаваться в модели RGB. Давайте определим набор цветовых констант: 
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)                 
Я думаю так будет удобней:) 
А меж тем мы изменили изображение на экране, поэтому надо бы картинку на экране обновить, сделаем же это: 
pygame.display.update()      
После того как вы что-либо закрасили, нарисовали фигуру и т.д. обязательно вставляйте строку с вызовом функции обновления изображения экрана. 
Теперь нарисуем закрашенную  окружность черного цвета, а для этого нам понадобится функция circle. 
circolor=BLACK #цвет круга
center=(420/2,320/2)#центр окружности 
radius=100#радиус круга 
pygame.draw.circle(screen, circolor, center, radius)     
Итак с цветом понятно,а центр это кортеж из x-координаты и y-координаты 
радиус число больше нуля. 
На самом деле есть еще параметр width, однако сейчас мы его оставили со значением по умолчанию 0. Так как границы у нового изображения нет, то оно все закрашивается черным цветом. 
Но если в вызов функции после radius мы добавим через запятую 3, то увидим совсем иное. В чем дело? А лаарчик открывается просто: мы дали указание pygame начертить линию с толщиной 3 и цветом BLACK, вот ровно это она и сделала. Собственно говоря именно так можно получить незакрашенные фигуры во многих случаях.      
добавим pygame.display.update() 
В принципе все, за исключением того,что скрипт, не управляем пользователем. Единственный метод сейчас из него выйти это набрать в консоли python pygame.quit()
Это неправильно тем более что pygame нам предоставляет возможность обрабатывать различные события. Напишем код останавливающий  наш скрипт, либо по нажатию крестика в окне, либо по нажатию клавиши Esc:    
while True:
         for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            if  event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    pygame.quit()
                    sys.exit()            
Что мы сделали? Мы организовали бесконечный цикл обработки событий. Как только  событие  попадает в очередь обработки оно будет извлечено при первой возможности и pygame передаст его в наш цикл. А в нем мы проверим следующее: 
1) Это событие сигнал к выходу? (генерируется при нажатии крестика)Если да,то завершаем  приложение и закрываем сам интерпретатор.      
2) Это нажатие клавиши ? Если да, то проверяем, что нажата клавиша Escape (самая верхняя слева) . Да? закрываем приложение и интерпретатор.   
Мы рассмотрели лишь очень малую часть возможностей этой замечательной библиотеки, зайдите на сайт www.pygame.org 
Там вы найдете документацию, ссылки на руководства и сможете загрузить различные версии библиотеки.Кстати она является OpenSource разработкой и распространяется на условиях LGPL . 
А в завершении заметки полный исходный текст нашего приложения(закрашенный круг): 
# -*- coding: utf-8 -*-
import pygame
import sys 
pygame.init()
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
resolution=(420,320)#ширина и высота области 
flag=0#никаких дополнительных условий и настроек 
depth=32#глубина
screen=pygame.display.set_mode(resolution, flag,depth)
color=(255, 255, 255)# задаем белый цвет модели RGB цветов   
screen.fill(color) #закрашиваем всю область, цветом color
pygame.display.update()
circolor=BLACK #цвет круга
center=(420/2,320/2)#центр окружности 
radius=100#радиус круга 
pygame.draw.circle(screen, circolor, center, radius)
pygame.display.update()
while True:
         for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            if  event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    pygame.quit()
                    sys.exit()      
А вот и незакрашенная окружность:
# -*- coding: utf-8 -*-
import pygame
import sys 
pygame.init()
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
resolution=(420,320)#ширина и высота области 
flag=0#никаких дополнительных условий и настроек 
depth=32#глубина
screen=pygame.display.set_mode(resolution, flag,depth)
color=(255, 255, 255)# задаем белый цвет модели RGB цветов   
screen.fill(color) #закрашиваем всю область, цветом color
pygame.display.update()
circolor=BLACK #цвет круга
center=(420/2,320/2)#центр окружности 
radius=100#радиус круга 
pygame.draw.circle(screen, circolor, center, radius,3)
pygame.display.update()
while True:
         for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            if  event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    pygame.quit()
                    sys.exit()            

       

воскресенье, 23 января 2011 г.

Python:загружаем файлы и информируем пользователя о прогрессе операции

       Есть в Python такой модуль urllib2 это высокоуровневый интерфейс к  библиотекам Python, работающим с протоколами HTTP,FTP и так далее. Передо мной встала необходимость реализовать возможность загрузки файла средствами этой библиотеки. Поэтому я определил такую функцию:
def Load(lpath,path):
        percent=10#процент загрузки файла
        myfile=open(lpath,'wb')#итак как в моем случае будут сохранять бинарные данные, то 
 #открываем в бинарном режиме на запись                   
        f=urllib2.urlopen(path)#открываем целевой URL 
        meta=f.info()#получаем информацию об URL (точнее заголовки в виде словаря)
        remotesize=meta['Content-Length'] #получаем размер из ключа Content-Length 
        print remotesize 
        blocksize = int(remotesize)/10.0 # определяем в байтах сколько составляет 10% 
        while 100>=percent:#пока загружено менее или ровно 100%.....
           myfile.write(f.read(blocksize ))#записываем блок данных размером blocksize, прочитанный #объектом f  
           print 'получено %d  процентов файла'%(percent)
           percent=percent+10
       myfile.close() #закрываем файл 
     Открывая URL библиотека urllib2 возвращает нам объект,имитирующий файл. Если мы вызовем read без параметров, то будет считан сразу весь объект, однако это может быть длительный процесс(все зависит от размера файла). Естественно перед использованием импортируйте модуль urllib2 в  вашу программу           

суббота, 1 января 2011 г.

SQLalchemy:что это?

Вобще вокруг этого класса систем идет много дискуссий.Но в целом мне кажется очень хорошая идея заложена в ORM системы(Object-Relation System ). Основная их идея в том, чтобы создать слой между языком программирования и SQL. При чем этот слой нужен для абстрагирования от SQL и перевод работы с базой от ее создания до удаления в инструменты и понятия родные для конкретного языка, а не SQL. В данном случае python. И естественно,  исходя из названия предположить что там активно используются классы. Итак что же мы имеем? Таблицы связываются с классами, которые их описывают в программе, поля классов это поля таблиц, естественно к классам можно добавлять методы. Такие вещи как запрос и различные типы фильтрации то же представлены как типичный Python-объект, для задания сложных и не очень условий можно использовать операторы и функции Python. Так же при помощи ORM-модели в терминах языка можно описывать соединения таблиц между собой. Системы типа SQLalchemy стараются быть максимально универсальными, чтобы поддерживать независимость от конкретной СУБД, что не дает возможность задействовать некоторые "фичи" различных СУБД. Но это как говорится борьба универсализма и специализированности.    Для Python главной  ORM системой является sqlalchemy-opensource продукт (либеральная лицензия MIT) .Она позволяет в терминах и структурах данных python создавать приложения для работы с БД, начиная от описание структуры таблиц и связей в БД и заканчивая модификацией и извлечением данных.             

суббота, 6 ноября 2010 г.

Python:алгоритм бинарного поиска

Идея этого алгоритма проста(работает на отсортированных массивах\списках):
Сначала высчитываем индекс среднего элемента по формуле (m+n)//2.Где n это индекс начального элемента, а m количество элементов в массиве  В случае нечетного числа элементов округляем до ближайшего целого полученный результат. А дальше уже смотрим  что получается:
а) Элемент найден и мы возвращаем его индекс 
б) Средний элемент меньше ключа поиска 
в) Средний элемент больше ключа поиска 
В случае б) мы должны отсечь те элементы которые меньше среднего, то есть правую часть массива\списка. Дробится этого можно приняв за начальную границу поиска первый элемент со значением больше чем средний элемент, а у нас массив\список сортированный значит это элемент с индексом  i+1, где  i индекс среднего элемента. а конечная граница поиска последний элемент. в случае в) нам нужно принять за начальную границу первый элемент меньший среднего, а значит нам нужен элемент с индексом i-1.  Как конечная граница поиска естественно принять индекс первого элемента. Итак весь процесс будем повторять пока не выполниться любое из трех условий:
1) Элемент найден 
2) Начальная граница стала равна наибольшему элементу массива
3) Начальная граница стала равна индексу наименьшего элемента.
Самый положительный для нас случай 1.Преимущество алгоритма в том что при каждом сравнении убавляется половина отрезка, где происходит поиск элементов.
Краткое описание алгоритма:
1. Взять  индекс первого  элемента (n)
2. Взять индекс конечного элемента (длину массива ) (m)
3. Рассчитать индекс среднего элемента по формуле (m+n)\2 (i)
4. Сравнить средний элемент с ключом
4a Пока 0<=i
5а Если ключ = =элементу в выходим из программы
5б Если ключ>элементу,то n=i+1 m=len(l)
5в Если ключ<элементу, то n=i m=i-1  
6. Переходим к шагу 4a      
А вот и код на python,реализующий алгоритм:
def  quick_sort(l,k):
    m=len(l)
    n=0
    i=(m+n)//2
    while 0<=i
        if l[i]==k:
            return i
        elif  l[i]
            m=len(l)
            n=i+1
        elif  l[i]>k:
            m=i-1
            n=i
        i=(m+n)//2  
    return None  

понедельник, 25 октября 2010 г.

Python: типы данных.

Здесь я решил собирать небольшие записки путешествия по миру python +примеры. И начнем мы его с типов данных. Python это язык типизированный, но сама система типизации в нем динамическая. Что это для нас значит?   Это значит что в одной и той же переменной мы можем совершенно спокойно хранить: числа, строки,кортежи, списки и ваши собственные типы данных. Кошмар:)И например такие строки совершенно нормально воспримет интерпретатор:
 a='Stroka'
a=1
a=[4,3]
Как такое возможно ? Вся тонкость в том чтобы понять что такое переменная в python: это не жестко статически выделенная область памяти, а динамически распределяемая область памяти, которая реализована за счет не типизированных указателей С. Именно поэтому python может свободно жонглировать типами данных, приводя переменную к нужному типу данных по мере необходимости.
А зачем же типы? А они нужны затем, что для каждого типа данных определен свой собственный набор операций и то что например вполне корректно для числа будет совсем некорректно для списка или кортежа.
Так же важно помнить, что python делит все типы данных на две категории:
1. Изменяемые
2. Неизменяемые
На всякий случай поясню: если мы создаем объект первого типа, то мы можем его изменять целиком или отдельные части и мы будем работать все с тем же объектом.
А вот со вторым типом объектов такие штучки не пройдут.
Продемонстрируем это на примере работы с двумя одинаковыми по содержанию коллекциями, но одна из них это список (изменяемый тип данных), а вторая кортеж (неизменяемые объекты).
am=[1,2,3,4]
aim=(1,2,3,4)
for i in xrange(0,len(am)-1):
     am[i]=7*am[i]
 print am           
В результате нам спокойно покажут:
>>>
[7, 14, 21, 4]
Но стоит нам добавить такие строки в скрипт:
 for i in xrange(0,len(am)-1):
     aim[i]=7*aim[i]
print aim
Как Python нам сообщит:
Traceback (most recent call last):
  File "/home/abc/блог/PyMutInmut.py", line 7, in
    aim[i]=7*aim[i]
TypeError: 'tuple' object does not support item assignment  
Собственно и произошло то о чем говорилось ранее: нельзя в неизменяемых объектах менять отдельные части,
Зачем так было придумано? Логика в этом есть и неплохая между прочим, неизменяемость объектов позволяет легче реализовывать, быстрее доступ к таким объектам на чтение но не на запись.Кроме того неизменяемые объекты нужны для функционального программирования, где воздействия на аргументы кроме возврата результата функции не допускаются.  
Здесь есть одна тонкость: неизменяемые объекты можно изменять!) Как ?Ну например так:
stri='hel'
stri=stri+'hel'
Произойдет прозаическая конкатенация строк. Однако заглянем за кулисы:
1) Python возьмет копию исходной строки+вторая
2) Пометит а потом и утилизирует (то есть уничтожит в памяти) исходную строку
3) Присвоит идентификатор новой строке.
То есть видите любая операция с неизменяемым объектом где он меняется порождает новый объект . Но на самом деле список и другие изменяемые структуры могут легко решить ваши проблемы по скорости записи и уступают по скорости чтения не намного.        

воскресенье, 17 октября 2010 г.

Python: запускаем скрипты

 Если вы пользователь Linux то скорее всего у вас уже все есть и проверить наличие python довольно просто:откройте командную  строку и наберите: python
На самом деле все вы уже можете писать программы) Каждое ваше действие вы непосредственно передаете интерпретатору и его результаты будут немедленно показаны на экране в командной строке. Можно так же установить IDLE это штатная и очень неплохая среда разработки на python:
apt-get install idle. 
  А если нам захочется немедленнот в консоли проверить команду python? Ответ: 
python -c "print( 'Twest')"
-с заставляет python интерпретировать строку как код. 
Чтобы запустить скрипт в консоли можно написать python имя_скрипта.py 
А если написать в скрипте первой строчкой: #!env/python 
То python будет запущен с этим скриптом автоматом по команде 
./имя_скрипта.py    
./ Так как заставляет искать скрипт не по переменным окружения, а в текущем каталоге   

четверг, 30 сентября 2010 г.

Python для студента

Python это простой для освоения, открытый интерпритируемый язык. Но чем он полезен студенту? Кроме всех перечисленных свойств он имеет кучу открытых расширений.
Пройдемся по некоторым:
Numpy это библиотека матричных вычислений на Python. Его особенностью является использование С++ и С кода для реализации матричных вычислений.Это дает хороший прирост скорости,так как все эти операции сразу используют скомпилированные расширения python, написанные на С/С++ c использованием низкоуровневой библиотеки  LAPPACK(решатель задач линейной алгебры). Эта же библиотека лежит в основе MATLAB
Но одной линейной алгебры мало нам и по сему обратим свой взор к Scipy она использует numpy и предоставляет такие возможности(взято из Википедии):
Доступные субпакеты

  • constants: Физические константы и коэффициенты пересчёта (с версии 0.7.0)
  • cluster: Векторное квантование
  • fftpack: Дискретные алгоритмы преобразования Фурье
  • integrate: Инструменты для интегрирования
  • interpolate: Инструменты для интерполяции
  • io: Ввод/вывод данных
  • lib: Врапперы Python для внешних библиотек
  • linalg: Линейная алгебра
  • misc: Разные утилиты
  • optimize: Средства оптимизации
  • sandbox: Экспериментальный код
  • signal: Обработка сигналов
  • sparse: Поддержка разреженных матриц
  • special: Специальные функции
  • stats: Статистические функции
  • weave: Позволяет включение кода C/C++ внутри кода Python

Дополнительная функциональность:
Основной функционал SciPy расширяется за счёт других инструментов.
Например:
Графика. На данный момент рекомендованным пакетом для отрисовки двухмерной графики является Matplotlib, тем не менее существует множество других, например HippoDraw, Chaco, и Biggles. Также популярными являются Python Imaging Library и MayaVi (для 3D визуализации)
Оптимизация. Хотя SciPy имеет свой пакет для оптимизации, OpenOpt имеет доступ к большему количеству оптимизационных пакетов и решателей
Продвинутый анализ данных. При помощи RPy, SciPy обеспечивает интерфейс к статистическому пакету R предназначенному для сложного анализа данных.
База данных. SciPy может взимодействовать с  PyTables, иерархической базой данных разработанной для эффективного управления большими объёмами данных на основе HDF5.
Интерактивная оболочка. IPython это интерактивная среда которая обеспечивает дебаггинг и создание кода в стиле близком к MATLAB. Ну что ж мне кажется Вики все вполне хорошо описала для затравки.
Символьная математика. Существует несколько библиотек для Python, такие как PyDSTool, Symbolic и SymPy-- которые позволяют работать с символьной математикой.Библиотеки
Как видите это довольно серьезный набор для математика.Кроме того такие библиотеки как NetworkX,Boost.Python,igraph позволяют работать со структурами типа графов.  
    Если же касаться вопроса о символьной математике детальней, то остановемся на Sympy
Это библиотека позволяет дифференцировать, интегрировать, раскладывать в ряды и производить упрощения символических выражений. Библиотека свободная для использования под лицензией BSD, а по сему вы можете делать на ее основе и коммерческие продукты. В конце статьи будут приведены некоторые дополнительные ссылки.
А если мы хотим написать игру? Пожалуйста BSD библиотека PyGame спешит нам на помощь.Она позволит нам:
Создать нестандартный интерфейс
Работать с текстурами
Звуком
Другими графическими файлами
Библиотека использует средства OpenGL. Кроссплатформеная. Легка в инсталяции. На ее основе сделаны различные разработки в области графики кроме 2D игр.
Кстати если вы психолог, то вас может заинтересовать система проведения экспериментов в области восприятия PsychoPy. Это открытая разработка интгерирующая в себе инструменты для проведения экспериментов и их последующую численную обработку. Начинается все с того что вы пишите python скрипт, который описывает будущий эксперимент. Затем уже по его результатам система позволит провести различные статистические рассчеты по его результатам. Поддерживается весьма широкий спектр статических и прочих математических функций.
  А захотелось нам например реализовать задачи связанные со сложной обработкой и анализом текстов. Пожалуйста! для этого у нас есть такой инструмент как NLTK (опять же под лицензией Apache).Эта библиотека разработана для того, чтобы предоставить инструменты анализа слов, синтаксического анализа и максимально облегчить работу с информацией текстового характера. Вокруг этой библиотеки реализовано много академических и учебных проектов. Кроме того на основе этой библиотеки написан учебник по синтаксическому анализу и прочим вопросам работы с текстовой информацией: Natural Language Processing with python.Книжечка зарубежная и непереведенная, но сама в рунете есть. Можете поискать ее в списке книг на форуме сайта python.su 
На самом деле есть еще большое множество иных библиотек, которые в обзор не попали. А для многих компонентов Linux и OpenSource приложений поставляются python-библиотеки, открывающие доступ к возможностям последних. Вобщем возможности python заслцуживают внимания:)
Ссылки:
Расширения Python,упомянутые в заметке:

  1. Библиотека Numpy 
  2. Библиотека Scipy
  3. Библиотека Sympy
  4. Библиотека   анализа данных, имитации систем и физ. процессов  PyDSTool    
  5. Библиотека  NetworkX
  6. Библиотека Boost.Python
  7. Библиотека igraph
  8. Комплекс Psychopy
  9. Библиотека NLTK 
  10. библиотека Pygame
Статьи:
  1. Программирование и научные вычисления на языке Python

  2. Математический Python
  3. Анализ социального графа
              


      среда, 18 августа 2010 г.

      устанавливаем PyMedia (библиотеку для работы с мультимедиа данными в Python)


      Понадобилось мне провести установку вышеуказанной библиотеки и здесь я предоставляю HOWTO по установке:
      Итак по горячим следам:
      1) Устанавливаем: dev файлы python 2.6
      2) libasound2-dev (это файлы разработчика ALSA, именно они нужны что бы установщик pymedia задетектил ALSA )
      3) lame 3.98.4 (переходим в папку с исходниками lame и вводим:


      ./configure
      make
      make install

      )
      При чем лучше из под sudo
      4) Устанавливаем faad (я сначала установил faad 2.7 из сорцов: переходим в директорию faad и пишем

      ./configure --with-mp4v2
      make
      sudo make install


      )Однако после импорта pymedia она сказала не видим мы libfaad.so.2. Пришлось установить deb пакет 2.6 и "импортная" ошибка прошла
      5) Теперь из консоли перейдя в папку с pymedia введем: sudo python setup.py install. Он должен показать следующее

      OGG : found
      VORBIS : found
      FAAD : found
      MP3LAME : found
      VORBISENC : found
      ALSA : found

      Что ж на вопрос отвечаем буквой y и тут у нас могут начаться ошибки из-за того что GCC 4 не дружит с pymedia. Если так то нам придется сделать следующее:
      В файле в строке 31 вводим:

      #define HAVE_LRINTF
      #include
      #define HAVE_LRINTF
      #include "libavcodec/dsputil.h"
      #include "version.h"

      наш #define должен быть до #include "libavcodec/dsputil.h" Это обязательно!
      Однако этого шаманизма от пользователя Illusion форума на http://indashpc.org/ недостаточен
      Админ того же форума jbors дополнил, что строку #define HAVE_LRINTF надо ввести и в
      audio/config.h
      Вот тогда сборка и установка должна пройти нормально. И инструкция

      >>>from pymedia import *

      Должна пройти без ошибок
      Ссылки:
      1) для системы устанавливаем в консоли sudo apt-get install libasound2-dev
      2) Для faad: качаем здесь или
      здесь
      Исходники 2.7:Берем здесь
      3) lame:качаем здесь
      4) pymedia: качаем здесь
      5) Источник поправок: здесь (по dev пакетам для alsa) и страница обсуждений инсталяции pymedia расположен здесь
      6) Заголовочные файлы для python sudo apt-get install python2.6- dev
      Впервые я опубликовал это HOWTO: здесь

      суббота, 31 июля 2010 г.

      Заметки о python в народном хозяйстве linuxoида: вызываем утилиты командной строки

      Язык python разработанный Гвидо ван Россум  при всей своей простате синтаксиса обладает мощными возможностями. Поэтому находит активное применение как в науке, так и в повседневной работе с системой. Сегодня я хотел бы показать как вызывать приложения командной строки из python, для примера рассмотрим общеизвестную консольную утилиту wget.  Эта утилита имеет следующий синтаксис вызова: wget [параметры ] [адрес]. Пример вызова:
       wget  http://www.google.ru , а если хотим сохранить закаченный материал в каком то другом месте то: wget -P /path/to/save  http://www.google.ru Просто? А как это запрограммировать в python? Для определенности поставим задачу так: написать функцию, которая бы обеспечивала загрузку заданного файла либо в домашний, каталог, либо в заданный каталог. Фактически нам надо чтобы функция генерировала и передавала на исполнение командной оболочке в первом случае: wget url, а во втором: wget -P /path/to/save url. И здесь нам на помощь приходит модуль subprocess и его функция call(*popenargs, **kwargs) . Она позволяет вызвать приложение и передать ему набор аргументов в виде кортежа:
       retcode=subprocess.call(["wget","www.site.com"]). в retcode идет код возврата от вызванной программы. В первом параметры передаем имя программы для вызова, а во втором параметр, при чем каждый из них идет как член списка. А вот собственно и код самой функции полностью:
      import subprocess #импортируем модуль subprocess
      def basic_download(key,url):  # определяем функцию с двумя параметрами(первый содержит #ключи,а второй адрес)   
       if url=='':  #если адрес пуст вернем ошибку                   
           return -1
       if key=='':  # если параметр key не задан, вызываем wget с параметрами по умолчанию... 
          retcode=subprocess.call(["wget",url])
          return retcode
       else: #иначе
          key='-P'+key #конкатенация ключа и пути сохранения  
          retcode=subprocess.call(["wget",key,url])
          return retcode     
       Это базовый пример, но  этот модуль предоставляет куда большие возможности, в чем можно убедится заглянув сюда
      Смело указывайте на ошибки и неточности, ведь я только начинаю свой путь в python. 
      P.S. надеюсь хватит сил довести до полноценной GUI оболочки для wget