UNIVERSIDADE FEDERAL DO ESPÍRITO SANTO
DEPARTAMENTO DE INFORMÁTICA
__________________________________________________________________
Trabalho Temático do PET
Processamento de Dados II
Autores: Adriana Campos e Matheus Dilem
Grupo PET
Engenharia de Computação
http://www.inf.ufes.br/~pet
__________________________________________________________________
Novembro – 2008
Eleições 2008
1 Motivação
Desde o início do programa, o PET - Engenharia de Computação da UFES vem propondo trabalhos adicionais
aos cursos do Departamento de Informática com o intuito de reforçar os conceitos aprendidos em sala de aula e de
mostrar a aplicabilidade desses conceitos em problemas reais. Assim, com a aplicação dessa prática pedagógica há um
enriquecimento da formação tanto dos alunos envolvidos na elaboração do trabalho, através do desenvolvimento de
práticas como escrita; quanto dos alunos aos quais o trabalho será aplicado, através da prática de aplicar conceitos
teóricos na solução de problemas reais.
Inspirados no período eleitoral, propomos uma simulação de eleição para candidatos a prefeito e vereador.
Cabe a nós monitores, ressaltar que qualquer semelhança encontrada nos dados do problema é pura coincidência.
2 Objetivo
Espera-se que os alunos que aceitarem a proposta exercitem a manipulação de vetores de structs e solidifiquem
o conceito de tipo abstrato de dado. Além disso, é necessário que os alunos tenham em mente que esse trabalho é um
pequeno desafio, pois terá que ser implementado em pouco tempo. Porém, vale ressaltar que todas as dúvidas referentes
aos conceitos utilizados no trabalho serão esclarecidas pelos monitores.
3 Descrição
A cidade de Esperança Eterna encontra-se em período eleitoral. O representante local do TRE (Tribunal
Regional Eleitoral) está interessado em automatizar a apuração dos votos, a fim de tornar o processo mais ágil e
confiável.
A eleição
A eleição se processará da seguinte forma:
O prefeito é eleito pelo sistema majoritário (vence quem tiver mais votos, contando apenas os votos válidos).
Os vereadores são eleitos pelo sistema proporcional,ou seja, as vagas da câmara são preenchidas proporcionalmente ao
número de votos obtidos pelas coligações. Essas vagas são ocupadas pelos candidatos mais votados das coligações.
Coligação é a reunião de partidos políticos para disputar uma eleição em conjunto, seja para concorrer à
eleição de prefeito, vereador, ou ambas. A coligação participa do processo eleitoral como se fosse um único partido
político.
Vale ressaltar o voto de legenda, no qual o eleitor pode votar simplesmente no partido que preferir. Como a
coligação funciona como uma reunião de partidos, os votos de legenda de um certo partido são contabilizados como
votos da sua coligação.
Roteiro para definição da distribuição das cadeiras dos vereadores entre as coligações:
Passo 1: Retire do total de votos os votos em branco e os que anularam o voto para obter os votos válidos.
Passo 2: Divida os votos válidos pelo número de cadeiras da Câmara dos Vereadores e encontre o quociente eleitoral.
Passo 3: Observe que se uma coligação não atinge o quociente eleitoral ela não pode receber nenhuma cadeira.
Passo 4: Divida o total de votos de cada coligação pelo quociente eleitoral. O resultado indicará o número de
vereadores que cada coligação elegerá.
Passo 5: Se não forem alocadas todas as cadeiras. O número restante será distribuído pelo método de maiores médias: o
total de votos de cada coligação é dividido pelas cadeiras que ela obteve mais uma. Depois da divisão, os que ficarem
com os maiores médias elegem a próxima cadeira.
Passo 6: Os candidatos mais votados de cada coligação ocupam as vagas obtidas.
Exemplo Hipotético:
Imagine uma cidade com 60.000 eleitores que elege 10 vereadores. Cinco partidos apresentaram candidatos a
vereador e tiveram as seguintes votações: Partido A (16.000 votos), Partido B (14.000 votos), Partido C (11.000 votos)
Partido D (7.500 votos), e Partido E (1.500 votos). O número de eleitores que não foram votar é de 6.000 e dos que
deixaram os votos em branco ou anularam é de 4.000.
Passo 1: No exemplo, faltaram 6.000 pessoas. Assim, ficamos com 54.000 eleitores que compareceram. O total de
pessoas que votaram em branco ou anularam foi de 4.000. Ficamos com 50.000 votos válidos.
Passo 2: Divida os votos válidos (50.000) pelo número de cadeiras da Câmara dos Vereadores (10) e encontre o
quociente eleitoral: 5.000 votos.
Passo 3: No exemplo, o Partido E obteve 1.500 votos, então ele não elegerá nenhum vereador.
Passo 4:
Partido Votos
Quociente eleitoral
Cadeiras
Partido A
16.000/5.000 = 3,2
3
Partido B
14.000/5.000 = 2,8
2
Partido C
11.000/5.000 = 2,2
2
Partido D
7.500/5.000 = 1,5
1
Passo 5: Observe que após a divisão acima oito cadeiras foram alocadas para os partidos. Ficaram, portanto, faltando
duas.
Partido Votos
Média
Cadeiras
Partido A
16.000/4 = 4.000
1
Partido B
14.000/3 = 4.666,7
1
Partido C
11.000/3= 3.666,7
0
Partido D
7.500/2 = 3.750
0
As duas maiores médias foram do Partido A e do Partido B, por isso estes dois partidos receberam as duas cadeiras
restantes.
O número final de vereadores eleitos pelos partidos é o seguinte: Partido A (4); Partido B (3); Partido C (2); Partido D
(1).
O trabalho
O trabalho consiste em implementar um programa que faça a contabilização dos votos para os candidatos a
prefeito e vereador.
O seu programa deverá ler 4 arquivos de entrada, o 1° arquivo denominado prefeitos.txt com as informações
dos candidatos a prefeito (NOME, NUMERO,PARTIDO), o 2° arquivo denominado vereadores.txt terá as informações
dos candidatos a vereador (NOME, NUMERO, PARTIDO), o 3° arquivo coligacoes.txt com as informações das
coligações (PARTIDOS,NUMEROS) e o 4º arquivo votos.txt com todos os votos dos candidatos a prefeito e vereador.
Após a leitura dos dados iniciais, deve ser feito a contabilidade dos votos para prefeito e vereador, respeitando
a descrição feita acima, considerando que não houve abstinência.
O seu algoritmo deverá ter como saída dois arquivos: resultadoPrefeito.txt com o resultado da apuração (Votos
Apurados; Votos Válidos; Votos Nulos; Votos Brancos) e dos votos em ordem decrescente para prefeito (Nome e
Quantidade de Votos) e resultadoVereadores.txt com o resultado da apuração (Votos Apurados; Votos Válidos; Votos
Nulos; Votos Brancos) e dos votos em ordem decrescente de classificação para vereadores eleitos (Nome e Quantidade
de Votos) .
O TRABALHO PODERÁ SER FEITO EM DUPLA.
4 Informações Importantes
Operações sobre arquivos
Na linguagem C, o tipo FILE, definido na biblioteca stdio.h, é usado para se tratar arquivos. Um ponteiro para
FILE deve ser declarado sempre que uma variável arquivo for utilizada no programa. Por exemplo, o seguinte comando
declara uma variável do tipo ponteiro para arquivo denominada arq:
FILE *arq;
Abertura de arquivos
Após a declaração de uma variável do tipo arquivo, essa deve ser associada a um nome de arquivo, o qual
identifica um arquivo de fato, com correspondência na memória secundária.
Se o arquivo com o nome especificado já existir, então o programador terá acesso a seu conteúdo, e poderá-lo
e alterá-lo. Mas um nome de arquivo que ainda não existe também pode ser utilizado. Nesse caso, um novo arquivo,
”em branco”, com o nome especificado, será criado. Esses detalhes são resolvidos passando-se as informações corretas
à função responsável por abrir o arquivo.
Na linguagem C, essa função é a fopen(). Seu protótipo:
FILE *fopen (const char *nomearq, const char *modo);
O primeiro argumento de fopen(), nomearq, é uma string, e refere-se ao nome do arquivo que será aberto. O
segundo argumento, modo, também uma string, um código passado a fopen(), responsável por indicar que tipo de
arquivo e operação será realizada sobre esse arquivo.
Neste trabalho você usaram os seguintes códigos:
Parâmetro
Efeito
r
Abre um arquivo-texto para leitura
w
Cria um arquivo-texto para escrita
Um ponto importante a ser ressaltado sobre a função fopen() é a avaliação de seu valor de retorno. Muitas
vezes ocorrem erros na abertura de um arquivo, como, por exemplo, passar para fopen() o código ”r” mas o arquivo
com o nome especificado não existir no disco. Esses erros podem ser detectados porque a função fopen() retornará
NULL para indicar que houve falha na abertura de um arquivo.
Fechamento de arquivos
Quando um arquivo aberto não for mais utilizado num programa, ele deve ser fechado. Esse fechamento
desassocia o arquivo físico, em disco (por exemplo), com a variável do tipo arquivo usada para abri-lo. Um arquivo
aberto pode ser fechado usando-se uma função que execute essa tarefa e que o receba como argumento.
Na linguagem C, a função fclose() é usada para fechar um arquivo. Seu protótipo:
fclose (fp);
Leitura
A função fscanf() funciona de forma semelhante à scanf(), já estudada em capítulos anteriores. A diferença está
no fato de que fscanf() trabalha com arquivos, e não com a entrada padrão (normalmente o teclado), caso de scanf()
.
Seu protótipo:
fscanf ( FILE *fp, char *format, ... );
A passagem de argumentos é semelhante a de scanf()., com o acréscimo de que deve ser colocado como
primeiro argumento o ponteiro para FILE representando o arquivo do qual serão lidas as variáveis.
No formato comum de uso, fscanf(), assim como scanf()., encerra a leitura de uma string (ou seja, argumento
de código ”%s”) assim que um caractere de espaço em branco, tabulação ou quebra de linha é encontrado. Dessa forma,
fscanf() não é recomendada para a leitura de strings. C oferece outra função para esse fim, fgets(), função que permite
ler strings completas.
Seu protótipo:
char *fgets (char *str, int length, FILE *fp);
Essa função lê os caracteres do arquivo fp passado como argumento e armazena-os na string str, também
passada como argumento, até que ou length-1 caracteres sejam lidos ou um caractere de nova linha (’\n’) seja lido. Se
um caractere de nova linha for lido, ele será armazenado em str. Já quando a leitura de caracteres do arquivo finaliza,
fgets() encerrará string str armazenando ’\0’ no próximo caractere (ou seja, finalizando a string). O exemplo mostra
como a fun ção
̧
fscanf() pode ser usada para ler um inteiro, uma string (não formada por espaços ou quebras de linha) e
um float de um arquivo-texto. Note que necessário o uso de & antes da variável int e float, já que deve-se passar o
endereço delas a fscanf(), e que isso não é necessário com a variável string (como ocorre com o uso de scanf() ).
Escrita
A linguagem C oferece a função fprintf(), que pode ser usada para gravar em arquivos de texto.
A função fprintf() é semelhante a printf().
Seu protótipo:
fprintf ( FILE *fp, const char *format, ... );
A passagem de parâmetros é semelhante a de printf(), com o acréscimo de que deve ser colocado como
primeiro argumento o ponteiro para FILE representando o arquivo no qual serão gravadas as informações. A gravação
de strings pode ser feita sem problemas com o uso de fprintf().
Exemplo:
main(){
FILE *f,*s;
int inteiro;
char str[40];
float real;
f=fopen(“arquivo.txt”,”r”);
s=fopen(“saida.txt”,”w”);
// Criação do ponteiro para o arquivo
while (!feof (f)){
// Verifica se chegou ao fim do arquivo
// Abertura do arquivo arquivo.txt para leitura
// Abertura do arquivo saida.txt para escrita
fscanf ( f ," % d \ n % s \ n % f " , & inteiro , str , & real ) ;
// Leitura do arquivo arquivo.txt
fprintf (s , " % d \ n % s \ n % f " , inteiro , str , real ) ;
// Escrita no arquivo saida.txt
}
fclose(f);
fclose(s);
}
// Fechamento do arquivo arquivo.txt
// Fechamento do arquivo saida.txt
5 Entrada
prefeitos.txt
Nome_do_candidato1
nº_do_candidato1 Partido_do_candidato1
Nome_do_candidato2
nº_do_candidato2 Partido_do_candidato2
...
Considerações: 1) O número máximo de candidatos a prefeito é 5.
2) Os dados número e partido serão separados pelo caractere 'espaço em branco'.
3) O número do candidato a prefeito é representado por dois dígitos, no intervalo de [10;99].
4) Os dados Nome_do_candidato e Partido_do_candidato são do tipo 'string' ; o dado nº_do_candidato
é do tipo 'int'.
vereadores.txt
Nome_do_candidato1
nº_do_candidato1 Partido_do_candidato1
Nome_do_candidato2
nº_do_candidato2 Partido_do_candidato2
...
Considerações: 1) O número máximo de candidatos a prefeito é 120.
2) Os dados de número e partido serão separados pelo caractere 'espaço em branco'.
3) O número do candidato a vereador é representado por cinco dígitos, no intervalo de [10000;99999].
4) Os dois primeiros algarismos representam o partido do candidato a vereador (Ex: 10222 ; nº do
partido → 10).
5) Os dados Nome_do_candidato e Partido_do_candidato são do tipo 'string' ; o dado nº_do_candidato
é do tipo 'int'.
coligacoes.txt
Nome_do_PartidoA n°_do_PartidoA Nome_do_PartidoB nº_do_PartidoB ...
Nome_do_PartidoX n°_do_PartidoX Nome_do_PartidoY nº_do_PartidoY ...
...
Considerações: 1) O número máximo de coligações é 6.
2) O número máximo de partidos por coligação é 4.
3) Os dados de nome e número do partido são separados pelo caractere 'espaço em branco'.
4) Cada linha de dados corresponde a uma coligação diferente com seus respectivos partidos.
5) O dado Nome_do_Partido é do tipo 'string' ; o dado n°_do_Partido é do tipo 'int'.
votos.txt
n°_do_prefeito
n°_do_vereador
n°_do_prefeito
n°_do_vereador
...
Considerações: 1) Cada duas linhas corresponde aos votos de um eleitor.
2) O número máximo de eleitores é de 150.000.
3) O voto 'branco' será representado pelo valor 0 (zero).
4) O voto 'nulo' será representado pelo valor negativo -1.
5) O voto de legenda (apenas para vereadores) será o número do partido (Ex: 19).
6) Os dados n°_do_prefeito e n°_do_vereador são do tipo 'int'.
6 Saída
resultadoPrefeito.txt
Total de Votos : nº_total_de_votos_para_prefeito
Votos Válidos: nº_de_votos_válidos_para_prefeito
Votos Nulos: nº_de_votos_nulos_para_prefeito
Votos Brancos: nº_de_votos_brancos_para_prefeito
Nome_do_candidatoC
nº_total_de_votos_do_candidatoC
Nome_do_candidatoD
nº_total_de_votos_do_candidatoD
...
Considerações: 1) Os dados nº_total_de_votos_para_prefeito , nº_de_votos_válidos_para_prefeito ,
nº_de_votos_nulos_para_prefeito, nº_de_votos_brancos_para_prefeito, nº_total_de_votos_do_candidato são do tipo
'int'.
2) O dado Nome_do_candidato é do tipo 'string'.
resultadoVereador.txt
Total de Votos : nº_total_de_votos_para_vereador
Votos Válidos: nº_de_votos_válidos_para_vereador
Votos Nulos: nº_de_votos_nulos_para_vereador
Votos Brancos: nº_de_votos_brancos_para_vereador
Nome_do_candidatoC
nº_total_de_votos_do_candidatoC
Nome_do_candidatoD
nº_total_de_votos_do_candidatoD
...
Considerações: 1) Os dados nº_total_de_votos_para_vereador , nº_de_votos_válidos_para_ vereador ,
nº_de_votos_nulos_para_vereador, nº_de_votos_brancos_para_vereador, nº_total_de_votos_do_candidato são do tipo
'int'.
2) O dado Nome_do_candidato é do tipo 'string'.
3) O número de vereadores eleitos deverá ser 10 (dez).
7 Entrega
O trabalho deverá ser enviado para o email [email protected] até às 23:59:59 do dia 19 de novembro
de 2008, com o assunto no seguinte formato desafioPET:nome1:nome2
Exemplo:
assunto: desafioPET:João Silva:Maria de Souza
8 Avaliação
Se o trabalho compilar, exibir o resultado esperado a dupla receberá nota 10. Obviamente, o não cumprimento
de alguma das especificações implicará em redução da nota, proporcionalmente à gravidade do erro. Qualquer suspeita
de plágio implicará em nota ZERO para todos os envolvidos. Se o trabalho não compilar também implicará em nota
ZERO.
O trabalho será corrigido (compilado e executado) com compilador gcc versão 4.3.1 (Debian 4.3.1-9).
Bom trabalho!