Mudanças entre as edições de "AULA Proposta de Projetos - Programação 1 - Engenharia"
Linha 248: | Linha 248: | ||
preocupados em propor estruturas de dados sofisticadas. Neste sentido, duas possibilidades pode se apresentar: | preocupados em propor estruturas de dados sofisticadas. Neste sentido, duas possibilidades pode se apresentar: | ||
− | *usar um contador de itens na tabela e sempre inserir um novo item após todos os demais. Neste caso, a remoção de um item implica em deslocar todos os dados posteriores para que ocupem o espaço liberado. (ver https://www.edureka.co/blog/c-program-for-deletion-and-insertion/) | + | *REGISTROS LIVRES SEMPRE SEM ENCONTRAM NO FINAL DA TABELA: usar um contador de itens na tabela e sempre inserir um novo item após todos os demais. Neste caso, a remoção de um item implica em deslocar todos os dados posteriores para que ocupem o espaço liberado. (ver https://www.edureka.co/blog/c-program-for-deletion-and-insertion/). |
− | *usar flags indicadores de registro livre ou ocupado na tabela. A inserção de um novo item na tabela deve passar por encontrar uma posição livre, colocando o flag do registro como ocupado. A remoção implica em simplesmente colocar o flag como livre. Um contador de itens pode ser usado para facilitar a identificação caso não exista mais posições livres na tabela. | + | *POSSIBILIDADE DE "LACUNAS LIVRES" NO ARRAY: usar flags indicadores de registro livre ou ocupado na tabela. A inserção de um novo item na tabela deve passar por encontrar uma posição livre, colocando o flag do registro como ocupado. A remoção implica em simplesmente colocar o flag como livre. Um contador de itens pode ser usado para facilitar a identificação caso não exista mais posições livres na tabela. |
+ | ==Exemplo de REGISTRO COM "LACUNAS LIVRES"== | ||
+ | |||
+ | <code> | ||
+ | #include <stdio.h> | ||
+ | #include <unistd.h> | ||
+ | #include <stdlib.h> | ||
+ | #include <string.h> | ||
+ | |||
+ | |||
+ | /* Autores: Professores PRG1 - IFSC -SJ */ | ||
+ | /******************************************/ | ||
+ | /* | ||
+ | Para fins didáticos, demonstramos como gerenciar um | ||
+ | vetor de structs marcando registros livres através de um flag | ||
+ | */ | ||
+ | /******************************************/ | ||
+ | |||
+ | #define LIVRE 0 | ||
+ | #define OCUPADO 1 | ||
+ | |||
+ | #define TAM_USER 10 | ||
+ | #define TAM_NOME 20 | ||
+ | |||
+ | /******************************************/ | ||
+ | /* Protótipos de funções - colocar em .h */ | ||
+ | /******************************************/ | ||
+ | |||
+ | void gerenciar_usuarios(); | ||
+ | void adicionar_usuario(); | ||
+ | void remover_usuario(); | ||
+ | void iniciar_tabela(); | ||
+ | int retornar_item_livre_tab_usuarios(); | ||
+ | |||
+ | |||
+ | /******************************************/ | ||
+ | /* Variáveis Globais */ | ||
+ | /******************************************/ | ||
+ | |||
+ | /* a fazer */ | ||
+ | |||
+ | struct tipo_usuario{ | ||
+ | char nome[TAM_NOME]; | ||
+ | int idade; | ||
+ | char flag; /* se 0 registro livre - se 1 ocupado */ | ||
+ | } tab_usuarios[TAM_USER]; | ||
+ | |||
+ | /******************************************/ | ||
+ | |||
+ | int main() | ||
+ | { | ||
+ | iniciar_tabela(); /* liberar todos os registros */ | ||
+ | gerenciar_usuarios(); | ||
+ | } | ||
+ | |||
+ | /* | ||
+ | Esta função inicia a tabela com todos registros livres | ||
+ | Aqui seria uma boa oportunidade para ler dados de um arquivo e iniciar a tabela | ||
+ | */ | ||
+ | void iniciar_tabela() | ||
+ | { | ||
+ | int i; | ||
+ | |||
+ | for (i=0;i<TAM_USER;i++){ | ||
+ | tab_usuarios[i].flag=LIVRE; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | /* | ||
+ | retorna -1 se não existe item livre na tabela | ||
+ | ou retorna o índice onde existe item livre | ||
+ | */ | ||
+ | int retornar_item_livre_tab_usuarios() | ||
+ | { | ||
+ | int i=0; | ||
+ | |||
+ | while(i<TAM_USER && tab_usuarios[i].flag==OCUPADO) { | ||
+ | i++; | ||
+ | } | ||
+ | if (i==TAM_USER) | ||
+ | i=-1; | ||
+ | return i; | ||
+ | } | ||
+ | |||
+ | /* | ||
+ | * Esta função insere usuário na tabela. NOTE que ela não testa se o | ||
+ | * usuário já se encontra na mesma... Poderia ser criada uma função para isto... | ||
+ | */ | ||
+ | void adicionar_usuario() | ||
+ | { | ||
+ | int ret; | ||
+ | ret = retornar_item_livre_tab_usuarios(); | ||
+ | if (ret==-1) | ||
+ | printf("Não existe espaço\n"); | ||
+ | else { | ||
+ | printf("Entre com usuario\n"); | ||
+ | scanf("%s", tab_usuarios[ret].nome); | ||
+ | tab_usuarios[ret].flag = OCUPADO; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void remover_usuario() | ||
+ | { | ||
+ | char buffer[TAM_NOME]; | ||
+ | int i=0; | ||
+ | |||
+ | printf("Qual o nome do usuário a remover?\n"); | ||
+ | scanf ("%s", buffer); | ||
+ | for (i=0;i<TAM_USER;i++){ | ||
+ | if (tab_usuarios[i].flag == OCUPADO && strcmp(buffer, tab_usuarios[i].nome)==0) { | ||
+ | break; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | if (i<TAM_USER) {/* usuário encontrado */ | ||
+ | tab_usuarios[i].flag = LIVRE; | ||
+ | printf("usuario %s removido da posição %d\n", tab_usuarios[i].nome, i); | ||
+ | } else { | ||
+ | printf("Usuário não se encontra na tabela\n"); | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | /***************************************************/ | ||
+ | /* Esta funções deveriam estar em arquivo separado */ | ||
+ | /***************************************************/ | ||
+ | void gerenciar_usuarios() | ||
+ | { | ||
+ | int opcao; | ||
+ | |||
+ | do { | ||
+ | system("clear"); | ||
+ | printf("**********************************\n"); | ||
+ | printf("Menu Nível 2 - Gerenciar Usuários\n\n"); | ||
+ | printf("1. Adicionar Usuário\n"); | ||
+ | printf("2. Remover Usuário\n"); | ||
+ | printf("3. Sair do Gerenciar Usuários\n"); | ||
+ | printf("**********************************\n"); | ||
+ | scanf("%d",&opcao); | ||
+ | switch (opcao) { | ||
+ | case 1: adicionar_usuario(); | ||
+ | break; | ||
+ | case 2: remover_usuario(); | ||
+ | break; | ||
+ | case 3: printf("Finalizando Gerenciar Usuários...\n"); | ||
+ | sleep(1); /* tempo somente para fins de visualização */ | ||
+ | break; | ||
+ | default: printf("Opção inexistente. Tente novamente...\n"); | ||
+ | sleep(1); /* tempo somente para fins de visualização */ | ||
+ | break; | ||
+ | } | ||
+ | |||
+ | } while (opcao != 3); | ||
+ | } | ||
+ | |||
+ | </syntaxhighlight> | ||
===Links Interessantes === | ===Links Interessantes === | ||
*[https://regex101.com Expressões regulares] | *[https://regex101.com Expressões regulares] |
Edição das 11h04min de 27 de novembro de 2019
Projeto final
O aluno deve propor ao professor um projeto de sua preferência que respeite os requisitos mínimos. Sendo aceito deverá desenvolver o projeto e apresentá-lo.
Requisitos mínimos
- Utilizar funções (ao menos três além do main, sendo que devem receber argumentos e possuir retorno);
- Apresentar menu utilizando switch case;
- Utilizar Structs e Ponteiros;
- Utilizar bibliotecas (manipulação de strings, tempo, matemática);
- Utilizar diretivas de pré-compilação (define, compilação condicional);
- Utilizar comentários (mas sem excesso - usar nomes significativos de funções e variáveis);
- Utilizar breaks com moderação e não usar gotos;
- Realizar acesso a arquivo, lendo e escrevendo informações (busque requisitos que requerem persistência de dados);
Metodologia e Entregas
Etapa 1
Enviar arquivo no SIGAA até 19/11/19
- Apresentar a proposta de projeto ao professor. Construir um pequeno documento com o escopo do projeto contendo:
- Título do Projeto
- Integrantes da Equipe
- Descrição do que o programa vai executar (3 parágrafos)
- Descrição de Cenários de uso identificando os atores. Exemplo: em um sistema de controle de retirada de livros pode-se ter 2 atores: o aluno e o bibliotecário.
- Cenário 1: Cadastro de aluno - Ator principal: Bibliotecário
- Através de uma interface o bibliotecário seleciona inserção de alunos.
- Entra com o nome do aluno
- Entra coma a matrícula.
- Finaliza o registro.
- Cenário 2: Insere livro...
- Cenário 3:
- Cenário 1: Cadastro de aluno - Ator principal: Bibliotecário
- Descrição das principais estruturas de dados do programa.
- Exemplo: Os alunos serão representados por um vetor de estruturas. Cada estrutura será da forma da forma:
- Exemplo: Os alunos serão representados por um vetor de estruturas. Cada estrutura será da forma da forma:
struct tipo_aluno{
char nome[TAM_NOME];
char matricula[TAM_MAT];
};
</syntaxhighlight>
- Proposta de cronograma (defesa final 4/5 de 12): Exemplo:
- Semana 1 (de 17 a 23/11): Implementação dos cenários 1 e 2
- Semana 2 (de 24 a 30/11): Implementação dos cenários 3 e 4
- Semana 3 (de 1 a 5/12): Testes Finais
Etapa 2
- Controle de Desenvolvimento: postar código até dia 25/11
Etapa 3
- Controle de Desenvolvimento: postar código até dia 2/12
Etapa 4
- Defesa Individual: 05/12/2019
Algumas ideias de projetos
- Sugestão geral: veja em outras disciplinas que processos podem ser automatizados e proponha um projeto que realiza esta tarefa como de cálculos diversos de eletrônica, de rádio transmissão, etc.
- Implementar software para realização de cálculos de eletrônica. Neste software um menu apresenta várias opções de cálculo como de potencia através de tensão e corrente, como obtenção do valor de um resistor, como solução de equivalência de paralelo de vários resistores e outras. Num arquivo texto pode ser armazenado um histórico de operações realizadas.
- Implementação de software para apostas na mega sena. Neste software são dadas sugestões de números para apostas de acordo com o número do sorteio da mega sena. Com este histórico armazenado é possível então entrar com um número de sorteio e digitar quais foram os números verdadeiramente sorteados na loteria federal checagem os acertos.
- sistema que controle individualmente as temperaturas das salas, monitorando em tempo real, permitindo alterações, adições e remoções das salas em tempo de execução.
- Implementar o jogo Pedra, papel ou tesoura. Neste jogo dois ou mais jogadores em diferentes computadores devem rodar um aplicativo que fará a leitura de um arquivo compartilhado. O algoritmo deve tratar as etapas do jogo (Setup do aplicativo, entrada na sala, escolha da figura e apresentação do resultado)
- Implementar o jogo da velha escrevendo em arquivo. Neste jogo dois jogadores em diferentes computadores devem rodar um aplicativo que fará a leitura de um arquivo compartilhado. O algoritmo deve tratar as etapas do jogo (Setup do aplicativo, entrada na sala, seleção das casas e apresentação do resultado)
- Implementar controle de empréstimo de objetos. Neste software o usuário poderá digitar nomes de objetos que emprestou, a pessoa a quem emprestou e automaticamente o software guarda a data. Deve haver uma opção para gerar relatório dos itens emprestados e opção para marcar a devolução (podendo manter o registro em histórico ou apagando o registro).
- Implementar software gerador de lista de compras. Neste software o usuário poderá digitar itens de supermercado com nome e quantidade. O software escreve num arquivo que poderá depois ser impresso. O software também pode ter função de numa segunda execução já trazer a antiga listagem digitada e permitir que o usuário apenas selecione novas quantidades ou inclua novos itens.
Uso de Interface Gráfica (GTK)
Exemplo de Uso de Interfaces Multiníveis em modo texto
Baseado nas discussões em cboard.cprogramming.com
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
/* Autores: Professores PRG1 - IFSC -SJ */
/******************************************/
/*
Para fins didáticos estão concentradas aqui
todas as funções para exemplificar a elaboração
de menus em modo texto.
Em versões finais o código deve ser organizado em arquivos .h
e .c, agrupando as funções conforme a funcionalidade.
Por exemplo: em um arquivo salas.c colocar as funções
de gerenciamento de sala, com os protótipos no salas.h
*/
/******************************************/
/******************************************/
/* Protótipos de funções - colocar em .h */
/******************************************/
void gerenciar_usuarios();
void gerenciar_salas();
void adicionar_usuario();
void remover_usuario();
void adicionar_sala();
void remover_sala();
/******************************************/
/* Variáveis Globais */
/******************************************/
/* a fazer */
/******************************************/
main()
{
int opcao;
do {
system("clear");
printf("**********************************\n");
printf("Menu Nível 1\n\n");
printf("1. Gererenciar Usuários\n");
printf("2. Gerenciar Salas\n");
printf("3. Sair\n");
printf("**********************************\n");
scanf("%d",&opcao);
switch (opcao) {
case 1: gerenciar_usuarios();
break;
case 2: gerenciar_salas();
break;
case 3: printf("Finalizando Programa...\n");
break;
default: printf("Opção inexistente. Tente novamente...\n");
sleep(1); /* tempo somente para fins de visualização */
break;
}
} while (opcao != 3);
}
/***************************************************/
/* Esta funções deveriam estar em arquivo separado */
/***************************************************/
void gerenciar_usuarios()
{
int opcao;
do {
system("clear");
printf("**********************************\n");
printf("Menu Nível 2 - Gerenciar Usuários\n\n");
printf("1. Adicionar Usuário\n");
printf("2. Remover Usuário\n");
printf("3. Sair do Gerenciar Usuários\n");
printf("**********************************\n");
scanf("%d",&opcao);
switch (opcao) {
case 1: adicionar_usuario();
break;
case 2: remover_usuario();
break;
case 3: printf("Finalizando Gerenciar Usuários...\n");
sleep(1); /* tempo somente para fins de visualização */
break;
default: printf("Opção inexistente. Tente novamente...\n");
sleep(1); /* tempo somente para fins de visualização */
break;
}
} while (opcao != 3);
}
void adicionar_usuario()
{
/* aqui poderia ter um menu nível 3 */
printf("adicionando usuário\n ");
sleep(1);
printf("usuário adicionado\n ");
sleep(1);
}
void remover_usuario()
{
/* aqui poderia ter um menu nível 3 */
printf("removendo usuário\n ");
sleep(1);
printf("usuário removido\n ");
sleep(1);
}
/***************************************************/
/* Esta funções deveriam estar em arquivo separado */
/***************************************************/
void gerenciar_salas()
{
int opcao;
do {
system("clear");
printf("**********************************\n");
printf("Menu Nível 2 - Gerenciar Salas\n\n");
printf("1. Adicionar Sala\n");
printf("2. Remover Sala\n");
printf("3. Sair do Gerenciar Salas\n");
printf("**********************************\n");
scanf("%d",&opcao);
switch (opcao) {
case 1: adicionar_sala();
break;
case 2: remover_sala();
break;
case 3: printf("Finalizando Gerenciar Sala...\n");
sleep(1); /* tempo somente para fins de visualização */
break;
default: printf("Opção inexistente. Tente novamente...\n");
sleep(1); /* tempo somente para fins de visualização */
break;
}
} while (opcao != 3);
}
void adicionar_sala()
{
/* aqui poderia ter um menu nível 3 */
printf("adicionando sala\n ");
sleep(1);
printf("sala adicionada\n ");
sleep(1);
}
void remover_sala()
{
/* aqui poderia ter um menu nível 3 */
printf("removendo sala\n ");
sleep(1);
printf("sala removida\n ");
sleep(1);
}
Gerenciamento de Itens em um Vetor (array)
Um problema recorrente nos projetos é como gerenciar itens que são inseridos e colocados no vetor (array) de tamanho fixo. Em PRG 1 não estamos
preocupados em propor estruturas de dados sofisticadas. Neste sentido, duas possibilidades pode se apresentar:
- REGISTROS LIVRES SEMPRE SEM ENCONTRAM NO FINAL DA TABELA: usar um contador de itens na tabela e sempre inserir um novo item após todos os demais. Neste caso, a remoção de um item implica em deslocar todos os dados posteriores para que ocupem o espaço liberado. (ver https://www.edureka.co/blog/c-program-for-deletion-and-insertion/).
- POSSIBILIDADE DE "LACUNAS LIVRES" NO ARRAY: usar flags indicadores de registro livre ou ocupado na tabela. A inserção de um novo item na tabela deve passar por encontrar uma posição livre, colocando o flag do registro como ocupado. A remoção implica em simplesmente colocar o flag como livre. Um contador de itens pode ser usado para facilitar a identificação caso não exista mais posições livres na tabela.
Exemplo de REGISTRO COM "LACUNAS LIVRES"
- include <stdio.h>
- include <unistd.h>
- include <stdlib.h>
- include <string.h>
/* Autores: Professores PRG1 - IFSC -SJ */
/******************************************/
/*
Para fins didáticos, demonstramos como gerenciar um
vetor de structs marcando registros livres através de um flag
- /
/******************************************/
- define LIVRE 0
- define OCUPADO 1
- define TAM_USER 10
- define TAM_NOME 20
/******************************************/
/* Protótipos de funções - colocar em .h */
/******************************************/
void gerenciar_usuarios();
void adicionar_usuario();
void remover_usuario();
void iniciar_tabela();
int retornar_item_livre_tab_usuarios();
/******************************************/
/* Variáveis Globais */
/******************************************/
/* a fazer */
struct tipo_usuario{
char nome[TAM_NOME];
int idade;
char flag; /* se 0 registro livre - se 1 ocupado */
} tab_usuarios[TAM_USER];
/******************************************/
int main()
{
iniciar_tabela(); /* liberar todos os registros */
gerenciar_usuarios();
}
/*
Esta função inicia a tabela com todos registros livres
Aqui seria uma boa oportunidade para ler dados de um arquivo e iniciar a tabela
- /
void iniciar_tabela()
{
int i;
for (i=0;i<TAM_USER;i++){
tab_usuarios[i].flag=LIVRE;
}
}
/*
retorna -1 se não existe item livre na tabela
ou retorna o índice onde existe item livre
- /
int retornar_item_livre_tab_usuarios()
{
int i=0;
while(i<TAM_USER && tab_usuarios[i].flag==OCUPADO) {
i++;
}
if (i==TAM_USER)
i=-1;
return i;
}
/*
* Esta função insere usuário na tabela. NOTE que ela não testa se o
* usuário já se encontra na mesma... Poderia ser criada uma função para isto...
*/
void adicionar_usuario()
{
int ret;
ret = retornar_item_livre_tab_usuarios();
if (ret==-1)
printf("Não existe espaço\n");
else {
printf("Entre com usuario\n");
scanf("%s", tab_usuarios[ret].nome);
tab_usuarios[ret].flag = OCUPADO;
}
}
void remover_usuario()
{
char buffer[TAM_NOME];
int i=0;
printf("Qual o nome do usuário a remover?\n");
scanf ("%s", buffer);
for (i=0;i<TAM_USER;i++){
if (tab_usuarios[i].flag == OCUPADO && strcmp(buffer, tab_usuarios[i].nome)==0) {
break;
}
}
if (i<TAM_USER) {/* usuário encontrado */
tab_usuarios[i].flag = LIVRE;
printf("usuario %s removido da posição %d\n", tab_usuarios[i].nome, i);
} else {
printf("Usuário não se encontra na tabela\n");
}
}
/***************************************************/
/* Esta funções deveriam estar em arquivo separado */
/***************************************************/
void gerenciar_usuarios()
{
int opcao;
do {
system("clear");
printf("**********************************\n");
printf("Menu Nível 2 - Gerenciar Usuários\n\n");
printf("1. Adicionar Usuário\n");
printf("2. Remover Usuário\n");
printf("3. Sair do Gerenciar Usuários\n");
printf("**********************************\n");
scanf("%d",&opcao);
switch (opcao) {
case 1: adicionar_usuario();
break;
case 2: remover_usuario();
break;
case 3: printf("Finalizando Gerenciar Usuários...\n");
sleep(1); /* tempo somente para fins de visualização */
break;
default: printf("Opção inexistente. Tente novamente...\n");
sleep(1); /* tempo somente para fins de visualização */
break;
}
} while (opcao != 3);
}
</syntaxhighlight>
Links Interessantes