Skip to content

Tag: Programação

Criando uma galeria de imagens com Python

Esse é um script que eu uso muito rotineiramente. Eu escrevi ele porque eu tentei várias soluções mas nenhuma era exatamente o que eu precisava e o que eu preciso é geralmente bem simles.

Só quero pegar um monte de fotos de várias resoluções diferentes e gerar uma página em HTML com as miniaturas das imagens com largura de 500 pixeis e com o link para a imagem original. É uma implementação bem simples, sem muita sofisticação. Eu coloco aqui porque ele é fácil de adaptar para outros usos.

#!/usr/bin/env python
import os
import Image
 
cwd = os.getcwd()
for arquivo in os.listdir(cwd):
   if arquivo.endswith('.JPG'):
      im = Image.open(arquivo)
      im.thumbnail((500,375), Image.ANTIALIAS)
      nome = arquivo.split('.')[0]
      tnome = nome + "_thumb.jpg"
      im.save(tnome, "JPEG")
      print '<a href="%s"><img src="%s"/></a><br/>' % (arquivo, tnome)

Ele procura os arquivos do diretório que terminam com .JPG, cria uma miniatura de tamanho 500 por 375 e cospe o HTML na saída padrão. Para usar ele, entre no terminal do diretório onde você quer fazer a galeria e execute o script:

python galeria.py > saida.html

Ele cria galerias bem simples como essa ou essa.

XII Maratona Brasileira de Programação

Logo da Maratona Brasileira de Programação

Esse sábado eu participei, junto com o Carlos Pontual e o Heraldo Carneiro, da décima segunda edição da Maratona Brasileira de Programação.

Maratona Brasileira de Programação

A sede do Ceará na competição ia ser em Sobral, com o pessoal da Engenharia da Computação da UFC, mas acabou sendo na Unifor. Uma pena, eu queria ter viajado pra conhecer o curso novo.

Embora antigamente eu tenha competido na OBI (Olimpíada Brasileira de Informática), eu nunca havia competido na Maratona Brasileira de Computação. Enquanto a OBI é uma competição voltada para alunos do ensino médio e básico a maratona é voltada para alunos do ensino superior da graduação e mestrado. Pelas minhas contas já faziam aí uns 3 anos que eu não competia.

Para quem não conhece esse tipo de competição, funciona assim: uma pessoa ou uma equipe (dependendo da competição) tem um certo tempo para resolver uma série de problemas usando programação. A correção do programa é automatizada. Seu programa é testado através de uma bateria de testes e deve retornar as respostas corretas. É uma ótima forma de melhorar seus conhecimentos sobre grafos, lógica, programação dinâmica, estruturas de dados, programação etc. Também é uma ótima oportunidade para conhecer ou rever o pessoal dos cursos de computação.

Heraldo Carneiro, Silveira Neto e Carlos Pontual

Bem, vamos aos problemas que nós fizemos:

  • Varetas, problema H, era um problema bem simples. Esse nós fizemos em C e foi aceito de primeira.
  • Histórico, problema E, também um problema não muito complicado. Mas foi por ele que nós nos enrolamos. Nós resolvemos o problema em Java e submetemos, mas a correção deu runtime error para ele. Nós re analisamos o problema, modificamos o programa e mandamos novamente e ganhamos outro runtime error. Como nós estávamos bem confiantes que nossa resposta estava certa nós refizemos o programa em C e submetemos. Dessa vez o programa passou sem problemas. Mais Tarde ficamos sabendo que devido a um erro da correção automática, não havia como um programa em Java ter acertado essa questão. Isso fez que passemos 1 hora e 44 minutos nesse problema.
  • Rouba, problema B, basicamente um problema para simular um jogo de cartas. O Heraldo pegou esse problema e fez ele em Java. Depois de 3 submissões e 3 time limit exceeded da correção automática, nós estávamos certos que nosso programa estava correto. Nós já haviamos feitas varias otimizações de velocidade no programa. Havia agora três alternativas: ou abandonar o problema e tentar outra questão ou continuar a otimizar o programa ou refaze-lo em C. Até tentamos sair do problema, mas ele não saiu da cabeça do Heraldo :). Refaze-lo em C implicaria em implementar uma série de estruturas na unha, o que iria ser muito chato e não havia certeza que isso ia resolver nossa vida.Por fim o Heraldo fez mais um última pequena otimização no programa e ele passou.

Nós ainda tentamos sem sucesso resolver os problemas Mário (o problema do armário hehehe) e o Zak.

Algumas estatísticas (parciais) da sede do Ceará:

Problema Submissões Aceitos
Histórico 27 9 (33%)
Rouba 17 6 (35%)
Tubos 1 0
Volei 1 0
Zak 6 2 (33%)
bolhas 4 0 (0%)
caixas 23 5 (22%)
mario 8 2 (25%)
olimp 0 0
varetas 17 10 (59%)

Equipes e problemas resolvidos:

Equipe Resolvidos Problemas
UECE – Camila, Tainara, Leonilia 6 Rouba (7/207), mario (1/172), Histórico (1/41), caixas (1/233), varetas (1/49), Zak (2/273)
UECE – Die aphthe schmerzen 5 Rouba (1/161), mario (2/0-), Histórico (1/47), caixas (2/223), varetas (1/35), Zak (4/186)
AVL Team 5 Rouba (1/135), mario (1/277), Histórico (1/77), caixas (5/296), varetas (1/67)
Os Entrevistados 4 Rouba (1/90), Tubos (1/-), Histórico (1/79), caixas (2/182), varetas (1/66)
GOF 4 Rouba (2/73), Histórico (5/151), Caixas (5/289), Varetas (1/39)
Eupodiatamatando 3 Rouba (4/181), Mário (4/-), Histórico (3/143), Varetas (1/39)
UECE – n^n 2 Rouba (1/-), Histórico (1/90), caixas (1/-), varetas (2/122)
UECE – n! 2 Histórico (2/206), varetas (1/61)
unifor2 2 Histórico (2/206), varetas (1/61)
Mazela.cpp 1 Vôlei (1/-), Histórico (4/-), caixas (7/-), varetas (1/71)
unifor1 1 Histórico (2/-), Varetas 6

Observações: A equipe Singularidade de Sobral não estava presente lá, eu não sei se eles competiram. As equipes da UECE tiveram a boa idéia de colocar o nome da faculdade no nome da equipe.

Eu gostei muito dos resultados. Tivemos muitas equipes com bons resultados. Isso demonstra que os esforços, principalmente do Joel Uchôa, em divulgar e particularizar a competição estão sendo frutíferos. Todas as universidades conseguiram bons resultados. Ano que vem eu espero ver mais universidades competindo.

Sugestões para a organização:

  • Linguagens: segundo o Joel Uchôa me informou há planos para inserir novas linguagens na competição. Fica minha sugestão para que Python e Ruby sejam incluídas.
  • Java: me parece que há um longo histórico de problemas com a correção de programas em Java, sendo inclusive o uso desta desaconselhado por alguns. Eu espero que isso seja melhorado na próxima edição. Eu e minha equipe tivemos sérios problemas por conta disso mas nem por isso tenho planos de usar outra linguagem na próxima edição.
  • Distribuição: há uma distribuição GNU/Linux própria para a competição o Maratona Linux. Ele tem várias sacadas legais como redes separadas para que nenhuma equipe possa usar a Internet ou enxergar as outras equipes, boot remoto etc. Porém é necessário boot pelo disquete o que tem sido uma fonte constante de problemas. O sistema de janelas WindowMaker também é fonte de confusão com usuários iniciantes, se é realmente necessário um sistema minimalista eu recomendaria o Fluxbox, XFCE ou Icewm.
  • Correção: eu não gosto do esquema de correção da Maratona. Eu prefiro o da OBI. Na OBI há varias baterias de testes, cuidadosamente preparadas para filtrar cada tipo de erro ou algoritmos. Cada acerto em uma bateria resulta em pontuação. Já na maratona ou se acerta uma questão completamente ou ela está totalmente errada. Isso impede algoritmos mais triviais, algoritmos com complexidade alta (os não polinomiais) e impede também usar técnicas de Inteligência Artificial. Acho que isso interfere muito na forma de se elaborar os problemas e de se resolver os problemas. No universo dos problemas reais, nem tudo pode ser resolvido em tempo e espaço polinomial. Esse é o universo em que vivemos.

Fotos:


almoço Almoço Maratona Brasileira de Programação Maratona Brasileira de Programação Maratona Brasileira de Programação Maratona Brasileira de Programação Mesa desorganizada Maratona Brasileira de Programação Maratona Brasileira de Programação Maratona Brasileira de Programação Maratona Brasileira de Programação Maratona Brasileira de Programação Maratona Brasileira de Programação Heraldo Carneiro Maratona Brasileira de Programação balões laboratório computadores Maratona Brasileira de Programação Joel Uchôa Maratona Brasileira de Programação Heraldo Carneiro Silveira Neto Carlos Pontual Maratona Brasileira de Programação confraternização Maratona Brasileira de Programação confraternização

bônus: um vídeo que eu fiz quando já estava bem cansado. Aqui.

A Maratona Brasileira de Programação é uma realização da Sociedade Brasileira de Computação, USP, Fundação Carlos Chagas, IBM e diversas universidades e voluntários por todo o Brasi.

JavaScript: Vetores

Um tutorial básico orientado a exemplos de como funcionam os vetores em JavaScript.

Criando e acessando um vetor

var planetas = new Array()
planetas[0] = "Mercúrio"
planetas[1] = "Vênus"
planetas[2] = "Terra"
planetas[3] = "Marte"
planetas[4] = "Júpiter"
planetas[5] = "Saturno"
planetas[6] = "Urano"
planetas[7] = "Neptuno"
 
for (i=0;i

Que vai escrever isso:

Mercúrio
Vênus
Terra
Marte
Júpiter
Saturno
Urano
Neptuno

Iterando no vetor

var planetas = new Array()
planetas[0] = "Mercúrio"
planetas[1] = "Vênus"
planetas[2] = "Terra"
planetas[3] = "Marte"
planetas[4] = "Júpiter"
planetas[5] = "Saturno"
planetas[6] = "Urano"
planetas[7] = "Neptuno"
 
for (i in planetas){
    document.write(planetas[i] + "")
}

vai retornar a mesma saída do primeiro programa:

Que vai escrever isso:

Mercúrio
Vênus
Terra
Marte
Júpiter
Saturno
Urano
Neptuno

Concatenando dois vetores

var litoral = new Array()
litoral[0] = "Jericoacoara"
litoral[1] = "Paracuru"
litoral[2] = "Tabuba"
 
var sertao = new Array()
sertao[0] = "Itapipoca"
sertao[1] = "Ubajara"
sertao[2] = "Juazeiro"
 
var ceara = litoral.concat(sertao)
 
document.write(litoral+"
")
document.write(sertao+"
")
document.write(ceara+"
")

Jericoacoara,Paracuru,Tabuba
Itapipoca,Ubajara,Juazeiro
Jericoacoara,Paracuru,Tabuba,Itapipoca,Ubajara,Juazeiro

Unindo os elementos de um vetor

var letras = new Array(3)
letras[0] = "A"
letras[1] = "B"
letras[2] = "C"
document.write(letras.join() + "")
document.write(letras.join("@"))

A,B,C
A@B@C

Ordenação Literal

Essa ordenação é feita sem usar nenhum parâmetro, então a ordem lexicográfica, a do dicionário.

var coisas = new Array(4)
coisas[0] = "casa"
coisas[1] = "bonde"
coisas[2] = "alvo"
coisas[3] = "dado"
 
document.write(coisas + "")
document.write(coisas.sort()+ "")
document.write(coisas + "")

Note que depois do .sort() o vetor é alterado.

casa,bonde,alvo,dado
alvo,bonde,casa,dado
alvo,bonde,casa,dado

Ordenação usando uma função de ordenação

A ordenação literal não vai funcionar bem nesse caso, então nos definimos uma função para ordenação. Ela deve retornar zero se ambos forem iguais, um número positivo se o primeiro for maior que o segundo e um número negativo se o segundo for maior que o primeiro.

function sortNumber(a, b){
return a - b
}
 
var arr = new Array(6)
arr[0] = "10"
arr[1] = "5"
arr[2] = "40"
arr[3] = "25"
arr[4] = "1000"
arr[5] = "1"
 
document.write(arr + "")
document.write(arr.sort()+"
")
document.write(arr.sort(sortNumber))

10,5,40,25,1000,1
1,10,1000,25,40,5
1,5,10,25,40,1000

Retirando o último elemento

O pop retorna o último elemento do vetor e o retira.

var gatos = new Array(3)
gatos[0] = "Frida"
gatos[1] = "Sauber"
gatos[2] = "Boris"
document.write(gatos + "")
document.write(gatos.pop() + "")
document.write(gatos)

Frida,Sauber,Boris
Boris
Frida,Sauber

Inserindo elementos no final do vetor

O push insere um elemento no final do vetor e retorna seu novo tamanho.

var animais = new Array(3)
animais[0] = "Frida"
animais[1] = "Sauber"
animais[2] = "Frida"
document.write(animais + "")
document.write(animais.push("Vida")+ "")
document.write(animais)

Frida,Sauber,Frida
4
Frida,Sauber,Frida,Vida

Inserindo elementos no inicio do vetor

var inst = new Array(3)
inst[0] = "Baixo"
inst[1] = "Guitarra"
inst[2] = "Piano"
document.write(inst + "")
document.write(inst.unshift("Flauta") + "")
document.write(inst)

Baixo,Guitarra,Piano
4
Flauta,Baixo,Guitarra,Piano

Retirando elemento no inicio do vetor

var inst = new Array(3)
inst[0] = "Baixo"
inst[1] = "Guitarra"
inst[2] = "Piano"
 
document.write(inst + "")
document.write(inst.shift() + "")
document.write(inst)

Baixo,Guitarra,Piano
Baixo
Guitarra,Piano

JavaScript: Relógio Digital


Código-Fonte

Aqui na página colocamos:

<input type='text' value='00:00:00' id='relogio' readonly size='6'
style="font-size: 200%; color:red"/>
<script type="text/javascript" src="/scripts/relogio.js"></script>

Que cria um input de texto com nome relógio e depois chamamos o script relogio.js que contém o seguinte código:

function proximo_segundo(){
	var hoje = new Date
	var hora = hoje.getHours()
	var minutos = hoje.getMinutes()
	var segundos = hoje.getSeconds()
	relogio = document.getElementById('relogio')
	relogio.value = hora +":"+minutos+":"+segundos
	setTimeout('proximo_segundo()',1000)
}
proximo_segundo()

Ele cria um objeto Date, encontro o elemento com id ‘relogio’ e coloca no valor dele as informações extraídas do objeto Date. Em seguida ele agenda para daqui a um segundo chamar a si próprio, recursivamente.

Um refinamento que se pode fazer nesse código é uma função auxiliar para preencher com um zero à esquerda, transformando 1:2:3 em 01:02:03. Eu não coloquei isso para deixar o código o mais simples possível.

Como eu ainda sou muito novinho no JavaScript eu não sei se usar uma recursão desse tipo é uma boa idéia ou não. Era isso ou um laço infinito.

JavaScript: Informações sobre o Navegador do Usuário


Você deve estar vendo na caixinha de cima várias informações sobre o seu navegador.
O trecho do código JavaScript que gerou isso foi:

<TEXTAREA id="nav_info" cols="60"></textarea>
<script type="text/javascript">document.getElementById("nav_info").value =
navigator.appName+
navigator.appVersion+
navigator.appCodeName+
navigator.platform+
navigator.userAgent</script>

Cada um das variáveis lidas de navigator contém algum tipo de informação útil sobre as características do navegador.