Mudanças entre as edições de "Programação para Redes de Computadores (técnico) (diário 2012-2)"

De MediaWiki do Campus São José
Ir para navegação Ir para pesquisar
 
(33 revisões intermediárias por 2 usuários não estão sendo mostradas)
Linha 1: Linha 1:
 
Endereço encurtado: http://bit.ly/prc20122
 
Endereço encurtado: http://bit.ly/prc20122
 
__TOC__
 
__TOC__
=Avaliação=
+
=Avaliações=
 
São 4 avaliações, uma por mês - sem data pré-estabelecida:
 
São 4 avaliações, uma por mês - sem data pré-estabelecida:
* Outubro
 
 
* Novembro
 
* Novembro
* Dezembro
+
* [[Programação para Redes de Computadores (técnico) (diário 2012-2) - prova 2|Dezembro]]
 +
* [[Programação para Redes de Computadores (técnico) (diário 2012-2) - prova 3|Fevereiro]]
 
* Março
 
* Março
  
O conceito final da disciplina é elaborado da seguinte forma:
+
O [https://docs.google.com/spreadsheet/ccc?key=0AvKQkavuEKVtdE53Ulh3T2NoUE5TX183Ul9aT0JDT0E conceito final] da disciplina é elaborado da seguinte forma:
 
* '''A''': todas as avaliações em '''A'''.
 
* '''A''': todas as avaliações em '''A'''.
 
* '''B''': no máximo 1 '''C'''.
 
* '''B''': no máximo 1 '''C'''.
Linha 15: Linha 15:
  
 
=Aulas=
 
=Aulas=
==01: 08/10==
+
==08/10==
Teste de conhecimento 1: instalação manual do Portugol.
+
* Teste de conhecimento 1: instalação manual do Portugol.
 +
* Sobre a matéria: entendimento de do sistema computacional de Von Neumann.
 +
 
 +
Um número é primo? Em Portugol:
 +
<syntaxhighlight lang=c>
 +
inicio
 +
 
 +
// Entrada de dados
 +
escrever "Por favor, escreva um número inteiro: "
 +
inteiro dividendo
 +
ler dividendo
 +
 
 +
// Processamento
 +
inteiro divisor
 +
inteiro divisores
 +
inteiro resto
 +
divisores <- 0
 +
para divisor de (dividendo - 1) até 2 passo -1
 +
    escrever "."
 +
    resto <- dividendo % divisor
 +
    se resto = 0 então
 +
        divisores <- divisores + divisor
 +
    fimSe
 +
próximo
 +
texto resposta
 +
se divisores > 0 então
 +
    resposta <- " não é primo."
 +
senão
 +
    resposta <- " é primo."
 +
fimSe
 +
 
 +
// Saída de dados
 +
escrever "Calculei que ", dividendo, resposta
 +
 
 +
fim
 +
</syntaxhighlight>
 +
 
 +
E se for perfeito? O que muda no código anterior?
 +
 
 +
==15/10==
 +
* Teste de conhecimento: Matemática básica aplicada.
 +
* Sobre a matéria: tipos de funções ou procedimentos de um programa.
 +
 
 +
Um triângulo é pitagórico?
 +
<syntaxhighlight lang=c>
 +
inicio
 +
 
 +
// Entrada de dados
 +
inteiro a, b, c
 +
escrever "Por favor, digite um número inteiro: "
 +
ler a
 +
escrever "Agora, outro número inteiro: "
 +
ler b
 +
escrever "E, por último, mais um número inteiro: "
 +
ler c
 +
 
 +
// Processamento
 +
inteiro a2
 +
a2 <- potencia(a, 2)
 +
 
 +
inteiro b2c2
 +
b2c2 <- potencia(b, 2) + potencia(c, 2)
 +
 
 +
texto resposta
 +
se (a2 = b2c2) então
 +
    resposta <- "é pitagórico."
 +
senão
 +
    resposta <- "não é pitagórico."
 +
fimSe
 +
 
 +
// Saída de dados
 +
escrever "O triângulo ", resposta
 +
 
 +
fim
 +
</syntaxhighlight>
 +
 
 +
Um número é potência de outro?
 +
<syntaxhighlight lang=c>
 +
inicio
 +
 
 +
//Entrada de dados
 +
texto resposta
 +
inteiro numero
 +
escrever "Por favor, digite um número inteiro: "
 +
ler numero
 +
 
 +
// Processamento
 +
real raizquadrada, resto
 +
raizquadrada <- raiz(numero)
 +
resto <- frac(raizquadrada)
 +
se (resto > 0) então
 +
    resposta <- "não é potência quadrada de outro número inteiro: "
 +
senao
 +
    resposta <- "é potência de: "
 +
fimSe
 +
 
 +
// Saída de dados
 +
escrever resposta, raizquadrada
 +
fim
 +
</syntaxhighlight>
 +
 
 +
Outra forma (alternativa):
 +
<syntaxhighlight lang=c>
 +
inicio
 +
 
 +
// Entrada de dados
 +
inteiro numero
 +
escrever "Por favor, digite um número inteiro: "
 +
ler numero
 +
 
 +
// Processamento
 +
texto resposta
 +
inteiro respostaNumero
 +
real expoente, resultado, rodada
 +
para rodada de 2 ate 5 passo 1
 +
    expoente <- 1 / rodada
 +
    resultado <- potencia(numero, expoente)
 +
    se (frac(resultado) = 0) então
 +
        resposta <- "é potência de "
 +
        respostaNumero <- int(resultado)
 +
    fimSe
 +
próximo
 +
 
 +
// Saída de dados
 +
escrever resposta
 +
escrever respostaNumero
 +
 
 +
fim
 +
</syntaxhighlight>
 +
 
 +
Desenhando uma "caixa" em volta de um número até 9999:
 +
<syntaxhighlight lang=c>
 +
inicio
 +
 
 +
// Entrada de dados
 +
inteiro numero
 +
escrever "Por favor, digite SEMPRE um número inteiro: "
 +
ler numero
 +
 
 +
// Processamento
 +
inteiro colunas, linhaembranco
 +
colunas <- 1
 +
se (numero > 9) então
 +
    colunas <- 2
 +
fimSe
 +
se (numero > 99) então
 +
    colunas <- 3
 +
fimSe
 +
se (numero > 999) então
 +
    colunas <- 4
 +
fimSe
 +
se (numero > 9999) então
 +
    colunas <- 5
 +
fimSe
 +
colunas <- colunas + 4
 +
linhaembranco <- colunas - 2
 +
 
 +
// Saída de dados
 +
inteiro coluna
 +
para coluna de 1 ate colunas passo 1
 +
    escrever "!"
 +
próximo
 +
escrever "\n"
 +
 
 +
escrever "!"
 +
para coluna de 1 ate linhaembranco passo 1
 +
    escrever " "
 +
próximo
 +
escrever "!\n"
 +
 
 +
escrever "! ", numero, " !"
 +
escrever "\n"
 +
 
 +
escrever "!"
 +
para coluna de 1 ate linhaembranco passo 1
 +
    escrever " "
 +
próximo
 +
escrever "!\n"
 +
 
 +
para coluna de 1 ate colunas passo 1
 +
    escrever "!"
 +
próximo
 +
 
 +
fim
 +
</syntaxhighlight>
 +
 
 +
==22/10==
 +
Como "descobrir" que número o usuário digitou? Usando árvore!
 +
<syntaxhighlight lang=c>
 +
inicio
 +
 
 +
// Entrada de dados
 +
inteiro numero
 +
texto resultado
 +
 
 +
escrever "Por favor, digite um número inteiro entre 0 e 7: "
 +
ler numero
 +
 
 +
// Processamento
 +
se numero > 3.5 então
 +
    se numero > 5.5 então
 +
        se numero > 6.5 então
 +
            resultado <- "7"
 +
        senão
 +
            resultado <- "6"
 +
        fimSe
 +
    senão
 +
        se numero > 4.5 então
 +
            resultado <- "5"
 +
        senão
 +
            resultado <- "4"
 +
        fimSe
 +
    fimSe
 +
senão
 +
    se numero > 1.5 então
 +
        se numero > 2.5 então
 +
            resultado <- "3"
 +
        senão
 +
            resultado <- "2"
 +
        fimSe
 +
    senão
 +
        se numero > 0.5 então
 +
            resultado <- "1"
 +
        senão
 +
            resultado <- "0"
 +
        fimSe
 +
    fimSe
 +
fimSe
 +
 
 +
// Saída de dados
 +
escrever "O número é ", resultado , "."
 +
fim
 +
</syntaxhighlight>
 +
... ou caso a caso (meio óbvio, mas estamos ainda no terceiro dia de aula, ok? :):
 +
<syntaxhighlight lang=c>
 +
inicio
 +
 
 +
// Entrada de dados
 +
inteiro numero
 +
texto resultado
 +
 
 +
escrever "Por favor, digite um número inteiro entre 0 e 7: "
 +
ler numero
 +
 
 +
// Processamento
 +
escolhe numero
 +
    caso 9:
 +
        resultado <- "9"
 +
    caso 8:
 +
        resultado <- "8"
 +
    caso 7:
 +
        resultado <- "8"
 +
    caso 6:
 +
        resultado <- "6"
 +
    caso 5:
 +
        resultado <- "5"
 +
    caso 4:
 +
        resultado <- "4"
 +
    caso 3:
 +
        resultado <- "3"
 +
    caso 2:
 +
        resultado <- "2"
 +
    caso 1:
 +
        resultado <- "1"
 +
    defeito:
 +
        resultado <- "0"
 +
fimEscolhe
 +
 
 +
// Saída de dados
 +
escrever "O número é ", resultado , "."
 +
fim
 +
</syntaxhighlight>
 +
 
 +
==29/10==
 +
[[#08/10|Lembra como descobrir se um número é primo]]? Outra forma:
 +
<syntaxhighlight lang=c>
 +
inicio
 +
 
 +
inteiro dividendo
 +
escrever "Por favor, digite um número inteiro: "
 +
ler dividendo
 +
 
 +
inteiro divisores, divisor
 +
real resto
 +
divisores <- 0
 +
para divisor de 2 até (dividendo -1) passo 1
 +
    resto <- dividendo % divisor
 +
    se resto = 0 então
 +
        divisores <- divisores + 1
 +
        escrever "(",divisor,")"
 +
    senão
 +
        escrever "."
 +
    fimSe
 +
próximo
 +
 
 +
escrever "\nO número ", dividendo, " possui ", divisores, " divisores."
 +
fim
 +
</syntaxhighlight>
 +
 
 +
==05/11==
 +
O [[#29/10|mesmo programa do número primo]], agora em Bash:
 +
<syntaxhighlight lang=bash>
 +
#!/bin/bash
 +
 
 +
# Limpa a tela.
 +
clear
 +
 
 +
# Entrada de dados: pede ao usuário um número inteiro.
 +
echo -n "Por favor, digite um número inteiro: "
 +
read dividendo
 +
 
 +
# Assume, inicialmente, que o número é primo.
 +
divisores="0"
 +
 
 +
# Agora, para todos os números compreendidos entre 2 e (número -1)
 +
# é feita a divisão. Se o resto for zero, o número tem divisor e,
 +
# portanto, não é primo.
 +
for divisor in $(seq 2 $(expr ${dividendo} - 1))
 +
do
 +
# Calcula o resto da divisão.
 +
resto=$(echo "${dividendo} % ${divisor}" | bc)
 +
# Verifica se o resto é zero.
 +
if [ "${resto}" = "0" ]
 +
then
 +
# Se for zero, mostra o divisor entre parênteses.
 +
echo -n "(${divisor})"
 +
divisores=$(expr ${divisores} + ${divisor})
 +
else
 +
# Senão, mostra apenas um ponto na tela.
 +
echo -n "."
 +
fi
 +
done
 +
# Apenas formata com uma linha a mais.
 +
echo ""
 +
 
 +
# Verifica o resultado dos divisores.
 +
if [ "${divisores}" -gt "0" ]
 +
then
 +
# Se há pelo menos um divisor, não é primo.
 +
echo "O número não é primo."
 +
else
 +
# Senão, mantém-se como primo.
 +
echo "O número é primo."
 +
fi
 +
</syntaxhighlight>
 +
 
 +
==12/11==
 +
Uma outra forma de resolver a questão 3 da primeira prova:
 +
<syntaxhighlight lang=bash>
 +
#!/bin/bash
 +
 
 +
# Entrada de dados
 +
# Argumento 1: idade da mãe
 +
# Argumento 2: idade do filho mais velho
 +
 
 +
# Processamento
 +
idadeFilhoDoMeio=$(echo "${2} / 2" | bc)
 +
idadeFilhoMaisNovo=$(echo "${idadeFilhoDoMeio} - 3" | bc)
 +
idadeMaeFilhoMaisVelho=$(echo "${1} - ${2}" | bc)
 +
idadeMaeFilhoDoMeio=$(echo "${1} - ${idadeFilhoDoMeio}" | bc)
 +
idadeMaeFilhoMaisNovo=$(echo "${1} - ${idadeFilhoMaisNovo}" | bc)
 +
 
 +
# Saída de dados
 +
echo "A mãe teve filho com ${idadeMaeFilhoMaisVelho}, ${idadeMaeFilhoDoMeio} e ${idadeMaeFilhoMaisNovo} anos."
 +
</syntaxhighlight>
 +
 
 +
==19/11==
 +
Um ''menu'': estrutura de decisão combinada com outra, de repetição:
 +
<syntaxhighlight lang=bash>
 +
#!/bin/bash
 +
 
 +
while [ "${opcao}" != "5" ]
 +
do
 +
clear
 +
echo "Sistema: menu principal"
 +
echo ""
 +
echo "1) Usuários conectados."
 +
echo "2) Processos."
 +
echo "3) Espaço em disco."
 +
echo "4) Configuração da rede."
 +
echo "5) Sair do programa."
 +
echo ""
 +
echo -n "Escolha a sua opção: "
 +
read opcao
 +
case ${opcao} in
 +
"1")
 +
w
 +
;;
 +
"2")
 +
ps
 +
;;
 +
"3")
 +
df -h
 +
;;
 +
"4")
 +
ifconfig
 +
;;
 +
"5")
 +
exit
 +
;;
 +
esac
 +
echo ""
 +
echo -n "Tecle [ENTER] para avançar..."
 +
read enter
 +
done
 +
</syntaxhighlight>
 +
 
 +
Valendo 2 pontos na próxima prova: em Bash, um programa que verifica os números entre 1 e 1000 que são primos e/ou perfeitos. Uma possível resposta:
 +
<syntaxhighlight lang=bash>
 +
#!/bin/bash
 +
 
 +
for numero in $(seq 1 1000)
 +
do
 +
        divisores="0"
 +
        for divisor in $(seq 2 $(echo "${numero} - 1" | bc))
 +
        do
 +
                resto=$(expr ${numero} % ${divisor})
 +
                if [ "${resto}" = "0" ]
 +
                then
 +
                        divisores=$(expr ${divisores} + ${divisor})
 +
                        echo -n "(${divisor})"
 +
                else
 +
                        echo -n "."
 +
                fi
 +
        done
 +
 
 +
        # Mostra os valores
 +
        echo -n "${numero}"
 +
        if [ "${divisores}" = "0" ]
 +
        then
 +
                echo -n "p"
 +
        fi
 +
        if [ "$(expr ${divisores} + 1)" = "${numero}" ]
 +
        then
 +
                echo -n "P"
 +
        fi
 +
        echo ""
 +
done
 +
</syntaxhighlight>
 +
 
 +
==26/11==
 +
Verifica se um valor informado pelo usuário é um endereço IPv4:
 +
<syntaxhighlight lang=bash>
 +
#!/bin/sh
 +
#
 +
# O usuário precisa digitar alguma coisa, qualquer coisa.
 +
# Caso contrário, o programa encerrará por falta de informação.
 +
#
 +
# Verifica se o usuário não digitou um argumento.
 +
# Se sim, o programa será encerrado (exit).
 +
if [ "${1}" = "" ]
 +
then
 +
# Mostra a mensagem de como executar corretamente.
 +
echo "Use: ${0} (endereço IPv4)"
 +
# Fecha o programa.
 +
exit
 +
fi
 +
#
 +
# Separa o primeiro argumento em  4 partes; ou melhor, 4 octetos.
 +
octeto1=$(echo ${1} | cut -d \. -f 1)
 +
octeto2=$(echo ${1} | cut -d \. -f 2)
 +
octeto3=$(echo ${1} | cut -d \. -f 3)
 +
octeto4=$(echo ${1} | cut -d \. -f 4)
 +
#
 +
# Para cada um dos octetos (acima separados), é verificado se
 +
# ele é um número E está entre os limites 0 e 255 (2^8 - 1).
 +
for octeto in ${octeto1} ${octeto2} ${octeto3} ${octeto4}
 +
do
 +
# Realiza uma soma simples.
 +
soma=$(echo "${octeto} - 1" | bc)
 +
# Se a soma falhou ao processar usando o comando "bc",
 +
# ignorando a exceção zero, significa que não é um número inteiro.
 +
if [ "${soma}" = "-1" -a "${octeto}" != "0" ]
 +
then
 +
echo "${octeto} não é número inteiro."
 +
exit
 +
else
 +
# Caso contrário, é um número inteiro.
 +
# Próximo passo: verificar se é um byte a compor um IPv4.
 +
if ! [ "${octeto}" -ge "0" -a "${octeto}" -le "255" ]
 +
then
 +
# Está fora dos limites.
 +
echo "${octeto} é um número qualquer."
 +
exit
 +
fi
 +
fi
 +
done
 +
echo "${1} é um endereço válido."
 +
</syntaxhighlight>
 +
 
 +
==03/12==
 +
Aproveitando o programa da [[#26/11|aula anterior]], verificamos se a configuração de rede está OK, começando pelo arquivo <tt>/etc/resolv.conf</tt>. Como pode-se perceber, a verificação de IP - válido ou não - passa a ser uma função do programa maior:
 +
<syntaxhighlight lang=bash>
 +
#!/bin/sh
 +
#
 +
# 20121203 Ederson Torresini: validador de configuração de rede.
 +
 
 +
# Função IPvalido: valida endereço IP com 4 octetos.
 +
IPvalido(){
 +
# O usuário precisa digitar alguma coisa, qualquer coisa.
 +
# Caso contrário, o programa encerrará por falta de informação.
 +
#
 +
# Verifica se o usuário não digitou um argumento.
 +
if [ "${1}" = "" ]
 +
then
 +
# Mostra a mensagem de como executar corretamente.
 +
echo "Use: ${0} (endereço IPv4)"
 +
else
 +
# Separa o primeiro argumento em  4 partes; ou melhor, 4 octetos.
 +
octeto1=$(echo ${1} | cut -d \. -f 1)
 +
octeto2=$(echo ${1} | cut -d \. -f 2)
 +
octeto3=$(echo ${1} | cut -d \. -f 3)
 +
octeto4=$(echo ${1} | cut -d \. -f 4)
 +
#
 +
# Assume-me, inicialmente, que o endereço está correto;
 +
# ou seja, o 'estado' é "sim".
 +
retorno="sim"
 +
#
 +
# Para cada um dos octetos (acima separados), é verificado se
 +
# ele é um número E está entre os limites 0 e 255 (2^8 - 1).
 +
# Se for, muda o 'estado' para "não".
 +
for octeto in ${octeto1} ${octeto2} ${octeto3} ${octeto4}
 +
do
 +
# Realiza uma soma simples.
 +
soma=$(echo "${octeto} - 1" | bc)
 +
# Se a soma falhou ao processar usando o comando "bc",
 +
# ignorando a exceção zero, significa que
 +
# não é um número inteiro.
 +
if [ "${soma}" = "-1" -a "${octeto}" != "0" ]
 +
then
 +
retorno="não"
 +
else
 +
# Caso contrário, é um número inteiro.
 +
# Próximo passo: verificar os limites de 1 byte (0-255).
 +
if ! [ "${octeto}" -ge "0" -a "${octeto}" -le "255" ]
 +
then
 +
# Está fora dos limites.
 +
retorno="não"
 +
fi
 +
fi
 +
done
 +
fi
 +
echo ${retorno}
 +
}
 +
 
 +
 
 +
# Valida o arquivo de resolução DNS.
 +
ARQUIVO="/etc/resolv.conf"
 +
LINHAS=$(cat ${ARQUIVO} | wc -l)
 +
echo ""
 +
echo "Arquivo ${ARQUIVO}:"
 +
for linha in $(seq 1 ${LINHAS})
 +
do
 +
tipo=$(head -n ${linha} ${ARQUIVO}| tail -n 1 | cut -d \  -f 1)
 +
valor=$(head -n ${linha} ${ARQUIVO} | tail -n 1 | cut -d \  -f 2)
 +
case ${tipo} in
 +
"domain")
 +
if [ "${valor}" = "" ]
 +
then
 +
echo "[ERRO] Domínio (domain) em branco."
 +
else
 +
echo "[ OK ]  Domínio: ${valor}."
 +
fi
 +
;;
 +
"search")
 +
if [ "${valor}" = "" ]
 +
then
 +
echo "[ERRO] Busca (search) em branco."
 +
else
 +
echo "[ OK ]  Domínio de busca: ${valor}."
 +
fi
 +
;;
 +
"nameserver")
 +
if [ "${valor}" = "" -o "${valor}" = "nameserver" ]
 +
then
 +
echo "[ERRO] Servidor DNS com endereço vazio."
 +
else
 +
resposta=$(IPvalido ${valor})
 +
if [ "${resposta}" = "não" ]
 +
then
 +
echo -n "[ERRO] Servidor DNS com endereço "
 +
echo    "IP inválido: ${valor}."
 +
else
 +
echo "[ OK ] Servidor DNS: ${valor}."
 +
fi
 +
fi
 +
;;
 +
*)
 +
echo "[ERRO] Tipo inválido: ${tipo}."
 +
;;
 +
esac
 +
done
 +
 
 +
# Valida o arquivo de configuração de interfaces de rede
 +
ARQUIVO="/etc/network/interfaces"
 +
echo ""
 +
echo "Arquivo ${ARQUIVO}:"
 +
LINHAS=$(cat ${ARQUIVO} | wc -l)
 +
for linha in $(seq 1 ${LINHAS})
 +
do
 +
contexto=$(cat ${ARQUIVO} | head -n ${linha} | tail -n 1)
 +
echo ${contexto} | grep -q '^auto.*' && \
 +
interface=$(echo ${contexto} | cut -d \  -f 2)
 +
# E agora...?
 +
done
 +
</syntaxhighlight>
 +
 
 +
==04/02==
 +
No retorno às aulas, houve uma revisão da matéria com problema para contextualizar: como limpar um disco (quase) cheio? Uma solução é executar, na sequência:
 +
# Identificar a(s) partição(ões) (quase) cheia(s).
 +
# Identificar o(s) diretório(s) com mais espaço ocupado.
 +
# Identificar o(s) arquivo(s) daquele(s) diretório(s) com mais espaço ocupado.
 +
 
 +
Uma proposta do primeiro item:
 +
<syntaxhighlight lang=bash>
 +
#!/bin/bash
 +
 
 +
TEMP="/tmp/.df-h"
 +
 
 +
# Primeira parte do programa: listar as partições
 +
# e deixar o usuário escolher uma
 +
 
 +
mostrar_arquivo_numerado()
 +
{
 +
linhas=$(cat ${1} | wc -l)
 +
for linha in $(seq 1 ${linhas})
 +
do
 +
echo -n "["
 +
echo -n "${linha}"
 +
echo -n "] "
 +
cat ${1} | head -n ${linha} | tail -n 1
 +
done
 +
}
 +
 
 +
listar_particoes()
 +
{
 +
df -h > ${TEMP}
 +
mostrar_arquivo_numerado ${TEMP}
 +
echo -n "Por favor, escolha uma partição: "
 +
read numero
 +
diretorio=$(cat ${TEMP} | head -n ${numero} | tail -n 1 | cut -d % -f 2)
 +
cd ${diretorio}
 +
echo "Agora você está no diretório $(echo ${diretorio})."
 +
}
 +
 
 +
listar_particoes
 +
</syntaxhighlight>
 +
 
 +
==18/02==
 +
Após o [http://www.boston.com/bigpicture/2013/02/carnival_2013.html carnaval], a continuação do programa, agora analisando arquivos e diretórios. Uma sugestão:
 +
<syntaxhighlight lang=bash>
 +
#!/bin/bash
 +
 +
TEMP="/tmp/.df-h"
 +
 +
# Primeira parte do programa: listar as partições
 +
# e deixar o usuário escolher uma
 +
 +
mostrar_arquivo_numerado()
 +
{
 +
linhas=$(cat ${1} | wc -l)
 +
for linha in $(seq 1 ${linhas})
 +
do
 +
echo -n "["
 +
echo -n "${linha}"
 +
echo -n "] "
 +
cat ${1} | head -n ${linha} | tail -n 1
 +
done
 +
}
 +
 +
listar_particoes()
 +
{
 +
df -h > ${TEMP}
 +
mostrar_arquivo_numerado ${TEMP}
 +
echo -n "Por favor, escolha uma partição: "
 +
read numero
 +
diretorio=$(cat ${TEMP} | head -n ${numero} | tail -n 1 | cut -d % -f 2)
 +
cd ${diretorio}
 +
echo "Agora você está no diretório $(echo ${diretorio})."
 +
}
 +
 
 +
listar_diretorios()
 +
{
 +
while true
 +
do
 +
echo ""
 +
echo "[1] Listar os arquivos/diretórios do diretório corrente."
 +
echo "[2] Entrar em sub-diretório."
 +
echo "[3] Voltar ao diretório anterior."
 +
echo -n "Por favor, escolha uma opção: "
 +
read opcao
 +
echo ""
 +
echo "Diretório corrente: $(pwd)"
 +
case ${opcao} in
 +
"1")
 +
echo "Os 5 mais:"
 +
du * 2> /dev/null | sort -n | tail -n 5
 +
;;
 +
"2")
 +
echo -n "Por favor, informe qual o diretório: "
 +
read diretorio
 +
cd ${diretorio}
 +
;;
 +
"3")
 +
cd ..
 +
;;
 +
*)
 +
exit
 +
esac
 +
done
 +
}
 +
 
 +
listar_particoes
 +
listar_diretorios
 +
</syntaxhighlight>
 +
 
 +
=Projeto Integrador=
 +
Serão 3 semanas para o [[Projeto Integrador - 2012.2|Projeto Integrador]].
 +
 
 +
{{Voltar|Programação para Redes de Computadores (técnico) (página)|página principal da disciplina}}

Edição atual tal como às 22h14min de 4 de março de 2013

Endereço encurtado: http://bit.ly/prc20122

Avaliações

São 4 avaliações, uma por mês - sem data pré-estabelecida:

O conceito final da disciplina é elaborado da seguinte forma:

  • A: todas as avaliações em A.
  • B: no máximo 1 C.
  • C: no máximo 1 D, e para cada D no mínimo um B correspondente.
  • D: demais casos.

Aulas

08/10

  • Teste de conhecimento 1: instalação manual do Portugol.
  • Sobre a matéria: entendimento de do sistema computacional de Von Neumann.

Um número é primo? Em Portugol:

inicio

// Entrada de dados
escrever "Por favor, escreva um número inteiro: "
inteiro dividendo
ler dividendo

// Processamento
inteiro divisor
inteiro divisores
inteiro resto
divisores <- 0
para divisor de (dividendo - 1) até 2 passo -1
    escrever "."
    resto <- dividendo % divisor
    se resto = 0 então
        divisores <- divisores + divisor
    fimSe
próximo
texto resposta
se divisores > 0 então
    resposta <- " não é primo."
senão
    resposta <- " é primo."
fimSe

// Saída de dados
escrever "Calculei que ", dividendo, resposta

fim

E se for perfeito? O que muda no código anterior?

15/10

  • Teste de conhecimento: Matemática básica aplicada.
  • Sobre a matéria: tipos de funções ou procedimentos de um programa.

Um triângulo é pitagórico?

inicio

// Entrada de dados
inteiro a, b, c
escrever "Por favor, digite um número inteiro: "
ler a
escrever "Agora, outro número inteiro: "
ler b
escrever "E, por último, mais um número inteiro: "
ler c

// Processamento
inteiro a2
a2 <- potencia(a, 2)

inteiro b2c2
b2c2 <- potencia(b, 2) + potencia(c, 2)

texto resposta
se (a2 = b2c2) então
    resposta <- "é pitagórico."
senão
    resposta <- "não é pitagórico."
fimSe

// Saída de dados
escrever "O triângulo ", resposta

fim

Um número é potência de outro?

inicio

//Entrada de dados
texto resposta
inteiro numero
escrever "Por favor, digite um número inteiro: "
ler numero

// Processamento
real raizquadrada, resto
raizquadrada <- raiz(numero)
resto <- frac(raizquadrada)
se (resto > 0) então
    resposta <- "não é potência quadrada de outro número inteiro: "
senao
    resposta <- "é potência de: "
fimSe

// Saída de dados
escrever resposta, raizquadrada
fim

Outra forma (alternativa):

inicio

// Entrada de dados
inteiro numero
escrever "Por favor, digite um número inteiro: "
ler numero

// Processamento
texto resposta
inteiro respostaNumero
real expoente, resultado, rodada
para rodada de 2 ate 5 passo 1
    expoente <- 1 / rodada
    resultado <- potencia(numero, expoente)
    se (frac(resultado) = 0) então
        resposta <- "é potência de "
        respostaNumero <- int(resultado)
    fimSe
próximo

// Saída de dados
escrever resposta
escrever respostaNumero

fim

Desenhando uma "caixa" em volta de um número até 9999:

inicio

// Entrada de dados
inteiro numero
escrever "Por favor, digite SEMPRE um número inteiro: "
ler numero

// Processamento
inteiro colunas, linhaembranco
colunas <- 1
se (numero > 9) então
    colunas <- 2
fimSe
se (numero > 99) então
    colunas <- 3
fimSe
se (numero > 999) então
    colunas <- 4
fimSe
se (numero > 9999) então
    colunas <- 5
fimSe
colunas <- colunas + 4
linhaembranco <- colunas - 2

// Saída de dados
inteiro coluna
para coluna de 1 ate colunas passo 1
    escrever "!"
próximo
escrever "\n"

escrever "!"
para coluna de 1 ate linhaembranco passo 1
    escrever " "
próximo
escrever "!\n"

escrever "! ", numero, " !"
escrever "\n"

escrever "!"
para coluna de 1 ate linhaembranco passo 1
    escrever " "
próximo
escrever "!\n"

para coluna de 1 ate colunas passo 1
    escrever "!"
próximo

fim

22/10

Como "descobrir" que número o usuário digitou? Usando árvore!

inicio

// Entrada de dados
inteiro numero
texto resultado

escrever "Por favor, digite um número inteiro entre 0 e 7: "
ler numero

// Processamento
se numero > 3.5 então
    se numero > 5.5 então
        se numero > 6.5 então
            resultado <- "7"
        senão
            resultado <- "6"
        fimSe
    senão
        se numero > 4.5 então
            resultado <- "5"
        senão
            resultado <- "4"
        fimSe
    fimSe
senão
    se numero > 1.5 então
        se numero > 2.5 então
            resultado <- "3"
        senão
            resultado <- "2"
        fimSe
    senão
        se numero > 0.5 então
            resultado <- "1"
        senão
            resultado <- "0"
        fimSe
    fimSe
fimSe
  
// Saída de dados
escrever "O número é ", resultado , "."
fim

... ou caso a caso (meio óbvio, mas estamos ainda no terceiro dia de aula, ok? :):

inicio

// Entrada de dados
inteiro numero
texto resultado

escrever "Por favor, digite um número inteiro entre 0 e 7: "
ler numero

// Processamento
escolhe numero
    caso 9:
        resultado <- "9"
    caso 8:
        resultado <- "8"
    caso 7:
        resultado <- "8"
    caso 6:
        resultado <- "6"
    caso 5:
        resultado <- "5"
    caso 4:
        resultado <- "4"
    caso 3:
        resultado <- "3"
    caso 2:
        resultado <- "2"
    caso 1:
        resultado <- "1"
    defeito:
        resultado <- "0"
fimEscolhe
  
// Saída de dados
escrever "O número é ", resultado , "."
fim

29/10

Lembra como descobrir se um número é primo? Outra forma:

inicio

inteiro dividendo
escrever "Por favor, digite um número inteiro: "
ler dividendo

inteiro divisores, divisor
real resto
divisores <- 0
para divisor de 2 até (dividendo -1) passo 1
    resto <- dividendo % divisor
    se resto = 0 então
        divisores <- divisores + 1
        escrever "(",divisor,")"
    senão
        escrever "."
    fimSe
próximo

escrever "\nO número ", dividendo, " possui ", divisores, " divisores."
fim

05/11

O mesmo programa do número primo, agora em Bash:

#!/bin/bash

# Limpa a tela.
clear

# Entrada de dados: pede ao usuário um número inteiro.
echo -n "Por favor, digite um número inteiro: "
read dividendo

# Assume, inicialmente, que o número é primo.
divisores="0"

# Agora, para todos os números compreendidos entre 2 e (número -1)
# é feita a divisão. Se o resto for zero, o número tem divisor e,
# portanto, não é primo.
for divisor in $(seq 2 $(expr ${dividendo} - 1))
do
	# Calcula o resto da divisão.
	resto=$(echo "${dividendo} % ${divisor}" | bc)
	# Verifica se o resto é zero.
	if [ "${resto}" = "0" ]
	then
		# Se for zero, mostra o divisor entre parênteses.
		echo -n "(${divisor})"
		divisores=$(expr ${divisores} + ${divisor})
	else
		# Senão, mostra apenas um ponto na tela.
		echo -n "."
	fi
done
# Apenas formata com uma linha a mais.
echo ""

# Verifica o resultado dos divisores.
if [ "${divisores}" -gt "0" ]
then
	# Se há pelo menos um divisor, não é primo.
	echo "O número não é primo."
else
	# Senão, mantém-se como primo.
	echo "O número é primo."
fi

12/11

Uma outra forma de resolver a questão 3 da primeira prova:

#!/bin/bash

# Entrada de dados
# Argumento 1: idade da mãe
# Argumento 2: idade do filho mais velho

# Processamento
idadeFilhoDoMeio=$(echo "${2} / 2" | bc)
idadeFilhoMaisNovo=$(echo "${idadeFilhoDoMeio} - 3" | bc)
idadeMaeFilhoMaisVelho=$(echo "${1} - ${2}" | bc)
idadeMaeFilhoDoMeio=$(echo "${1} - ${idadeFilhoDoMeio}" | bc)
idadeMaeFilhoMaisNovo=$(echo "${1} - ${idadeFilhoMaisNovo}" | bc)

# Saída de dados
echo "A mãe teve filho com ${idadeMaeFilhoMaisVelho}, ${idadeMaeFilhoDoMeio} e ${idadeMaeFilhoMaisNovo} anos."

19/11

Um menu: estrutura de decisão combinada com outra, de repetição:

#!/bin/bash

while [ "${opcao}" != "5" ]
do
	clear
	echo "Sistema: menu principal"
	echo ""
	echo "1) Usuários conectados."
	echo "2) Processos."
	echo "3) Espaço em disco."
	echo "4) Configuração da rede."
	echo "5) Sair do programa."
	echo ""
	echo -n "Escolha a sua opção: "
	read opcao
	case ${opcao} in
		"1")
			w
			;;
		"2")
			ps
			;;
		"3")
			df -h
			;;
		"4")
			ifconfig
			;;
		"5")
			exit
			;;
	esac
	echo ""
	echo -n "Tecle [ENTER] para avançar..."
	read enter
done

Valendo 2 pontos na próxima prova: em Bash, um programa que verifica os números entre 1 e 1000 que são primos e/ou perfeitos. Uma possível resposta:

#!/bin/bash

for numero in $(seq 1 1000)
do
        divisores="0"
        for divisor in $(seq 2 $(echo "${numero} - 1" | bc))
        do
                resto=$(expr ${numero} % ${divisor})
                if [ "${resto}" = "0" ]
                then
                        divisores=$(expr ${divisores} + ${divisor})
                        echo -n "(${divisor})"
                else
                        echo -n "."
                fi
        done

        # Mostra os valores
        echo -n "${numero}"
        if [ "${divisores}" = "0" ]
        then
                echo -n "p"
        fi
        if [ "$(expr ${divisores} + 1)" = "${numero}" ]
        then
                echo -n "P"
        fi
        echo ""
done

26/11

Verifica se um valor informado pelo usuário é um endereço IPv4:

#!/bin/sh
#
# O usuário precisa digitar alguma coisa, qualquer coisa.
# Caso contrário, o programa encerrará por falta de informação.
#
# Verifica se o usuário não digitou um argumento.
# Se sim, o programa será encerrado (exit).
if [ "${1}" = "" ]
then
	# Mostra a mensagem de como executar corretamente.
	echo "Use: ${0} (endereço IPv4)"
	# Fecha o programa.
	exit
fi
#
# Separa o primeiro argumento em  4 partes; ou melhor, 4 octetos.
octeto1=$(echo ${1} | cut -d \. -f 1)
octeto2=$(echo ${1} | cut -d \. -f 2)
octeto3=$(echo ${1} | cut -d \. -f 3)
octeto4=$(echo ${1} | cut -d \. -f 4)
#
# Para cada um dos octetos (acima separados), é verificado se
# ele é um número E está entre os limites 0 e 255 (2^8 - 1).
for octeto in ${octeto1} ${octeto2} ${octeto3} ${octeto4}
do
	# Realiza uma soma simples.
	soma=$(echo "${octeto} - 1" | bc)
	# Se a soma falhou ao processar usando o comando "bc",
	# ignorando a exceção zero, significa que não é um número inteiro.
	if [ "${soma}" = "-1" -a "${octeto}" != "0" ]
	then
		echo "${octeto} não é número inteiro."
		exit
	else
		# Caso contrário, é um número inteiro.
		# Próximo passo: verificar se é um byte a compor um IPv4.
		if ! [ "${octeto}" -ge "0" -a "${octeto}" -le "255" ]
		then
			# Está fora dos limites.
			echo "${octeto} é um número qualquer."
			exit
		fi
	fi
done
echo "${1} é um endereço válido."

03/12

Aproveitando o programa da aula anterior, verificamos se a configuração de rede está OK, começando pelo arquivo /etc/resolv.conf. Como pode-se perceber, a verificação de IP - válido ou não - passa a ser uma função do programa maior:

#!/bin/sh
#
# 20121203 Ederson Torresini: validador de configuração de rede.

# Função IPvalido: valida endereço IP com 4 octetos.
IPvalido(){
	# O usuário precisa digitar alguma coisa, qualquer coisa.
	# Caso contrário, o programa encerrará por falta de informação.
	#
	# Verifica se o usuário não digitou um argumento.
	if [ "${1}" = "" ]
	then
		# Mostra a mensagem de como executar corretamente.
		echo "Use: ${0} (endereço IPv4)"
	else
		# Separa o primeiro argumento em  4 partes; ou melhor, 4 octetos.
		octeto1=$(echo ${1} | cut -d \. -f 1)
		octeto2=$(echo ${1} | cut -d \. -f 2)
		octeto3=$(echo ${1} | cut -d \. -f 3)
		octeto4=$(echo ${1} | cut -d \. -f 4)
		#
		# Assume-me, inicialmente, que o endereço está correto;
		# ou seja, o 'estado' é "sim".
		retorno="sim"
		#
		# Para cada um dos octetos (acima separados), é verificado se
		# ele é um número E está entre os limites 0 e 255 (2^8 - 1).
		# Se for, muda o 'estado' para "não".
		for octeto in ${octeto1} ${octeto2} ${octeto3} ${octeto4}
		do
			# Realiza uma soma simples.
			soma=$(echo "${octeto} - 1" | bc)
			# Se a soma falhou ao processar usando o comando "bc",
			# ignorando a exceção zero, significa que
			# não é um número inteiro.
			if [ "${soma}" = "-1" -a "${octeto}" != "0" ]
			then
				retorno="não"
			else
				# Caso contrário, é um número inteiro.
				# Próximo passo: verificar os limites de 1 byte (0-255).
				if ! [ "${octeto}" -ge "0" -a "${octeto}" -le "255" ]
				then
					# Está fora dos limites.
					retorno="não"
				fi
			fi
		done
	fi
	echo ${retorno}
}


# Valida o arquivo de resolução DNS.
ARQUIVO="/etc/resolv.conf"
LINHAS=$(cat ${ARQUIVO} | wc -l)
echo ""
echo "Arquivo ${ARQUIVO}:"
for linha in $(seq 1 ${LINHAS})
do
	tipo=$(head -n ${linha} ${ARQUIVO}| tail -n 1 | cut -d \  -f 1)
	valor=$(head -n ${linha} ${ARQUIVO} | tail -n 1 | cut -d \  -f 2)
	case ${tipo} in
		"domain")
			if [ "${valor}" = "" ]
			then
				echo "[ERRO] Domínio (domain) em branco."
			else
				echo "[ OK ]  Domínio: ${valor}."
			fi
			;;
		"search")
			if [ "${valor}" = "" ]
			then
				echo "[ERRO] Busca (search) em branco."
			else
				echo "[ OK ]  Domínio de busca: ${valor}."
			fi
			;;
		"nameserver")
			if [ "${valor}" = "" -o "${valor}" = "nameserver" ]
			then
				echo "[ERRO] Servidor DNS com endereço vazio."
			else
				resposta=$(IPvalido ${valor})
				if [ "${resposta}" = "não" ]
				then
					echo -n "[ERRO] Servidor DNS com endereço "
					echo    "IP inválido: ${valor}."
				else
					echo "[ OK ] Servidor DNS: ${valor}."
				fi
			fi
			;;
		*)
			echo "[ERRO] Tipo inválido: ${tipo}."
			;;
	esac	
done

# Valida o arquivo de configuração de interfaces de rede
ARQUIVO="/etc/network/interfaces"
echo ""
echo "Arquivo ${ARQUIVO}:"
LINHAS=$(cat ${ARQUIVO} | wc -l)
for linha in $(seq 1 ${LINHAS})
do
	contexto=$(cat ${ARQUIVO} | head -n ${linha} | tail -n 1)
	echo ${contexto} | grep -q '^auto.*' && \
		interface=$(echo ${contexto} | cut -d \  -f 2)
	# E agora...?
done

04/02

No retorno às aulas, houve uma revisão da matéria com problema para contextualizar: como limpar um disco (quase) cheio? Uma solução é executar, na sequência:

  1. Identificar a(s) partição(ões) (quase) cheia(s).
  2. Identificar o(s) diretório(s) com mais espaço ocupado.
  3. Identificar o(s) arquivo(s) daquele(s) diretório(s) com mais espaço ocupado.

Uma proposta do primeiro item:

#!/bin/bash

TEMP="/tmp/.df-h"

# Primeira parte do programa: listar as partições
# e deixar o usuário escolher uma

mostrar_arquivo_numerado()
{
	linhas=$(cat ${1} | wc -l)
	for linha in $(seq 1 ${linhas})
	do
		echo -n "["
		echo -n "${linha}"
		echo -n "] "
		cat ${1} | head -n ${linha} | tail -n 1
	done
}

listar_particoes()
{
	df -h > ${TEMP}
	mostrar_arquivo_numerado ${TEMP}
	echo -n "Por favor, escolha uma partição: "
	read numero
	diretorio=$(cat ${TEMP} | head -n ${numero} | tail -n 1	| cut -d % -f 2)
	cd ${diretorio}
	echo "Agora você está no diretório $(echo ${diretorio})."
}

listar_particoes

18/02

Após o carnaval, a continuação do programa, agora analisando arquivos e diretórios. Uma sugestão:

#!/bin/bash
 
TEMP="/tmp/.df-h"
 
# Primeira parte do programa: listar as partições
# e deixar o usuário escolher uma
 
mostrar_arquivo_numerado()
{
	linhas=$(cat ${1} | wc -l)
	for linha in $(seq 1 ${linhas})
	do
		echo -n "["
		echo -n "${linha}"
		echo -n "] "
		cat ${1} | head -n ${linha} | tail -n 1
	done
}
 
listar_particoes()
{
	df -h > ${TEMP}
	mostrar_arquivo_numerado ${TEMP}
	echo -n "Por favor, escolha uma partição: "
	read numero
	diretorio=$(cat ${TEMP} | head -n ${numero} | tail -n 1	| cut -d % -f 2)
	cd ${diretorio}
	echo "Agora você está no diretório $(echo ${diretorio})."
}

listar_diretorios()
{
	while true
	do
		echo ""
		echo "[1] Listar os arquivos/diretórios do diretório corrente."
		echo "[2] Entrar em sub-diretório."
		echo "[3] Voltar ao diretório anterior."
		echo -n "Por favor, escolha uma opção: "
		read opcao
		echo ""
		echo "Diretório corrente: $(pwd)"
		case ${opcao} in
			"1")
				echo "Os 5 mais:"
				du * 2> /dev/null | sort -n | tail -n 5
				;;
			"2")
				echo -n "Por favor, informe qual o diretório: "
				read diretorio
				cd ${diretorio}
				;;
			"3")
				cd ..
				;;
			*)
				exit
		esac
	done
}

listar_particoes
listar_diretorios

Projeto Integrador

Serão 3 semanas para o Projeto Integrador.



Voltar para página principal da disciplina