Planeta PythonBrasil

PythonBrasil[9]

April 19, 2014

Bruno Cezar Rocha

Usando o Flask Cache

Como framework o Flask não tem nenhuma funcionalidade de cache embutida, porém existe a cache API do werkzeug e uma excelente extensão para prover essas funcionalidades de cache para suas aplicacoes Flask, esta extensão foi criado pelo @thadeusb e é bastante fácil de implementar e utilizar.

instalando

Em sua env instale pelo PyPI (recommended)

pip install Flask-Cache  

Você também pode instalar diretamente através do github se quiser pegar a última versao de desenvolvimento.

pip install https://github.com/thadeusb/flask-cache/tarball/master

Configurando

Existe uma série de chaves de configuração que podem ser setadas, mas a mais importante é a que define o backend de cache CACHE_TYPE.

A chave CACHE_TYPE pode ser uma string resolvendo um caminho de importação de uma classe que implemente a api de cache do werkzeug, mas existem alguns alias que mapeam as implemetações default que estão no werkzeug.contrib.cache

Por padrão o CACHE_TYPE é NUll o que significa que o cache não terá efeito, então você precisa escolher um backend para o cache.

chave | Cache type

  • null | Sem Cache - NullCache
  • simple | Usará pickle em memória e é recomendado apenas em servidor single process durante o desenvolvimento
  • memcached | Requer pylibmc ou memcached e precisa das configs do memcached no settings
  • redis | Requer redis, werkzeug 0.7 e configurações do Redis no settings
  • filesystem | O mesmo que o simple, porém armazena o pickle em filesystem ao inves da memoria
  • gaememcached | Para o Google AppEngine
  • saslmemcached | Mesmo que o memcached mas para instalações em SASL - requer pylibmc

Todas as opções e outras chaves de config em http://pythonhosted.org/Flask-Cache/#configuring-flask-cache

App Flask simples

em um arquivo nomeado app.py

import time
from flask import Flask

app = Flask(__name__)

@app.route("/")
def view():
    return time.ctime()

if __name__ == "__main__":
    app.run(port=5000, debug=True, host='0.0.0.0')

Execute com python app.py e abra a url http://localhost:5000 no seu browser, aperte F5 (refresh) para ver a data e hora correntes.

Habilitando o cache para a view

agora vamos habilitar o cache para esta pequena app e evitar que a hora seja atualizada a cada request. (neste exemplo usamos a data atual mas imagine que isso poderia ser o carregamento de um grande conjunto de dados ou cálculos complexos)

em um arquivo nomeado cached_app.py

import time
from flask import Flask

# importe a extensao
from flask.ext.cache import Cache   

app = Flask(__name__)

# defina a configuração do cache (isso pode ser feito em um arquivo de settings)
app.config['CACHE_TYPE'] = 'simple'

# instancie o cache e atribua a sua aplicação
app.cache = Cache(app)   

@app.route("/")
@app.cache.cached(timeout=300)  # cache this view for 5 minutes
def cached_view():
    return time.ctime()

if __name__ == "__main__":
    app.run(port=5000, debug=True, host='0.0.0.0')

Execute com python cached_app.py e abra http://localhost:5000 em seu browser e aperte F5 (refresh) para ver a data e hora cacheadas durante 5 minutos.

O decorator @cache.cached utiliza o request.path para a view como chave de cache, se por algum motivo você precisar especificar uma chave diferente poderá passar o argumento key_prefix para o decorator. Neste caso, se o seu argumento incluir um placeholder "%s" ele será substituido pelo request.path.

O exemplo acima é a mais simples e regular app Flask com o uso de cache, mas se sua app é projetada usando app factories, blueprints, class based views ou views separadas em arquivos diferentes você precisará usar abordagens avançadas.

Cacheando funções

O mesmo decorator cached pode ser usado para cachear funções (que não são views), neste caso será preciso especificar um key_prefix, caso contrário o request.path será usado e então poderá cair em conflito quando existir mais de uma função cacheada.

Neste exemplo usaremos o módulo this para extrair citações do Zen do Python.

Em um arquivo nomeado cached_function_app.py

import time
import random

from this import s, d
from string import translate, maketrans

from flask.ext.cache import Cache
from flask import Flask

app = Flask(__name__)
app.config['CACHE_TYPE'] = 'simple'
app.cache = Cache(app)

@app.cache.cached(timeout=10, key_prefix="current_time")
def get_current_time():
    return time.ctime()

def random_zen_quote():
    """Pega uma citação aleatória do Zen do Python""" 
    transtable = maketrans("".join(d.keys()), "".join(d.values()))
    return random.choice(translate(s, transtable).split("\n")[2:])

@app.route("/")
def zen():
    return """
    <ul>
        <li><strong>Com cache:</strong> {cached}</li>
        <li><strong>Sem cache:</strong> {not_cached}</li>
    </ul>
    """.format(
        cached=get_current_time(),
        not_cached=random_zen_quote()
    )

if __name__ == "__main__":
    app.run(debug=True, port=5000, host='0.0.0.0')

Execute com python cached_function_app.py acesse http://localhost:5000 apertando F5 (refresh) você verá que a data atual é cacheada mas a citação continua sendo atualizada, você pode alternar o cache para ver como fica.

def get_current_time():
    return time.ctime()

@app.cache.cached(timeout=10, key_prefix="zen_quote")
def random_zen_quote():
    transtable = maketrans("".join(d.keys()), "".join(d.values()))
    return random.choice(translate(s, transtable).split("\n")[2:])

@app.route("/")
def zen():
    return """
    <ul>
        <li><strong>Sem cache:</strong> {cached}</li>
        <li><strong>Com cache:</strong> {not_cached}</li>
    </ul>
    """.format(
        cached=get_current_time(),
        not_cached=random_zen_quote()
    )

NOTE: por ter usado o módulo this você verá algumas citações serem impressas em seu terminal mas isso não tem nenhum problema.

Cacheando views modulares

agora um exemplo com views separadas em um arquivo diferente para melhor organização

Em um pasta chamada app coloque 3 arquivos __init__.py, app.py e views.py

app/__init__.py um arquivo vazio

app/views.py

import time
import random
from this import s, d
from string import translate, maketrans

def get_current_time():
    return time.ctime()

def random_zen_quote():
    transtable = maketrans("".join(d.keys()), "".join(d.values()))
    return random.choice(translate(s, transtable).split("\n")[2:])

def zen_view():
    return """
    <h1>No cache por 10 segundos!</h1>
    <ul>
        <li>{time}</li>
        <li>{quote}</li>
    </ul>
    """.format(
        time=get_current_time(),
        quote=random_zen_quote()
    )

Como pode ver no exemplo acims definimos a view em um arquivo separado. Para evitar import circular não seria recomendado usar @app.route nem o @app.cache portanto esta view será agnostica com relação a app pois iremos registrar seu mapeamento de urls e seu cache no arquivo principal da app.

Este tipo de estrutura é necessária quando se tem muitas views e é preciso organizar em vários arquivos separados.

NOTE: Para uma melhor organização é recomendado o uso de blueprints que será explicado em seguida.

app/app.py

agora na app principal importaremos as views e explicitamente decoraremos com o cache e também registraremos a regra de url.

from flask import Flask
from flask.ext.cache import Cache
from views import zen_view

app = Flask(__name__)
app.config['CACHE_TYPE'] = 'simple'
app.cache = Cache(app)

# aplique o cache usando o velho estilo de uso dos decorators
cached_zen_view = app.cache.cached(timeout=10)(zen_view)

# registre o mapeamento de url
app.add_url_rule("/", view_func=cached_zen_view)

if __name__ == "__main__":
    app.run(debug=True, port=5000, host='0.0.0.0')

NOTE: Tambem é possivel colocar o cache em um arquivo separado como veremos em seguida.

Cacheando views em Blueprints

Como foi mencionado anteriormente, a melhor maneira de organizar uma app Flask é com o uso de Blueprints, que é uma maneira de criar ' meta-apps' que serão conectadas ao app principal no momento da inicialização, O problema aqui é que o Blueprint é feito pensando em criar módulos reutilizaveis por diferentes apps, portanto o controle do cache precisa ser delegado dinamicamente.

Para evitar import circular criaremos uma instancia de cache em um arquivo separado (considere usar application factory se estiver criando algo mais complexo)

Crie uma pasta chamada blueprint_app com os seguintes arquivos

cached_blueprint_app/
├── app.py
├── cache.py
├── blueprints
│   ├── __init__.py
│   └── zen_blueprint.py
└── __init__.py

No cache.py

from flask.ext.cache import Cache    
cache = Cache()

Criamos uma instancia burra do Cache, ela ainda não foi inicializada mas já pode ser usada, no futuro ela será inicializada junto com a app e estará disponivel quando a view for chamada. Para isso reimportaremos a mesma instancia de cache e chamaremos o metodo init_app.

Um blueprint básico blueprints/zen_blueprint.py

import time
import random
from this import s, d
from string import translate, maketrans
from flask import Blueprint
from cache import cache

zen = Blueprint('zen', __name__)

def get_current_time():
    return time.ctime()

def random_zen_quote():
    transtable = maketrans("".join(d.keys()), "".join(d.values()))
    return random.choice(translate(s, transtable).split("\n")[2:])

@zen.route("/")
@cache.cached(timeout=20)
def zen_view():
    return """
    <h1>Cacheado por 20 segundos!</h1>
    <ul>
        <li>{time}</li>
        <li>{quote}</li>
    </ul>
    """.format(
        time=get_current_time(),
        quote=random_zen_quote()
    )

NOTE: Em uma aplicação real é recomendado separar mais o blueprint em arquivos diferents para views, urls e helpers, para isso você poderá promover este blueprint para um pacote Python.

A app principal app.py

from flask import Flask

from blueprints.zen_blueprint import zen
from cache import cache

app = Flask(__name__)
app.config['CACHE_TYPE'] = 'simple'
cache.init_app(app)

app.register_blueprint(zen)

if __name__ == "__main__":
    app.run(debug=True, port=5000, host='0.0.0.0')

Repare que criamos a instancia burra do cache no arquivo cache.py e usamos esta instancia para decorar as views do blueprint, então o cache foi inicializado no app.py utilizando o método init_app. Isso e possivel por conta do ciclo de inicialização do Flask e também pelo fato da extensão Flask-Cache ter sido criada pensando nesses casos. Se um dia pretender escrever sua própria extensão para o Flask aconselho dar uma olhada no código fonte da Flask-Cache.

Execute com python cached_blueprint_app/app.py acesse http://localhost:5000 e a view será cacheada por 20 segundos

Cacheando MethodViews

Vamos usar o mesmo exemplo cached_blueprint_app transformado a view zen_view em uma MethodView

Altere o zen_blueprint.py para:

import time
import random
from this import s, d
from string import translate, maketrans
from flask import Blueprint
from flask.views import MethodView
from cache import cache

zen = Blueprint('zen', __name__)

class ZenView(MethodView):

    @cache.cached(30)
    def get(self):
        return """
        <h1>Cacheado por 30 segundos!</h1>
        <ul>
            <li>{time}</li>
            <li>{quote}</li>
        </ul>
        """.format(
            time=self.get_current_time(),
            quote=self.random_zen_quote()
        )

    @staticmethod
    def get_current_time():
        return time.ctime()

    @staticmethod
    def random_zen_quote():
        transtable = maketrans("".join(d.keys()), "".join(d.values()))
        return random.choice(translate(s, transtable).split("\n")[2:])


zen.add_url_rule("/", view_func=ZenView.as_view('zen'))

MethodViews mapeiam os métodos HTTP como GET, POST e DELETE para métodos da classe como get, post, delete etc, então neste caso criamos um método chamado get e decoramos com o @cache.cached.

NOTE: Você geralmente não pode usar decorators em métodos individuais de MethodViews, porém o Flask-Cache foi implementado de forma que permite este uso.

alternativamente você pode querer cachear todos os métodos de uma mesma view, para isso basta cachear o dispatch_request ou melhor ainda cachear a view completa usando um decorator explicito.

Cacheando o dispatcher
class ZenView(MethodView):
    @cache.cached(timeout=30)
    def dispatch_request(self):
        return super(ZenView, self).dispatch_request()

    ...
Cacheando a view com decorator explicito (recomendado)
zen = Blueprint('zen', __name__)

class ZenView(MethodView):
    ...

cached_zen_view = cache.cached(timeout=50)(ZenView.as_view('zen'))
zen.add_url_rule("/", view_func=cached_zen_view)

Cacheando blocos de template

O Flask-Cache vem com uma template tag que permite cachear blocos de template, vamos mudar a ZenView e faze-la renderizar um template com Jinja2

No zen_blueprint.py

import time
import random
from this import s, d
from string import translate, maketrans
from flask import Blueprint, render_template
from flask.views import MethodView

zen = Blueprint('zen', __name__)

class ZenView(MethodView):

    def get(self):
        return render_template(
            'zen.html',
            get_random_quote=self.random_zen_quote
        )

    @staticmethod
    def get_current_time():
        return time.ctime()

    @staticmethod
    def random_zen_quote():
        transtable = maketrans("".join(d.keys()), "".join(d.values()))
        return random.choice(translate(s, transtable).split("\n")[2:])

zen.add_url_rule("/", view_func=ZenView.as_view('zen'))

Agora teremos que criar o template cached_blueprint_app/templates/zen.html

<h3> Zen of Python Aleatório </h3>
<strong>{{get_random_quote()}}</strong>

Execute com python cached_blueprint_app/app.py e abra http://localhost:5000 você verá a citação ser atualizada a cada request, vamos evitar isso cacheando durante 30 segundos.

Change the zen.html template

{% cache 30 %}
<h3> Zen of Python Aleatório </h3>
<strong>{{get_random_quote()}}</strong>
{% endcache %}

Salve o template e de o refresh varias vezes e você verá que a citação estará cacheada por 30 segundos.

Cacheando funções com argumentos variaveis usando o decorator memoize

as vezes as views ou funções recebem argumentos através do mapeamento de urls ou diretamente passados, você pode querer cachear utilizando esses argumentos como chave do cache para ter caches diferentes para cada chamada. No Flask-Cache tem o decorator memoize para isso.

NOTE: Para funções que não recebem argumentos cached e memoize terão o mesmo efeito

Com uma app simples memoize_app.py

import time
from flask.ext.cache import Cache
from flask import Flask

app = Flask(__name__)
app.config['CACHE_TYPE'] = 'simple'
app.cache = Cache(app)

@app.cache.memoize(timeout=5)
def get_current_time_and_name(name):
    return "%s - %s" % (name, time.ctime())

@app.route("/<name>")
def view(name):
    return get_current_time_and_name(name)

if __name__ == "__main__":
    app.run(debug=True, port=5000, host='0.0.0.0')

Rode com python memoize_app.py abra http://localhost:5000/seunome e repare que a chamada é cacheada separadamente para cada argumento passado.

Cacheando objetos diretamente

As vezes não podemos usar decorators e precisamos cachear objetos diretamente.

Dentro de uma view ou blueprint é possivel usar o current_app

from flask import current_app

def some_function():
    cached = current_app.cache.get('a_key')
    if cached:
        return cached
    result = do_some_stuff()
    current_app.cache.set('a_key', result, timeout=300)
    return result

Ou se estiver usando uma instancia separada de cache (recomendado)

from cache import cache

def function():
    cached = cache.get('a_key')
    if cached:
        return cached
    result = do_some_stuff()
    cache.set('a_key', result, timeout=300)
    return result

Limpando o cache

Você pode criar um script para limpar o cache ou uma função para ser chamada quando preciso.

from flask.ext.cache import Cache    
from yourapp import app
cache = Cache()

def main():
    cache.init_app(app)

    with app.app_context():
        cache.clear()

if __name__ == '__main__':
    main()

AVISO: Em alguns backends a limpeza completa do cache não é suportada. Se não estiver usando key_prefix em alguns backends como redis irá fazer com que todo o database seja apagado.

Existe uma série de exemplos e uma API bem documentada no site do Flask-Cache http://pythonhosted.org/Flask-Cache/ também é possivel criar um novo backend de cache seguindo este exemplo.

por Bruno Rocha em 19 de April de 2014 às 00:42

April 16, 2014

Eric Hideki

1535023_1418633858389341_696287647_n

No último dia 29 houve o encontro das Pyladies Brasil em Natal/RN, um grupo internacional com o foco em ajudar mais mulheres a se tornarem líderes de comunidades Python de código aberto, criar um ambiente envolvente e inclusivo para mulheres que desejam ingressar e conhecer sobre tecnologia. E com isso conversei com a Gabriela e a Katyanna que foram umas das organizadoras para falarem sobre a experiência do evento.

Gostaria que se apresentassem e falar um pouco sobre vocês

1460238_1416640048588722_1466677372_n

Eu sou a Gabriela, tenho 19 anos, curso o Bacharelado em Tecnologia da Informação na Universidade Federal do Rio Grande do Norte e acabei de concluir o técnico em Informática no Instituto Federal do RN. Sou definitivamente apaixonada pela minha área. Amo programação, desenvolvimento, tecnologia… realmente, não tenho para onde fugir. Nem sempre tive essa certeza do que fazer profissionalmente e no início até resistir a possibilidade entrar no curso de TI, mas percebi que era nisso que eu me sentia feliz e que eu tinha prazer. Agora que estou junto com as meninas no PyLadies, sinto que fiz a escolha certa.

1964771_1416644341921626_1077483920_n

Katyanna Moura, 20 anos. Queria ser bailarina, depois mudei para escritora e me decidi por Engenharia Mecânica. Entrei no IFRN para estudar Operações Comerciais no ensino médio técnico e descobri a existência de programação de softwares por lá. Achei legal, me decepcionei com o “Hello World”, mas meus olhos brilharam depois do programinha que resolveu o raio da circunferência. Decidi fazer Engenharia da Computação para depois me especializar em robótica. Mudei de idéia, fui para o curso de Tecnologia da Informação e estou aqui agora. Me juntei à dois amigos do IFRN e juntos administramos os maiores portais de empregos e estágios do RN, criamos a primeira de Feira de Estágios do estado e fundamos uma agência de publicidade. Trabalho como redatora, analista de mídias sociais e monitora de inglês. Ainda tenho aulas de ballet. “Not all those who wander are lost.” (:

Quais foram as motivações para criar um evento da Pyladies no Brasil?

1661031_1418737858378941_1360692540_n

Gabriela: O porquê de termos tão poucas meninas na área tecnológica. Acho que esse foi o principal motivo que nos fez sair do canto e pensar em mudar. Não entendemos o que houve ao longo da história que fez com que as garotas se assustassem tanto e fugissem disso. Temos grandes nomes como Ada Augusta Byron, Grace Murray Hoper, Radia Joy Perlma e muitas outras que marcaram a linha do tempo da computação e que deveriam ser exemplos para mais meninas entrarem nesse mundo… mas infelizmente poucas conhecem a histórias dessas mulheres. O PyLadies existe para ser um motivador, uma ponte para levar garotas ao mundo da programação. Nosso propósito não é criar ilhas, ou afastar as garotas dos meninos, ou ser um grupo sexista, queremos somente mostrar que mulher pode sim mudar o mundo mesmo sem seu “código fonte”. Não importa o seu sexo, isso não define sua escolha profissional nem limita sua capacidade intelectual, isso é algo que depende somente de você… Yes you can! \o

Katyanna: Um belo dia fui à um dojo da potilivre e vi uma menina falando sobre o PyLadies. Achei incrível ter outra menina ali e ainda mais estando tão envolvida com a coisa, então quando ela me chamou para falar do projeto, eu já estava completamente encantada pela ideia. A área de T.I. é dominada pelos rapazes hoje e isso acaba assustando as garotas. Quando você se coloca lá na frente e traz mais um monte de mulher para falar que a gente também faz parte disso e faz coisas incrivelmente legais, essa imagem de “tecnologia é para garotos” se quebra e abre portas para as moças que estavam em cima do muro.

Tiveram grandes nomes femininos palestrando, quem colaborou e quais foram os assuntos abordados?

Gabriela: Nós tivemos a Professora Adja Ferreira, da UFRN falando sobre o fato da tecnologia ser uma coisa para mulheres também. Logo apos ela, a Camilla Crispin, que é Consultora de Desenvolvimento da ThoughtWorks e trabalha com projetos em ambiente ágil, e falou um pouco sobre a participação feminina na área, deu várias dicas para as garotas e falou um pouco sobre alguns dos problemas sofridos por algumas de nós no meio tecnológico, como a síndrome do impostor.Depois tivemos duas palestras, uma dada pela Débora Azevedo sobre Python (ela já é um fruto do PyLadies, é uma de nossas monitoras), e a última dada por mim sobre o framework Flask.

1149001_1418728171713243_302355628_n

Adja Ferreira

10155541_1418734075045986_628663690_n

Camila Crispin

Débora Azevedo

Débora Azevedo

10154477_1418760598376667_543259386_n

Gabriela Cavalcante

Qual foi o feedback dos participantes? O que lhes surpreendeu?

Gabriela: O feedback foi realmente incrível. Tudo foi muito surpreendente, a quantidade de meninas que compareceram, o empenho delas em aprender algo totalmente novo, e como o evento repercutiu. Ouvir delas que o evento foi ótimo e que elas estão ansiosas para os próximos, nos mostrou que todo o trabalho valeu a pena. Além disso foi incrível vê-las festejando por cada conquista que vinham tendo, por terem conseguido ver o resultado do código no navegador, por terem feito um “Hello World”… isso foi encantador.

10155422_1418730708379656_1378747725_n

Por que Python? O que a linguagem trouxe de facilidade para ensino de programação a pessoas sem qualquer conhecimento?

Gabriela: Python é uma linguagem que está sendo cada vez mais utilizada, é poderosa e extremamente fácil de assimilar. Além disso, a quantidade de materiais, cursos, aulas que podemos ter acesso é enorme, inclusive o curso que utilizamos para treinar as monitoras foi o Python para Zumbis, um material de qualidade oferecido gratuitamente a que se interessa. E ainda tem o fator da comunidade PyLadies já trabalhar com Python, unimos o útil ao agradável. A linguagem é realmente muito boa para trabalhar com quem esta iniciando no desenvolvimento, e para aqueles mais experientes, ela é robusta o bastante para ser usada em seus projetos.

Quanto foi importante o apoio da comunidade para a realização do evento?

Gabriela: Não poderíamos ter feito isso sozinhas. Tivemos o apoio da comunidade local, a PotiLivre, que nos ajudou com treinamento, organização, suporte… tivemos a contribuição da Thoughtworks também, tanto para a palestra com a Camilla, como com pessoas para a monitoria para ajudar as meninas durante o evento, o Ronualdo e a Ana Clara Lacerda ficaram conosco correndo para um canto e para outro, e recebemos muitos conselhos e dicas extremamente importantes, o Ricardo Garcia e muitos outros da empresa foram bem pacientes com a nossa inexperiência com algumas coisas e nos fizeram crescer bastante. Além disso, fomos extremamente incentivadas pelo pessoal da Evolux, uma empresa regional que vestiu a camiseta do PyLadies literalmente. E também há a própria comunidade PyLadies, as meninas de outros países sempre tiraram nossas dúvidas, elogiavam, criticavam, sugeriam… demonstraram o real sentido da palavra comunidade. E as meninas que estavam na monitoria aqui do evento também suaram a camisa para fazer tudo dar certo, temos muito a agradecer à elas, e a várias outras pessoas que ergueram a bandeira do PyLadies conosco.

10151842_1418727458379981_450574345_n

E por fim gostaria que vocês deixassem umas dicas para a pessoas conhecerem os projetos da Pyladies Brasil, envolverem-se na comunidade e considerações sobre o evento em um todo.

1535023_1418633858389341_696287647_n

Gabriela: É importante entender o que queremos passar com o PyLadies. Como eu comentei anteriormente, não somos um grupo com propósito de segregar ou de criar ilhas, e deixar as meninas longe dos rapazes enquanto pregamos um discurso sexista (rsrs tá bem longe disso).

Queremos ser um incentivo para elas não se sentirem inferiores ou inseguras. Eu acredito que maior parte da pressão sofrida pelas meninas, muitas vezes parte delas mesmas. Muitas não se acham capazes, ou se sentem intimidades pela grande quantidade de rapazes, ou acham que estão tomando o lugar de alguém que realmente merecia estar lá… ideias totalmente equivocadas, e que queremos por um fim. Se você se sente curios@ e quer descobrir um pouco mais sobre nós, tem a nossa página pyladiesnatal.potilivre.org, ou envie-nos um email para brazil@pyladies.com. Ainda tem nossa página no Facebook, sempre postamos novidade, links com materiais e avisos sobre a comunidade. Teremos várias novidades mais para frente, não pensem que o PyLadies acabou só no primeiro encontro! Mensalmente teremos reuniões, encontros, formais e informais para falar de programação, tecnologias, novidades, maratonas, fofocas… :) Fiquem atentos e se envolvam, posso garantir que não vão se arrepender.


por Eric Hideki em 16 de April de 2014 às 23:45

Aprenda Python

Um ou dois sublinhados?

Muita gente confunde o uso de nomes iniciados com o caractere sublinhado, o underscore. Essa é uma das convenções adotadas em Python. Mas o uso vai além de simples convenções. O interpretador Python se baseia em regras de nomes para determinar alguns comportamentos. Na seção Reserved classes of identifiers, vemos a citação de três formas de nomeação que têm significados especiais: Nomes

por Vinicius Assef (noreply@blogger.com) em 16 de April de 2014 às 08:43

April 15, 2014

Magnun Leno

Curso de Filosofia GNU - Parte 5

Nesta quinta parte do Curso de Filosofia GNU, Djalma Valois Filho discorre sobre a nossa realidade no Brasil — em que setores do país o Software Livre deve ser aplicado, o objetivo de erradicar o analfabetismo tecnológico, o desenvolvimento de valores (solidariedade, cooperação e apoio mútuo) e o como/onde aplicar o retorno deste investimento — bem como suas próprias expectativas.

Open Source

Lembrando que este é um conteúdo livre obtido no CDTC.

Curso de Filosofia GNU - Parte 5 é um artigo original de Mind Bending

por Magnun em 15 de April de 2014 às 14:34

April 12, 2014

Francisco Souza

Speaking at OSCON 2014

Wow, one year without any posts! But I'm trying to get back...

This is a very short post, just to tell everybody that this year, I will have the opportunity to speak at OSCON 2014. I'm speaking about tsuru, and check more details of the talk in the tsuru blog.

por Francisco Souza (noreply@blogger.com) em 12 de April de 2014 às 22:22

Filipe Saraiva

Qualis Conferências para Ciência da Computação

Se preferir vá direto ao documento Qualis Conferências para Ciência da Computação 2012; ou leia o texto para contextualização sobre o tema.

A Coordenação de Aperfeiçoamento de Pessoal de Nível Superior (CAPES), juntamente com as sociedades científicas das diferentes áreas, mantém um índice de avaliação sobre os veículos de publicação científica utilizados pelos pesquisadores. Esse sistema, conhecido como Qualis, leva em conta uma série de critérios como indexação em bases de dados, fator de impacto, índice H, e outros, para estratificar os veículos que variam, do menor para o maior, entre os índices C, B5, B4, B3, B2, B1, A2, e A1.

É mais comum encontrarmos referências ao índice Qualis quando falamos de periódicos científicos – entretanto, determinadas áreas tem algumas especificidades e o Qualis acaba sendo aplicado também em outros meios de divulgação científica.

Por exemplo, para a área de Ciência da Computação, as conferências podem ter Qualis. O parágrafo abaixo, retirado do Documento de Área 2013 – Ciência da Computação, justifica:

(…) Na área, as publicações submetidas a conferências tradicionais passam por um rigoroso processo de avaliação por pares e os artigos publicados, disponíveis em bases de dados internacionais, são hoje tão importantes para o avanço da área como os melhores artigos em veículos classificados de periódicos. Qualquer pesquisador da área de Ciência da Computação sabe que há conferências de enorme prestígio e que os artigos publicados nos anais dessas conferências são levados em alta conta em avaliações de pesquisa. Há documentos, inclusive do IEEE, enfatizando a importância das conferências para a área.

Eu não sei como funciona nas outras áreas, mas imagino que cada qual deve ter um certo conjunto de conferências cujas características casam com as descritas acima. Mas enfim, a decisão sobre o uso ou não de Qualis em conferências depende de cada área e, se elas não utilizam, deve haver algum motivo – ou não, muito pelo contrário. =)

Para calcular o Qualis das conferências de Ciência da Computação, foi montado um banco de dados com artigos provenientes de aproximadamente 1650 eventos científicos. Esses artigos foram extraídos de repositórios reconhecidos na área, como o DBLP, ACM-DL, IEEEXplorer, BDBComp, e outros. Também foi utilizado o número de citações de cada artigo, dado extraído através do Google Scholar.

A partir desses dados, foi estimado o índice H para as conferências. Há inclusive um site onde é possível pesquisar esse índice para cada conferência da base de dados, o SHINE – Simple H Index Estimation. Com o índice H, aplicou-se os limiares calculados na classificação dos periódicos e, assim, foi possível estratificar as conferências no índice Qualis.

O documento atual da Qualis Conferências para Ciência da Computação data de 2012. Como o anterior foi produzido em 2010, há a perspectiva de que esse documento será atualizado esse ano. Fique de olho na página da Comissão de Área – Ciência da Computação na CAPES pois o documento deverá ser disponibilizado por lá – ou fique atento a esse blog pois escreverei sobre assim que sair a nova versão.

por Filipe Saraiva em 12 de April de 2014 às 18:36

Kodumaro

Modelo de dados em Python

Ao escrever uma classe em Python, é preciso ficar atento a algumas convenções a serem respeitadas.

Métodos especiais

Em Python, métodos começando e terminando com sublinha dobrado (__*__) são reservados e chamados especiais. Você não deve implementá-los se não souber o que está fazendo.

Métodos especiais podem fazer coisas maravilhosas ou criar comportamentos inesperados que zoarão com sua aplicação. São divididos em 12 tipos:
  1. Personalização básica;
  2. Acesso personalizado a atributos;
  3. Criação personalizada de classes;
  4. Verificações personalizadas de instâncias e subclasses;
  5. Emulação de chamada;
  6. Emulação de recipiente;
  7. Emulação de tipos sequenciais;
  8. Emulação de tipos numéricos;
  9. Regras de coerção;
  10. Gerenciamento de contexto;
  11. Pesquisa de classes old-style;
  12. Pesquisa de classes new-style.

Recomendo fortemente a leitura do documento Data model, é essencial ao bom programador.

Métodos privados

Métodos privados são iniciados com sublinha dobrado, mas não terminados da mesma forma (__*).
Um método privado não pode ser acessado de outro contexto a não ser da classe onde ele foi definido.

Isso não é de todo verdade… o que acontece de fato é que métodos privados são prefixados com um sublinha seguido do nome da classe, para evitar que sejam sobrescritos e prevenir acesso a partir de subclasses ou de fora do contexto da classe.

Por exemplo, no contexto da classe Person, todos os métodos iniciados com sublinha dobrado serão prefixados com _Person. Assim, __fix_data vira _Person__fix_data.

Isso permite que você faça herança múltipla de classes que possuem o mesmo nome de método privado sem conflitos.

Métodos protegidos

Há uma convenção em Python de que métodos com nome iniciado com um sublinha (_*) são protegidos, ou seja, só devem ser acessados no contexto da classe e de suas subclasses.

Nenhum tratamento é feito para evitar que sejam acessados de outros contextos, mas se espera que os programadores sigam a convenção.

A orientação em Python é que o programador não é nenhum bebezinho que precisa ser guiado e sabe o que está fazendo, portanto não aja como um bebê e respeite as convenções.

Atributos e propriedades

Tudo o que foi dito sobre métodos especiais, privados e protegidos também vale para atributos e propriedades.

[]’s
Cacilhας, La Batalema

por noreply@blogger.com (Darth Batalema) em 12 de April de 2014 às 14:42

Ordem de chamada dos métodos de inicialização

Quando você cria e instancia uma classe em Python, muita coisa acontece e acho que nem todos estão familiarizados com os passos.

Vamos dar uma olhada na sequência.

Criação da classe

Quando você cria uma classe com o statement class, a primeira coisa que acontece é o construtor (__new__) da metaclasse (por padrão type) ser chamado.

O construtor recebe como parâmetros a própria metaclasse, o nome da classe (str ou bytes), uma tupla contendo as classes base da classe criada e um dicionário com métodos e atributos declarados no corpo da classe.

Caso você sobrescreva o construtor da metaclasse, ele precisa retornar o objeto instanciado, que você obtém do construtor da classe pai da metaclasse.

Em seguida o método de inicialização (__init__) da metaclasse é chamado, recebendo como parâmetros o retorno do construtor, o nome da classe, a tupla de classes base e o dicionário de métodos e atributos.

É recomendável não sobrescrever o construtor da metaclasse. Qualquer procedimento pode ser tranquilamente executado nos métodos e inicialização e de chamada.

Instanciação da classe

Quando você instancia a classe, o primeiro método a ser chamado é o método de chamada (__call__) da metaclasse. Ele recebe como parâmetros a classe e quaisquer parâmetros passados no comando de instanciação.

Em seguida é evocado o construtor da classe, recebendo a classe e quaisquer parâmetros passados no comando de instanciação.

É obrigatório que a instância criada pelo construtor de super seja retornada, caso o construtor seja sobrescrito.

Após o construtor, o método de inicialização da classe é chamado, recebendo como parâmetros o retorno do construtor e quaisquer parâmetros passados no comando de instanciação.

Chamando a instância

Caso o método de chamada seja implementado na classe, a instância é “chamável” (callable). Na chamada o método de chamada é executado recebendo a instância e quaisquer parâmetros passados na chamada da instância.

Quem é quem

Um pequeno código apenas com boilerplates que não executam nada, com o único objetivo de demonstrar onde fica cada método citado:
class Metaclasse(type):

def __new__(meta, name, base, dict_):
""" Este é o construtor da metaclasse """
return type.__new__(meta, name, base, dict_)

def __init__(cls, name, base, dict_):
""" Este é o método de inicialização da metaclasse """
type.__init__(cls, name, base, dict_)

def __call__(cls, *args, **kwargs):
""" Este é o método de chamada da metaclasse """
return type.__call__(cls, *args, **kwargs)


class Classe(object):
__metaclass__ = Metaclasse

def __new__(cls, *args, **kwargs):
""" Este é o construtor da classe """
return super(Classe, cls).__new__(cls)

def __init__(self, *args, **kwargs):
"""
Este é o método de inicialização da classe.
Como ela herda de object, não há necessidade de
chamar super, mas quando houver, a forma é:
super(Classe, self).__init__(*args, **kwargs)
"""

def __call__(self, *args, **kwargs):
""" Este é o método de chamada da classe """
return None

Dois dedos de prosa sobre método destruidor

O método destruidor (__del__) não é chamado quando o objeto perde todas as referências ativas, mas sim quando é coletado pelo garbage collector (gc).

Como o gc não tem hora certa para rodar e seu comportamento varia muito de uma implementação de Python para outra, não é recomendável confiar nele para executar procedimentos críticos.

O que você pode fazer é usá-lo para garantir determinados estados que podem ter sido esquecidos ou perdidos depois que a instância ficou sem referências.

Observações finais

As assinaturas do construtor e do método de inicialização da classe devem ser rigorosamente iguais.

[update]
Um detalhe importante é que, se o método de inicialização for sobrescrito alterando sua assinatura, não há necessidade de sobrescrever o construtor, porém se o construtor for sobrescrito alterando sua assinatura, é obrigatório que o método de inicialização também seja sobrescrito.

Detalhes da linguagem…
[/update]

A chamada do método de chamada da classe pai da meta classe deve passar os parâmetros esperados pelos argumentos nas assinaturas do construtor e da inicialização da classe. No exemplo acima, esta chamada (precedida por return) é:
type.__call__(cls, *args, **kwargs)

[update]
Um detalhe que esqueci de mencionar é que é justamente nessa chamada que o construtor e o método de inicialização são evocados.
[/update]

Os parâmetros passados são os esperados nas assinaturas citadas.

[]’s
Cacilhας, La Batalema

por noreply@blogger.com (Darth Batalema) em 12 de April de 2014 às 12:40

April 11, 2014

Magnun Leno

Vocal: Gerenciador de Podcasts para o Linux

Eu não sei vocês, mas eu sou fanático por Podcasts. Atualmente, no meu android, tenho 17 podcasts inscritos sendo que destes apenas 8 nacionais (consequentemente 9 internacionais). Isso dá uma boa ideia de como seria a vida das pessoas que gostam de podcast sem um gerenciador.

Vocal

Em outras plataformas (Windows e Mac OS) existem ótimas ferramentas para isso e, infelizmente, o GNU/Linux falhava nesse ponto. Até este momento…

Vocal: Gerenciador de Podcasts para o Linux é um artigo original de Mind Bending

por Magnun em 11 de April de 2014 às 21:26

Curso de Filosofia GNU - Parte 4

Essa é uma parte delicada na Filosofia GNU, muitas pessoas não entendem porquê Richard Stallman implica tanto com a nomenclatura de sistemas operacionais. Muitas pessoas dizem que Stallman começou da forma errada, escrevendo as ferramentas antes do kernel. Mas se analisarmos o contexto histórico (a "decadência" do Unix), fazia sentido escrever primeiro as ferramentas para substituir aos poucos as ferramentas não livres, para posteriormente escrever um novo kernel.

I Want GNU!

Lembrando que o Curso de Filosofia GNU é um conteúdo livre obtido no CDTC.

Curso de Filosofia GNU - Parte 4 é um artigo original de Mind Bending

por Magnun em 11 de April de 2014 às 14:13

April 10, 2014

Sidnei da Silva

How to help your kid gain confidence at home?

Speech impairment is getting very common nowadays. If you feel that your kid is facing difficulty in pronouncing some of the letters or words then possibly he could be facing a sort of speech impairment. Few years back, if a child had problems while speaking then he had to live with them till the end of his life. But now this is not the case as medical science and information technology has made much advancement. You can easily make use of online speech therapy to correct problems of your child. The speech therapist is a qualified medical practitioner who will help your child in pronouncing those words and letter that he is not able to pronounce.

Speech therapists use different techniques and technological devices that help your child in overcoming his speech impairment. But preparing your kid psychologically to meet with a speech therapist is a really tough task. Most of the kids feel deeply ashamed and uncomfortable while meeting with the speech therapist so that’s why they are unable to co-operate with the therapist.

With the advancements in the field of information technology, you could easily have a speech therapy of your child through your computer in the comfort of your home. The internet has proved to a very miraculous invention of the 21st century as it has and it is still solving many problems of common human beings. Now there are many websites available online through which your child could easily solve his speech problems. These websites have different tongue twisting games that would help your child pronounce those words or letters that can’t be pronounced by him.

Now get your speech therapist at your home:

Most of the people fall in to doubt when it comes to hiring the services of a speech therapist as the services of these professional speech therapists are very expensive. But now with the introduction of online speech therapy, this problem is completely solved. You can get the services of a speech therapist for your child by sitting in the comfort of your home without paying any sort of cost or fee.

Now there are some websites where these speech therapists are also available through video conferencing. In order to avail the facility of video conferencing, you just have to make sure that your device has the feature of a video camera with it. After this, all you have to do is to register the name of your child on that website and then these websites through emails would notify you of the timings when the speech therapist would be available online. The speech therapist would provide a complete professional online speech therapy to your child without any expense, right in the privacy and comfort of your home. Plus he would also guide your child to play those games that would improve his speech. Through these websites you could also purchase a set of certain tools that would help your child in improving his speech.

por admin em 10 de April de 2014 às 22:36

Magnun Leno

PyCon2014 em Montréal

Na última Quarta-Feira (dia 09 de Abril) teve início a PyCon2014, desta vez localizada em Montréal, conferência oficial da linguagem Python que se estenderá até o 17 de Abril. Como das outras vezes o evento é dividido em Tutoriais (do dia 9 ao dia 10), Conferência (do dia 11 ao dia 13) e Sprints (do dia 14 ao dia 17).

Pycon2014 Montréal

Para quem ouve falar pela primeira vez da PyCon a seção Tutorial é a parte do evento onde ocorrem "aulas" e treinamentos, a seção conferência é a porção do evento que temos as palestras e as lightning talks e a ultima porção, os sprints é um período que os participantes de organizam em grupos e programam juntos, visando implementar alguma funcionalidade, resolver algum bug ou simplesmente colaborar com algum projeto Open Source.

PyCon2014 em Montréal é um artigo original de Mind Bending

por Magnun em 10 de April de 2014 às 19:39

Entendendo o Heartbleed e Previnindo-se

Há um tempo nos acostumamos a pensar que, se estamos em um site com HTTPS (Protocolo HTTP encriptado por SSL/TLS) estamos seguros, assim como nossos dados. A criptografia SSL/TLS baseada em certificados supostamente previne qualquer tipo de interceptação de dados entre você e o servidor. Isso até aparecer o Heartbleed.

Heartbleed

O Heartbleed é uma vulnerabilidade séria que afeta a biblioteca e os softwares de criptografia contidos no OpenSSL. Esta falha permite que informações protegidas sejam roubadas (mesmo em circunstâncias normais de uso) em diversos serviços como web, email, instant messaging (IM) e algumas VPNs (virtual private networks).

Entendendo o Heartbleed e Previnindo-se é um artigo original de Mind Bending

por Magnun em 10 de April de 2014 às 14:26

April 09, 2014

Osvaldo Santana Neto

“Ondas” tecnológicas

Kindle

Já é de conhecimento de todos que trabalho com computação já faz muito tempo. Vi muitas ondas passarem.

Quando comecei com BASIC em máquinas de 8bits vi a primeira onda chegar… eram as linguagens estruturadas. Linguagens “procedurais”… código sem GOTO, etc. Quem programava só em BASIC e não conhecia esse “novo paradigma” (aspas propositais) estava fadado ao fracasso e ao ostracismo. Não mereceriam ser chamados de programadores.

Parti para a luta e fui aprender Pascal, C e/ou Clipper.

Assim que dominei esse “novo paradigma” avistei outra “nova onda”: Programação Orientada a Objetos.

Essa foi uma das primeiras grandes ondas que contaram com apoio de Marketing de grandes empresas. Lembro-me de ler sobre “orientação a objetos” até em jornais de bairro (hipérbole detectada!). E mais uma vez fui convencido de que se não dominasse esse “novo paradigma” eu estaria fadado ao esquecimento.

Então comecei a estudar o assunto e no meu entendimento inicial (e duradouro) uma “classe” nada mais era do que um “struct” (ou RECORD) com esteróides. Ainda existem registros da minha primeira incursão nesse novo mundo. Eu só fui entender melhor OOP recentemente.

Outra onda que “bombou” mais ou menos na mesma época era a dos bancos de dados relacionais (SQL e afins). Mas eu não tinha muito contato com esse mundo que era restrito às “elite$”.

E com OOP e SQL essas empresas de marketing que, eventualmente, produziam software começaram a ganhar rios de dinheiro vendendo “gelo para esquimó”.

A tecnologia dos computadores surgiu para empresários em mensagens como: “Se sua empresa não usar OOP ou SQL você (perderá dinheiro|será devorado pela concorrência|será feio e bobo).” — (IBM|Gartner|Oracle)

Os empresários eram completamente ignorantes sobre esses assuntos e, num ato de fé, acreditavam em tudo o que as “IBMs” diziam. Afinal elas ficaram grandes e ricas por lidar com tecnologia, certo? Conseguem detectar a falha primordial nesse raciocínio?

Esse tipo de mensagem juntamente com a outra que dizia: “ninguém é demitido por ter escolhido IBM” fez muito bem para o lucro dessas empresas.

Naquela época isso fazia sentido, afinal, os computadores não faziam parte da vida de todo mundo. Tecnologia e mágica eram sinônimos. Mas hoje isso não deveria mais ser assim. A fábrica de “hypes” continua funcionando e os empresários e profissionais da área continuam investindo em tecnologias “da moda” apenas por estarem na moda.

Outras “ondas” movimentaram e ainda movimentam o mercado e com certeza não lembrei de todas: OpenSource, Java (J2EE), XML, NoSQL, Cloud, metodologias de desenvolvimento (ágeis ou não), Big Data, Internet of Things, Frontend/Backend engineering, etc.

Para cada uma delas temos defensores (não é uma onda! é realidade! olha só isso aqui!) e detratores (isso é hype! isso não funciona!). Ambos estão certos e errados.

Meus amigos devem estar pensando: “Mas ele é o cara que mais compra esses hypes! Andava com uma camiseta ‘você ainda usa banco de dados?’!”.

Eu, de fato, acompanho todas essas ondas. Cada uma delas acrescenta algo na minha caixa de ferramentas. Sempre que vejo uma delas chegando já vou logo dando uma chance pra elas se provarem úteis. Mas isso não significa que vou adotá-las em tudo o que farei e que as coisas antigas são lixo.

É o velho clichê: existem ferramentas certas para resolver cada tipo de problema.

Resolvi escrever isso pra que vocês possam refletir sobre a adoção racional de tecnologias. Usar critérios técnicos para a escolha e não ficar pegando jacaré em qualquer onda que aparece.

Outra coisa importante é não parecer bobo falando que você faz “Big Data” pra um cara que já processava toneladas de dados antes mesmo de terem cunhado essa expressão. Ou falar que usa NoSQL pra um cara que já usava Caché (kind of OODBMS), LDAP (hierárquico), ou Isis (schemaless).

Como vivi todas essas ondas eu saco logo que esses caras são mais “gogó” do que outra coisa.

Mantenham o foco em criar coisas boas que resolvam problemas importantes e escolham tecnologia usando critérios técnicos.

Ser proficiente numa linguagem é um critério muito importante mas ele deve ser considerado em conjunto com outros critérios (robustes, disponibilidade de recursos, etc).

Dia desses vi um anúncio procurando programador Clipper e pensei: esse contratante deve ter um excelente software. Deve ser um software tão bom e deve resolver problemas tão importantes que ele resistiu à várias ondas e não virou areia.

The post “Ondas” tecnológicas appeared first on Blog do Osvaldo.

por osantana em 09 de April de 2014 às 17:36

Magnun Leno

Curso de Filosofia GNU - Parte 3

Na terceira parte do Curso de Filosofia GNU lhe serão apresentadas as 4 liberdades básicas que um software livre te garante e você irá entender porque a FSF (Free Software Foundation) luta para garantir esta liberdade.

Free Sfotware Word Cloud

Lembrando que este é um conteúdo livre obtido no CDTC.

Curso de Filosofia GNU - Parte 3 é um artigo original de Mind Bending

por Magnun em 09 de April de 2014 às 13:17

Sidnei da Silva

The wonderful way for correcting speech online

The speech therapy is that methodology which is in practice for quite a long time or years. According to the medical science, the speech therapy is used for the people to correct their verbal communication in the best possible ways. It is done because they might be suffering from some serious communication disorder. The online speech therapy to correct problems regarding speech is found at different medical sites present around the web. The biggest advantage of such a facility is that disorders regarding verbal communication and speech are sorted out. The main focus of this online speech is on your language and your expressive tone.

This disorder in speech and verbal communication can be birth or it can be also caused from a certain disease or some injury. The online speech therapy option gives a patient a place to overcome this disorder in speech. The speech is of different types. It can be in the form of communication, gestures, body language and some verbal data, etc. A person suffering from speech disorders suffer from two major issues which are mentioned below:

  • Lisping
  • Stuttering

The two above mentioned issues are often seen in people suffering from disorders in the speech therapy. The online speech therapy gives them a special treatment called as therapeutic treatment. Basically, the aim of this treatment is to deal with the distorted speech issues. This online speech therapy technique uses special methods for the patient.

Advantages of online speech therapy:

Given below are some of the advantages of using online speech therapy

• You can stay at home and then just by sitting comfortable on the chair, you would be able to polish your distorted speech disorder.

• Online speech therapy is good as it does not allow the patient to do any sort of physical movement or exertion.

• You will find a wide variety of different online therapy platforms on the web and in this way; you can easily mend your disorders regarding speech in the best possible way.

Why speech therapy is recommended?

Imagine a person who is not really dumb and he can speak but by having some disorder in the speech so it would be really great if he starts speaking well. This can only be done if that certain person goes through a complete process of speech therapy. The fact is that speech therapy has the complete power to boost up your tongue cells and then by exercising being followed in this technique you start speaking up in a better form. This is the only reason why speech therapy is recommended. So, you must search well for the best online speech therapist as all it depends on your research for the right online speech therapist. It is all about which therapist you have selected for your speech therapy. A good service would lead to the better results indeed.

por admin em 09 de April de 2014 às 06:17

April 08, 2014

Magnun Leno

Curso de Filosofia GNU - Parte 2

Dando continuidade ao Curso de Filosofia GNU, hoje veremos um pouco porquê o software proprietário é considerado anti ético e anti social. Como podemos ser controlados pela obsolescência programada e como as empresas públicas e privadas gastam bilhões para garantir que suas próprias informações continuarão disponíveis e acessíveis para eles próprios.

Vida de Programador #55

Tirinha #55 "Software Prorietário" do site Vida de Programador

Lembrando que este é um conteúdo livre obtido no CDTC.

Curso de Filosofia GNU - Parte 2 é um artigo original de Mind Bending

por Magnun em 08 de April de 2014 às 13:52

April 07, 2014

Sidnei da Silva

Speech therapy made easier

Correcting speech disorders online is called online speech therapy to correct problems. Speech disorder means having a difficulty in communicating with people verbally. It can happen when there is a difficulty in producing certain sounds in terms of fluency and correctness. The ability to receive and comprehend verbal sounds is known as receptive language and it is a tool used in speech therapy. Speech is a result of coordination between lips, tongue, jaws and vocal tract.

For a person having speech disorder, all these problems are accommodated and the speech and learning process is recreated. Because of the better communication through the internet and the advancements in technology, this method is becoming more common where schools and universities also hire the services of famous speech therapists from all over the world. If you have a child who is unable to speak fluently and feels under confident, you can hire the services of speech therapists from anywhere in the world. There are many benefits of online speech treatment to correct problems.

Speech language pathologists from anywhere in the world can be appointed for your child. There is no question of limited accessibility because of the innovation in technology. The therapists are culturally and linguistically versatile and would be available outside your office time if you prefer.

Therapy tools that are available online have been beneficial to people and children with speech issues because they have been created in such a way that positive outcomes can be expected. Due to the availability of an SLP on a more frequent basis, the improvement rate is also high.

Learning to speak fluently and communicate in a better way will not only make kids happy, rather, their parents will also be satisfied. Because children have been exposed to the technology at a rate faster than adults of today, they are more attracted towards the gadgets and devices. They like to learn in an interactive manner so the use of digital technology will prove to be much better than simple methods.

Schools, colleges and other institutes have been able to cut their cost by reduction in the budget that they kept aside for SLPs before. With SLPs now available online, there is no expense in terms of employment, travel expenses and management. Besides, the whole process has become a lot more time saving as the travel time has been reduced.

Because of real time reporting and feedback, any improvement or complaints in the person having speech difficulty is seen by the therapist. Analysis of the situation and the change in strategy is also thus easier.

There are primarily no set up costs involved in offering SLP services to others. All that is needed is a fast internet connection and the devices to interact with students. Headsets, computers, webcams etc are sometimes provided by the firm itself.

SLPs that offer online services are usually recognized for the services that they provide. They are known the world over and the services are widely accepted in different regions. Because of being certified by international training companies, it becomes very easy for SLPs to deliver services.

por admin em 07 de April de 2014 às 19:12

Wonders and effects of online speech therapy

The internet has proved to be very beneficial for human beings in all aspects of life. Now this fabulous invention is also used in the field of medicine. Many great and complicated diseases are cured due to this invention. There are many people around the world who are facing the problems of speech injury and are not able to hire the expensive services of a speech therapist due to the financial stress they face in their everyday life. Here, online speech therapy has emerged as miracle for these people. The use of online speech therapy to correct problems of all those people who have trouble during speaking is getting very common these days. And due to its cost effectiveness, many people around the world prefer this mode of speech therapy in comparison to visiting a professional speech therapist at his clinic.

Online speech therapists not only treat the speech injury of kids but those adults who have difficulties in speaking can also benefit from these speech therapists. Getting a speech therapy from speech therapist at his clinic seems to be a very disturbing procedure for most of the adults.

Many adults feel very uncomfortable about the idea of meeting with a speech therapist and also fear that how the community and their colleagues at work would react to the fact that they are having a speech therapy. But due to the fact that many speech therapists are also providing online speech therapy, the problems of these adults have been solved. Through online speech therapy, all the adults can easily benefit from these speech therapists in the seclusion and privacy of their home. The greatest wonder of the internet is the online speech therapy through which any adult can improve his speech without any sort of fear from the society.

Effects of online speech therapy:

You will feel the following effects of online speech therapy:

  • With the help of online speech therapy, you would definitely feel high level of confidence. You can deal with your day-to-day activities with high level of confidence and ease after this therapy as these therapies have a special focus on the confidence level of the patient.
  • Most of the people who face speech impairment also seem to have receptive problems which mean that they are not able to understand the things said by another person. So, after the speech therapy, a person not only feels a great change in his speaking ability but he also feels a great improvement in his receptive disorders.

Benefits of online speech therapy:

Although, most of the people think that getting a speech therapy directly from a speech therapist in his clinic is much better than getting an online speech therapy. After much advancements in the field of technology, online speech therapy is catching quite fame from around the world. Some of the reasons that are compelling people to adopt online speech therapy are mentioned below:

  • No expenses incur during online speech therapy
  • No need to travel
  • Flexibility of time
  • Complete privacy
  • Faraway areas can also have access to this miracle through the internet

Online speech therapy is getting very famous and proving very beneficial for most of the people around the world.

por admin em 07 de April de 2014 às 19:07

Magnun Leno

Curso de Filosofia GNU - Parte 1

Olá pessoa! Há muito tempo eu descobri o Projeto CDTC (Centro de Difusão de Tecnologia e Conhecimento), onde fiz alguns cursos na área de tecnologia utilizando softwares livres. O Projeto CDTC visa a promoção e o desenvolvimento de ações que incentivem a disseminação de soluções que utilizem padrões abertos e não proprietários de tecnologia, em proveito do desenvolvimento social, cultural, político, tecnológico e econômico da sociedade brasileira.

GNU

Alguns dos cursos disponibilizados por eles me chamaram muito a atenção pelo simples fato de não ter visto antes um agregado de informações tão bem elaborado sobre certos assunto, um destes assuntos é o curso de Filosofia GNU. Uma vez que o conteúdo do curso é disponibilizado sobre os termos da FDL (GNU Free Documentation License) eu tenho o direito de reproduzi-lo aqui (mantendo os créditos).

Curso de Filosofia GNU - Parte 1 é um artigo original de Mind Bending

por Magnun em 07 de April de 2014 às 14:42

Servindo Sites Estáticos Com o NGINX

Três fatos me deixaram muito satisfeitos ao migrar para o Pelican, conforme informado nesses outros artigos. O primeiro deles foi não ter que utilizar mais nenhum editor WYSIWYG (what you see is what you get), agora escrevo apenas no VIM. O segundo deles foi utilizar o Pelican em conjunto com o Git, tanto para versionamento de artigos, configurações, temas, plugins e etc, quanto para fazer publicações, através do Git Hooks. Por último, mas não menos importante, foi o fato de finalmente parar de o usar o Apache e migrar para o NGINX!

NGINX Logo

Lembrando que tudo que será apresentado neste artigo é usável (sob certos ajustes) tanto para ambientes de produção (para o servidor que "roda" seu site) quando para ambientes de desenvolvimento (sua estação de trabalho).

Servindo Sites Estáticos Com o NGINX é um artigo original de Mind Bending

por Magnun em 07 de April de 2014 às 03:40

April 02, 2014

Elcio Luiz Ferreira

Acessibilidade para Twitter Bootstrap

Dica do Hans Mösl no grupo de trabalho de acessibilidade do W3C Brasil:

Plugin de Acessibilidade para Twitter Bootstrap. Plugin de código aberto, no GitHub. Promete tornar acessíveis uma porção de componentes Javascript do Bootstrap e, até onde eu consegui conferir, funciona muito bem.

Considere incluir em seu próximo projeto. Considere incluir nos seus projetos antigos baseados em Bootstrap 3. Considere incluir sempre.

O post Acessibilidade para Twitter Bootstrap apareceu primeiro em fechaTag.

por elcio em 02 de April de 2014 às 16:16

April 01, 2014

Elcio Luiz Ferreira

Microsoft quer ressuscitar o Flash

winphone8-title-cardDepois de uma tentativa frustrada de parceira com a Nokia, a Microsoft encontra uma nova parceira para sua batalha contra a Apple: a Adobe. A parceria parece ser boa para ambos os lados: ao mesmo tempo em que a Microsoft luta para manter sua posição no mercado de PCs contra o avanço dos Macs, a Adobe teve um de seus principais produtos, Flash, morto pela Apple.

A parceira envolve lançar uma nova versão do Adobe Flash, que deixará de ser produzido para Macs e a partir de agora funcionará apenas no sistema operacional Windows. Essa nova versão estará integrada ao Visual Studio, ao .Net Framework e ao Microsoft Sharepoint. O objetivo é tornar o Flash um novo padrão para a construção de sites, portais e aplicações web. Além disso, o ponto forte da estratégia é fazer do Flash a ferramenta oficial para a construção de aplicativos para as plataformas Windows 8 e Windows Phone.

Segundo Emmett Brown, vice presidente de estratégias globais para o futuro da Microsoft, plataformas abertas como o HTML5 são prejudiciais à livre concorrência e à inovação no mercado de desenvolvimento web e, ao trazer o Flash de volta, a Microsoft pretende inaugurar uma nova era no mundo dos aplicativos móveis.

Para mais detalhes sobre a parceria, leia o anúncio na íntegra no site oficial.

O post Microsoft quer ressuscitar o Flash apareceu primeiro em fechaTag.

por elcio em 01 de April de 2014 às 12:19

March 30, 2014

Elcio Luiz Ferreira

Minha palestra no GAiN

Update: saiu o vídeo: Tendências para o futuro da Web: uma leitura a partir do trabalho do W3C – SAC/GAiN 2014.

Apresentei hoje cedo uma palestra no GAiN, um encontro de profissionais de comunicação e internet da minha igreja. Há um tempo que venho falando às pessoas que trabalham com internet na igreja sobre os padrões do W3C. Mas hoje tive a oportunidade de falar para gente que trabalha com isso de toda a América do Sul, de uma vez.

Muito obrigado aos organizadores pelo convite. Quem quiser conferir minha palestra no GAiN, sobre as tendências para o futuro próximo da web, pode encontrar a apresentação aqui: aqui.

Não sei se minha palestra foi gravada. Se eles publicarem lá, aviso por aqui.

O post Minha palestra no GAiN apareceu primeiro em fechaTag.

por elcio em 30 de March de 2014 às 19:28

March 28, 2014

Elcio Luiz Ferreira

March 26, 2014

Magnun Leno

Lançado o Gnome 3.12

Hoje, dia 26 de Março de 2014, o foi lançado o GNOME 3.12, o próximo milestone da série GNOME 3. Esta release contém diversas melhorias, atualizações, novas funcionalidades, bem como diversas mudanças na API para desenvolvedores. Já está disponível a Press Release e o Release Notes.

GNOME 3.12 Window Selection

Citando Matthias Clasen, da Equipe de Lançamento do GNOME

Esta é uma versão emocionante para GNOME, traz muitas novidades e melhorias, incluindo pastas de aplicativos, melhorias no system status e suporte a monitores de alta resolução.

Lançado o Gnome 3.12 é um artigo original de Mind Bending

por Magnun em 26 de March de 2014 às 19:26

March 22, 2014

Henrique Bastos

SQLFormatter: Beautiful colored SQL statements for logging

Logging your SQL to the console helps you understand whats going on under the ORM.

However, queries can get pretty big resulting on a code wall.

SQLFormater is a logging formatter that idents and colorize your SQL statements making everything legible again.


Latest PyPI version
Number of PyPI downloads

How it looks like?

Screenshot

Install

    pip install sqlformatter

Usage

If you’re using Django, simply add it to your LOGGING settings:

    LOGGING = {
        'version': 1,
        'disable_existing_loggers': False,
        'handlers': {
            'sqlhandler': {
                'level': 'DEBUG',
                'class': 'logging.StreamHandler',
                'formatter': 'sqlformatter'
            }
        },
        'formatters': {
            'sqlformatter': {
                '()': 'sqlformatter.SqlFormatter',
                'format': '%(levelname)s %(message)s',
            },
        },
        'loggers': {
            'django.db.backends': {
                'handlers': ['sqlhandler'],
                'level': 'DEBUG',
            },
        }
    }

License

The MIT License (MIT)

Copyright (c) 2013 Henrique Bastos <henrique at bastos dot net>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

por Henrique Bastos em 22 de March de 2014 às 17:05

Filipe Saraiva

Haverá futuro para o Diaspora?

Diaspora é aquela rede social que foi financiada via crowdfunding no Kickstarter e fez muito barulho na imprensa do mundo todo por conta do discurso que seus criadores utilizavam: “Diaspora será o Facebook killer”. Mas isso foi em 2010.

Perambulo pelo Diaspora desde a versão de testes, lançada em 2011. Na época você tinha que conseguir um convite para ter uma conta na instância (também chamada de pod) mantida pelo time de desenvolvedores, o joindiaspora. De lá para cá pouca coisa mudou quando falamos em funcionalidades – o que contrasta bastante com as grandes mudanças que ocorreram no gerenciamento do projeto, onde hoje os quatro programadores que recorreram ao crowdfunding para levantar a grana que pagaria o desenvolvimento já não trabalham mais com a plataforma, “doada para a comunidade” há um ano e meio, e que agora depende exclusivamente desta para avançar.

Antes de começar o artigo de fato, quero dizer aos amigos que não me tomem como pessimista ou alguém do gênero – ou pior, como alguém que não acredita que comunidades podem criar e gerir bons projetos de software livre. Eu participo ativamente como desenvolvedor em pelo menos dois projetos comunitários (a saber, KDE e Mageia) e sei que, sim, é possível termos bons projetos baseados em comunidades. Mas o que acompanho do Diaspora, em termos de desenvolvimento, não me deixa muito animado. Por outro lado, talvez os brasileiros que nos últimos meses lotaram o Diaspora possam dar sua contribuição para não deixar a plataforma morrer.

De qualquer forma, caso o Diaspora não decole, ainda temos muitos bons projetos de redes sociais descentralizadas, federadas, em software livre, para podermos migrar.

Diaspora – funcionalidades

Para um projeto que se propôs a desbancar o Facebook, faltam muitas funcionalidades no Diaspora. Basicamente você tem o stream (a sua timeline) com as pessoas que você segue. Você também pode seguir tags – a rede social permite a inclusão delas nos posts. E quando você adiciona alguém, a pessoa adicionada não o segue automaticamente de volta. Sempre que adicionar alguém você colocará o contato em um ou mais aspects – conceito criado aqui, depois copiado como Listas no Facebook ou o Círculos no Google+. Os posts podem ser escritos usando a linguagem de marcação Markdown – não há um editor WYSIWYG para usá-la.

Olhando bem para esse conjunto de funcionalidades, o Diaspora lembra muito mais o Twitter do que o Facebook, porém sem a limitação de caracteres do primeiro.

A partir das funcionalidades presentes, podemos listar as funcionalidades que mais fazem falta no projeto: não há suporte a grupos; não há chat; não há uma API que permita o desenvolvimento de clientes ou outras aplicações que utilizem o Diaspora; as tags não são federadas – portanto você só verá as tags dos perfis que estão no mesmo pod que você; entre outras.

Caramba, não há uma funcionalidade para importar um perfil em outro pod! Ou seja, você tem uma rede descentralizada, mas o seu perfil está amarrado ao pod no qual você o criou até o fim daquele pod. Você conseguirá exportar seu perfil, mas servirá apenas como backup em algum canto perdido do seu HD.

É um tanto decepcionante constatar isso, em especial quando você sabe que em outras redes sociais livres essas funcionalidades estão presentes, ou quando você conhece a história de um famoso fork do Diaspora chamado Diasp0raca.

Esse fork era mantido por um desenvolvedor chamado Pistos. Nenhuma de suas contribuições de funcionalidades foram aceitas pelos desenvolvedores do projeto original, mas Pistos mantinha-as em seu fork e também gerenciava um pod que rodava o seu código – que ficava em http://diasp0ra.ca/. Com o tempo, devido à presença dessas funcionalidades, outros pods adotaram o código de Pistos.

Para resumir, o Diasp0raca tinha grupos, chat, possibilidade de importar os contatos de um perfil, CSS customizável, preview de posts, entre outras funcionalidades. Inclusive ele estava trabalhando em uma API! Tudo isso já funcionava no início de 2012. Mais de dois anos depois, e a única dessas funcionalidades disponível no Diaspora é… o preview de posts.

Pistos acabou rompendo relações com o Diaspora após o anúncio de que os desenvolvedores desta fariam uma profunda alteração no protocolo de comunicação, o que cortaria a comunicação entre diversos pods e outras redes sociais que conseguiam se comunicar com a rede Diaspora (por exemplo, o Friendica), sem qualquer discussão com os desenvolvedores interessados e sem disponibilização de documentação. O hacker chutou o balde e lançou um novo projeto de redes sociais distribuídas, o LiberTree.

Diaspora – gerenciamento do projeto

Como já comentado, o Diaspora começou como o projeto de um pequeno grupo de desenvolvedores – quatro caras. Apesar do desenvolvimento ser livre e colaborativo, o gerenciamento do projeto era bastante centralizado nesse time, e poucas funcionalidades criadas por desenvolvedores externos foram absorvidas pelo projeto.

A impressão que fica é que eles tentaram criar um modelo de negócios no estilo do WordPress, mas não tiveram êxito. Relatório de dívidas quanto à manutenção do pod público (o joindiaspora), a falta de um plano de negócios para captar recursos, a criação de um novo projeto baseado na criação de memes (!!!), e o triste suicídio de Ilya, um dos fundadores, acabaram levando o grupo à decisão de desistirem do projeto e a tomarem a típica atitude de uma empresa que não está mais interessada em investir em um software livre antes desenvolvido por ela: “doaram o projeto para a comunidade”. Era agosto de 2012.

Desde então o Diaspora tem sido gerenciado por um grupo de desenvolvedores reunidos sob a Diaspora Foundation. Seus principais canais de discussão sobre o desenvolvimento da ferramenta são o grupo de e-mails, a wiki, a ferramenta de deliberação loomio, e o repositório do código hospedado no github.

O que sinto ao visitar esses lugares é um projeto ainda perdido, com pouco gás, sem aqueles desenvolvedores que se metem a criar grandes funcionalidades, que dedicam seu tempo a fazer o projeto caminhar de verdade. Claro que o pessoal está trabalhando, e o trabalho deles deve ser agradecido – mas a maior parte são ainda em pequenos detalhes, coisas pontuais diante das necessidades da rede.

Olhe por exemplo a lista de e-mails de desenvolvimento: você pode rolá-la e não verá nada de discussão sobre qualquer funcionalidade que aponte maneiras de implementá-la. Apenas diálogos sobre algo que precisa ser feito, ou propostas de implementações de funcionalidades pequenas.

No loomio também é assim. Há importantes tópicos abertos, mas que tiveram início há muito tempo – vários meses e alguns com quase um ano de idade. Há discussão no período imediato à abertura do tópico, depois ele esfria. Passam-se meses, depois volta um pouco de diálogo, apenas para morrer em seguida.

Enquanto escrevia esse post aconteceu algo que ilustra bem essa situação: compartilhei um merge request no github com código para prover acesso à aplicações de terceiros para o Diaspora – ou seja, boa parte de uma API. O Diaspora precisa disso para facilitar que seus usuários gerem e direcionem conteúdo para a rede. Há um serviço, o PaperBod, que direciona para o Diaspora o stream de sua conta do Twitter, Facebook, ou mesmo um feed RSS. O que ele precisa para funcionar? O seu login e a sua senha! Que dizer de uma rede social cujo discurso é baseado em maior privacidade e controle dos dados pelo usuário, onde você entrega o login e senha do seu perfil para uma aplicação?

Enfim, voltando à API, o desenvolvedor abriu o pedido de merge 5 meses atrás. O código foi dado como terminado por outro desenvolvedor há um mês, seguido de um pedido de revisão. Desde então, não houveram quaisquer manifestações – o código está lá, “flutuando”.

O Diaspora tem pela frente grandes desafios se ele quiser manter-se relevante. Há a necessidade da definição de um protocolo de comunicação que possibilite as diversas funcionalidades esperadas pela rede. Há discussões sobre o uso de protocolos já existentes, como o tent.io, zot2, ou pumpio, por exemplo, mas são discussões antigas, que não definiram a direção que o desenvolvimento deve tomar e que não produziram resultado até o momento.

Por conta dessas indefinições, eu tendo a ver os desenvolvedores do Diaspora como programadores que querem sim ter uma rede social distribuída funcionando, mas que eles não dão a ela uma importância central para o contexto das redes sociais hoje, mais ou menos como os históricos desenvolvedores de software livre encaravam suas aplicações como substitutas para os softwares proprietários que eram comumente utilizados, principalmente no início da história do movimento software livre. Essa atitude true é mais presente, penso eu, nos desenvolvedores do Friendica/Red – basta citar que os desenvolvedores do core dessas redes não tem conta em nenhuma outra rede social. Para eles, o Friendica/Red não é um “acessório”, algo que eles usam em paralelo com as redes centralizadas. Eles são obcecados com privacidade, segurança de dados – o software deles tem que funcionar porque eles não tem alternativa, não estão dispostos a utilizar uma rede social proprietária, centralizada, que terá acesso aos dados deles e de quem eles levarem para lá.

Haverá futuro para o Diaspora?

Apesar do post em sua maior parte apresentar uma visão negativa do Diaspora, essa rede social conseguiu algo que nenhuma outra rede social descentralizada conseguiu – ela tem muitos usuários. Certamente devido ao grande barulho e propaganda que uma rede autodenominada anti-Facebook conseguiu na mídia, mas também por pessoas dedicadas que subiram servidores, colocaram o projeto debaixo do braço, e foram fazer palestras/montar stands/dar entrevistas/participar de reportagens e todo o mais do bom trabalho de promoção que todo ativista de software livre, quando se encanta por determinado projeto, se propõe a fazer.

E sabemos que o que atrai usuários para uma rede social é a presença de outros usuários – que geram conteúdo e atrai atenção para a rede, resultando em mais conteúdo que atrairá a atenção de mais usuários que irão gerar mais conteúdo… e por aí segue.

Existem redes sociais hoje que entregam as funcionalidades mais desejadas que não existem no Diaspora. O Friendica é uma delas, que utilizei por quase um ano, e era ótimo como tudo funcionava bem. Mas acabei saindo porque só me relacionava com outras 2 pessoas. Enquanto isso continuo no Diaspora, mesmo tendo consciência de todo o cenário que descrevi aqui – querendo ou não, lá ainda existe alguma interação.

No final de 2013 um pod brasileiro, o DiasporaBR, foi lançado e enquanto escrevo essa frase ele conta com 6475 usuários. É muita gente. 1% disso dá 64.75 pessoas, com certeza um número muito maior que os atuais desenvolvedores do Diaspora. Se 0.1% desses usuários se tornarem desenvolvedores (6 pessoas e meia =D), com certeza será uma boa arrancada para a rede social.

O que fica para nós, ativistas do software livre, é uma encruzilhada complicada. O Diaspora tem mais usuários, mas se ele não avançar e prover novas funcionalidades, esses perfis serão apenas números sem pessoas por trás. Mas a alternativa de migrar todo esse contingente para uma rede social que funciona hoje, é uma alternativa viável? Se sim, quem está disposto a bancá-la – na forma de disponibilizar servidores e mão de obra técnica?

por Filipe Saraiva em 22 de March de 2014 às 03:16

March 21, 2014

Artificial Intelligence in Motion

New year, new work and new posts about Bioinformatics, NGS sequencing e Machine learning!



Hi all,

It has been a while since my last post at the blog. No, I didn't abandon the blog! It has happened many events at my life since november that I decided to pause a bit my posts marathon and started to organize my work life! The best news this year is that I am now facing new challenges on machine learning, data mining, big data and now on: bioinformatics!! That's right.  I am now CTO of Genomika Diagnósticos, a brazilian genetics laboratory at Recife, Pernambuco.  The laboratory combines the state-of-art genetic testing with comprehensive interpretation of test results by specialists, geneticists to provide clinically relevant molecular tests for a variety of genetic disorders and risk factors.



My work there now is work with NGS (next-gen sequencing) tools to support the exome and genome sequencing to analyse genes and exons in panels to detect any significant genetic variations, which are candidates to cause the patient's phenotype. There are a lot of work to do, so in the next weeks I will post some tutorials about bioinformatics, machine learning, parallelism and big data applied on genoma sequencing.

This field is a novel study field and there are many applications related to disease detection, prevention, and treatment. Could you imagine that sequencing DNA would cost more than $10,000 dollars in 2001 and it has been decreasing exponentially the cost of the procedure.




My next posts will talk about how DNA sequencing works and how machine learning and data ming can be applied in this exciting and promising field!

Regards,

Marcel Caraciolo


por Marcel Caraciolo (noreply@blogger.com) em 21 de March de 2014 às 19:12

Gustavo Niemeyer

Arbitrary Qt extensions with Go QML

As part of the on going work on Ubuntu Touch phones, I was invited to contribute a Go package to interface with ubuntuoneauth, a C++ and Qt library that authenticates against Ubuntu One using the system account made available by the phone owner. The details of that library and its use case are not interesting for most people right now, but the work to interface with it is a good example to talk about because, besides the result (uoneauth) being an external and independent Go package that extends the qml package, ubuntuoneauth is not a QML library, but rather a plain Qt library. Some of the callbacks use even traditional C++ types that do not inherit from QObject and have no Qt metadata, so offering that functionality from Go nicely takes a bit more work.

What follows are some of the highlights of that integration logic, to serve as a reference for similar extensions in the future. Note that if your interest is in creating QML applications with Go, none of this is necessary and the documentation is a better place to start.

As an initial step, the following examples demonstrate how the original C++ library and the Go package being designed are meant to be used. The first snippet contains the relevant logic taken out of the examples/signing-main.cpp file, tweaked for clarity:

int main(int argc, char *argv[]) {
    (...)
    UbuntuOne::SigningExample *example = new UbuntuOne::SigningExample(&a);
    QTimer::singleShot(0, example, SLOT(doExample()));
    (...)
}

SigningExample::SigningExample(QObject *parent) : QObject(parent) {
    QObject::connect(&service, SIGNAL(credentialsFound(const Token&)),
                     this, SLOT(handleCredentialsFound(Token)));
    QObject::connect(&service, SIGNAL(credentialsNotFound()),
                     this, SLOT(handleCredentialsNotFound()));
    (...)
}

void SigningExample::doExample() {
    service.getCredentials();
}

void SigningExample::handleCredentialsFound(Token token) {
    QString authHeader = token.signUrl(url, QStringLiteral("GET"));
    (...)
}
 
void SigningExample::handleCredentialsNotFound() {
    qDebug() << "No credentials were found.";
}

The example hooks into various signals in the service, one for each possible outcome, and then calls the service’s getCredentials method to initiate the process. If successful, the credentialsFound signal is emitted with a Token value that is able to sign URLs, returning an HTTP header that can authenticate a request.

That same process is more straightforward when using the library from Go:

service := uoneauth.NewService(engine)
token, err := service.Token()
if err != nil {
        return err
}
signature := token.HeaderSignature("GET", url)

Again, this gets a service, a token from it, and signs a URL, in a “forward” way.

So the goal is turning the initial C++ workflow into this simpler Go API. A good next step is looking into how the NewService function is implemented:

func NewService(engine *qml.Engine) *Service {
        s := &Service{reply: make(chan reply, 1)}

        qml.RunMain(func() {
                s.obj = *qml.CommonOf(C.newSSOService(), engine)
        })

        runtime.SetFinalizer(s, (*Service).finalize)

        s.obj.On("credentialsFound", s.credentialsFound)
        s.obj.On("credentialsNotFound", s.credentialsNotFound)
        s.obj.On("twoFactorAuthRequired", s.twoFactorAuthRequired)
        s.obj.On("requestFailed", s.requestFailed)
        return s
}

NewService creates the service instance, and then asks the qml package to run some logic in the main Qt thread via RunMain. This is necessary because a number of operations in Qt, including the creation of objects, are associated with the currently running thread. Using RunMain in this case ensures that the creation of the C++ object performed by newSSOService happens in the main Qt thread (the “GUI thread”).

Then, the address of the C++ UbuntuOne::SSOService type is handed to CommonOf to obtain a Common value that implements all the common logic supported by C++ types that inherit from QObject. This is an unsafe operation as there’s no way for CommonOf to guarantee that the provided address indeed points to a C++ value with a type that inherits from QObject, so the call site must necessarily import the unsafe package to provide the unsafe.Pointer parameter. That’s not a problem in this context, though, since such extension packages are necessarily dealing with unsafe logic in either case.

The obtained Common value is then assigned to the service’s obj field. In most cases, that value is instead assigned to an anonymous Common field, as done in qml.Window for example. Doing so means qml.Window values implement the qml.Object interface, and may be manipulated as a generic object. For the new Service type, though, the fact that this is a generic object won’t be disclosed for the moment, and instead a simpler API will be offered.

Following the function logic further, a finalizer is then registered to ensure the C++ value gets deallocated if the developer forgets to Close the service explicitly. When doing that, it’s important to ensure the Close method drops the finalizer when called, not only to facilitate the garbage collection of the object, but also to avoid deallocating the same value twice.

The next four lines in the function should be straightforward: they register methods of the service to be called when the relevant signals are emitted. Here is the implementation of two of these methods:

func (s *Service) credentialsFound(token *Token) {
        s.sendReply(reply{token: token})
}

func (s *Service) credentialsNotFound() {
        s.sendReply(reply{err: ErrNoCreds})
}

func (s *Service) sendReply(r reply) {
        select {
        case s.reply <- r:
        default:
                panic("internal error: multiple results received")
        }
}

Handling the signals consists of just sending the reply over the channel to whoever initiated the request. The select statement in sendReply just ensures that the invariant of having a reply per request is not broken without being noticed, as that would require a slightly different design.

There’s one more point worth observing in this logic: the token value received as a parameter in credentialsFound was already converted into the local Token type. In most cases, this is unnecessary as the parameter is directly useful as a qml.Object or as another native type (int, etc), but in this case UbuntuOne::Token is a plain C++ type that does not inherit from QObject, so the default signal parameter that would arrive in the Go method has only a type name and the value address.

Instead of taking the plain value, it is turned into a more useful one by registering a converter with the qml package:

func convertToken(engine *qml.Engine, obj qml.Object) interface{} {
        // Copy as the one held by obj is passed by reference.
        addr := unsafe.Pointer(obj.Property("plainAddr").(uintptr))
        token := &Token{C.tokenCopy(addr)}
        runtime.SetFinalizer(token, (*Token).finalize)
        return token
}

func init() {
        qml.RegisterConverter("Token", convertToken)
}

Given that setup, the Service.Token method may simply call the getCredentials method from the underlying UbuntuOne::SSOService method to fire a request, and block waiting for a reply:

func (s *Service) Token() (*Token, error) {
        s.mu.Lock()
        qml.RunMain(func() {
                C.ssoServiceGetCredentials(unsafe.Pointer(s.obj.Addr()))
        })
        reply := <-s.reply
        s.mu.Unlock()
        return reply.token, reply.err
}

The lock ensures that a second request won’t take place before the first one is done, forcing the correct sequencing of replies. Given the current logic, this isn’t strictly necessary since all requests are equivalent, but this will remain correct even if other methods from SSOService are added to this interface.

The returned Token value may then be used to sign URLs by simply calling the respective underlying method:

func (t *Token) HeaderSignature(method, url string) string {
        cmethod, curl := C.CString(method), C.CString(url)
        cheader := C.tokenSignURL(t.addr, cmethod, curl, 0)
        defer freeCStrings(cmethod, curl, cheader)
        return C.GoString(cheader)
}

No care about using qml.RunMain has to be taken in this case, because UbuntuOne::Token is a simple C++ type that does not interact with the Qt machinery.

This completes the journey of creating a package that provides access to the ubuntuoneauth library from Go code. In many cases it’s a better idea to simply rewrite the logic in Go, but there will be situations similar to this library, where either rewriting would take more time than reasonable, or perhaps delegating the maintenance and stabilization of the underlying logic to a different team is the best thing to do. In those cases, an approach such as the one exposed here can easily solve the problem.

por niemeyer em 21 de March de 2014 às 14:35

March 19, 2014

Kodumaro

RLock

Dando continuidade o artigo sobre thread, um recurso muito útil é lock reentrante.

Lock reentrante é uma variação de lock que pode ser realocado múltiplas vezes pelo mesmo thread e não pode ser liberado por outro thread. É muito útil em funções recursivas, mas funciona também para garantir que o lock seja alocado e liberado pelo mesmo thread.

A fábrica (factory) para criar locks reentrantes é threading.RLock.

É preciso tomar cuidado para que todos os threads compartilhem o mesmo lock, senão ele se torna inútil:
lock = RLock()

thr1 = Thread(target=func1, args=(lock, ))
thr2 = Thread(target=func2, args=(lock, ))
thr3 = Thread(target=func3, args=(lock, ))

Dentro da função, é preciso alocá-lo (acquire) no inicío e liberá-lo (release) ao final. Por exemplo:
def func1(lock):
lock.acquire()
try:
# executa o procedimento
...
finally:
lock.release()

Protegendo um objeto mutável

Uma utilidade para o lock reentrante é proteger métodos que alterem o conteúdo de um objeto.

Imagine que temos uma classe Person com dados, como identity_code (CPF) que podem sofrer alterações em threads diferentes (sei que não é uma boa abordagem, mas apenas como exemplo).

Podemos criar um decorador que torna um método thread-safe usando lock reentrante:
def lock(wrapped):
lock_ = RLock()

@wraps(wrapped)
def wrapper(*args, **kwargs):
lock_.acquire()
try:
return wrapped(*args, **kwargs)
finally:
lock_.release()

return wrapper

Esse decorador pode ser usado nos setters de cada propriedade:
class Person(object):

...

@property
def identity_code(self):
return self.__identity_code

@identity_code.setter
@lock
def identity_code(self, value):
self.__identity_code = value

...

Na verdade essa abordagem não resolve 100% o problema, mas já reduz muito a ocorrência de bugs.

Protegendo qualquer objeto

Porém a abordagem acima apenas protege parcialmente o objeto e não funciona para classes de terceiros.

Outra abordagem é usar um lock para todo o objeto, tanto leitura quanto gravação, agnóstico a qual objeto está sendo protegido. Assim, não há necessidade de usarmos propriedades.

Vamos criar uma classe para trancar qualquer objeto:
class ObjectLocker(object):

def __init__(self, obj):
self.__obj = obj
self.__lock = RLock()

def __enter__(self):
self.__lock.acquire()
return self.__obj

def __exit__(self, etype, exc, traceback):
self.__lock.release()

No código a instância dessa classe será passada para os threads, que terá de usar with para acessar o objeto original.

Ao usar with, o objeto original será trancado para o thread atual e liberado ao final.

A passagem será:
locker = ObjectLocker(Person(...))
thr = Thread(target=func, args=(locker, ))

Dentro da(s) função(ões) func a instância de Person deve ser acessa da seguinta forma:
with locker as person:
name = person.name
person.identity_code = data['identity_code']

Espero que os exemplos tenham sido úteis.

[]’s
Cacilhας, La Batalema

por noreply@blogger.com (Darth Batalema) em 19 de March de 2014 às 21:12

March 17, 2014

Eric Hideki

Nacho

1495497_10152040120833726_252377080_n

Thiago Avelino é uma das pessoas que tem grandes contribuições para a comunidade Open Source, trabalhando em projetos grandes como o Django, Plone e agora também um dos core-commiters do Bottle, um microframework web em Python.

Tendo em vista que muitas pessoas tem interesse de aprender em colaborar em projetos mas não sabem por onde começar, compartilho essa conversa que tive com o Thiago para ele falar mais sobre suas experiências e projetos.


Thiago, por favor fale um pouco de você.

Eu não sei muito o que falar de mim, mas sou casado e tenho um filho (que cá entre nós é lindo) que tem 1 ano, trabalho há mais de 7 anos com tecnologia, comecei trabalhar com infra e em pouco tempo comecei programar em Perl, trabalhei com diversas tecnologia (Perl, VB.Net, C++, C, Python, Ruby, Go, entre outras que estudei).

Tive uma fase da minha vida que passei empreendendo, onde tive uma startup e foi comprada por uma empresa de fora do Brasil. Muitos me pergunta se depois da venda da startup porque eu parei de empreender, com filho pequeno não é muito fácil empreender, até porque temos que viver uma vida de desapego de bens materiais (Ao menos o que nos dá conforto, carro por exemplo).

Hoje contribuo com alguns projetos open source, para saber mais de mim dê uma olhada no github e twitter.

https://github.com/avelino
https://twitter.com/avelino0

Eu fiz parte do sprint que a YACOWS havia feito para falar sobre o Opps CMS, que foi feito com Django, sendo utilizado para portais de alta visibilidade. Conte um pouco sobre quais foram as dificuldades e desafios encontrados.

Manter um software open source é um grande desafio. Quando nós desenvolvedores começamos a escrever qualquer código é para solucionar um problema X ou Y, sabendo mais ou menos qual será o nível das pessoas que irão usar. Já em projetos open source não é assim, pois o código está aberto e você não sabe quem irá usar, quais as necessidades reais que são um dos pontos importante para desenvolver um software.

Quando começamos o Opps CMS a YACOWS tinha a necessidade de colocar um portal no ar (ou seja, tínhamos algumas premissas), com isso começamos a versão 0.1.x do Opps, em mais ou menos 3 meses o portal já estava no ar, assim desenvolvemos a primeira versão do CMS em 3 meses.

Mas nem tudo são flores, depois de entregar o projeto comecei a ver que o CMS estava com característica que apenas o cliente precisava, ou seja, não era um CMS flexível e sim um CMS para o cliente X, eis que começamos a desenvolver a nova versão do CMS com novas ideias que discutimos nessa issue (https://github.com/opps/opps/issues/93), o CMS ter um ambiente de plugins (usando a base do Django de apps) e o core do CMS na versão 0.1.x não sabia exatamente o que estava acontecendo dentro dos plugins.

Um outro ponto é evolução rápida, isso realmente é complicado, chega em um ponto que não se sabe o que está implementado dentro do projeto, começando a implementar novos métodos sendo que tem outro implementado (provavelmente feito por outro contribuidor) que atende sua necessidade, ou seja, um projeto open source precisa de documentação (um ponto muito importante para qualquer projeto).

Tivemos problemas com algumas coisas do core do Django que tivemos que fazer alguns ajustes, estendendo classe para implementar a necessidade do CMS. Muitas ideia e decisões foram tiradas da arquitetura do Plone.

Para o que você indica a utilização de Plone? E quais são as vantagens desse CMS?

Plone é um excelente CMS, não só isso, eu em particular contribuí pouco com o projeto, mas tenho orgulho da comunidade e código Plone (100% testado).

Eu indico para uso de qualquer portal de conteúdo e intranet, ou seja, qualquer projeto que precise gerenciar conteúdo ele atente perfeitamente, ele tem uma estrutura de workflow extremamente flexível.

Sobre as vantagens do Plone, a comunidade Python deveria agradecer a existência dele pois via o Plone a comunidade Python tem uma abertura grande no governo Brasileiro, deixe citar algums motivos:

  • Segurança;
  • Workflow flexível;
  • Gerenciamento de conteúdo na mesma pagina do site (não tem um /admin);
  • Foco escritor (facilitando a entrada de dados no CMS);
  • Gerenciamento de imagens;
  • Desenvolvimento de novos recursos simplificado;
  • Zope como base do CMS, isso faz com que tenhamos uma base extremamente robusta;
  • Sistema de Portlets;
  • Desempenho;
  • Diversos outros;

Sei que irão me pergunta o porquê de desenvolver o Opps CMS. Para quem não tem domínio de Plone, a curva de aprendizado é grande, por isso a Opps existe, para quando você tem um time que já trabalha com Django e não tem o tempo para estudar como o Plone funciona.

Também temos o Nacho, um micro web-framework. Para o que ele serve?

Nacho

Nacho

O Nacho nasceu com a existência do Tulip (framework assíncrono para Python 3 mantido pelo Guido), hoje o projeto está parado por falta de tempo mas pretendo voltar mexer nele assim que sair o Python 3.4 (onde o Tulip se tornou a biblioteca asyncio no core do Python 3.4).

Ele é um framework para simplificar o desenvolvimento assíncrono de aplicações web com Python 3.4, criar um framework do zero foi uma iniciativa radical pois estava desenvolvendo um projeto que precisava de processamento paralelo e queria ver como estava se saindo o Python 3, com isso resolvi organizar e disponibilizar o código que estava escrevendo.

Como de forma rápida as pessoas podem começar a colaborar com projetos? 

Contribuir com software livre é um assunto de uma palestra que dei da Campus Party desse ano, eu recomendo a todos contribuírem, principalmente com os softwares que vocês usam no dia a dia, por exemplo trabalho com um framework web X (Django, Flask, Bottle e/ou qualquer outro), porque não contribuir com o projeto, contribuir não é só escrever código, dentro de um projeto open source tem diversas sub-áreas e necessidades, como design, testers, documentação e assim por diante.

Não existe uma fórmula mágica que eu possa falar para vocês, faça assim, isso vai depender de projeto para projeto, recomendo fortemente que comece a participar da comunidade local (nacional) e oficial do projeto, comece a dar ideias para o projeto, interagir com o projeto e use IRC (geralmente rede IRC) os desenvolvedores do projeto ficam muito online em canais de IRC, eu comecei a contribuir com o Django por uma demanda que surgiu no IRC.

Uma coisa que ajuda muito os projetos open source quando esta no Github é dá “star”, se você gostou do projeto, dê star, isso ajuda a você localizar o projeto futuramente.

E por último seu projeto mais recente é o Open Mining, que é uma aplicação de análise escrita em Python, feito com Numpy, Riak, MongoDB e Bottle.

O projeto final será uma aplicação de BI, ele nasceu da necessidade da empresa que eu trabalho UP!  onde a diretoria precisa saber como anda a empresa. Sei que existe o Pentaho (e outros softwares open source de BI), passei 1 mês estudando o Pentaho e realmente é muito bom, só que peca na parte que eu jugo mais importante para o projeto, o dashboard (nome usado para montar um conjunto de relatório). Para criar um dashboard dentro do Pentaho você usa um plugin chamado ctools (desenvolvido pela comunidade e precisa evoluir muito) ou você compra a licença do Pentaho, julgo mais importante pois é onde o usuário final vai usar.

Com essa carência do Pentaho logo vi uma ótima oportunidade no mercado de BI para desenvolver um novo projeto open source que seja simples e flexível criar dashboard.

Começamos o projeto com Tornado que é um ótimo framework, por gostar muito de gevent resolvi mudar para Bottle com gevent (para processar async onde precisa), o projeto é um SPA (Single-page application) cenário ideal para o Bottle (por isso resolvi mudar para Bottle).

O projeto está em desenvolvimento, seguem alguns screenshots – https://github.com/avelino/mining#screenshot

Usamos o Riak (Em um futuro próximo será possível usar outros banco como hadoop) como data warehouse e MongoDB como armazenamento de dados do admin.

Desde já convido a todos a participar do projeto, https://github.com/avelino/mining (estou 100% disposto a ajudar no que for necessário).


Há algum tempo o Marcel Caraciolo fez uma série muito bacana entrevistando diversas pessoas da comunidade, e nessa oportunidade o Thiago também foi entrevistado. Caso queria saber mais a respeito, dê uma olhada. E também outra palestra sobre MongoDB.

Aproveite e veja também sobre outro pythonista, o Alex Gaynor.


por Eric Hideki em 17 de March de 2014 às 23:57

Django Unchained

Django Unchained

Não esse Django.

Quando se está iniciando um projeto surge a questão sobre qual ferramenta escolher. Python tem uma infinidade de possibilidades de acordo com seus objetivos, e muitas vezes as opções podem atrapalhar sua escolha.

E o Allisson Azevedo fez uma colaboração fantástica para a comunidade liberando seu curso de Django gratuitamente no youtube. E com isso me fez pensar em que o Django se destaca?

Com isso perguntei a alguns amigos porque escolher Django para suas aplicações, quais as vantagens e o que mais gostam desse fantástico framework.


Henrique Bastos

Acho que minha palestra Trabalhando com Django para não ter trabalho expressa cada detalhe sobre isso.

Django é excelente oferecendo convenções e 90% das funcionalidades que todo mundo precisa. Além disso, quando o framework não te atende perfeitamente, torna fácil você contornar e fazer aquele pedaço do seu jeito. Pra mim isso é reflexo de um design focado no uso, no desenvolvimento pragmático.


Allisson Azevedo – Soda Virtual

O Django é um projeto sólido, principal framework web em python, com uma comunidade ativa e operosa. A desconfiança no framework que existia já caiu por terra e sua adoção não para de crescer, principalmente entre startups. Hoje temos um mercado muito promissor e o que falta muitas vezes são candidatos qualificados, por isso que eu tenho bastante interesse nessa área de treinamento.


Filipe Ximenes – Diretor da Associação Python Brasil e sócio da Vinta software studio

Utilizar Django tem pouco a ver com a linguagem [Python] no qual ele é escrito ou até mesmo com as características do framework em si e tem TUDO a ver com ecossistemas. Em primeiro lugar, o ecossitema Python que envolve além de uma linguagem extremamente poderosa, versátil e aberta, uma comunidade acolhedora, que segue os mesmos princípios de liberdade da linguagem e é bastante ativa no Brasil e no mundo. Tudo isso acompanhado do ecossistema Django, que possui uma comunidade nos mesmos moldes de Python e que deixa a disposição dos programadores milhares de bibliotecas [apps], e todo tipo de material necessário para facilitar, acelerar e melhorar o desenvolvimento de aplicações web.


Gilson Filho - Trippics.com

O Django é um framework que se tornou carro chefe para aqueles que desejam entrar no ecossistema Python, como Rails foi para o Ruby. Temos percebido através de pesquisas como também ao olhar o mercado de trabalho, que a linguagem tem sido destaque. Diante da escolha massiva da gema, Python e Django se tornou uma alternativa para as startups nos últimos tempos. Através dos projetos conhecidos como Instagram, Rdio, vemos que eles usam o Django na sua arquitetura, por ser fiel ao que promete:

“O framework web para perfeccionistas com prazos”


Gileno AlvesPycursos

Django foi o primeiro framework web Python com que trabalhei. A coisa que mais me deixou empolgado no início foi o ORM, antes trabalhava com Java e o acesso ao banco era muito precário, nesse caso específico não era culpa do Java e sim do projeto que não usava Hibernate e coisas do tipo.

Atualmente, Django é meu framework favorito porque a minha forma de trabalho se encaixa bem nele e com isso eu consigo ser bastante produtivo. A separação em app’s é muito legal e intuitiva. No início podem gerar dúvidas mas rapidamente se percebe isso.

O fato de ser batteries included é fundamental para aumentar a produtividade, muitas pessoas consideram isso uma coisa ruim porque preferem fazer suas próprias escolhas em relação a quais ferramentas vão usar em: URL’s, Banco de Dados, Templates …, mas para essas pessoas existem outros frameworks que podem se adequar melhor aos seus projetos como o Flask.

Alguns aspectos positivos de Django:

Batteries Included: O fato de vir com várias coisas de “fábrica”, ajuda muito o desenvolvimento, evita que o desenvolvedor perca muito tempo fazendo muitas escolhas e configurações. Muita gente afirma que prefere fazer suas escolhas em relação aos aspectos do projeto, entretanto se você desejar fazer um projeto de fato organizado e bem estruturado você levará um bom tempo para organizá-lo e configurá-lo, se formos procurar esqueletos de projetos em flask ou pyramid (mesmo com o scaffold) por exemplo, vamos ver muito código para deixar as coisas de fato organizadas para começar um projeto de pequeno/médio porte (de grande nem se fala). Além disso o fato de fazer escolhas por você não significa que você precisa adotar todas as escolhas, django é bastante flexível (sim ele é) e você pode deixar de usar algumas coisas, o problema é que quando você começa a “cancelar” algumas escolhas que ele faz por você, o desenvolvimento começa a perder produtividade.

Comunidade: Django sem dúvida nenhuma tem a maior comunidade e aceitação entre os frameworks web Python. Você conseguirá tirar quaisquer dúvida e usar diversas apps prontas para quase tudo que você precise.

Estrutura: Django tem uma excelente estrutura base para projetos, você organiza seu projeto em apps tornando o projeto bem estruturado desde o início e facilita a integração entre projetos e apps de terceiros. Particularmente eu quando começo qualquer projeto a primeira coisa que faço é organizar a estrutura, módulos e coisas do tipo, para que conforme o crescimento do projeto ele não fique desorganizado e com Django isso fica muito intuitivo.

Simplicidade: A startproject do django gera poucos arquivos e pastas, o ORM é um dos mais simples que eu já vi, o sistema de templates também, tudo gira em torno da simplicidade e do DRY.

Alguns aspectos negativos:

Projetos muito pequenos: para projetos muito pequenos django perde um pouco da sua simplicidade, porque ele já considera que você vai precisar de um banco relacional e de diversas outras configurações. Nesses casos o Flask, Bottle e outros microframeworks se saem muito melhor.

Aprendizado: Para ensinar Python e Web django também não se sai bem, pelo mesmo fato de ter várias configurações que poderão ser desnecessárias, principalmente porque normalmente quando se está ensinando web com python você só precisaria de escrever algumas funções para renderizar algum texto (o sistema de templates seria desnecessário) e fazer apenas alguns cálculos simples.

Projetos fora do padrão: Para projetos que precisem de muitas coisas diferenciadas como: um banco de dados não relacional, que não precise exibir páginas html ou que use apenas algum outro ORM que não o padrão do django. Projetos assim, ainda podem ter proveito do django mas dependendo da situação pode gerar uma improdutividade e assim torna-se melhor usar outro framework mas flexível em relação a essas escolhas

Deixo um dos slides mais completos de Python/Django que conheço. Muito bem indicado para aqueles que querem aprender Python e Django ao mesmo tempo.


E deixo também mais 2 vídeos tutoriais atualizados de qualidade excelente em inglês.


E não esqueça de colocar nos comentários sobre o que você mais gosta no Django.


por Eric Hideki em 17 de March de 2014 às 22:38

Magnun Leno

Temas no Pelican

Muito bem, agora que temos nosso site com o conteúdo migrado, e os plugins ativados está na hora de definir a aparência do nosso site e de quebra 75% da funcionalidade do seu site. Sim isso mesmo, o tema que você adota para o Pelican influencia (e muito) as funcionalidades do seu site, como por exemplo, o sistema de comentários utilizado, onde serão apresentadas os ícones das redes sociais, onde e como serão apresentadas as tags, categorias, arquivos e tudo mais.

Pelican

Não sabe do que eu estou falando? Então, antes de prosseguir, descubra o que é o Pelican, como instalá-lo, como configurá-lo, como migrar artigos antigos do Wordpress e quais plugins utilizar.

Temas no Pelican é um artigo original de Mind Bending

por Magnun em 17 de March de 2014 às 20:46

Andrews Medina

Dia 18/03 tem Meetup sobre Docker

Na próxima semana (terça-feira, 18/03) teremos um meetup de Docker na semana que vem, na Globo.com. É uma oportunidade bem legal para quem quiser conhecer mais sobre o projeto.

Quem tiver algum projeto relacionado com docker legal pra apresentar, teremos lightning talks também!

Mais informação na página do meetup: http://www.meetup.com/Docker-Rio-de-Janeiro/events/165622462/

por andrewsmedina@gmail.com (Andrews Medina) em 17 de March de 2014 às 01:57

March 15, 2014

Kodumaro

Thread-safe

Tenho tido a necessidade de lidar com muitas bibliotecas de terceiros e teno percebi um erro (ou seria uma abordagem?) comum nas mais novas: quase nenhuma delas é thread-safe.

Acredito que, com o modismo do uso de corrotinas (chamadas lightweight threads), os programadores mais novos passaram a considerar os threads de sistema obsoletos, deixando de tomar cuidados essenciais para boas bibliotecas.

Bem, tenho uma novidade para vocês: threads não são obsoletos e corrotinas não resolvem todos os problemas do mundo. Há situações em que usar corrotinas pode ser a melhor opção sim, mas em alguns casos os bons e velhos threads ainda são o salva vidas.

Para que isso seja possível, na criação de bibliotecas é necessário tomar alguns cuidados:
  • Prefira sempre que possível usar objetos imutáveis. Prefira tuplas, strings, tipos numéricos básicos, etc.
  • Evite permitir que objetos agregados façam alteração em seu objeto contentor sempre que possível.
  • Em todos métodos e propriedades de um objeto que pode ser compartilhado (como o contentor citado) que alterem o estado do objeto, inicie com um RLock, chamando seu método acquire, e encerre chamando seu método release. Tome cuidado para que seja usada a mesma instância de RLock!
  • Não tenha medo de usar objetos do módulo threading: Condition, Event, Lock, RLock e BoundedSemaphore. Eles são seus amigos. ;-)
  • Se estiver difícil escrever testes, substitua threading por dummy_threading para os testes unitários, mas use threading para testes de aceitação.

[]’s
Cacilhας, La Batalema

por noreply@blogger.com (Darth Batalema) em 15 de March de 2014 às 12:40

March 13, 2014

Magnun Leno

Plugins no Pelican

Como já demonstrei nos artigos anteriores, o Pelican é extremamente flexível e poderoso. Mas algumas funcionalidades só podem ser obtidas através de plugins.

Pelican

Felizmente, os desenvolvedores do Pelican fizeram um repositório para hospedar os principais plugins existentes.

Plugins no Pelican é um artigo original de Mind Bending

por Magnun em 13 de March de 2014 às 21:07

Gustavo Niemeyer

Go QML Contest

A couple of weeks ago a probe message was sent to a few places questioning whether there would be enough interest on a development contest involving Go QML applications. Since the result was quite positive, we’re moving the idea forward!

OpenGL Gopher

This blog post provides further information on how to participate. If you have any other questions not covered here, or want technical help with your application, please get in touch via the mailing list or twitter.

Eligible applications

Participating applications must be developed in Go with a graphic interface that leverages the qml package, and must be made publicly available under an Open Source license approved by the OSI.

The application may be developed on Linux, Mac OS, or Windows.

Review criteria

Applications will be judged under three lenses:

  • Quality
  • Features
  • Innovation

We realize the time is short, so please submit even if you haven’t managed to get everything you wanted in place.

Deadline

All submissions should be made before the daylight of the Monday on April 21st.

Sending the application

Applications must be submitted via email including:

  • URL for the source code
  • Build instructions

If necessary for judging, a screencast may be explicitly requested, and must be provided before the daylight of Wednesday 23rd.

Prizes

There are two prizes for the winner:

Judging and announcement

Judging will be done by well known developers from the Go community, and will take place during GopherCon. The result will be announced during the conference as well, but the winner doesn’t have to be in the conference to participate in the contest.

Learning more about Go QML

The best places to start are the package documentation and the mailing list.

por niemeyer em 13 de March de 2014 às 20:08

Magnun Leno

Configurando o Pelican

Conforme destacado nesses outros artigos, agora estou usando o Pelican. Mas simplesmente instalá-lo não é o suficiente, é necessário customizá-lo para atender suas necessidades. Para isso, hoje vamos ver como configurar o Pelican através do comando pelicanconf.py.

Pelican

É importante lembrar que todas as configurações estão documentadas aqui e eu não vou poder explicar todas, vou passar rapidamente pelas mais importantes e as que eu precisei modificar.

Configurando o Pelican é um artigo original de Mind Bending

por Magnun em 13 de March de 2014 às 18:14

March 12, 2014

Eric Hideki

1429005_15420938

Vi esse texto sendo compartilhado pelo Fábio Akita e achei sensacional e gostaria de compartilhar com a galera. Irei colocar o original em inglês e uma tradução livre minha logo abaixo.

Ruby on Rails (web framework): How to become an expert ruby on rails developer?
What does a ror expert developer need to know? And what are the steps to get to that level of knowledge?

The question is actually “how to become an expert” in anything. Practicing. There is no recipe, no step-by-step solution. The only way is to start practicing. By doing, you will quickly learn where it hurts. Every time you stumble upon an invisible wall, stopping you from going forward, that’s when you will have to go out of your way to Google, books, other colleagues of practice and learn what’s necessary to go over that wall.

More often than not, you will quickly learn that the initial solution for that wall was not the best one, and you will have to humbly relearn. Every time, all the time. It’s a massacre. If it’s not hurting you’re not learning. No pain, no gain.

Then you repeat and keep going over wall after wall. The path is long, frustration will hit you hard many times, and only after you spend years learning how to go over every wall thrown against you, that’s when you start becoming an expert. Takes years of uninterrupted practice.


Ruby on Rails: Como se tornar expert em desenvolver em Ruby on Rails?
O que um programador Ruby on Rails precisa saber? E quais são os passos para chegar a esse nível de conhecimento?

A questão realmente é “Como se tornar um expert” em qualquer coisa. Praticando. Não há receita, nenhuma solução passo a passo. O único caminho é começar praticando. Fazendo, você logo verá onde machuca. Toda hora você tropeçar em uma parede invisível, impedindo de seguir em frente, será então quando deverá fugir do seu caminho normal para procurar no Google, livros, colegas de faculdade e aprender o que é necessário para seguir adiante através dessa parede invisível.

De uma forma aprenderá rapidamente de que solução inicial para atravessar a parede não será a das melhores, e humildemente terá que reaprender. Toda hora, todo tempo. É massacrante. Se não está machucando você não está aprendendo. Sem dor, sem ganho.

1429005_15420938

Então repetirá o processo parede por parede que surgir no processo. O processo é longo, frustrações irão te machucar muito diversas vezes, e apenas gastando anos em aprender a atravessar essas paredes que surgirem contra você é que se tornará um expert. Serão anos ininterruptos de prática.


por Eric Hideki em 12 de March de 2014 às 20:17

Magnun Leno

Migrando do Wordpress Para o Pelican

Conforme relatado neste outro artigo, migrei este blog para o Pelican. Entretanto, meu blog atualmente possui 123 artigos (em português, em inglês são mais 55 artigos), o que torna praticamente inviável uma migração manual. Para acelerar o processo acabei utilizando ótimas ferramentas. Como outras pessoas podem querer migrar para o Pelican, resolvi documentar aqui os meus passos.

Pelican

Claro que não consegui automatizar tudo, e parte do processo ainda foi manual, mas o uso de ferramentas como o sed e o shell scripts valem a menção.

Migrando do Wordpress Para o Pelican é um artigo original de Mind Bending

por Magnun em 12 de March de 2014 às 18:17

March 10, 2014

Eric Hideki

Alex Gaynor

Alex é um dos maiories contribuidores do Python, tendo atuado em projetos importantes como o framework Django, o Pypy, e criado o Topaz e diversos outros projetos.

Alex Gaynor

Alex Gaynor

Trabalha no Rackspace, empresa voltada a serviços em Cloud, e também tendo passagem por empresas como Rdio e Quora, além de colaborações na Django Software foundation.

Palestrante em diversos países, compartilhando suas experiências e projetos, fazendo parte da PSF(Python software foundation), organização sem fins lucrativos que visa promover e alavancar a linguagem.

As pessoas que fazem parte são aquelas que tem contribuições enormes ao Python, sendo indicado em 2011. Vale lembrar que temos diversos brasileiros dentro dessa lista, tais como Henrique Bastos, Bruno Rocha, Érico Andrei, Luciano Ramalho e outros.

Conheça um pouco mais sobre seus projetos e contribuições.

Topaz

Topaz é uma implementação de Ruby escrito em Python, sendo usado RPython Virtual Machine.

http://docs.topazruby.com/
https://speakerdeck.com/jan/topaz-is-ruby-in-python

Cryptography

Cryptography foi feito para expor receitas e informações para desenvolvedores Python. Alex tendo a necessidade de de trabalhar com criptografia, analisando as possibilidades disponíveis não atendiam de forma ideal, assim como qualquer programador faz, se não existe algo bacana, nada como fazer você mesmo. Podendo ser usando tanto no Python 2.x, 3.x e PyPi.

Em seu blog ele detalha melhor sua experiência ao criar esse projeto: http://alexgaynor.net/2014/feb/12/why-crypto/

Warehouse

Uma iniciativa para criar um novo repositório de pacotes Python para poder substituir os pacotes legados que o PyPi tem atualmente.

E também tem diversas contribuições no Core do Django.

Temos também o destaque em suas diversas palestras, tanto falando sobre Open Source, Django ou PyPy. Podemos acompanhar através dos vídeos disponibilizados pela pyvideo.org. Vejam alguns:

Veja seus projetos no Github ou acompanhe suas ideias no Twitter. Uma coisa legal são as respostas no formspring comentando sobre suas ideias, como aprendeu a programar e porque gosta tanto de Python.


por Eric Hideki em 10 de March de 2014 às 20:36

Magnun Leno

Instalando o Pelican

Conforme relatado neste outro artigo, migrei este blog para o Pelican. Como é de praxe, acabei anotando tudo o que fiz e realizando uma documentação. Para essa instalação utilizei o Pelican 3.3, virtualenv e o Python 2.7.

Pelican

É muito raro você precisar recriar o ambiente do Pelican, mas como outros podem ter dúvidas resolvi disponibilizar todas as minhas notas em forma de artigo.

Instalando o Pelican é um artigo original de Mind Bending

por Magnun em 10 de March de 2014 às 18:17

March 08, 2014

Eric Hideki

Pernas...A vá!

Pernas...A vá!

Pernas…A vá!

Na verdade seria “pernas pra que te quero”, mas python é uma cobra, e cobras não tem pernas. Enfim.

Como foi o carnaval? Tranquilo? Bora ver uns links bacanas para nos atualizarmos sobre o que está rolando internet afora?

Vou começar com 3 links que acho serem importantíssimos para esclarecer o que está acontecendo em nosso país e quase ninguém percebe: O ódio, a loucura e a superficialidade.

Escutem o louco

Uma reflexão bem interessante sobre o caso do ‘louco’ que empurrou uma passageira nos tilhos do metrô, e se pararmos para pensar um pouco, cada pessoa é tão louca quanto ele.

A história do ódio no Brasil

O famoso ‘mundo cão’ que vivemos atualmente, pessoas se isolando por medo de se machucarem, fobia por sair em locais desconhecidos ou dirigir em grandes metrópoles e se tornar mais um número entre tantas estatísticas de loucuras que acontecem a cada minuto.

Como ler um livro difícil

E quanto estamos aprendendo uma tecnologia nova, totalmente fora da nossa zona de conforto, e logo desistimos? Vejamos algumas ideias para mudarmos esse cenário.

Screencasts gratuitos de Python do Neckbeard Republic

Devido a mudanças de perspectivas, o Neckbeard resolveu liberar todos os seus screencasts de Python. Conteúdo premium agora free, não percam.

Projetos no Github para iniciantes contribuirem

Saiba como iniciantes podem colaborar com projetos open source no Github sem tem conhecimentos aprofundados de programação ou lógica, e olha que não estou falando só sobre tradução ou documentação.

Entendendo TDD com Django

O site ArunRocks fez um excelente trabalho falando sobre como funciona o TDD, porque ele é fundamental para o crescimento da qualidade dos seus projetos, e de quebra como implementar isso no Django.

O quanto preciso saber de Python para aprender Django

Como criar filtros do Instagram com Python

Desenvolvimento web com Python e Django

Não se esqueçam de colocar nos comentários links que acharam interessantes recentemente.


por Eric Hideki em 08 de March de 2014 às 15:52

Rodrigo Delduca

Qt no Android? Interoperabilidade entre Qt e o Android

Como alguns de vocês sabem, tenho cada vez mais me aprofundado no desenvolvimento mobile, usando os mais variados SDKs. Recentemente precisei integrar a SDK da RevMob num projeto mobile usando Qt; hoje irei cobrir apenas o Android, mas em breve postarei como fiz o mesmo para iOS.

Como podemos ver na página da SDK da RevMov, temos suporte a diversas plataformas, bibliotecas e frameworks, mas não para o Qt. #chatiado

Minha primeira tentativa consistiu em desenvolver uma SDK do zero, a partir da versão em javascript, porém notei que estaria reinventando a roda, e que levaria muito mais tempo; por outro lado teria apenas uma base de código para iOS, Android, Desktop e o que mais o Qt suportar.

Resolvi recomeçar pela versão em Android. Baixei o SDK para Android, pacote onde temos a documentação, um exemplo e um arquivo jar, que é a RevMob SDK propriamente dita.

Eis que começa a aventura! Olhando o exemplo e a documentação, o primeiro passo é instanciar a classe RevMob usando o método start, que recebe uma instância de Activity do Android em Java, como pode ser visto abaixo:

public static RevMob start(android.app.Activity activity)

Já temos um problema: o Qt é um framework em C++. Embora existam as classes como a QAndroidJniObject e QAndroidJniEnvironment, que nos ajudam na interoperabilidade, abstraindo as chamadas de funções e conversões de tipos usando o JNI, era preciso a instância de alguma Activity.

É sabido que toda aplicação para Android deve ter um AndroidManifest.xml e que deve ter pelo menos uma Activity. E onde estaria esse código que magicamente aparecia durante as etapas de compilação? Infelizmente isto ainda não é muito bem documentado no Qt (ou acabei passando batido :P). De qualquer forma precisava adicionar uma Activity customizada e alterar o AndroidManifest.xml.

Depois de uma breve pesquisa no diretório de instalação do Qt, encontrei o seguinte caminho:

$QTDIR/5.*.*/android_(armv5|android_armv7|android_x86)/src/android/java

  • $QTDIR É o diretório de instalação
  • 5.*.* A versão
  • android_(armv5|android_armv7|android_x86) A arquitetura

É onde tem exatamente o que precisava, o AndroidManifest.xml, version.xml, os diretórios src e res. E o que temos dentro de _src/org/qtproject/qt5/android/bindings_? Temos QtActivity QtApplication, que herdam Activity e Application do Android SDK respectivamente, e como podemos ver, no AndroidManifest.xml

<application android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="@string/app_name">

  <activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|locale|fontScale|keyboard|keyboardHidden|navigation"
    android:name="org.qtproject.qt5.android.bindings.QtActivity"
                  android:label="@string/app_name"
                  android:screenOrientation="unspecified">

  ...
</application>

Agora que temos quase tudo que precisamos, só é preciso descobrir como colocar toda essa tranqueira na hora do deploy. Lendo a documentação, descobri a variável ANDROID_PACKAGE_SOURCE_DIR, que faz justamente o que precisava, então copiei o AndroidManifest.xml do Qt para o diretório android-sources e adicionei a seguinte entrada no .pro do projeto

ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android-sources

Para poder usar as classes QAndroidJniObject e QAndroidJniEnvironment é necessário adicionar androidextras à variável QT

QT += core gui widgets androidextras

Precisamos de algumas customizações no AndroidManifest.xml; uma delas é para adicionar a FullscreenActivity do RevMob:

<application ...>
  <activity android:name="com.revmob.ads.fullscreen.FullscreenActivity"
            android:theme="@android:style/Theme.Translucent"
            android:configChanges="keyboardHidden|orientation">
  </activity>

  ...
</application>

Lembram que era preciso a instância de uma activity? Para isto criei um wrapper, No diretório android-sources, criei a estrutura de diretórios src/com/revmob e dentro um arquivo com o nome RevMobActivity.java, com o seguinte conteúdo:

package com.revmob;

import org.qtproject.qt5.android.bindings.QtActivity;
import com.revmob.RevMob;
import com.revmob.RevMobTestingMode;
import com.revmob.client.RevMobClient;
import android.util.Log;
import android.app.Activity;
import java.lang.String;

public class RevMobActivity extends QtActivity {

  private static Activity activity;

  public RevMobActivity() {
    activity = this;
  }

  public static void startSession(String appId) {
    RevMobClient.setSDKName("qt-android");
    RevMobClient.setSDKVersion("0.0.1");
    RevMob.start(activity, appId);
  }

  public static void showFullscreen() {
    RevMob revmob = RevMob.session();
    revmob.showFullscreen(activity);
  }

  ...
}

E apontamos essa nova classe no AndroidManifest.xml, substituindo org.qtproject.qt5.android.bindings.QtActivity por com.revmob.RevMobActivity. Com isto, o Android passa a instanciar a classe customizada ao invés da classe do Qt, e finalmente temos um wrapper.

Para finalizar esta etapa precisamos adicionar o arquivo revmob-6.8.2.jar da SDK do RevMob no diretório libs, ainda dentro de android-sources.

Finalmente poderemos voltar à programação de verdade, C++ :)

Para começar a utilizar precisamos iniciar uma sessão, o que pode ser feito na inicializacão do app, da seguinte maneira:

QString appId = "";

QAndroidJniObject param = QAndroidJniObject::fromString(appId);
QAndroidJniObject::callStaticMethod<void>("com/revmob/RevMobActivity",
                                          "startSession",
                                          "(Ljava/lang/String;)V",
                                          param.object<jstring>());

Onde appId é um código fornecido pela RevMob que identifica sua app.

Para mostrar um banner em FullScreen é bem simples - só precisamos invocar aquele método showFullscreen que foi criado logo acima, assim:

QAndroidJniObject::callStaticMethod<void>("com/revmob/RevMobActivity", "showFullscreen");

O trecho acima invoca um método em Java da classe RevMobActivity, responsável por carregar e exibir um anúncio em fullscreen.

É muito legal poder rodar meus projetos em Qt no meu celular, apenas recompilando, e mais legal ainda saber que posso acessar recursos da SDK do Android de forma semi transparente...

por Rodrigo Delduca em 08 de March de 2014 às 00:00

March 07, 2014

Álvaro Jüsten

Armazenando dicionários no MongoDB com MongoDict

Muitas das vezes que precisamos persistir dados chave-valor optamos por utilizar bases de dados focados somente em armazenar esse tipo de dado: as chamadas key-value stores, como por exemplo Riak, Redis e Memcached (esse último, persiste apenas em memória). Porém, adicionar mais um software/serviço em uma aplicação trás mais trabalho para a equipe (deployment, manutenção) e maior possibilidade de falhas (não somente de segurança, mas relacionadas a lentidão e downtime também).

Riak logo   Redis logo   Memcached logo

Caso você já tenha o MongoDB rodando em sua infraestrutura e necessite de uma key-value store, você poderá utilizar a biblioteca Python mongodict, que desenvolvi em julho de 2012 para aproveitar a infra já disponível e, ao mesmo tempo, poder utilizar os dados persistidos com facilidade.

Dicionários no MongoDB

Desenvolvedores Python são hash-addicted (rá!) - usamos muito os dicionários, para tudo (às vezes até excessivamente). Meu objetivo ao desenvolver o mongodict foi justamente aproveitar a interface que já conhecemos de dicionários (dict[chave] = valor) para persistir os dados no MongoDB sem precisar utilizar uma API diferente da que já estamos acostumados.

Logo MongoDB

Instalando

Sem mais blá blá blá, vamos lá: o mongodict está disponível no PyPI então, para instalá-lo, basta executar o comando:

pip install mongodict

Ele funciona em Python 2.7 e 3.3.

Usando

A biblioteca é bem simples: existe apenas uma classe MongoDict dentro do módulo. Aprenda com exemplos:

from mongodict import MongoDict

# Cria uma instância do "dicionário", já conectando no mongod
# Argumentos `host`, `port`, `database` e `collection` são opcionais
mydict = MongoDict()

mydict['answer'] = 42
print(mydict['answer']) # 42

print('answer' in mydict) # True
del mydict['answer']
print('answer' in mydict) # False

mydict.update({'spam': 'eggs', 'ham': 'damn'})
for key, value in mydict.items():
    print('{} = {}'.format(key, value))
# ham = damn
# spam = eggs

Para assegurar que a classe MongoDict segue o protocolo MutableMapping, utilizei os testes do próprio CPython! :-)

Serialização de Dados

O mongodict utiliza a biblioteca pickle para serializar/desserializar os dados (apenas os valores, não as chaves), portanto, qualquer dado que puder ser serializado com a pickle poderá ser salvo.

Porém, em alguns casos é desejável alterar o serializador. Digamos, por exemplo, que eu esteja salvando o conteúdo de arquivos HTML e queira compactá-los para economizar espaço em meu servidor - daí basta passar o parâmetro codec:

from zlib import compress, decompress
from urllib import urlopen

from mongodict import MongoDict

mydict = MongoDict(codec=(compress, decompress))
url = 'http://www.CursoDeArduino.com.br/'
mydict['curso-de-arduino'] = urlopen(url).read()
print(mydict['curso-de-arduino'])
# <... imprime o HTML da página ...>

Nesse caso, se conectarmos no MongoDB diretamente podemos ver o tamanho armazenado lá:

colecao = mydict._collection
documento = colecao.find_one({'_id': 'curso-de-arduino'})
print(len(documento['v'])) # 5763
print(len(mydict['curso-de-arduino'])) # 20076

Cuidado com Objetos Mutáveis

Caso o valor de uma das chaves seja um objeto mutável (por exemplo: uma lista), lembre-se que alterar o objeto recuperado do MongoDict não irá atualizá-lo no banco (pois ele fica em memória e é um objeto Python nativo). Por exemplo:

from mongodict import MongoDict

mydict = MongoDict()
mydict['compras'] = ['tomate', 'rúcula', 'queijo']
mydict['compras'].append('azeite')
print(mydict['compras'])
# ['tomate', 'r\xc3\xbacula', 'queijo']

Para corrigir isso, devemos explicitamente atualizar o valor da chave:

compras = mydict['compras']
compras.append('azeite')
mydict['compras'] = compras
print(mydict['compras'])
# ['tomate', 'r\xc3\xbacula', 'queijo', 'azeite']

Autenticação

Para autenticar-se no servidor MongoDB, utilize o parâmetro auth:

from mongodict import MongoDict

mydict = MongoDict(auth=('user', 'myprecious'))

Dica Bônus

Caso você ache chato ter que acessar mydict['chave'] e prefira mydict.chave, utilize a biblioteca attrdict. Instale-a a partir do PyPI:

pip install attrdict

E para usar, é bem fácil:

from attrdict import AttrDict
from mongodict import MongoDict

mydict = AttrDict(MongoDict())
mydict.answer = 42
mydict.question = '?'

print('Answer to "{question}" = {answer}'.format(**mydict))

Você só conseguirá acessar como atributo o primeiro nível, ou seja, mydict.chave.outra_chave não funcionará (utilize mydict.chave['outra_chave']).

Contribuindo

Caso queira contribuir, acesse o issue tracker do mongodict no GitHub. Fique à vontade para relatar bugs, sugerir funcionalidades e enviar pull requests! =)

por noreply@blogger.com (Álvaro Justen "Turicas") em 07 de March de 2014 às 16:06

March 06, 2014

Magnun Leno

Adeus Wordpress

De uns tempos pra cá eu tenho percebido o quão desperdício de recursos computacionais (e humanos) é utilizar um blog em Wordpress. Pensem um pouco, eu comecei este blog em 2010, por qual motivo o 1º artigo que eu escrevi precisa ser "regerado" toda vez que que alguém o acessa? Ele poderia muito bem ser uma página HTML estática servida pelo Apache. E quanto a toda a interface web e administração? Já faz um ano que eu escrevo todos os artigos deste blog no VIM, diretamente em HTML.

Pelican

Por esses (e alguns outros poucos) motivos, migrei meu blog (na verdade dois) inteiro para o Pelican, uma gerador de sites estáticos escrito em Python. E vocês aí achando que eu estava a toa este tempo todo.

Adeus Wordpress é um artigo original de Mind Bending

por Magnun em 06 de March de 2014 às 22:08

Osvaldo Santana Neto

Code Review e a Teoria das Janelas Quebradas

Kindle

Na empresa onde trabalho temos o (bom) hábito de fazer Code Review no código dos projetos que desenvolvemos. A prática não é obrigatória mas todos os desenvolvedores gostam de ter seu código revisado.

Eu adoro revisar código alheio tanto quanto gosto de ver meu código revisado e, por isso, me esforço para dar pitaco até em quase todos os projetos da empresa. Até em projetos de outras equipes.

Eventualmente eu entro em debates para que os desenvolvedores renomeiem variáveis ou até mesmo que coloquem ou retirem espaços em branco que violam o Coding Style da empresa. Como usamos Python adotamos a PEP-8 com apenas uma ressalva relativa ao número de colunas por linha que acaba estabelecida apenas pelo bom senso de cada programador.

E eu sou “chato” com isso. Eu realmente implico com qualquer desvio coisa que não me pareça certa. Sejam elas críticas ou triviais recebem a mesma atenção.

Existe uma teoria que afirma que as janelas quebradas de edifícios em uma região da cidade tem relação direta com a criminalidade nesta mesma região.

Eu acredito nessa teoria e, por isso, sou extremamente exigente nas minhas revisões. Faço isso porque acredito que um mero relaxo numa linha em branco dentro do arquivo pode evoluir para um desenho ruim de um módulo inteiro da aplicação.

Ok, admito, isso pode parecer exagero mas… e se não for? E se a teoria das janelas quebradas se aplica também no contexto do código fonte de uma aplicação?

Esse tipo de cuidado é ainda mais importante quando trabalhamos com linguagens de programação com tipagens dinâmica ou fraca pois certas convenções de nomenclatura podem dizer muito sobre os tipos envolvidos em uma operação. Exemplo?

Uma função chamada get_user() retorna que tipo de objeto? Eu presumo que seja uma instância de um objeto representando um usuário (ex. User). Mas só consigo presumir isso pelo nome da função (ou me dando ao trabalho de ler e entender a sua implementação).

E a função get_users(), o que retorna? Presumo que seja uma coleção (collection) de objetos representando usuários, certo? Se o desenvolvedor descuidar dessas e de outras convenções o trabalho ficará bem mais complicado para os outros membros da equipe.

Certa vez eu encontrei um código que fazia algo parecido com isso:

user = self._get_user_from_credentials(request)

Conseguem perceber o que está errado? O método diz que retorna um usuário a partir de suas credenciais (ex. username, senha, …) e enviamos para ele um objeto do tipo Request? Pedi para corrigir o problema de uma das duas formas:

  1. passando as credenciais do usuário para o método ou;
  2. renomeando o método.

Optaram por renomear o método e o código ficou assim:

user = self._get_user_from_request(request)

Note que é um método protegido (em Python o prefixo ‘_’ é usado para informar que o método em questão não deve ser chamado externamente) e, por isso, não seria um problema muito grave manter o nome antigo. Mas mantendo como estava deixariamos uma janela quebrada em nosso código.

The post Code Review e a Teoria das Janelas Quebradas appeared first on Blog do Osvaldo.

por osantana em 06 de March de 2014 às 17:42

Thiago Avelino

Golang, C and Python the benchmark time

I was wondering how performant Golang is, so I decided to put together a little benchmarking example for myself.

The benchmark will be done in my personal computer:

Processor  3 GHz Intel Core i7
Memory  8 GB 1600 MHz DDR3
Software  OS X 10.9.2 (13C64)

So I started with Python, which is what I know best and created the following simple script;

#!/usr/bin/env python

def fac(n):
    if n == 0:
        return 1
    return n * fac(n - 1)

if __name__ == "__main__":
    t = 0
    for j in range(100000):
        for i in range(8):
            t += fac(i)
    print("total: {0}".format(t))

The reason for the total output, was to have a check to ensure that I was getting the same results in each of the scripts. To make sure that they are doing the same amount of work.

Running the script gives us the following execution time;

$ time python factorial.py

total: 591400000

0.68s user
0.01s system
99% cpu
0.688 total

So I am getting about 1s in total execution time. Not bad.

Now the same code sample in C, to see what the time execution would be;

#include <stdio.h>

int fac(int);

int fac(int n) {
  if (n == 0) {
    return 1;
  }
  return n * fac(n - 1);
}

main() {
  int i, j;
  int t = 0;

  for (j = 0; j < 100000; j++) {
    for (i = 0; i <= 7; i++) {
      t += fac(i);
    }
  }

  printf("total: %d\n", t);
}

Compile and execute the above snippet of code;

$ gcc factorial.c -o factorial
$ time ./factorial

total: 591400000

0.01s user
0.00s system
91% cpu
0.016 total

Ok, that's quite an improvement. This is C, so we do expect there to be a great improvement.

Finally we create our code sample in Go;

package main

import "fmt"

func fact(n int) int {
    if n == 0 {
        return 1
    }
    return n * fact(n-1)
}

func main() {
    t := 0
    for j := 0; j < 100000; j++ {
        for i := range []int{1, 2, 3, 4, 5, 6, 7, 8} {
            t += fact(i)
        }
    }
    fmt.Println("total: ", t)
}

Then build and run the code sample and we get the following;

$ go build factorial.go
$ time ./factorial

total:  591400000

0.01s user
0.00s system
93% cpu
0.018 total

So, that's pretty much the same as C, which is excellent. The best part of it all, is that it is actually fun to code in Go compared to C. Python was always an attraction for me as the language is a breeze to work with and enjoyable programming with it. Go is also a nice language to work with and it's really fast to boot. So I'm very excited about the language.

por avelino em 06 de March de 2014 às 12:03

March 03, 2014

Filipe Saraiva

Novidades no Editor de Scripts do Cantor

Um post rápido sobre o Cantor antes da última metade das festas de Carnaval.

KDE 4.13 está com as funcionalidades congeladas agora, e tive tempo de desenvolver algumas melhorias para o editor de scripts do Cantor, que estará disponível no próximo lançamento estável do KDE por volta de 16 de abril.

Agora, os backends para Python 2 e Scilab tem suporte ao editor de scripts! Veja algumas imagens:

python_script_editorEditor de scripts do Cantor para Python 2

scilab_script_editor Editor de scripts do Cantor para Scilab

Você pode acessar o editor de scripts via barra de menu Exibir -> Mostrar Editor de Script. O editor é baseado em kate-part, então ele disponibiliza destaque de sintaxe, numeração de linhas, mini-mapa do texto, e todas as outras coisas legais disponíveis no Kate. Você também tem um botão Executar Script que, após pressionado, carrega o script na área de trabalho do Cantor, como pode ser visto nos exemplos.

Há outras novidades também para os demais backends do Cantor. O Editor de Scrips agora carrega o destaque de sintaxe padrão para cada backend – nas versões anteriores, isso não acontecia. E também, se você pressionar o botão Novo, o novo editor já terá o destaque de sintaxe padrão funcionando também.

Estas são as novidades do meu trabalho no Cantor para o KDE 4.13. Eu pretendo melhorar o backend para Python 2 e o editor de scripts em lançamentos futuros.

Mas agora é hora de aproveitar o restinho do carnaval nas festas de rua do Brasil. Feliz Carnaval! ;)

por Filipe Saraiva em 03 de March de 2014 às 14:52

February 28, 2014

Elcio Luiz Ferreira

Dúvida: URLs de categoria amigáveis

Um amigo me escreveu:

Ola Elcio,

vc tem algum tutorial de como reescrever a url para deixar mais amigável?

no momento eu tenho isso

http://www.meusite.com.br/index.php/category/produtos/produtos-especiais/

quero deixar assim:

http://www.meusite.com.br/produtos-especiais/

Muito bem, vamos lá. O primeiro passo é, se você não quer que as categorias apareçam uma dentro da outra, não usá-las de forma hierárquica no cadastro. Edite a categoria “produtos-especiais” e faça com que ela não seja mais filha de “produtos”. Isso deve deixar a URL dela assim:

http://www.meusite.com.br/index.php/category/produtos-especiais/

O passo seguinte é ir em “Configurações -> Links Permanentes” e configurar corretamente a estrutura de links permanentes, para retirar o “index.php” da URL. Escolha o formato que mais lhe agradar lá. Você vai precisar:

  1. Estar rodando Apache. Essa dica não vai funcionar em outro servidor web, a não ser que você acrescente uma boa dose de hacking.
  2. Ter o mod_rewrite habilitado no seu Apache.
  3. Que o PHP tenha permissão de escrita no arquivo .htaccess.

Tendo feito isso, a URL vai ficar:

http://www.meusite.com.br/category/produtos-especiais/

Por fim, você pode usar esse plugin: Top Level Categories. Ele consegue retirar aquele /category/ da URL, deixando o formato final da URL do jeito que você quer.

Boa sorte!

 

O post Dúvida: URLs de categoria amigáveis apareceu primeiro em fechaTag.

por elcio em 28 de February de 2014 às 12:13

February 25, 2014

Henrique Bastos

Python Decouple 2.2: Strict separation of settings from code

Decouple helps you to organize your settings so that you can change parameters without having to redeploy your app.

It also makes easy for you to:

  1. store parameters on ini or .env files;
  2. define comprehensive default values;
  3. properly convert values to the correct data type;
  4. have only one configuration module to rule all your instances.

It was originally designed for Django, but became an independent generic tool for separating settings from code.

Test Status
Code Helth
Latest PyPI version
Number of PyPI downloads

Why?

Web framework’s settings stores many different kinds of parameters:

  • Locale and i18n;
  • Middlewares and Installed Apps;
  • Resource handles to the database, Memcached, and other backing services;
  • Credentials to external services such as Amazon S3 or Twitter;
  • Per-deploy values such as the canonical hostname for the instance.

The first 2 are project settings the last 3 are instance settings.

You should be able to change instance settings without redeploying your app.

Why not just use environment variables?

Envvars works, but since os.environ only returns strings, it’s tricky.

Let’s say you have an envvar DEBUG=False. If you run:

if os.environ['DEBUG']:
    print True
else:
    print False

It will print True, because os.environ['DEBUG'] returns the string "False". Since it’s a non-empty string, it will be evaluated as True.

Decouple provides a solution that doesn’t look like a workaround: config('DEBUG', cast=bool).

Install

pip install python-decouple

Usage

On your settings.py.

  1. Import the config object:
    from decouple import config
  2. Retrieve the configuration parameters:
    SECRET_KEY = config('SECRET_KEY')
    DEBUG = config('DEBUG', default=False, cast=bool)
    EMAIL_HOST = config('EMAIL_HOST', default='localhost')
    EMAIL_PORT = config('EMAIL_PORT', default=25, cast=int)

Where the settings data are stored?

Decouple supports both .ini and .env files.

Ini file

Simply create a settings.ini next to your configuration module in the form:

[settings]
DEBUG=True
TEMPLATE_DEBUG=%(DEBUG)s
SECRET_KEY=ARANDOMSECRETKEY
DATABASE_URL=mysql://myuser:mypassword@myhost/mydatabase
PERCENTILE=90%%

Note: Since ConfigParser supports string interpolation, to represent the character % you need to escape it as %%.

Env file

Simply create a .env text file on your repository’s root directory in the form:

DEBUG=True
TEMPLATE_DEBUG=True
SECRET_KEY=ARANDOMSECRETKEY
DATABASE_URL=mysql://myuser:mypassword@myhost/mydatabase
PERCENTILE=90%

Example: How do I use it with Django?

Given that I have a .env file at my repository root directory, here is a snippet of my settings.py.

I also recommend using unipath and dj-datatabase-url.

# coding: utf-8
from decouple import config
from unipath import Path
from dj_database_url import parse as db_url
 
BASE_DIR = Path(__file__).parent
 
DEBUG = config('DEBUG', default=False, cast=bool)
TEMPLATE_DEBUG = DEBUG
 
DATABASES = {
    'default': config(
        'DATABASE_URL',
        default='sqlite:///' + BASE_DIR.child('db.sqlite3'),
        cast=db_url
    )
}
 
TIME_ZONE = 'America/Sao_Paulo'
USE_L10N = True
USE_TZ = True
 
SECRET_KEY = config('SECRET_KEY')
 
EMAIL_HOST = config('EMAIL_HOST', default='localhost')
EMAIL_PORT = config('EMAIL_PORT', default=25, cast=int)
EMAIL_HOST_PASSWORD = config('EMAIL_HOST_PASSWORD', default='')
EMAIL_HOST_USER = config('EMAIL_HOST_USER', default='')
EMAIL_USE_TLS = config('EMAIL_USE_TLS', default=False, cast=bool)
 
# ...

Atention with undefined parameters

On the above example, all configuration parameters except SECRET_KEY = config('SECRET_KEY') have a default value to fallback if it does not exist on the .env file.

If SECRET_KEY is not present on the .env, decouple will raise an UndefinedValueError.

This fail fast policy helps you avoid chasing misbehaviors when you eventually forget a parameter.

How it works?

Decouple is made of 5 classes:

  • Config

    Coordinates all the configuration retrieval.

  • RepositoryIni

    Can read values from ini files.

  • RepositoryEnv

    Can read .env files and when a parameter does not exist there,
    it tries to find it on os.environ.

    This process does not change nor add any environment variables.

  • RepositoryShell

    Can only read values from os.environ.

  • AutoConfig

    Detects which configuration repository you’re using.

    It recursively searches up your configuration module path looking for a
    settings.ini or a .env file.

The config object is an instance of AutoConfig to improve decouple‘s usage.

License

The MIT License (MIT)

Copyright (c) 2013 Henrique Bastos <henrique at bastos dot net>

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

por Henrique Bastos em 25 de February de 2014 às 06:31

February 24, 2014

Rodrigo Amaral

amaral

Durante a tarde do último sábado, tive a oportunidade de ser o facilitador de um mini-curso prático sobre Google App Engine e Python para o pessoal do Google Developer Group Aracaju. O evento foi bastante produtivo e certamente mais pessoas vão passar a acompanhar também as atividades do PUG-SE.

Meus agradecimentos a todos e compareceram e ao pessoal que viabilizou o encontro. Organização de primeira, parabéns!

Mais detalhes no post do blog do GDG Aracaju.

Abaixo os slides que usamos como roteiro da atividade prática:

 


por Rodrigo Amaral em 24 de February de 2014 às 16:57

February 21, 2014

Aprenda Python

Como perguntar

Todos nós temos dúvida sobre alguma coisa. Ninguém nasce sabendo. Porém, o que pode separar aqueles que continuam sem saber, dos que já conhecem sobre o assunto, é a forma com que eles fazem perguntas. Esse assunto não é novo. Sobre ele, temos o excelente artigo Como fazer perguntas inteligentes, que é uma tradução do How to Ask Questions The Smart Way do Eric Raymond. Se você tem um tempinho

por Vinicius Assef (noreply@blogger.com) em 21 de February de 2014 às 09:29

O que você sugere para eu me desenvolver na plataforma Python?

Esse artigo será praticamente a transcrição de uma conversa que mantive por email com um colega que é membro da comunidade Python e, como muitos de nós, não ganha a vida com a linguagem que gosta. Ele estuda análise de sistemas na faculdade, conhece Java, tem paixão por programação, mas trabalha em outra área de conhecimento. Assistiu minha palestra "Python na vida real, onde estão as vagas", e

por Vinicius Assef (noreply@blogger.com) em 21 de February de 2014 às 09:15

Thiago Avelino

Business Intelligence (BI) Application Server written in Python

I started a new project with the name OpenMining, new application server written in Python.

OpenMining

OpenMining is software for creating OLAP (online analytical processing) cubes (multi-dimensional) using Numpy, Scipy and Pandas for data management and flexibility in processing dynamical filters. Open-source provider of reporting, analysis, dashboard, data mining and workflow capabilities.

Our goals

  • Business Intelligence software (Pentaho/Jaspersoft) alternative;
  • OLAP manager;
  • Generate report (grid, charts, pdf and etc);
  • Dashboard manager, link one or more element (report);
  • Easy dashboard generate;
  • Not one data is processed on the basis of source data;
  • Friendly interface;
  • Used websocket on cube load;

Python libs used

  • Pandas
  • Numpy
  • numexpr
  • ipython
  • Tornado
  • SQLAlchemy
  • RQ
  • Riak client
  • Redis client
  • Memcached client

More about OLAP cube

A cube can be considered a generalization of a three-dimensional spreadsheet. For example, a company might wish to summarize financial data by product, by time-period, and by city to compare actual and budget expenses. Product, time, city and scenario (actual and budget) are the data's dimensions.

Cube is a shortcut for multidimensional dataset, given that data can have an arbitrary number of dimensions. The term hypercube is sometimes used, especially for data with more than three dimensions.

Each cell of the cube holds a number that represents some measure of the business, such as sales, profits, expenses, budget and forecast.

OLAP data is typically stored in a star schema or snowflake schema in a relational data warehouse or in a special-purpose data management system. Measures are derived from the records in the fact table and dimensions are derived from the dimension tables.

Screenshot

Screenshot Screenshot Screenshot

The MIT License (MIT)

Copyright © 2014 Thiago Avelino

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Contribute

Star and fork in github.com/avelino/mining, send pull request!

Bug tracker

por avelino em 21 de February de 2014 às 04:13

New web framework asynchronous to Python 3

/media/nacho.png

I started a new project with the name nacho, asynchronous web framework for Python 3.

Our goals

  • It was designed to work on Python 3.x
  • Some of syntax were inspired on Tornado's syntax
  • Tornado is the default server, but Eventlet is stable as well
  • Templates are done by Jinja2
  • HTML5 as the big-main-thing
  • Work friendly with NoSQL (otherwise we should stop talking about them)
  • Handle asynchronous requests properly

Example

class MainHandler(ApplicationController):
    def get(self):
        data = {'title': 'testando lero lero'}
        self.render("home.html", **data)


r = Routers([(r"/", MainHandler),])

por avelino em 21 de February de 2014 às 03:23

February 18, 2014

Filipe Saraiva

Ajude a criar a programação do FISL 15

O Fórum Internacional de Software Livre (FISL) chega à sua 15ª edição e continua sendo referência para a comunidade de software e cultura livre latino-americana.

Você pode tanto participar da programação do FISL quanto ajudar a criá-la. Diversas modalidades de submissão de atividades encontram-se abertas, e você pode clicar nos links abaixo para saber mais informações.

A Chamada de Palestas foi prorrogada até o dia 27 de fevereiro, mesmo já havendo 413 propostas cadastradas! Esta é a forma de submissão de atividade mais convencional onde você descreve um tema sob qual irá palestrar.

A Chamada para Encontros Comunitários é voltada para comunidades de usuários/desenvolvedores que queiram fazer um pequeno encontro no espaço do FISL. O tempo disponibilizado pode ser um pouco maior que o de uma palestra (até 1 hora e 40 minutos de atividade). Submissões até dia 10 de março.

Uma das melhores atrações do FISL com certeza é o espaço dos grupos de usuários. Se você quer ter a sua comunidade por lá fique atento ao prazo e requisitos da Chamada de Grupos de Usuários. As propostas para participação desse espaço vão até dia 10 de março.

A Chamada para o Workshop de Software Livre (WSL) é o lado mais acadêmico do FISL. Aqui, pesquisadores acadêmicos do software livre, cultura livre, e mais, apresentam resultados de suas pesquisas em painéis científicos divididos por temas. Há diversos tipos de submissão de artigos e o deadline vai até dia 8 de março.

Mandem suas atividades e nos encontramos no FISL! ;)

por Filipe Saraiva em 18 de February de 2014 às 22:12

Kodumaro

Aspectos – parte II: mixins

Na parte I demos uma passada geral no conceito de aspectos. Aqui veremos os mixins.

Mixins são classes incompletas que apenas atribuem determinado comportamento às classes herdeiras.

Vamos a um exemplo bem esdrúxulo, mas suficiente: um objeto que armazena notas de alunos em um arquivo.
from cPickle import dumps, loads
import gdbm

__all__ = ['Banco', 'Notas']


class Banco(object):

def __init__(self, file=None):
if file is None:
file = 'notas.db'
if isinstance(file, basestring):
file = gdbm.open(file, 'c')
self.file = file

def close(self):
if self.file:
self.file.close()
self.file = None


class Notas(object):

def __init__(self, matricula, db):
self.matricula = matricula

if not isinstance(db, Banco):
raise TypeError(
'expected Banco instance, got {}'
.format(type(db).__name__)
)

self.db = db

try:
self.notas = loads(db[str(matricula)])
except KeyError:
self.notas = {}


def save(self):
db[str(self.matricula)] = dumps(self.notas)


@property
def primeiro_bimestre(self):
return self.notas.get('1bim')

@primeiro_bimestre.setter
def primeiro_bimestre(self, value):
self.notas['1bim'] = float(value)

@property
def segundo_bimestre(self):
return self.notas.get('2bim')

@segundo_bimestre.setter
def segundo_bimestre(self, value):
self.notas['2bim'] = float(value)

@property
def terceiro_bimestre(self):
return self.notas.get('3bim')

@terceiro_bimestre.setter
def terceiro_bimestre(self, value):
self.notas['3bim'] = float(value)

@property
def quarto_bimestre(self):
return self.notas.get('4bim')

@quarto_bimestre.setter
def quarto_bimestre(self, value):
self.notas['4bim'] = float(value)

@property
def recuperacao(self):
return self.notas.get('rec')

@recuperacao.setter
def recuperacao(self, value):
return self.notas['rec'] = float(value)

@property
def media(self):
soma = sum(
self.primeiro_bimestre or 0,
self.segundo_bimestre or 0,
self.terceiro_bimestre or 0,
self.quarto_bimestre or 0,
)
m = soma / 4.

rec = self.recuperacao
if rec is not None:
m = (m + rec) / 2.

return m

Repare que temos o mesmo problema apresentando na parte I: está tudo misturado em uma única classe!

Podemos separar as partes de gerência de banco e serialização em classes diferentes, dedicadas a seu próprio aspecto, chamadas mixins.

A classe de faz serialização pode ser apenas isso:
class NotaSerializavelMixin(object):
def load(self):
s = self.retrieve()
self.notas = loads(s) if s else {}

def __str__(self):
return dumps(self.notas)

A gerência de banco vai para outro mixin:
class PersistenciaMixin(object):
def retrieve(self):
try:
return self.db[str(self.matricula)]
except KeyError:
return None

def save(self):
db[str(self.matricula)] = str(self)

Preferindo, é possível separar a gerência de notas em um mixin também:
class NotasMixin(object):

@property
def primeiro_bimestre(self):
return self.notas.get('1bim')

@primeiro_bimestre.setter
def primeiro_bimestre(self, value):
self.notas['1bim'] = float(value)

...

@property
def media(self):
soma = sum(
self.primeiro_bimestre or 0,
self.segundo_bimestre or 0,
self.terceiro_bimestre or 0,
self.quarto_bimestre or 0,
)
m = soma / 4.

rec = self.recuperacao
if rec is not None:
m = (m + rec) / 2.

return m

Ao final, a classe principal será apenas uma cola dos mixins:
class Notas(NotaSerializavelMixin, PersistenciaMixin, MotasMixin):

def __init__(self, matricula, db):
self.matricula = matricula

if not isinstance(db, Banco):
raise TypeError(
'expected Banco instance, got {}'
.format(type(db).__name__)
)

self.db = db
self.load()

A API da classe continua idêntica: recebe o número da matrícula e o banco na instanciação, propriedades para acessar as notas e método save() para salvá-las em arquivo, porém agora cada aspecto está isolado e encapsulado em seu próprio mixin.

[]’s
Cacilhας, La Batalema

por noreply@blogger.com (Darth Batalema) em 18 de February de 2014 às 16:39

Aspectos – parte I

Um paradigma muito útil é a Programação orientada a Aspectos.

Consiste em separar e encapsular as funcionalidades de um código conforme sua importância.

Nesta primeira parte, abordaremos de forma simples tal separação e deixaremos o conceito de mixins para a parte II.

Vamos começar com um exemplo: imagine uma view que modifica o estado de um objeto, retornando um hash do novo estado:
@app.route('/people/<uuid>/', methods=['PATCH'])
def update_person(uuid):
person = db.person.find({ '_id': uuid }).first()
if not person:
raise Http404

try:
data = json.loads(request.data)
except ValueError:
return json.dumps({ 'error': 'invalid request' }), \
400, \
{ 'Content-Type': 'application/json' }

person.update(data)
db.person.save(person)

r = [(str(k), repr(v)) for k, v in person.iteritems()]
r.sort()
s = ';'.join('{}:{}'.format(k, v) for k, v in r)

return json.dumps({ 'etag': md5(s).hexdigest() }), \
200, \
{ 'Content-Type': 'application/json' }

A solução atende, mas é de difícil manutenção. Perceba que a função chamada update_person (atualiza pessoa) faz muito mais do que simplesmente atualizar os dados:
  • Recupera o documento do banco, retornando 404 se não existir;
  • Faz os parsing dos dados recebidos, retornando 400 em caso de erro;
  • Efetivamente atualiza o documento;
  • Serializa o objeto para a resposta;
  • Gera um hash da serialização;
  • Responde a requisição com formato conveniente.

Cada um desses passos é um aspecto do processo e pode ser isolado do restante.

Vamos então separar o primeiro aspecto: recuperação do documento.
def retrieve_person_aspect(view):
@wraps(view)
def wrapper(uuid):
person = db.person.find({ '_id': uuid }).first()
if not person:
raise Http404

return view(person)
return wrapper

@app.route('/people/<uuid>/', methods=['PATCH'])
@retrieve_person_aspect
def update_person(person):
try:
data = json.loads(request.data)
except ValueError:
return json.dumps({ 'error': 'invalid request' }), \
400, \
{ 'Content-Type': 'application/json' }

person.update(data)
db.person.save(person)

r = [(str(k), repr(v)) for k, v in person.iteritems()]
r.sort()
s = ';'.join('{}:{}'.format(k, v) for k, v in r)

return json.dumps({ 'etag': md5(s).hexdigest() }), \
200, \
{ 'Content-Type': 'application/json' }

Agora a recuperação do documento está isolada, podendo inclusive ser usada em outras views. Nossa view já recebe o documento recuperado e não precisa lidar com o fato dele existir ou não.

Porém ainda temos muita coisa misturada. Por exemplo, a obtenção e parsing dos dados recebidos: isso caracteriza outro aspecto do código, que não a atualização do documento.

Podemos portanto, separá-los:
def parse_data_aspect(view):
@wraps(view)
def wrapper(person):
try:
data = json.loads(request.data)
except ValueError:
return json.dumps({ 'error': 'invalid request' }), \
400, \
{ 'Content-Type': 'application/json' }

return view(person, data)
return wrapper

def retrieve_person_aspect(view):
...

@app.route('/people/<uuid>/', methods=['PATCH'])
@retrieve_person_aspect
@parse_data_aspect
def update_person(person, data):
person.update(data)
db.person.save(person)

r = [(str(k), repr(v)) for k, v in person.iteritems()]
r.sort()
s = ';'.join('{}:{}'.format(k, v) for k, v in r)

return json.dumps({ 'etag': md5(s).hexdigest() }), \
200, \
{ 'Content-Type': 'application/json' }

A função update_person já está muito mais limpa: atualiza o documento, serializa e retorna o hash, mas ainda faz coisas demais. Vamos separar o tratamento do retorno:
def respond_etag_aspect(view):
@wraps(view)
def wrapper(person, data):
response = view(person, data)
return json.dumps({ 'etag': md5(response).hexdigest() }), \
200, \
{ 'Content-Type': 'application/json' }
return wrapper

def parse_data_aspect(view):
...

def retrieve_person_aspect(view):
...

@app.route('/people/<uuid>/', methods=['PATCH'])
@retrieve_person_aspect
@parse_data_aspect
@respond_etag_aspect
def update_person(person, data):
person.update(data)
db.person.save(person)

r = [(str(k), repr(v)) for k, v in person.iteritems()]
r.sort()
return ';'.join('{}:{}'.format(k, v) for k, v in r)

As coisas estão ficando cada vez mais separadas. A única coisa que a função update_person faz agora além de atualizar o documento é serializá-lo. Isso também pode ser isolado:
def serialize_person_aspect(view):
@wraps(view)
def wrapper(person, data):
response = view(person, data)
r = [(str(k), repr(v)) for k, v in response.iteritems()]
r.sort()
return ';'.join('{}:{}'.format(k,v) for k, v in r)

def respond_etag_aspect(view):
...

def parse_data_aspect(view):
...

def retrieve_person_aspect(view):
...

@app.route('/people/<uuid>/', methods=['PATCH'])
@retrieve_person_aspect
@parse_data_aspect
@respond_etag_aspect
@serialize_person_aspect
def update_person(person, data):
person.update(data)
db.person.save(person)
return person

Perceba que, com a separação dos aspectos em funções distintas, o código ficou muito mais semântico:
  • retrive_person_aspect apenas recupera o documento do banco;
  • parse_data_aspect apenas faz o parsing dos dados recebidos;
  • respond_etag_aspect apenas gera o formato correto da resposta;
  • serialize_person_aspect apenas serializa o documento;
  • finalmente, update_persion apenas atualiza o documento.

Observações

  • db é um objeto de banco de dados MongoDB, apenas para fim de exemplo.
  • app é uma aplicação Flask, apenas para fim de exemplo.
  • A ordem dos decoradores é importante.
  • Os imports foram omitidos:
import json
from functools import wraps
from hashlib import md5

Na parte II abordaremos mixins.

[]’s
Cacilhας, La Batalema

por noreply@blogger.com (Darth Batalema) em 18 de February de 2014 às 15:34