Scrum e a gestão de pessoas
Neste artigo vim falar sobre o que tem de melhor no Scrum. Não creio que o melhor seja a capacidade de entregar valor ao negocio rápido, pois isso diversos métodos o fazem. Esta é uma grande caracterÃstica mas vários outros método como o RUP o OpenUP e até mesmo o EVO é capaz de fazer isso.
A construção de uma Equipe
O Scrum, de maneira empÃrica é, na verdade, um grande protocolo para a construção de uma equipe. Isso mesmo, construção de uma equipe. Todo projeto começa com um grupo e é uma necessidade básica transformar esse grupo em equipe. O Scrum provê, através de um método simples – uma instância do PDCA -, uma forma de forçar a conversação na equipe e a reflexão dos atos das pessoas e, claro, do produto.
Por que usar coisas na parede
Os post-its na parede são para o time, não são para a gestão de alto nÃvel. Usar um post-it na parede não elimina a possibilidade de alimentar dados em ferramentas de controle e auditoria; eu já fiz isso e é perfeitamente possÃvel e alcançável através da prática do Tracker.
Isso favorece a colaboração, assim como usar uma ferramenta colaborativa como um Wiki é melhor do que um fórum ou uma outra ferramenta. O Scrum incentiva a colaboração e isso é algo muito bom. Outro princÃpio oriundo do XP que também se aplica é a posse coletiva, porque assim as tarefas passam a ser focadas não mais no papel das pessoas, e começam a ser da equipe, assim como se todos estivessem em um barco, todos ganham ou todos naufragam.
Não recomendo você usar Scrum sem ter o painel de controle que é conhecido como dashboard. Isso é muito mais do que um relatório, porque os relatórios são para os gerentes e o painel é para a equipe. Nada mais justo porque a equipe que está na linha de frente deve ter um planejamento tático e ter isso visÃvel em um quadro na parede é essencial.
O Planejamento
Com o Scrum se tem a noção correta do que significa planejar. Pois isso é feito pela equipe, não exclusivamente pela gestão. Até porque não é a gestão que executa as coisas mas, sim, as pessoas, logo elas que têm que conversar. Esse planejamento já fiz diversas vezes com muito proveito.
Uma coisa que fiz que funcionou muito bem foi utilizar um projetor e projetar um notepad na parede onde todos poderiam ver. Com isso, ali entraram descritos tanto o objetivo da sprint como o critério de aceite da mesma.
Outra coisa que ficava visÃvel nesse notepad era o que todos iriam fazer e quem estava participando da sprint. Depois disso era só passar para o dashboard e pontuar usando o jogo do planejamento. Eu não utilizava cartas, mas, sim, aparelhos celulares. Como toda pessoa tem um celular, era com ele que fazÃamos as estimativas.
Por incentivar a conversação entre a equipe, por planejar com a equipe, por ter as reuniões diárias para forçar mais uma vez a comunicação e levantar problemas e gargalos, o Scrum é muito útil.
As Retrospectivas
Os maiores problemas de relacionamentos e qualidade de produto e processo que já tive em projetos foram levantados em sessões de retrospectivas no Scrum. Essas sessões foram sempre muito produtivas pra mim. Esse é outro grande recurso do Scrum, promover um momento para averiguação do que foi feito. E isso não é feito focando em estimativas, é feito focado na visão das pessoas e não em números.
Você pode verificar estimativas em uma sessão de retrospectiva no Scrum, mas isso não pode, de forma, alguma ser o foco da sessão. O foco são os eventos que aconteceram na sprint e esse eventos têm que ser ditos pelas pessoas, elas sabem o que está bom e o que não está.
O Scrum promove a disciplina e a comunicação através desses momentos e isso é só o começo. Com o tempo, isso acaba gerando mais sinergia entre a equipe e mais conversas informais e tudo isso só faz com que as pessoas cresçam como time e evoluam o seu processo e produto de software.
Fonte: Imasters
Barra de Progresso com AJAX
Uma das necessidades com que nos deparamos na hora de realizar projetos longos na web é indicar ao usuário o quanto é preciso esperar. Às vezes é bastante complicado criar uma barra de progresso que mostre o estado atual do processo que está sendo executado.
Uma forma de realizar essa tarefa é usando AJAX. Fazemos uma chamada AJAX que executa a ação, e quando o objeto AJAX tem o estado LOADING (readyState == 3), podemos obter a resposta do script chamado e passá-lo para mostrar o percentual da ação que está sendo realizada.
Para isso, desenvolveremos um script (res. php, por exemplo) que devolva a porcentagem seguida por um hÃfen. Por exemplo, quando passar por 1% será retornado pelo script “1-”, quando passar por 5% será retornado “1-2-3-4-5″. Processando isso podemos saber, através do último número, o percentual já processado.
O PHP seria o seguinte:
for($i=0; $i<10000000; $i++) {
if ($i%10000 == 0) echo ((int) $i/100000).'-';
flush();
}
E o JavaScript seria assim:
function ajaxobj() { Â
try { Â
_ajaxobj = new ActiveXObject("Msxml2.XMLHTTP"); Â
} catch (e) { Â
try { Â
_ajaxobj = new ActiveXObject("Microsoft.XMLHTTP"); Â
} catch (E) { Â
_ajaxobj = false; Â
} Â
} Â
if (!_ajaxobj && typeof XMLHttpRequest!='undefined') { Â
_ajaxobj = new XMLHttpRequest(); Â
} Â
return _ajaxobj; Â
}
function prueba () { Â
ajax = ajaxobj(); Â
ajax.open("GET", "res.php", true); Â
ajax.onreadystatechange=function() {
if (ajax.readyState == 3) { Â
// Mostramos o percentual
var res = ajax.responseText;
res = res.split('-'); Â
alert(res[res.length-2]); Â
} else if (ajax.readyState == 4) { Â
// Fim
alert('FIM'); Â
} Â
} Â
// Enviamos algo para que o processo funcione
ajax.send(null); Â
} Â
Como não existe nada perfeito, e menos ainda o Internet Explorer, esse script só funcionou no Firefox, Opera, Safari e Chrome.
Fonte: Imasters
Colocando minha empresa no mapa…
Este artigo, por mais simples que seja, tende a ser uma das maiores dúvidas e desejos dos usuários que estão iniciando nesta área. Como colocar minha empresa, estabelecimento, casa etc., no mapa. Com certeza no seu site é muito importante existir além do endereço da sua empresa um pequeno mapa representando tudo que está em volta dela para que os usuários possam se localizar mais facilmente.
Nosso foco hoje é criar um mapa utilizando a API do Google Maps. Com isso, não precisamos de nenhum banco de dados geográfico ou qualquer outro tipo de aplicação para desenvolvimento de mapas além das linguagens HTML e JavaScript.
Segundo o próprio Google, o que é a API do Google Maps?
A API do Google Maps permite usar JavaScript para incorporar o Google Maps em sua página da web. A API fornece diversos utilitários para manipular mapas (como na página http://maps.google.com) e adicionar conteúdo ao mapa através de diversos serviços. Você pode criar aplicativos de mapas robustos em seu site.
Passo 1: Obtendo uma chave para a API do Google Maps.
Para utilizarmos a API do Google, precisamos obter uma chave de identificação para o nosso site. É muito importante que você coloque a URL correta do caminho onde estará o mapa, caso contrário, ao instanciar a API no seu código, ela não funcionará.
Acesse o link : http://code.google.com/intl/pt-BR/apis/maps/signup.html, preencha as informações da URL do seu site e clique em GERAR chave de API. Não se esqueça de ler os termos de uso da API, nada de utilizá-la dentro de intranets.

Obs.: Você precisa ter um usuário cadastrado no Google para obtê-la.

Pronto, chave gerada, podemos ir para o próximo passo.
Passo 2: Obtendo o XY da sua empresa
Inicialmente, para identificarmos a sua empresa/estabelecimento/etc no mapa, precisamos da localização correta dela. A localização que comento é com relação ao seu XY. Mas o que é XY? Vamos à matemática…
Para a construção do modelo da superfÃcie topográfica de uma dada região, necessitamos das triplas (x, y, z) de uma série de pontos da superfÃcie do terreno. Os valores (x, y, z) são as coordenadas cartesianas de um ponto P, relativas a um sistema de coordenadas preestabelecido (como já vimos em meu outro artigo Sistemas de Informação Geográfica).
O plano XY é o plano horizontal de referência relativamente ao nÃvel médio dos mares, e z é a distância vertical do ponto P ao plano horizontal XY (se me permitem exemplificar desta maneira, seria a altura em relação ao nÃvel do mar, no nosso caso, não será necessária).
Como posso obter este ponto?
Existem diversas maneiras de se obter o XY de um endereço, vou exemplificar duas: a primeira é suscetÃvel a alguns erros, motivo pelo qual o mapeamento da numeração das ruas nas cidades do Brasil não ser de fato correto (mas confesso que é satisfatório). O que quero dizer é que muitas vezes quando você informa o seu endereço, por exemplo o número 567, seriam 567 metros do ponto inicial da sua rua, nem sempre esta numeração irá bater exatamente no local da sua casa (quando digo exatamente, ainda considero um erro de 50m). Pode acontecer de aparecer na quadra errada; quando ocorrer, sugiro utilizar o segundo exemplo de aquisição do XY.
A primeira maneira que me refiro é solicitar através da url http://maps.google.com/maps/geo?q=STRING+DO+ENDERECOoutput=xmlkey=SUA_CHAVE
Obs.: Separe a string com “+”.
Exemplo:
http://maps.google.com/maps/geo?q=avenidaipiranga1200portoalegrersbrasiloutput=xmlkey=
Exemplo da resposta (response) em XML:

Pronto, seu XYZ é a coordenada <coordinates>-51.2093204,-30.0451247,0</coordinates> .
Agora você pode pular o segundo exemplo e ir direto ao passo 3, mas antes vamos verificar se o ponto está mesmo no local correto.
Acesso o seguinte link:
http://maps.google.com.br/maps?f=qsource=s_qhl=pt-BRgeocode=q=(-30.0451247,-51.2093204)
OBS: Lembre-se de alterar a ordem dos pontos XY <-> YX
A segunda maneira de se obter as coordenadas XY é implementar um outro exemplo utilizando a API do Google Maps. Chamamos este exemplo de Geocode Reverso (através de um clique no mapa iremos obter as informações quanto a este local).
O exemplo abaixo está presente na página da API do Google Maps, mantive-o como o qual para explicar cada linha.
Código
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>Google Maps JavaScript API Example: Reverse Geocoder</title>
<script src="http://maps.google.com/maps?file=apiv=2.xkey=ABQIAAAAzr2EBOXUKnm_jVnk0OJI7xSosDVG8KKPE1-m51RBrvYughuyMxQ-i1QfUnH94QxWIa6N4U6MouMmBA"
type="text/javascript"></script>
<script type="text/javascript">
var map;
var geocoder;
var address;
function initialize() {
map = new GMap2(document.getElementById("map"));
map.setCenter(new GLatLng(-30.0270583,-51.2303402), 10);
map.addControl(new GLargeMapControl);
GEvent.addListener(map, "click", getAddress);
geocoder = new GClientGeocoder();
}
function getAddress(overlay, latlng) {
if (latlng != null) {
address = latlng;
geocoder.getLocations(latlng, showAddress);
}
}
function showAddress(response) {
map.clearOverlays();
if (!response response.Status.code != 200) {
alert("Status Code:" response.Status.code);
} else {
place = response.Placemark[0];
point = new GLatLng(place.Point.coordinates[1],
place.Point.coordinates[0]);
marker = new GMarker(point);
map.addOverlay(marker);
marker.openInfoWindowHtml(
'<b>orig latlng:</b>' response.name '<br/>'
'<b>latlng:</b>' place.Point.coordinates[1] "," place.Point.coordinates[0] '<br>'
'<b>Status Code:</b>' response.Status.code '<br>'
'<b>Status Request:</b>' response.Status.request '<br>'
'<b>Address:</b>' place.address '<br>'
'<b>Accuracy:</b>' place.AddressDetails.Accuracy '<br>'
'<b>Country code:</b> ' place.AddressDetails.Country.CountryNameCode);
}
}
</script>
</head>
<body onload="initialize()">
<div id="map" style="width: 500px; height: 400px"></div>
</body>
</html>


Você já viu um exemplo da resposta (response) em XML no exemplo anterior.
Exemplo da resposta (response) em JSON:

Através dos arquivos acima, você consegue identificar quais as variáveis necessárias para obter os dados do geocode.
Por fim e não menos importante, o corpo do HTML:
<body onload="initialize()">
  <div id="map" style="width: 500px; height: 400px"></div>
    <div id="temp"></div>
 </body>
Não se esqueça de utilizar o ONLOAD para chamar a função initialize() para tão logo carregar a página iniciar o procedimento da criação do mapa. Não quero ver ninguém comentando que o mapa não aparece!
Pronto, agora navegue no mapa, procure o endereço da sua empresa (ainda não criamos uma barra de pesquisa de endereço, nos próximos artigos irei explicar como), clique no local e copie as informações da linha latlng.
Agora temos o XY para continuar no nosso artigo.
Passo 3: Adicionando minha empresa no mapa
Bom, se você já criou o exemplo anterior do geocode reverso, este agora é muito mais simples. Caso contrário, vamos lá passo a passo.
Vamos ao código
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Google Maps JavaScript API Example: Simple Markers</title>
<script src="http://maps.google.com/maps?file=apiamp;v=2amp;key=
ABQIAAAAzr2EBOXUKnm_jVnk0OJI7xSosDVG8KKPE1-m51RBrvYughuyMxQ-i1QfUnH94QxWIa6N4U6MouMmBA"
type="text/javascript"></script>
<script type="text/javascript">
function initialize() {
if (GBrowserIsCompatible()) { // Verifica se o browser é compativel com a API do Google
// Instância a API do Google e a adiciona na DIV map.
var map = new GMap2(document.getElementById("map"));
// Centraliza o mapa no XY, zoom 16 em uma escala de [1..17] (Varia de acordo com a região)
map.setCenter(new GLatLng(-30.0451247,-51.2093204), 16);
// (OPCIONAL) Adiciona os controle de a esquerda do Mapa (Zoom , Zoom -, barra de Zoom, etc)
map.addControl(new GLargeMapControl);
// Padronizamos o XY de acordo com o latlng da API: (Y,X)
var latlng = new GLatLng(-30.0451247,-51.2093204);
map.addOverlay(new GMarker(latlng)); // Adiciona o marker no mapa
}//if
}//function
</script>
</head>
<body onload="initialize()" onunload="GUnload()">
<div id="map" style="width: 500px; height: 300px"></div>
</body>
</html>

OBS: Não se esqueça de trocar a sua chave da API. Não se esqueça de declarar o ONLOAD, para que a função initialize(), no meu exemplo, crie o mapa assim que a página seja carregada.
Resultado

Caso você queira incrementar o seu mapa e adicionar um evento de clique no marker, façamos algumas modificações no código:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Google Maps JavaScript API Example: Simple Markers</title>
<script src="http://maps.google.com/maps?file=api&v=2&key=
ABQIAAAAzr2EBOXUKnm_jVnk0OJI7xSosDVG8KKPE1-m51RBrvYughuyMxQ-i1QfUnH94QxWIa6N4U6MouMmBA"
type="text/javascript"></script>
<script type="text/javascript">
function initialize() {
if (GBrowserIsCompatible()) { // Verifica se o browser é compativel com a API do Google
// Instância a API do Google e a adiciona na DIV map.
var map = new GMap2(document.getElementById("map"));
// Centraliza o mapa no XY, zoom 16 em uma escala de [1..17] (Varia de acordo com a região)
map.setCenter(new GLatLng(-30.0451247,-51.2093204), 16);
// (OPCIONAL) Adiciona os controle de a esquerda do Mapa (Zoom +, Zoom -, barra de Zoom, etc)
map.addControl(new GLargeMapControl);
// Padronizamos o XY de acordo com o latlng da API: (Y,X)
var latlng = new GLatLng(-30.0451247,-51.2093204);
var marker = new GMarker(latlng); // Criamos um marker referenciado a uma variável
// Criamos um evento para ao se clicar no marker
GEvent.addListener(marker, "click", function() {
// Abrir um InfoWindow com o seguinte texto
marker.openInfoWindowHtml("Endereço da minha empresa! <br/> <strong>;)</strong>");
});
map.addOverlay(marker); // Adiciona o marker no mapa
}//if
}//function
</script>
</head>
<body onload="initialize()" onunload="GUnload()">
<div id="map" style="width: 500px; height: 300px"></div>
</body>
</html>

Pronto!
A web 3.0 será a rede dos robôs?
A Hillary Clinton disse no México que o muro que separa os dois paÃses não é a solução, mas, na mesma matéria, informa-se que os EUA continuarão a construir a parte que falta da obra.

O que se fala e o que se faz.
O Lula, por exemplo, diz que o governo dele é voltado para o povo, mas os lucros dos bancos nunca foram tão grandes.
A diferença do que falamos para o que realmente fazemos, muito mais do que um problema polÃtico passou a ser um dilema tecnológico-informacional, pois no mundo carente de relevância a mentira (ou melhor, o desconhecimento da verdade pelo próprio usuário) atrapalha cada vez mais.
O Google, principal representante desse futuro, por exemplo, anunciou já se basear somente naquilo que o usuário busca, mas também no website que visita.
É a tentativa de substituir o modelo atual do “aquilo que eu digo ou acho que faço”, por aquilo que “realmente faço e necessito”.
Essa inteligência necessária na rede para ampliar a relevância exige a chegada de um novo personagem: o robô inteligente.

O meu robô….
Qual a diferença dos softwares que temos hoje em dia na Web para o que vamos chamar de robôs inteligentes?
A Web, de certa forma é burra, não aprende com seus usuários.
Já os robôs aprenderão com os nossos hábitos, utilizando códigos de inteligência artificial, a partir das nossas ações, cliques, visitas, hábitos.
Sim, poderemos programar manualmente os nossos robôs.
E podemos dizer também quando vamos querer que ele aja automaticamente.
Mas a idéia é que “alguém artifical” estará nos ajudando a lidar e filtrar a massa cada vez maior de informação.

Seu personal robô assistente.
É uma escalada na qual tivemos para nos apoiar a recuperar e filtrar grandes massas da informação, entre outros, as fichas catalográficas, os computadores, o Altavista, o Google e agora os robôs inteligentes.
Alguns softwares anti-spam, por exemplo, já vão nessa direção, aprendendo com seus hábitos para saber quem é e quem não é spammer.
A Inteligência Artificial será apenas um novo tipo de código desenvolvido por pessoas, que têm determinado tipo de opções pré-definidas com os quais o usuário vai interagindo e utilizando áreas de códigos e da base de dados em lugar de outras.
Diria que um campo novo e espetacular para quem quer o iniciar uma nova carreira, tanto na área de tecnologia, que precisará de programadores para os novos códigos, quanto para o pessoal de informação, para quem caberá a concepção, a interface e o ajuste fino na relação de uso.

Um campo e tanto que se abre….
Do ponta de vista conceitual, é o surgimento de uma nova articulação entre os humanos na área informacional: tivemos camadas, nas quais predominaram o um para um (na rede de conhecimento oral), um para muitos (na rede de conhecimento escrita), muitos para muitos (na atual rede de conhecimento digital), e agora o eu-robô e, mais adiante, o robô-robô, um aprendendo e filtrando em cima do outro (na rede de conhecimento da inteligência artificial).
Quando?
Não muito longe.
Me interessa receber e-mails de fulano, mas não quando ele fala do Flamengo..;)
O site que vejo da Coca-Cola não será o mesmo que você vê.
Meu robô sabe que eu não gosto de Coca cafeÃnada.
E vai aprendendo quando eu clicar no site da Coca e me perguntará quando perceber alguma contradição.
Claro, se eu assim desejar.
(Sempre há a possibilidade na vida de se desligar o celular, sabia disso?)
Viagem?
Nem tanto.

Quer quantos litros de informação?
O New York Times publicou um artigo sobre softwares educacionais nos quais a Inteligência artificial passa a ser um instrumento importante no ensino nas escolas americanas.
Com esses novos softwares o estudante não só aprende como também ensina aos robôs, num processo relacional.
O robô aprende com os erros dos estudantes e aprimora as lições. Os resultados são animadores.
Não, os professores não acabam, mas passam a apicultores e depois como gestores de robôs, além do dia-a-dia com a turma.
Se existe a possibilidade de discutirmos uma Web 3.0 (se é assim que vamos chamar a nova rede de conhecimento), apostaria que estaremos discutindo uma Internet que aprende, cercada de inteligência artificial e de uma relação umbilical dos usuários e com seus robôs pessoais.
SaÃremos do atual interação da vez muitos para muitos para a articulação nova: eu-robô.
(Notem que a passagem de uma rede de conhecimento para outra se caracteriza pela massificação de um novo tipo de articulação informacional entre os humanos. Pela primeira vez, teremos robôs nos ajudando nesse processo, como forma de sobreviver ao caos informacional.)
E mais: a idéia também que os dos robôs pessoais poderão conversar com outros robôs pessoais, formando redes sociais de robôs-robôs, tudo na tentativa de ajudá-lo a ter mais relevância.
O futuro já está presente entre nós, basta ver as pequenas mudas que estão crescendo aqui e ali?
Dá medo?
Dá, mas não tem muito como pular do trem, tem?

Me diga…
Um pouco mais sobre essa procura do que as pessoas realmente fazerm on-line no livro Click. Em português. E um capÃtulo grátis em PDF.
Pós-escrito 1
Robôzinhos em ação:
A Revista Info 278, de abril de 2009, informa na matéria de “O Barato do Buscapé”, que fala do “Buscapé na hora” um robozinho que informa ao usuário se a compra que ele está fazendo é a melhor opção entre outras lojas. Um exemplo do inÃcio das redes dos robôs? Vamos em frente?
Pós-escrito 2
Robôzinhos em ação:
O Globo de 12 de abril publicou entrevista (precisa de assinatura – grátis – para acessar) com Luiz Alberto Oliveira, que aponta nessa direção do mundo de robôs, não falando apenas dos robôs na rede.

Fonte: Imasters
Métricas para avaliar seu blog corporativo
As empresas estão cada vez mais interessadas em investir em veÃculos colaborativos de informação, como blogs corporativos. A necessidade de estreitar laços de comunicação com o público é o motivo principal para este interesse pela estratégia colaborativa, mas também é necessário prestar atenção nas informações aparentemente ocultas dos blogs.
Estas informações têm a ver com a análise das métricas do blog. Claro que os comentários, a repercussão com clientes, funcionários e concorrentes é interessante, mas as métricas são a cereja do bolo afinal, comprovam numericamente a aposta da empresa neste tipo de comunicação.
Então, é interessante se ater a alguns procedimentos que facilitarão o monitoramento das métricas de seu blog.
Qual é o papel do seu blog no mix de comunicação?
Um blog pode servir a vários objetivos dentro de uma empresa: como um canal de comunicação com os clientes, ou então mais focado para o público interno, ou ainda como parte de uma campanha publicitária de um novo produto. E isto são apenas alguns exemplos. Portanto, antes de fazer seu plano de monitoramento, saiba o quê e para quê medir.
Métricas para blogs que querem obter audiência e receitas de publicidade.
Os programas de anúncios contextuais permitem que um blog possa ser um veÃculo de publicidade, e daà gerar receita. Muitos blogueiros estão ganhando um dinheiro interessante com esta utilização, mas no caso de um blog corporativo, é preciso muita cautela. Talvez não seja interessante seus clientes se depararem com links patrocinados em seu blog corporativo. Por isso, antes de tomar qualquer decisão a este respeito, é bom fazer benchmarking e analisar a questão com muito carinho.
Mesmo se o objetivo principal não for gerar receita, alguns indicativos bastante conhecidos, como troca de links, acompanhamento do número de citações e a presença do blog no ranking do Technorati, por exemplo, são um bom começo para a análise da performance.
Se a preocupação principal for a audiência, métricas clássicas como pageviews e número de visitantes únicos continuam tendo destaque, combinadas com os Ãndices acima.
O que você quer é gerar leads através de seus blogs?
Então, preste atenção nos Ãndices de preenchimento de cadastros gerados pelos blogs. Outra dica é checar se seu conteúdo está gerando interesse em seus visitantes,e isso não depende somente do número de comentários: veja como andam os Ãndices de stickness (tempo de permanência do visitante no blog durante as visitações), e também certifique-se de que seus visitantes únicos voltem regularmente.
E por falar em conteúdo…
O meio blogueiro funciona muito através de recomendações o velho e bom boca a boca. Por isso, cuide para que seu blog vire uma referência dentro da comunidade para a qual atua. Ofereça um bom conteúdo, com texto interessante e informações úteis, com potencial para serem viralizadas e citadas. Inclua seu blog nas listas e diretórios disponÃveis. Use a força da sua marca para que as pessoas fiquem curiosas em visitar seu blog e o recomendem.
Essa questão das citações não é só importante por causa do prestÃgio e da reputação: lembre-se que muitas citações em outros blogs geram melhores posições nos buscadores, o que aumenta o potencial da audiência e indiretamente gera negócios.
Portanto, prefira ferramentas que possam agregar os blogs ao domÃnio da empresa – fica mais apresentável e ainda por cima ajuda o seu blog a aparecer melhor nas buscas orgânicas, além de facilitar trabalhos de otimização.
E analise com cuidado…
Com esses procedimentos em mente, você terá plena capacidade para avaliar o impacto e o retorno do seu blog corporativo. Ajustes sempre terão que ser feitos, claro mas, se forem fundamentados por números, tanto mais fáceis de implementar serão.
Fonte: Imasters
A crise vista do Peopleware
São tempos difÃceis em que a economia global está imergida. A recessão em que todos vivemos, não deixa ninguém indiferente. Infelizmente todos constatámos o que um conjunto de alegados crimes fiscais, como o caso Madoff, executados por alguns barões conseguiram quase arruinar a economia global tal como a conhecÃamos até hoje.

O impacto da crise actual está a se repercutir nos empregos das pessoas e no seu poder de compra. Além das óbvias consequências para o bolso dos portugueses, a economia não arranca e existe um grande problema.
É uma problemática social, que deriva de vários factores graves tais como pessimismo generalizado, falta de confiança na classe polÃtica e grupos financeiros. Toda esta desconfiança nos órgãos pilares da nossa sociedade, geram um desânimo, uma certa revolta e omitem um grande factor potenciador das economias, o consumismo.

Nesta medida o Peopleware não pretende ficar de braços cruzados e a partir desta próxima segunda feira dia 27 de Abril, irá ter uma nova rubrica. A rubrica que esperamos que seja no mÃnimo mensal e será avaliada pela aceitação dos nossos leitores, irá incentivar e dar ânimo a uma pequena parte da população portuguesa e contribuir com algo positivo para esta crise.
Por isso e aproveitando este dia, o dia da liberdade, convidamos os nossos leitores como já é normal, os seus amigos e os amigos dos seus amigos, para esta segunda feira visitarem o nosso site, e nos apoiarem nesta causa que vamos iniciar.
Mas… já agora na vossa opinião, ao nÃvel geral, o que se pode fazer para inverter este cenários de crise?
Fonte: Peopleware
Nova API Google 3D para a Internet
Dois rivais dos browsers anunciaram o lançamento de um plug in que permite ver imagens 3D na Net. O projecto chama-se O3D e foi desenvolvido pela Google e pela Mozilla.
Segundo a PC Pro, a pequena aplicação tem por base tecnologias JavaScript, que permitem que um browser processe informação complexa relacionada com a geometria.
A interface gráfica OpenGL também foi usada, desta feita, para a produção de efeitos de sombra.
O O3D acaba por reunir dois rivais do sector tecnológico – de um lado a Google, que desenvolveu o browser Chrome, e do outro a Mozilla, que tem vindo a expandir a quota de mercado do Firefox.
Apesar desta parceria, o O3D não é compatÃvel com tecnologia C3DL, um projecto similar que a Mozilla desenvolveu anteriormente.
Os responsáveis pelo projecto acreditam que a nova tecnologia pode revelar-se especialmente útil em aplicações ou ferramentas da Web que não necessitem de downloads volumosos.
Faça aqui o download e aproveite para experimentar o O3D. Exame Informática
Esta tecnologia já havia sido referida aqui no Peopleware. Embora seja uma API nova, o Google não está a estrear nada.
Fish Shell 1.23.1 – Shell para tótós
A consola de Linux é apenas um último recurso nos dias actuais, para resolver graves problemas numa distribuição de Linux. Há no entanto, sempre quem se queira aventurar pelo mundo vasto da linha de comandos e aprender algo mais sobre o funcionamento interno deste sistema operativo.

Fish Shell, é uma linha de comandos (Shell) amiga do utilizador. Ora mas não estaremos perante uma antÃtese?
Como é que uma linha de comandos, uma caixa obscura com uma panóplia de opções, pode ser amigável para um novo utilizador?
Pode ser difÃcil lidar com a consola para um utilizador que apenas se está a iniciar, mas de facto o fish pode facilitar em muito a tarefa de aprendizagem, com várias ajudas ao seu utilizador.
Vejamos alguns exemplos destas caracterÃsticas:
SINTAX HIGHLIGHTING
O Fish shell traz por omissão suporte aos comandos mais comuns de Linux. Você poderá digitar um comando e assim que obter uma ocorrência de existência desse comando, este irá ficar com cor verde.
TAB COMPLETING
Outra das grandes funcionalidades é a possibilidade de ao escrever um comando, carregar em tab e quase instantaneamente lhe serão mostradas as alternativas que podem terminar o seu comando.
SUGESTÃO DE CORRECÇÃO
Apesar das anteriores funcionalidades, nada impede, por exemplo, que possa conjugar comandos aparentemente válidos ao nÃvel da sintaxe e lhe surja um erro da má formação dos seus parâmetros. Nestes ou noutros erros o Fish irá avaliar o comando introduzido-o e propondo-lhe uma alternativa.
É uma grande ajuda, para quando não se lembrar de um comando, mas tem uma ideia de como se invoca.
Claro que estas são apenas algumas das funcionalidades do Shell Fish. Caso pretenda explorar mais potencialidades do funcionamento desta shell inteligente, digite o comando help a qualquer altura e o seu browser irá ser aberto com o manual desta pequena aplicação.
Como instalar e arrancar com a aplicação?
Bem, já que este artigo, é apenas para utilizadores mais avançados, vou quebrar a minha regra de dar sempre instruções de instalações utilizando o gestor de pacotes synaptic. E já que está a aprender, nada como começar com os seguintes comandos para instalação de pacotes.
Instalação na consola do Ubuntu:
sudo apt-get install fish
Para utilizadores de Fedora, o comando já será:
yum install fish
Depois é só chamar esta shell, dentro da shell de linux do Ubuntu, escrevendo simplesmente fish.
Já não terá com certeza, desculpas para iniciar aquela aventura que já há algum tempo prometeu a si mesmo, de explorar todas as capacidades de shell em Linux. Já que vai começar aconselho-lhe estes artigos, disponÃveis no peopleware que lhe poderão ajudar:
- Correspondência de comandos DOS em Linux
- apt-get – a ferramenta mágica
- 10 dicas Linux Ubuntu
- Dicas Linux & Scripts em Bash
- Atalhos na BASH
Não tenha receio, aprender comandos em bash de Linux é como em certas coisas na vida, só custa a primeira vez
. E com o Fish Shell, mais fácil será.
Sistema Operativo: GNU/Linux
Download [Source]: Fish Shell 1.23.1 (1.13MB)
Homepage: Fish
Fonte: Peopleware
Adobe Flex – Como colocar gráficos em repeater
Estou desenvolvendo um modelo de Dashboard de Indicadores de Performace (KPI) utilizando o Adobe Flex, Asp.NET e SQL Server 2000.
Nesse Dashboard eu precisava exibir vários gráficos de acordo com o perfil de cada usuário. Por isso, construir um modelo fixo não seria possÃvel. Então busquei maneiras de fazer isso utilizando o mx:Tile e o mx:Repeater.
Na busca encontrei apenas um exemplo de Datagrid em um Repeater, com isso foi possÃvel construir o modelo para utilizar com Gráficos.
Primeiro é preciso entender a estrutura de DataProvider, necessária para que tudo funcione como o esperado.

Como na figura acima, o DataProvider é um ArrayCollection composto de um ArrayCollection para cada gráfico que será exibido no Repeater, cada um desse segundo ArrayCollection é composto por objetos que serão os pontos dos gráficos.
Abaixo está o código responsável pela configuração do ArrayCollection, que será o DataProvider do mx:Repeater.
<mx:Script>
    <![CDATA[
        import mx.utils.ObjectProxy;
        import mx.core.Application;
        import mx.utils.ObjectUtil;
        import mx.rpc.events.FaultEvent;
        import mx.rpc.events.ResultEvent;
        import mx.collections.ArrayCollection;
        //ArrayCollection que será o DataProvider do Repeater
        [Bindable]
        private var arDadosGraficoTotal:ArrayCollection = new ArrayCollection();
        private function load():void
        {
            var arDadosGrafico:ArrayCollection;
            var obDadosGrafico:ObjectProxy;
            //Gráfico 1
            //arDadosGrafico recebe um novo ArrayCollection
            arDadosGrafico = new ArrayCollection();
            //obDadosGrafico recebe um novo ObjectProxy
            obDadosGrafico = new ObjectProxy();
            //Cria a propriedade data1 e atribiu o 10, data1 será uma série no gráfico
            obDadosGrafico.data1 = 10;
            //Cria a propriedade data2 e atribiu o 5, data2 será outra série no gráfico
            obDadosGrafico.data2 = 05;
            //Cria a propriedade label e atribiu 'Jan', label será o eixo X do gráfico
            obDadosGrafico.label = 'Jan';         Â
//Cria a propriedade titulo e atribiu 'Vendas', titulo será o titulo do
gráfico, só existirá essa propriedade no primeiro ObjectProxy
            obDadosGrafico.titulo = 'Vendas';   Â
            //Adiciona o ObjectProxy obDadosGrafico ao ArrayCollection arDadosGrafico   Â
            arDadosGrafico.addItem(obDadosGrafico);
//obDadosGrafico recebe um novo ObjectProxy e receberá os mesmas
propriedades porém com valores distintos e também é inserido ao
ArrayCollection arDadosGrafico
            obDadosGrafico = new ObjectProxy();
            obDadosGrafico.data1 = 05;
            obDadosGrafico.data2 = 05;
            obDadosGrafico.label = 'Fev';         Â
            arDadosGrafico.addItem(obDadosGrafico);
            obDadosGrafico = new ObjectProxy();
            obDadosGrafico.data1 = 03;
            obDadosGrafico.data2 = 05;
            obDadosGrafico.label = 'Mar';         Â
            arDadosGrafico.addItem(obDadosGrafico);
            obDadosGrafico = new ObjectProxy();
            obDadosGrafico.data1 = 06;
            obDadosGrafico.data2 = 05;
            obDadosGrafico.label = 'Abr';         Â
            arDadosGrafico.addItem(obDadosGrafico);
//Quando terminam os pontos do gráfico é necessário inserir o
ArrayCollection arDadosGrafico ao ArrayCollection arDadosGraficoTotal
            arDadosGraficoTotal.addItem(arDadosGrafico);  Â
//Os passos anteriores devem ser feitos para cada gráfico que se deseja
exibir no Dashboard, abaixo estão identificos como Gráfico 2 e Gráfico 3
            //Gráfico 2
            arDadosGrafico = new ArrayCollection();
            obDadosGrafico = new ObjectProxy();
            obDadosGrafico.data1 = 07;
            obDadosGrafico.data2 = 02;
            obDadosGrafico.label = 'Jan';         Â
            obDadosGrafico.titulo = 'Custos';           Â
            arDadosGrafico.addItem(obDadosGrafico);
            obDadosGrafico = new ObjectProxy();
            obDadosGrafico.data1 = 08;
            obDadosGrafico.data2 = 02;
            obDadosGrafico.label = 'Fev';         Â
            arDadosGrafico.addItem(obDadosGrafico);
            obDadosGrafico = new ObjectProxy();
            obDadosGrafico.data1 = 05;
            obDadosGrafico.data2 = 02;
            obDadosGrafico.label = 'Mar';         Â
            arDadosGrafico.addItem(obDadosGrafico);
            obDadosGrafico = new ObjectProxy();
            obDadosGrafico.data1 = 04;
            obDadosGrafico.data2 = 02;
            obDadosGrafico.label = 'Abr';         Â
            arDadosGrafico.addItem(obDadosGrafico);
            arDadosGraficoTotal.addItem(arDadosGrafico);  Â
            //Gráfico 3
            arDadosGrafico = new ArrayCollection();
            obDadosGrafico = new ObjectProxy();
            obDadosGrafico.data1 = 10;
            obDadosGrafico.data2 = 08;
            obDadosGrafico.label = 'Jan';         Â
            obDadosGrafico.titulo = 'Produção';          Â
            arDadosGrafico.addItem(obDadosGrafico);
            obDadosGrafico = new ObjectProxy();
            obDadosGrafico.data1 = 12;
            obDadosGrafico.data2 = 08;
            obDadosGrafico.label = 'Fev';         Â
            arDadosGrafico.addItem(obDadosGrafico);
            obDadosGrafico = new ObjectProxy();
            obDadosGrafico.data1 = 06;
            obDadosGrafico.data2 = 08;
            obDadosGrafico.label = 'Mar';         Â
            arDadosGrafico.addItem(obDadosGrafico);
            obDadosGrafico = new ObjectProxy();
            obDadosGrafico.data1 = 08;
            obDadosGrafico.data2 = 08;
            obDadosGrafico.label = 'Abr';         Â
            arDadosGrafico.addItem(obDadosGrafico);
            arDadosGraficoTotal.addItem(arDadosGrafico);  Â
//Ao terminado de incluir todos os arDadosGrafico ao
arDadosGraficoTotal, é necessário declarar arDadosGraficoTotal como
dataProvider do repeater
            rpGrafico.dataProvider = arDadosGraficoTotal; Â
        }       Â
    ]]>
</mx:Script>
Abaixo está o código necessário para exibir os gráficos. Inicialmente foi utilizado um Tile e dentro um Repeater. Dentro do Repeater há um Panel e dentro do Panel está o gráfico que deve ser exibido de acordo com o dataProvider.
Como demonstrado acima, o dataProvider é associado ao término da função load(). Após a associação, o Repeater começará a renderizar o primeiro gráfico, e já no tÃtulo do Panel o valor atribuÃdo será a propriedade tÃtulo definida no primeiro objeto do arDadosGrafico.
Para isso é utilizada a instrução: {rpGrafico.currentItem.getItemAt(0).titulo}, ou seja, rpGrafico é o Repeater, a propriedade currentItem contém o arDadosGrafico do laço em questão e getItemAt(0) assegura que só buscará a propriedade tÃtulo no primeiro objeto dentro do arDadosGrafico.
Para o gráfico, só resta associar um dataProvider a ele para que sejam exibidos os seus pontos. O dataProvider em questão será o currentItem do Repeater rpGrafico, pois como dito acima, a propriedade currentItem contém o arDadosGrafico do laço em questão.
No eixo X, horizontalAxis, é definido label como o campo fonte dos dados. No eixo Y, verticalAxis, está configurado para não começar em zero. Logo abaixo estão as duas séries, uma para o data1 (Indicador Técnico) e outra para data2 (Meta).
<mx:Tile left="10" right="10" top="10" bottom="10" direction="horizontal">
    <mx:Repeater id="rpGrafico" width="100%">
    <mx:Panel width="250" height="200" layout="absolute" id="pnGrafico" title="{rpGrafico.currentItem.getItemAt(0).titulo}">
<mx:LineChart id="grIndicador" dataTipMode="single"
showDataTips="true" dataProvider="{rpGrafico.currentItem}" width="95%"
height="95%" horizontalCenter="0" verticalCenter="0">
            <mx:horizontalAxis>
            <mx:CategoryAxis categoryField="label" />               Â
        </mx:horizontalAxis>                                      Â
            <mx:verticalAxis>
                <mx:LinearAxis baseAtZero="false"/>
            </mx:verticalAxis>                                       Â
            <mx:series>          Â
            <mx:LineSeries form="segment" yField="data2" displayName="Meta"/>
            <mx:LineSeries form="segment" yField="data1" displayName="Indicador Técnico"/>
            </mx:series>
        </mx:LineChart>
    </mx:Panel>
    </mx:Repeater>
</mx:Tile>
Antes de executar o projeto e ver tudo funcionando legal, é necessário adicionar o código abaixo na segunda linha do código dentro da tag mx:Application
creationComplete=”load()”
Deixando-a assim:
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="load();">
Execute o projeto, você deve obter um resultado igual a imagem abaixo.

Complementando?
Para incluir as legendas basta adicionar logo após o gráfico o código abaixo:
<mx:Legend dataProvider="{grIndicador[0]}" bottom="10" left="10" right="10" height="25"/>

Fonte: Imasters
Crie Arquivos .ZIP com ASP.NET
Neste artigo vou mostrar como criar arquivos .ZIP e como descompactar utilizando o ASP.net.
Imagem de exemplo do exemplo deste artigo.
Um pouco de conhecimento antes de programarmos
Arquivos .zip é um formato muito conhecido. Em Matemática, um dos modos de se obter uma compressão de arquivos, é através de Transformada de Fourier. A compressão e compactação são importantÃssimas para conseguirmos informações em tempos menores de transmissão, de forma mais barata possÃvel.
Qual a diferença entre Compressão e Compactação?
A principal diferença entre os dois termos é que compactação não há perda de informação, enquanto que na compressão há perda. O Formato .MP3 é um exemplo de Compressão, pois há perda de informação, embora nossos ouvidos não notem muito. Mesmo entre os Mp3, temos aqueles com maior qualidade (menos perda) e os de menores qualidades (maior perda).
Entre os métodos mais conhecidos de compactação estão:
- Codificação por carreira
- Codificação por Shannon-Fano
- Codificação de Huffman (muito utilizado para compactar texto)
- Codificação de Lempel-Ziv-Welch (LZW)
- Codificação aritmética
Entre os métodos mais conhecidos de compressão estão:
- Redução do domÃnio
- Redução do espaço de quantização
- Codificação preditiva
- Codificação por sub-bandas
- Codificação por transformadas
- Quantização vetorial
Pré-requisitos
Este artigo foi montado nas configurações abaixo. Não foi testado em outros ambientes.
- Framework ASP.NET 2.0 com VB.net
- Visual Studio 2005.
Mãos a obra
Clique aqui para dar download no projeto de exemplo.
Primeiro, crie uma solução no seu VisualStudio. Adicione um novo projeto Web, e referencie a Biblioteca SharpZLib.
Caso você esteja usa utilizando a versão Express, crie um novo website, e coloque ICSharpCode.SharpZipLib.dll na pasta /bin.
Em seguida, vamos criar uma página chamada zip.ASPX.
Compactando Diretório Inteiro
Para compactar o diretório, você terá que informar o diretório de origem e o arquivo de destino.
''' <summary>
  ''' Evento do botão, gerar diretório
  ''' </summary>
  Protected Sub btnGerar_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnGerar.Click
    gerarZipDiretorio(txtOrigem.Text, txtDestino.Text)
    subInitDescompactarArquivos()
  End Sub
  ''' <summary>
  ''' Este método gera um zip, a partir de um diretório
  ''' </summary>
  ''' <param name="sDiretorioOrigem">
  ''' Diretório que será zipado
  ''' </param>
  ''' <param name="sDiretorioDestino">
  ''' Diretório que receberá o arquivo zipado
  ''' </param>
  ''' <remarks>
  ''' </remarks>
  Public Sub gerarZipDiretorio(ByVal sDiretorioOrigem As String, ByVal sDiretorioDestino As String)
    Dim sz As New FastZip()
    Dim sArquivoZip As String = String.Empty
    ' Aqui vou criar um nome do arquivo, com 6 caracteres randômicos.
    ' O Guid é um método do .net que gera string aleatórias únicas, baseada na hora e no
    ' endereço MAC na máquina gerada.
    sArquivoZip = "MeuZip" & Left(Guid.NewGuid.ToString, 6) & ".zip"
    ' Só um tratamento para garantir mais estabilidade
    If Right(sDiretorioOrigem, 1) <> "\" Then
      sDiretorioOrigem = sDiretorioOrigem & "\"
    End If
    ' Só um tratamento para garantir mais estabilidade
    If Right(sDiretorioDestino, 1) <> "\" Then
      sDiretorioDestino = sDiretorioDestino & "\"
    End If
    If Not Directory.Exists(sDiretorioDestino) Then
      lblErro.Text = "O Diretório de Destino informado não existe: <br />" & sDiretorioDestino
      Exit Sub
    End If
    If Not Directory.Exists(sDiretorioOrigem) Then
      lblErro.Text = "O Diretório de Origem informado não existe: <br />" & sDiretorioOrigem
      Exit Sub
    End If
    sz.CreateZip(sDiretorioDestino & sArquivoZip, sDiretorioOrigem & "" & "\", True, "", "")
    ' Aqui eu habilito o download do arquivo.
    ' Muito útil se você quiser salvar em diretórios protegidos
    ' Ou não acessÃvel pela raÃz do seu projeto web.
    HttpContext.Current.Response.TransmitFile(sDiretorioDestino & sArquivoZip)
    ' "Limpo" o objeto
    sz = Nothing
  End Sub
Obs.:
Você pode definir uma senha para seu .zip, utilizando a propriedade “password”.
Compactando Somente um Arquivo
Para compactar somente um arquivo, você terá que informar o arquivo a ser compactado, e o diretório de destino.
  ''' <summary>
  ''' Evento do botão gerar Arquivo
  ''' </summary>
  Protected Sub btnGerarArquivo_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnGerarArquivo.Click
    gerarZipArquivo(txtArquivoOrigem.Text, txtArquivoDestino.Text)
    subInitDescompactarArquivos()
  End Sub
  ''' <summary>
  ''' Este método gera um zip, a partir de um diretório
  ''' </summary>
  ''' <param name="sArquivoOrigem">
  ''' Arquivo que será zipado
  ''' </param>
  ''' <param name="sDiretorioDestino">
  ''' Diretório que receberá o arquivo zipado
  ''' </param>
  ''' <remarks>
  ''' </remarks>
  Public Sub gerarZipArquivo(ByVal sArquivoOrigem As String, ByVal sDiretorioDestino As String)
    Dim sz As New FastZip()
    Dim sArquivoZip As String = String.Empty
    ' Aqui vou criar um nome do arquivo, com 6 caracteres randômicos.
    ' O Guid é um método do .net que gera string aleatórias únicas, baseada na hora e no
    ' endereço MAC na máquina gerada.
    sArquivoZip = "MeuZip" & Left(Guid.NewGuid.ToString, 6) & ".zip"
    ' Só um tratamento para garantir mais estabilidade
    If Right(sDiretorioDestino, 1) <> "\" Then
      sDiretorioDestino = sDiretorioDestino & "\"
    End If
    If Not Directory.Exists(sDiretorioDestino) Then
      lblErroArquivo.Text = "O Diretório de Destino informado não existe: <br />" & sDiretorioDestino
      Exit Sub
    End If
    If Not File.Exists(sArquivoOrigem) Then
      lblErroArquivo.Text = "O Arquivo de Origem informado não existe: <br />" & sArquivoOrigem
      Exit Sub
    End If
    ' Crio um arquivo do tipo stream, aprontando para o meu zip de destino.
    Dim strmZipOutputStream As ZipOutputStream
    strmZipOutputStream = New ZipOutputStream(File.Create(sDiretorioDestino & sArquivoZip))
    ' Seto o nÃvel de compressão (0->Sem compressão / 9-> Compressão Máxima)
    strmZipOutputStream.SetLevel(9)
    ' Leio o arquivo de origem
    Dim strmFile As FileStream = File.OpenRead(sArquivoOrigem)
    Dim abyBuffer(strmFile.Length - 1) As Byte
    strmFile.Read(abyBuffer, 0, abyBuffer.Length)
    ' Aqui eu trato para pegar somente o arquivo, sem os diretórios
    ' O split é um método que separa a string, de acordo com um caractere, no meu caso "\"
    ' Cada indice da minha matriz é um diretório, e o ultimo é o arquivo
    Dim sAuxArquivo As String() = Split(sArquivoOrigem, "\")
    ' Crio uma variável, adicionando o meu Arquivo ao Zip
    ' Com ubound, eu pego o ultimo Ãndice da minha matriz, que é o nome do meu arquivo.
    Dim objZipEntry As ZipEntry = New ZipEntry(sAuxArquivo(UBound(sAuxArquivo)))
    ' Seto a data de criação
    objZipEntry.DateTime = DateTime.Now
    ' Informo o tamanho do stream. (Do meu arquivo a ser zipado)
    objZipEntry.Size = strmFile.Length
    ' Fecho meu stream para liberar memória
    strmFile.Close()
    ' Adiciono no objeto para gerar o zip.
    strmZipOutputStream.PutNextEntry(objZipEntry)
    strmZipOutputStream.Write(abyBuffer, 0, abyBuffer.Length)
    ' "Limpo" o objeto
    strmZipOutputStream.Finish()
    strmZipOutputStream.Close()
    ' Aqui eu habilito o download do arquivo.
    ' Muito útil se você quiser salvar em diretórios protegidos
    ' Ou não acessÃvel pela raÃz do seu projeto web.
    HttpContext.Current.Response.TransmitFile(sDiretorioDestino & sArquivoZip)
  End Sub
Descompactando um arquivo .zip
Para descompactar um arquivo .zip você terá que informar o arquivo, e o diretório de destino.
  Protected Sub btnDescompactar_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnDescompactar.Click
    descompactarZip(txtArquivoParaDescompactar.Text, txtDescompactarArquivos.Text)
  End Sub
  ''' <summary>
  ''' Sub que descompacta um arquivo .zip apra um diretório
  ''' </summary>
  ''' <param name="sArquivoZip">
  ''' Arquivo para ser descompactado
  ''' </param>
  ''' <param name="sDiretorioParaDescompactar">
  ''' Diretório para ser descompactado
  ''' </param>
  ''' <remarks></remarks>
  Private Sub descompactarZip(ByVal sArquivoZip As String, ByVal sDiretorioParaDescompactar As String)
    Dim oMeuZip As New FastZip
    ' Se o arquivo não existe eu aviso o usuário
    If Not File.Exists(sArquivoZip) Then
      lblErroDescompactar.Text = ("Arquivo zip não existe: " & sArquivoZip)
      Exit Sub
    End If
    ' Se o arquivo não for zip, eu aviso o usuário
    If LCase(Right(sArquivoZip, 3)) <> "zip" Then
      lblErroDescompactar.Text = ("Arquivo não é do formato .zip: " & sArquivoZip)
      Exit Sub
    End If
    ' Se o arquivo não for zip, eu aviso o usuário
    If Not Directory.Exists(sDiretorioParaDescompactar) Then
      lblErroDescompactar.Text = ("Diretório para descompactar os arquivos não existe: " & sDiretorioParaDescompactar)
      Exit Sub
    End If
    ' "Deszipo" o arquivo, sem nunca sobrescrever
    oMeuZip.ExtractZip(sArquivoZip, sDiretorioParaDescompactar, FastZip.Overwrite.Never)
    lblErroDescompactar.Text = "Arquivo Descompactado com sucesso!!!!!"
  End Sub
Para você testar!
Para que você possa testar, colocamos um formulário, e um código de inicialização da página.
Formulário:
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
  <title>Criar Arquivos Zip em Asp.Net</title>
  <style type="text/css">
  body, input{
  font-family: verdana;
  font-size: 10px;
  }
  </style>
</head>
<body>
  <form id="form1" runat="server">
    <div>
      <strong>Este exemplo utiliza componentes de terceiros. Verifique o termo de uso.
        .</strong>
      <br />
      <br />
      <fieldset>
        <legend>Criar Arquivo Zip do Diretório Inteiro </legend>
        <table style="border: none;">
          <tr>
            <td>
              Diretório de Origem:
            </td>
            <td>
              <asp:TextBox ID="txtOrigem" runat="server" Columns="60"></asp:TextBox>
            </td>
          </tr>
          <tr>
            <td>
              Diretório de Destino:
            </td>
            <td>
              <asp:TextBox ID="txtDestino" runat="server" Columns="60"></asp:TextBox>
            </td>
          </tr>
          <tr>
            <td colspan="2">
              <asp:Button runat="server" ID="btnGerar" Text="Gerar Zip do Diretório inteiro" />
              <asp:Label runat="server" ID="lblErro" Font-Bold="true" ForeColor="red"></asp:Label>
            </td>
          </tr>
        </table>
      </fieldset>
      <br />  <br />
      <fieldset>
        <legend>Criar Arquivo Zip de um único Arquivo </legend>
        <table style="border: none;">
          <tr>
            <td>
              Arquivo para ser "zipado":
            </td>
            <td>
              <asp:TextBox ID="txtArquivoOrigem" runat="server" Columns="60"></asp:TextBox>
            </td>
          </tr>
          <tr>
            <td>
              Diretório de Destino:
            </td>
            <td>
              <asp:TextBox ID="txtArquivoDestino" runat="server" Columns="60"></asp:TextBox>
            </td>
          </tr>
          <tr>
            <td colspan="2">
              <asp:Button runat="server" ID="btnGerarArquivo" Text="Gerar Zip de um único Arquivo" />
              <asp:Label runat="server" ID="lblErroArquivo" Font-Bold="true" ForeColor="red"></asp:Label>
            </td>
          </tr>
        </table>
      </fieldset>
    </div>
    <br />  <br />
    <fieldset>
      <legend>Descompactar Arquivo .ZIP </legend>
      <table style="border: none;">
        <tr>
          <td>
            Arquivo para ser "deszipado":
          </td>
          <td>
            <asp:TextBox ID="txtArquivoParaDescompactar" runat="server" Columns="60"></asp:TextBox>
          </td>
        </tr>
        <tr>
          <td>
            Diretório para arquivos serem descompactados :
          </td>
          <td>
            <asp:TextBox ID="txtDescompactarArquivos" runat="server" Columns="60"></asp:TextBox>
          </td>
        </tr>
        <tr>
        <td colspan="2">
        <asp:Button runat="server" ID="btnDescompactar" Text="Descompactar arquivo zip" />
        <asp:Label ID="lblErroDescompactar" runat="server" Font-Bold="true" ForeColor="red"></asp:Label>
        </td>
        </tr>
      </table>
    </fieldset>
  </form>
</body>
</html>
Inicialização da Página
  Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    If Not Page.IsPostBack Then
      ' Aqui eu dou um valor inicial, só para te ajudar a começar com um teste
      txtDestino.Text = Server.MapPath("") & "\Destino\"
      txtOrigem.Text = Server.MapPath("") & "\Origem\"
      ' Arquivo
      txtArquivoDestino.Text = Server.MapPath("") & "\Destino\"
      txtArquivoOrigem.Text = Server.MapPath("") & "\Origem\Figura.jpg"
      ' Descompactar
      txtDescompactarArquivos.Text = Server.MapPath("") & "\Descompactar\"
      subInitDescompactarArquivos()
    End If
  End Sub
  ''' <summary>
  ''' Sub só para demonstação, para você poder dezipar um arquivo, depois de enviá-lo
  ''' </summary>
  ''' <remarks></remarks>
  Protected Sub subInitDescompactarArquivos()
    Dim sArquivos As String()
    Dim sArquivo As String
    ' Seleciono todos os arquivos do tipo zip.
    sArquivos = Directory.GetFiles(txtArquivoDestino.Text, "*.zip")
    For Each sArquivo In sArquivos
      txtArquivoParaDescompactar.Text = sArquivo
      Exit For
    Next
  End Sub
Considerações finais
É possÃvel também trabalhar com arquivos .tar, Gzip e BZip2 de forma análoga.
Fonte: Imasters



