(CESGRANRIO/Petrobras – Analista de Sistemas Jr – 2008) Questão 54 – UML

Segue meu post no blog do Walter ( http://waltercunha.com/blog/ ).

Olá, pessoal.

Esta será minha primeira participação aqui no blog do Walter. Pretendo comentar sobre questões de Engenharia de Software, assunto como UML, Padrões de Projeto, Processos de software, Rup, Desenvolvimento OO…

Pois então, começarei por uma questão que envolve UML e Padrões e que achei muito bem elaborada , apesar do criador ter dado uma ajudinha nas alternativas. Uma pequena modificação, e mantida a idéia, ela poderia ser tornar uma questão de nível um pouco elevado.

Estou falando da questão 54 da prova da Petrobras – Analista de Sistemas Júnior – Engenharia de Software – CESGRANRIO – 2008.

Segue:

questao54petroanalistauml

(CESGRANRIO/Petrobras – Analista de Sistemas Jr – 2008) Questão 54 – UML – A figura acima mostra um diagrama de classes UML desenvolvido para um projeto em que ainda não se sabe em que linguagem será realizada a implementação. Sobre o diagrama, assinale a afirmação correta.

(A) Há um erro na cardinalidade da associação entre ClasseA e ClasseB, pois se trata de uma composição e, como tal, um objeto da ClasseB só pode estar associado a um objeto da ClasseA

(B) Há uma dependência cíclica entre ClasseB, ClasseC e ClasseE, o que não é permitido pela UML.

(C) O fato de que ClasseD generaliza ClasseA e ClasseB se traduz em herança múltipla, o que não é permitido pela UML.

(D) Retirando a ClasseA, o diagrama resultante corresponde ao padrão de projeto composite

(E) Invertendo o sentido de todas as generalizações, o diagrama resultante corresponde ao padrão de projeto chain of responsability.
Comentário:

Então o que nos parece a primeira vista é uma questão simples de UML [1], que mostra um diagrama e elabora algumas assertivas, e é isso mesmo que ela é. Apesar do diagrama assustar um pouco, pois utiliza Agregação, Composição, Generalização (herança composta), Navegação numa Agregação e dentre as assertivas cobrar do candidato entendimento da estrutura de dois Padrões de Projeto, na verdade a questão se resume ao entendimento do relacionamento de Agregação Composta (ou Composição).

Vejamos, na alternativa (B) é questionado o fato de haver uma dependência cíclica entre as classes B,C e E e que isso não seria permitido na UML. O que não é verdade, o que não é permitido na UML é o que foge da sua semântica e sintaxe, pois lembremos que UML é uma linguagem de modelagem. Ainda, essa pode ser extendida ( o que pode ser um terror para certas questões ). Logo, a UML em sua semântica e sintaxe não impede a existência da dependência cíclica, pois essa não se preocupa com problemas da arquitetura do sistema ou da solução, seria similar afirmar que a UML não permite uma baixa coesão e alto acoplamento. ( Lembre que buscamos, na medida do possível, alta coesão e baixo acoplamento).

O mesmo pode ser comentado na alternativa (C), só que aqui temos outro porém, não existe problemas na herança múltipla se você estiver usando C++, por exemplo. Já se o seu projeto definiu Java como linguagem não será a UML que impedirá você de modelar uma herança múltipla.

Agora vem a parte interessante da questão. Na alternativa D e E, é cobrado certo conhecimento da estrutura dos Padrões Composite e Chain of Responsability, o que não é muito comum. Mas, vamos relembrar:

Composite: Compor objetos em estruturas de árvore para representarem hierarquias partes-todo. [2]

Estrutura do Composite: 600px-composite-dpcd

Notem que retirando a ClasseA não iremos chegar à estrutura do Composite. Em sua estrutura o Composite é composto por Components e é um filho deste através da herança. Na questão não temos essa composição e herança ao mesmo tempo. Aqui vai uma observação importante sobre o livro do GOF, ele não utiliza a UML para representar a estrutura! Utiliza a Object Modeling Technique (OMT), que é bem parecida com a UML.

Chan of Responsability: Evitar o acoplamento do remetente de uma solicitação ao seu receptor, ao dar a mais de um objeto a oportunidade de tratar a solicitação. Encadear os objetos receptores, passando a solicitação ao longo da cadeia até que um objeto a trate.

Estrutura do Chain of Responsability: jw-0829-designpatterns2Para quem conhece o padrão Chain of Responsability sabe que ele é comportamental e portanto a idéia central reside mais em sua interação/colaboração. A estrutura do padrão é bem simples, e como podemos ver temos um auto-relacionamento, o que de imediato descartar a alternativa E.

Para o mais ligado em UML, bastaria ler a alternativa A e saber que está é a alternativa correta, conferrindo apenas com uma leitura rápidas nas outras, e mesmo que ficasse em dúvida sobre as estruturas dos Padrões, saberia a alternativa correta. Nessa alternativa é levantado um ponto importante entre a diferença de Agregação e Composição. Vejamos:

“A agregação simples é inteiramente conceitual e nada faz além de diferenciar o ‘todo’ da ‘parte’…. nem vincula o tempo de vida do todo e suas partes.”

“A composição é uma forma de agregação, com propriedade bem-definida e tempo de vida coincidente como parte do todo. … Isso significa que, em uma agregação composta (negrito por mim), um objeto poderá ser uma parte de somente uma composição em determinado momento.” Ou seja, na composição só teremos a multiplicidade do relacionamento 1 para muitos partindo do todo para a parte, pois a parte só se relaciona com uma composição em determinado momento. Por isso, a alternativa A é a correta, pois no diagrama da questão temos uma agregação composta com multiplicidade de relacionamento muitos para muitos.

Bom pessoal, acho que prolonguei demais. Mas é justamente por isso que escolhi essa questão, ela envolve dois assuntos interessantes da Engenharia de Software, que são os Padrões (Reúso) e a modelagem UML.

Nos vemos na próxima questão. []s

[1]: Booch, G.; Rumbaugh, J.; Jacobson, I. UML Guia do Usuário, 2ª edição. Ed. Campus.
[2]:Gamma, E.; Helm, R.; Johnson, R.; Vlissides, J. Padrões de Projeto, Soluções reutilizáveis de software orientado a objetos. Bookman.

Manoel Teixeira de Abreu (http://manoel.oxente.org/blog)

Biblioteca de Análise Técnica

TA Lib, uma biblioteca com:

  • Mais de 150 algoritmos de indicadores de análise técnica.
  • Inclui reconhecimento de candles
  • API abstrata para adição de novos algoritmos

De fato, para mim esta biblioteca foi uma descoberta genial. Vai facilitar e muito meu trabalho de sistemas multi-agentes com o MASSES ( próxima semana já terá site ).

Variações de estratégias com esses 150 indicadores não irão faltar. Fica aí uma excelente recomendação. Falarei mais sobre esta biblioteca após utilizá-la melhor.

Recuperando Dados do Yahoo Finance

Voltando ao papo anterior sobre recuperar dados da Bovespa do dia anterior.

Implementei hoje a tarde um método que irá fazer parte de um agente para a recuperação dos dados de uma ação da Bovespa. Está feito em Java e estou pegando os dados do Yahoo Finace.

Infelizmente, não tenho ainda o plugin do wordpress para highlight code. Quem se interessar pode entrar em contato. Provavelmente, irei editar este post e colocar o código.

Em breve falo sobre o HackGol, que tem uma funcionalidade parecida.

Edit: Como percebi que esse é um post de alguns acessos no blog, vou colocar o código para recuperar dados de uma página Web. Esse exemplo eu usava para pegar os preços das passagens no site da GOL. Não funciona mais e não está completo.

private void capture(){
// url
String urlString = “http://compre3.voegol.com.br/skylights/cgi-bin/skylights.cgi”;

// Datas necessárias

int mesIda = Calendar.getInstance().get(Calendar.MONTH) + 1; // Mês do segundo dia do intervalo
int diaIda = Calendar.getInstance().get(Calendar.DAY_OF_MONTH); // Dia do segundo dia do intervalo
int anoIda = Calendar.getInstance().get(Calendar.YEAR); // Ano do segundo dia do intervalo

GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();

if( gc.getActualMaximum(Calendar.DAY_OF_MONTH) == diaIda ) {
gc.set(Calendar.DAY_OF_MONTH, 1);
gc.set(Calendar.MONTH, mesIda );
} else {
gc.set(Calendar.DAY_OF_MONTH, diaIda + 1);
}

int mesVolta = gc.get(Calendar.MONTH) + 1;
int diaVolta = gc.get(Calendar.DAY_OF_MONTH);
int anoVolta = gc.get(Calendar.YEAR);

// Parâmetros
Properties parametros = new Properties();
try {
parametros.setProperty(“travel_type”, URLEncoder.encode(“on”, “UTF-8″) );
parametros.setProperty(“sector1_o”, URLEncoder.encode(this.origem, “UTF-8″));
parametros.setProperty(“sector1_d”,    URLEncoder.encode(this.destino.substring(1), “UTF-8″));
parametros.setProperty(“sector_1_d”,URLEncoder.encode((diaIda<10?”0″:”") + String.valueOf(diaIda), “UTF-8″) );  // Data da IDA
parametros.setProperty(“sector_1_m”,URLEncoder.encode((mesIda<10?”0″:”") + String.valueOf( mesIda )+ “” + String.valueOf( anoIda ), “UTF-8″) ); // Mês e Ano da IDA (mmaaaa)
parametros.setProperty(“sector_2_d”,URLEncoder.encode((diaVolta<10?”0″:”") + String.valueOf(diaVolta), “UTF-8″) ); // Data da Volta
parametros.setProperty(“sector_2_m”,URLEncoder.encode((mesVolta<10?”0″:”") + String.valueOf( mesVolta ) + “” + String.valueOf(anoVolta), “UTF-8″) ); // Mês e Ano da Volta
parametros.setProperty(“ADULT”,     URLEncoder.encode(“1″, “UTF-8″) ); // Quantidade de Adultos
parametros.setProperty(“CHILD”,     URLEncoder.encode(“0″, “UTF-8″) ); // Quantidade de Crianças
parametros.setProperty(“INFANT”,    URLEncoder.encode(“0″, “UTF-8″) ); // Quantidade de Bebês
parametros.setProperty(“oP”,         URLEncoder.encode(“”, “UTF-8″));
//parametros.setProperty(“rP”,         URLEncoder.encode(“”, “UTF-8″));
parametros.setProperty(“pT”,         URLEncoder.encode(“1ADULT0CHILD”, “UTF-8″));
parametros.setProperty(“nom”,        URLEncoder.encode(“2″, “UTF-8″));
parametros.setProperty(“pM”,         URLEncoder.encode(“0″, “UTF-8″));
parametros.setProperty(“tc”,         URLEncoder.encode(“1″, “UTF-8″));
parametros.setProperty(“sid”,         URLEncoder.encode(“”, “UTF-8″));
parametros.setProperty(“language”,    URLEncoder.encode(“PT”, “UTF-8″));
parametros.setProperty(“mode”,        URLEncoder.encode(“JURO”, “UTF-8″)); // PIDO ou JURO
parametros.setProperty(“module”,     URLEncoder.encode(“SB”, “UTF-8″));
parametros.setProperty(“page”,        URLEncoder.encode(“SELECT”, “UTF-8″));
parametros.setProperty(“openjaw_flag”,URLEncoder.encode(“true”, “UTF-8″) );
parametros.setProperty(“m1″, URLEncoder.encode(String.valueOf( anoIda ) + (mesIda<10?”0″:”") + String.valueOf( mesIda ) + (diaIda<10?”0″:”") + String.valueOf(diaIda) + this.origem.substring(1) + this.destino.substring(1), “UTF-8″) );
parametros.setProperty(“m1DP”,         URLEncoder.encode(“0″, “UTF-8″));
parametros.setProperty(“m1DO”,         URLEncoder.encode(“0″, “UTF-8″));
parametros.setProperty(“m2″, URLEncoder.encode(String.valueOf( anoVolta ) + (mesVolta<10?”0″:”") + String.valueOf( mesVolta ) + (diaVolta<10?”0″:”") + String.valueOf( diaVolta ) + this.destino.substring(1) + this.origem.substring(1), “UTF-8″));
parametros.setProperty(“m2DP”,         URLEncoder.encode(“0″, “UTF-8″));
parametros.setProperty(“m2DO”,         URLEncoder.encode(“0″, “UTF-8″));

} catch(Exception e){
e.printStackTrace();
}

int contador = 0;
String dados = “”;
for( Iterator i = parametros.keySet().iterator(); i.hasNext(); ){

String nome = (String) i.next();
String valor = parametros.getProperty(nome);
//System.out.println(nome + ” = “+ valor);
dados += (++contador == 1 ? “?” : “&”)
+ nome + “=” + valor;
}

//System.out.println(dados);

/*  GET  */

try{

URL url = new URL(urlString+dados);
//System.out.println(urlString+dados);

HttpURLConnection connection = (HttpURLConnection) url.openConnection();

connection.setRequestProperty(“Request-Method”, “GET”);
connection.setDoInput(true);
connection.setDoOutput(false);

connection.connect();

BufferedReader br = new BufferedReader( new InputStreamReader( connection.getInputStream() ) );
StringBuffer newData = new StringBuffer(10000);
String s = “”;
br.readLine();
boolean copiar = false;
while(null != ( (s = br.readLine()) )) {
if( copiar ) {
newData.append(s + “n”);
//System.out.println(s);
}
if( !copiar && s.equals(“</head>”))
copiar = true;

}
br.close();

Processamento.process(new String(newData));

//System.out.println(new String(newData));
//String x = new String(newData);
System.out.println(“Resultado: ” + connection.getResponseCode() + “/” + connection.getResponseMessage());

} catch (Exception e){
//e.printStackTrace();
System.out.println(“Dados não disponíveis no momento!”);
}

}

Mercado de Ações

Este é o tema da vez no meu mestrado. Das matérias de Engenharia de Software que estou pagando todas tenho trabalho relacionado a ele. Em sistemas multi-agentes estou trabalhando no MASSES, que irei apresentá-los mais a frente, em outro post. Em resumo o MASSES é um ambiente de simulação de uma Bolsa de Valores onde agentes podem atuar comprando ou vendendo as ações. Em Processo de Sistema de Software resolvi desenvolver um sistema baseado no MASSES, onde a idéia seria o apoio ao usuário na tomada de decisão da compra e da venda de um papel na bolsa.

Para o desenvolvimento deste último preciso de um banco de dados com as informações das ações de 120 dias anteriores ao dia atual, para a realização de alguns algorítmos de análise técnica e indicadores. Ou seja, um webservice com os dados da BOVESPA, seria genial. Porém, fazendo uma breve pesquisa notei que estes dados não são disponibilizados gratuitamente, e nem tão pouco baratos. Dentre as soluções que encontrei foram:

Eclipse Trade, um excelente software que já possui uma série de indicadores para o mercado de ações. Ele recupera os dados de sites que o fornecem gratuitamente, dentre eles o Yahoo Finance, que disponibiliza justamente os dados da BOVESPA. Vale até um post.

WebService do HoloCoCos, buscando do google encontrei este WebService em seu blog. Parece estar funcionando legal, e suspeito que ele esteja resgatando os dados do Yahoo também. Não testei, mas se tiver um tempinho irei testar. Também não entrei em contato com ele, e achei este projetinho dele bem parecido com o meu HackGol (coisa nerd). :P

Ainda não tomei a decisão de qual fonte usar, provavelmente meu agente ( Utilizarei um agente para recuperar essas informações) irá realizar a mesma proeza dos citados acima, buscar os dados do Yahoo Finance, só não encontrei ainda onde recuperar os dados anteriores, achei apenas os dados do dia.

Falarei mais sobre este assunto, bem como algoritmos de análise técnica nos próximo posts.

ScrapBook

ScrapBook é uma extensão do firefox utilizada para capturar páginas da Web.

ScrapBook is a Firefox extension, which helps you to save Web pages and easily manage collections. Key features are lightness, speed, accuracy and multi-language support. Major features are:
* Save Web page
* Save snippet of Web page
* Save Web site
* Organize the collection in the same way as Bookmarks
* Full text search and quick filtering search of the collection
* Editing of the collected Web page
* Text/HTML edit feature resembling Opera’s Notes

Agora a pergunta, e daí?

Bom, fiquei encarregado de fazer um manual de um sistema ( :S ), e o primeiro requisito era que fosse HTML e que outras pessoas pudessem trabalhar nele. Então, a escolha foi o wiki. Contudo, o material a ser entregue ao cliente deveria ser apenas HTML, logo, não poderia entrar o wiki para ele, visto que teria que instalar os serviços mysql e apache. Então pensei em utilizar o TeleportPro, que tem uma funcionalidade parecida com o ScrapBook, salva todo o conteúdo de um website, criando uma réplica. Porém, Teleport é pago, e não atendeu a alguns critérios, como falha no css e links com acento na url. ScrapBook está sendo, por enquanto, a solução para este caso.

Aceito sugestões quanto a outras ferramentas de fácil criação de manual, que tenha exportação para formato html. Word?