Mudanças entre as edições de "AULA Proposta de Projetos - Programação 1 - Engenharia"

De MediaWiki do Campus São José
Ir para navegação Ir para pesquisar
Linha 411: Linha 411:
  
 
*[https://regex101.com Expressões regulares]
 
*[https://regex101.com Expressões regulares]
 +
*[https://opensource.com/article/19/5/how-write-good-c-main-function Como construir uma boa função main.c]

Edição das 07h58min de 28 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

  1. Apresentar a proposta de projeto ao professor. Construir um pequeno documento com o escopo do projeto contendo:
    1. Título do Projeto
    2. Integrantes da Equipe
    3. Descrição do que o programa vai executar (3 parágrafos)
    4. 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.
      1. Cenário 1: Cadastro de aluno - Ator principal: Bibliotecário
        1. Através de uma interface o bibliotecário seleciona inserção de alunos.
        2. Entra com o nome do aluno
        3. Entra coma a matrícula.
        4. Finaliza o registro.
      2. Cenário 2: Insere livro...
      3. Cenário 3:
    5. Descrição das principais estruturas de dados do programa.
      1. 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>

    1. Proposta de cronograma (defesa final 4/5 de 12): Exemplo:
      1. Semana 1 (de 17 a 23/11): Implementação dos cenários 1 e 2
      2. Semana 2 (de 24 a 30/11): Implementação dos cenários 3 e 4
      3. 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);
}

Links Interessantes