Coding Dojo

Bom dia à todos.

Hoje vou falar sobre uma prática muito legal que desde o ano passado toma conta da empresa em que trabalho: O Coding Dojo, que não é nada mais nada menos do que reunir um grupo de pessoas para resolver um problema aleatório em uma linguagem aleatória. Não é uma competição (ou luta), como o nome sugere.

Alguns conceitos são bastante explorados:
- Pair programming: duas pessoas em uma máquina só. Um “codando” e outro dando dicas e pitacos.
- TDD: desenvolvimento orientado à testes. Basicamente funciona assim: Testa o que você quer, como não está implementado, vai dar erro. Corrige o erro da forma mais simples e rode o teste. Se funcionar, é a hora de refatorar ou criar outro teste que não esteja implementado. Desta forma, os testes cubram todo seu programa.

Regras básicas:
- Quando o teste falha, ninguém dá palpite. Todos ficam quietos a não ser que os dois programadores peçam ajuda.
- Um cronometro é iniciado para de 5 a 7 minutos trocar as pessoas que programam. O “co-piloto” vira “piloto” e entra um próximo soldado na fila.

Kung Fu Panda praticando Coding Dojo

Kung Fu Panda (DreamWorks, 2008) praticando Coding Dojo

Nesta sexta – feira,  a linguagem escolhida foi Objective C (a mesma utilizada pelos desenvolvedores de aplicações para Iphone) e o problema era sobre sacolas de mercado.
O problema consistia em receber uma lista de produtos, a quantidade máxima que uma sacola aguenta e retornar a quantidade de sacolas necessárias para todos os produtos. Um detalhe é que produtos iguais não se misturam, então mesmo que a carga máxima de uma sacola seja 2, feijão e café ficam sem sacolas separadas. Se tivermos feijão, café, café e café, precisaremos de 3 sacolas. 1- feijão, 2- [café, café], 3-[café]. E por aí vai.

Foi bacana a experiência de ver Objective C. Recomendo que quem puder, aprenda.

Não tenho Mac, pelo menos até este post, então dei uma roubada e fiz em PHP para pelo menos entenderem o problema. A outra roubada que eu dei é que só coloquei o algoritmo. Não fiz testes no link abaixo. Está no GitHub. Segue o link Coding Dojo Sacolas.

Até a próxima

ps: Eu sei que o Dojo é o local onde se praticam artes marciais japonesas e não chinesas (como o Kung Fu), mas vou manter o desenho porque … porque … porque sim!!

https://github.com/luisribeiro/coding-dojo-sacolas

Maratona de Programação Interna Apontador e o Local Wake Me Up

Olá, caros.
Este final de semana (08 e 09/01/2010), tivemos a primeira Maratona de Programação do Apontador. Nesta primeira versão, ela foi realizada internamente, ou seja, nós fomos as “cobaias” do evento. Hehehe.

O pessoal estava muito animado e com projetos extremamente interessantes. Como a idéia era inovar e, de preferência, com a API do Apontador, vimos muitas idéias relacionadas a pessoas, lugares e informação ao seu redor. Cheguei antes do horário previsto para o início no dia 08, e muitos já estavam lá. Enquanto eu voltei para casa por volta das 23 hrs, alguns guerreiros viraram a noite aperfeiçoando os projetos e se divertindo (um xbox com kinect foi colocado para divertir o pessoal).

Trago algumas fotos da abertura e prints do projeto que eu fiz.

Meu projeto foi o Local Wake Me Up. É um projeto desenvolvido para Android bastante simples com a idéia de que um usuário escolha o seu local de destino e possa acordar com um despertador sem a necessidade de especificar o horário de chegada (pelo menos a princípio). O projeto foi uma idéia do Ricardo Martins: ele gostaria de algo que o pudesse acordar no fretado, sem a preocupação do trânsito ou de qual pessoa desceu do ônibus.
É um projeto simples, para o qual tenho tido algumas idéias. Sugestões são bem vindas e, como viram, o projeto está no GitHub. Quem quiser contribuir, fique a vontade.

Quando ele estiver mais aceitável, pretendo colocar no Android Market e fazer atualizações.

Até a próxima,
Luis Laranja

Acessando a Api Apontador com Java

Recentemente, comecei a utilizar a API do Apontador (http://api.apontador.com.br/)  para testar as funcionalidades e, achei muito bacana.

Tive a idéia de desenvolver uma aplicação para Android, que utiliza Java. Como não quero mostrar os fins, mas os meios, vou tentar detalhar como utilizar a API Apontador em Java. Notei que no site oficial, os exemplos são com PHP e Python.

Como utilizei duas ou três bibliotecas, a integração ficará por parte de vocês.

Vamos lá?

Primeiramente, baixem as bibliotecas que foram utilizadas para “brincar” com a API.
Base64 – http://ostermiller.org/utils/download.html
JSON – http://www.json.org/java/

Eu preferi utilizar o formato JSON ao invés do XML, que é nativo.

Depois de encontrar o que precisava, criei uma classe com um método para fazer a chamada à API do Apontador. Segue a classe. Note que os valores consumerKey e consumerSecret devem ser gerados no site da própria API.

//obtem classes necessárias para requisição e resposta via http
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;

import org.json.JSONArray;
import org.json.JSONObject;

import aptUtil.AptLocal;
import aptUtil.AptLocalList;

import com.Ostermiller.util.Base64;

public class AptBasic {

private String consumerKey;
private String consumerSecret;
private String apiURL;

/**
* Construtor da classe
* Define as chaves do Apontador
* Define a url da api Apontador
*/
public AptBasic() {
this.consumerKey    = new String("gerar o seu codigo no site api.apontador.com.br");
this.consumerSecret = new String("gerar o seu codigo no site api.apontador.com.br");
this.apiURL         = new String("http://api.apontador.com.br/v1");
}

public AptLocalList search(String name, String city, String state) {

AptLocalList locals = new AptLocalList();

try {

//modifica encoding do parâmetros antes da busca, para ficarem no formato de URL
//o encoding UTF-8 é o encoding que eu estava utilizando - não é conversão para UTF-8
//o que foi feito abaixo seria semelhante ao urlencode e não ao utf8_encode
name = URLEncoder.encode(name, "UTF-8");
city = URLEncoder.encode(city, "UTF-8");
state = URLEncoder.encode(state, "UTF-8");

//realiza chamada a url
String urlApt = new String(this.apiURL.concat("/search/places/byaddress?city=" + city + "&state=" + state + "&term=" + name).concat("&type=json"));

URL url = new URL(urlApt);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("Authorization", "Basic " + this.getKey());

//converte retorno da chamada http para string - retorno em json
String res = new String("");
String aux = new String("");
BufferedReader buff = new BufferedReader(new InputStreamReader(conn.getInputStream()));
while((aux = buff.readLine()) != null) {
res = res.concat(aux).concat("\n");
}
conn.getInputStream().close();

//salva os valores da string json no objeto de locais
JSONObject json = new JSONObject(res);

JSONArray places = ((JSONObject) json.get("search")).getJSONArray("places");
locals.setTotal(Integer.parseInt(((JSONObject) json.get("search")).getString("result_count")));
locals.setPage(Integer.parseInt(((JSONObject) json.get("search")).getString("current_page")));

for(int i = 0; i < places.length(); i++) {

JSONObject pl = places.getJSONObject(i).getJSONObject("place");
AptLocal local = new AptLocal();

//atributos comuns
local.setId(pl.getString("id"));
local.setName(pl.getString("name"));
local.setReview(new Integer(pl.getString("review_count")));
local.setUrl(pl.getString("main_url"));
local.setUrl2(pl.getString("other_url"));
local.setIcone(pl.getString("icon_url"));
local.setRating(new Double(pl.getString("average_rating")));

//endereço
local.setAddress(
pl.getJSONObject("address").getString("street"),
pl.getJSONObject("address").getString("number"),
pl.getJSONObject("address").getString("district"),
pl.getJSONObject("address").getString("complement"),
pl.getJSONObject("address").getString("zipcode"),
pl.getJSONObject("address").getJSONObject("city").getString("name"),
pl.getJSONObject("address").getJSONObject("city").getString("state"),
pl.getJSONObject("point").getString("lng"),
pl.getJSONObject("point").getString("lat")
);

//categoria
local.setCategory(
pl.getJSONObject("category").getString("id"),
pl.getJSONObject("category").getString("name"),
pl.getJSONObject("category").getJSONObject("subcategory").getString("id"),
pl.getJSONObject("category").getJSONObject("subcategory").getString("name")
);

locals.add(local);

}

} catch (Exception e) {
System.out.println("Erro na URL\n" + e.getLocalizedMessage());
}

return locals;

}

/**
* Formata o consumerKey e consumerSecret de acordo com o que a API do Apontador solicita
* @return String
*/
private String getKey() {
return Base64.encode(this.consumerKey.concat(":").concat(this.consumerSecret));
}

}

A classe que acessa e obtem os dados é esta. As que guardam os dados (AptLocalList, AptLocal, AptAddress e AptCategory) são apenas classes para tratar os valores recebidos e formatar o que for necessário. Se alguém quiser, pode pedir que eu posto. Não coloquei aqui para não perder o foco de chamada à API do Apontador.

Espero que tenham gostado.

abs,
Luis Laranja

public AptLocalList search(String name, String city, String state) {AptLocalList locals = new AptLocalList();try {

//modifica encoding do parâmetros antes da busca, para não fazer caca
name = URLEncoder.encode(name, “UTF-8″);
city = URLEncoder.encode(city, “UTF-8″);
state = URLEncoder.encode(state, “UTF-8″);

//realiza chamada a url
String urlApt = new String(this.apiURL.concat(“/search/places/byaddress?city=” + city + “&state=” + state + “&term=” + name).concat(“&type=json”));

URL url = new URL(urlApt);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty(“Authorization”, “Basic ” + this.getKey());

//converte retorno da chamada http para string – retorno em json
//”result_count”:”200″,”current_page”:”1″}}
JSONObject json = new JSONObject(convertStreamToString(conn.getInputStream()));

JSONArray places = ((JSONObject) json.get(“search”)).getJSONArray(“places”);
locals.setTotal(Integer.parseInt(((JSONObject) json.get(“search”)).getString(“result_count”)));
locals.setPage(Integer.parseInt(((JSONObject) json.get(“search”)).getString(“current_page”)));

for(int i = 0; i < places.length(); i++) {

JSONObject pl = places.getJSONObject(i).getJSONObject(“place”);
AptLocal local = new AptLocal();

//atributos comuns
local.setId(pl.getString(“id”));
local.setName(pl.getString(“name”));
local.setReview(new Integer(pl.getString(“review_count”)));
local.setUrl(pl.getString(“main_url”));
local.setUrl2(pl.getString(“other_url”));
local.setIcone(pl.getString(“icon_url”));
local.setRating(new Double(pl.getString(“average_rating”)));

//endereço
local.setAddress(
pl.getJSONObject(“address”).getString(“street”),
pl.getJSONObject(“address”).getString(“number”),
pl.getJSONObject(“address”).getString(“district”),
pl.getJSONObject(“address”).getString(“complement”),
pl.getJSONObject(“address”).getString(“zipcode”),
pl.getJSONObject(“address”).getJSONObject(“city”).getString(“name”),
pl.getJSONObject(“address”).getJSONObject(“city”).getString(“state”),
pl.getJSONObject(“point”).getString(“lng”),
pl.getJSONObject(“point”).getString(“lat”)
);

//categoria
local.setCategory(
pl.getJSONObject(“category”).getString(“id”),
pl.getJSONObject(“category”).getString(“name”),
pl.getJSONObject(“category”).getJSONObject(“subcategory”).getString(“id”),
pl.getJSONObject(“category”).getJSONObject(“subcategory”).getString(“name”)
);

locals.add(local);

}

//            System.out.println(((JSONObject) json.get(“search”)).getJSONArray(“places”).toString());

} catch (Exception e) {
System.out.println(“Erro na URL\n” + e.getLocalizedMessage());
}

return locals;

}

Prolog e seu animado paradigma

Olá,

Recentemente, tenho feito um mini projeto em Prolog para entregar ao professor de I.A (ou A.I.) na faculdade. Já tive contato com a linguagem em outros dois ou três semestres e mesmo assim cada vez que faço algum trabalho com mais esforço em Prolog, apaixono – me por esta linguagem.

Para quem não sabe, Prolog é uma linguagem do paradigma de programação em lógica. Não é parecido com Java, nem com C, nem C#. Não me levem a mal: eu gosto destas linguagens também. Prolog se assemelha mais à haskell (paradigma de programação funcional) . Eu não disse que é igual, disse que é mais próximo de Haskell do que de Java. É a MINHA opinião.

Sou o tipo de pessoa que acha que quem programa em uma linguagem, programa em todas. Portanto, recomendo muito que “busquem conhecimento” (by E.T. Bilu) e aprendam um pouco de prolog, porque é muito show de bola.

AoA.

 

Final de Ano

Mais um ano chegando ao fim … eu, como gosto do horário de verão, estou bastante satisfeito. Estou bem cansado … a reta final da faculdade está cobrando e preciso concluir mais um semestre com sucesso.

O brasileirão também está nos momentos finais. Como o Palmeiras não tem mais perigo de cair, estou preocupado com a Copa Sul Americana: as chances de classificação para a Libertadores são maiores por lá.

Uma notícia boa está para sair do forno até janeiro … espero que tudo de certo para eu poder compartilhar com todos. =]

 

Dica: utilizei um framework que trabalha com o conceito MVC (http://www.enode.com/x/markup/tutorial/mvc.html) e conclui o trabalho mais rápido, porque é uma framework bem simples e organizada. Chama – se Code Igniter (http://codeigniter.com/). Recomendo.

 

Até a próxima, gente do bem.

Micro Apresentação

Primeiro post no blog … quem sabe quantas coisas aguardam por vocês  e por mim o.O
Breve apresentação: Sou Luis Ribeiro, conhecido fora do mundo corporativo como Luis Laranja. Sou Palmeirense e católico. Trabalho no Apontador (http://www.apontador.com.br) e estou no 8º de penúltimo semestre de Ciência da Computação no Mackenzie. Criei este blog para aprender mais e expor parte da minha opinião na internet sem uma rede social específica.

Volto com mais conteúdo.

Até a próxima.

http://www.twitter.com/luislaranja