Línguagens de Programação

Experiências na instalação do ambiente Ruby 1.8.7 on Rails 2.3.6

A configuração deste ambiente foi motivada por se tratar de um ambiente bem parecido com o de uma hospedagem de contratei esses dias no site5.com. Lá eles não tem a versão mais nova do Ruby (1.9.3), e não instalaram ainda por diversos motivos. A principal vantagem é que eles permitem a configuração do Rails 3. E esse era o meu interesse.

Este post tem por objetivo principal mostrar os passos necessários para instalar no Windows 7 32 bits o seguinte ambiente de desenvolvimento:

  • Ruby 1.8.7
  • Rails 2.3.6
  • Mysql Server Community 5.5.25

Comecei assim.

  1. Instalei o Ruby 1.8.7

  2. Instalei o DevKit

  3. Instalei o Rails

    • Abrir o prompt de comando (cmd)
    • Digitar o comando de instalação: gem install rails
  4. Instalei o MySql Community

  5. Instalei a libmysql.dll

    • Baixar o conector neste link: mysql-connector-c-noinstall-6.0.2-win32.zip
    • Extrair os arquivos para uma pasta qualquer: C:\MySqlConnector\ (Sugestão minha)
    • Copiar o arquivo C:\MySqlConnector\lib\libmysql.dll na pasta C:\Ruby187\bin\
  6. Criei o projeto

    • Abrir o prompt de comando
    • Criar a pasta: C:\sites\
    • Navergar até esta página com o seguinte comando: cd C:\sites\
    • Criar o projeto: rails new nome_do_seu_site -d mysql
    • Aguardar a finalização do processo
  7. Configurei os parâmetros de banco de dados

    • Usar as informações desta página para criar um usuário e garantir os privilégios dele
    • Abrir o arquivo: C:\sites\nome_do_seu_site\config\database.yml
    • Informar  usuário e senha
    • Configurar a porta de acesso (port: 3306)
    • Salvar e sair
  8. Configurei o arquivo hosts do Windows

    • Executar o notepad como administrador
    • Abrir o arquivo C:\Windows\System32\drivers\etc\hosts
    • Retirar o # (comentário) da linha: # 127.0.0.1    localhost
    • Salvar e sair
  9. Executar o seu projeto

    • Ser feliz! 😀

Principais problemas enfrentados

SyntaxError on the welcome to rails screen using Pow

  • Causa: Executei o comando (6) de criação da aplicação quando a versão do Ruby instalada era 1.9.3.
  • Solução: Desinstalar todas as versões do Ruby, instalar a versão correta, indicada na seção (1), e por fim, criar um novo projeto.

mysql2 gem compiled for wrong mysql client library

  • Causa: Usei a biblioteca libmysql.dll disponível no site Dll-files.com que está numa versão diferente da exigida pela gem mysql2 do Ruby.
  • Solução: Substitui o arquivo libmysql.dll pela versão oficial, disponível do site do MySql. Para fazer isso, basta executar o passo 5.

Can’t connect to MySQL server on ‘localhost’ (10061) (Mysql2::Error)

  • Causa: A aplicação não consegue encontrar o endereço localhost para se conectar ao banco de dados.
  • Solução: Editar o arquivo hosts e retorar o comentário da linha: # 127.0.0.1   localhost. Para fazer isso, basta executar o passo 8.

Code Smells

É interessante como nunca me ensinaram isso na faculdade. Quando uma pessoa aprende a desenvolver sistemas, também deveria aprender como não desenvolver. Principalmente isto. Assim, você pode focar na solução que deseja desenvolver e saberá se está fazendo algo muito errado. Saberá também quais as melhores práticas de desenvolvimento e, melhor ainda, poderá deixar seu código mais claro, conciso e flexível.
Sabe aquele código que você olha e sente um mau cheiro? Alguns pensam, outros preferem falar em voz baixa: – “Nossa, é um perigo mexer aqui”. Ou pior do que isso, você lê aquele comentário no início da classe: “Só Jesus entende o código abaixo, melhor você cair fora”. Pronto, você agora sente a prensença de um code smell.
Um code smell é uma parte do código fonte do seu programa que poderá causar algum problema. Na literatura existem vários padrões já identificados e difundidos. A partir destes padrões você pode avaliar seu código e verificar se ele está muito mau-cheiroso.
A Industrial Logic disponibilizou uma lista dos padrões de code smells mais conhecidos e das possíveis técnicas de refatoração que você pode utilizar para eliminar estes problemas. Acredito ser uma lista muito boa para consultar naquele momento em que queremos alterar o código fonte e tentar melhorá-lo.

Code smells mais comuns

Alguns autores preferem dividir a lista de code smells comuns em duas partes, os que estão em uma classe e os que envolvem mais de uma classe. Mas como o objetivo do post é ser introdutório, apresentarei uma lista única. São eles:

  • Comentários
  • Código duplicado
  • Método longo
  • Classe muito grande
  • Muitos parâmetros
  • Recurso invejoso
  • Intimidade inaproriada
  • Herança recusada
  • Classe preguiçosa
  • Complexidade inventada
  • Identificadores excessivamente longos
  • Identificadores excessivamente curtos
  • Uso excessivo de literais

Agora tenha muito cuidado quando decidir alterar uma parte do seu sistema que esteja “funcionando”. Tenha testes que garantam o comportamento do seu sistema, pois a chance de você inserir outros erros, ao tentar eliminar os maus cheiros, é grande! Muita calma nessa hora. Refatorações devem ser controladas, objetivas e pequenas para que tenham os resultados desejados.

E melhor do que ficar lendo sobre code smells aqui, é procurar mais informações e ler um pouco mais sobre o assunto. Comece por esta lista de links:

  1. Code smells by Wikipedia
  2. Code smells by Jeff Atwood in Coding Horror
  3. Code smells to refactoring, quick reference by Industrical Logic
  4. Badsmells to refactoring by java.net
  5. Code smells e refactoring by Carlos Duarte

Diferenças entre Gems e RubyGems

O Ruby também tem algo que o torna muito interessante. Este algo se chama RubyGems. Na verdade este é um módulo do Ruby que permite acessar um repositório de bibliotecas para o Ruby, as famosas Gems. Cuidado! Não confunda o RubyGems com as Gems.

  • RubyGems: Módulo para acesso ao repositório de bibliotecas através de comandos no terminal/prompt
  • Gems: Bibliotecas escritas em Ruby e armazenadas no servidor, que podem ser acessadas através dos comandos do RubyGems.

Para quem teve a oportunidades de conhecer o mecanismo de instalação de aplicativos do linux, especialmente no Ubuntu, sabe como é prático. O RubyGems possui um mecanismo muito parecido com o famoso apt-get do Linux. Em outros post detalharei melhor o funcionamento destes comandos.

Estruturas de Dados

O estudo sobre estruturas de dados é algo muito interessante para todos os que gostam de programar ou de procurar boas soluções para resolver problemas computacionais. Mas não é só no meio digital que esses estudos são aplicados. Filas de banco, organogramas, e produtos empilhados em uma prateleira de um supermercado são exemplos de estruturas que possuem regras para que você possa interagir para resolver um problema real.

Podemos fazer um comparativo bem simples entre um caixa de um banco e um processador de um computador. Vejam que, no banco não há caixas suficientes para atender prontamente a todos os que chegam para serem atendidos. Da mesma forma ocorre no computador. Internamente há muitas tarefas a serem realizadas e cada tarefa deve esperar em uma fila para que possa utilizar o processador. A diferença maior está na velocidade em elas são atendidas.

Observe o funcionamento geral de uma fila: chegue, espere no final da fila até você ser atendido. Esse mecanismo resolve o problema de poucos caixas para atender um número grande de clientes no banco. Agora veja uma pilha: coloque item por item, um sobre o outro. Quando for retirar, vá tirando item por item, mas sempre os de cima. Se puxar qualquer item que não seja o de cima, a pilha pode desabar. É com esse propósito que as estruturas de dados são usadas para resolver problemas do mundo real, no meio computacional.

“Na Ciência da computação, uma estrutura de dados é um modo particular de armazenamento e organização de dados em um computador de modo que possam ser usados eficientemente.” [1,2,3] Além disso é usado para estudar “os diversos mecanismos de organização de dados para atender aos diferentes requisitos de processamento”[4], ou seja, “são formas genéricas de se estruturar informação de modo a serem registradas e processadas pelo computador e só adquirem significado quando associadas a um conjunto de operações, que visam, de um modo geral, manipulá-las (algoritmos).” [5]

Bom, o que você deve ter entendido (eu acho) nesse paragrafo anterior é que as estruturas de dados são formas bem definidas de organizar a informação em um computador. Além disso, essas estruturas possuem formas de acesso para que você possa manipular a informação dentro da estrutura. Quando uma pessoa constrói uma estrutura, na verdade ele está definindo meios para que você possa utilizá-la, ou seja, a API da estrutura de dados.

Além desses conceitos, outros conceitos que são relativos à este são os tipos de dados e os tipos abstratos de dados, que podem, de uma maneira geral, se referir a mesma coisa, mas possuem definições e conceitos bem diferentes.

Referencias

  1. Paul E. Black (ed.), Data structure. Dictionary of Algorithms and Data Structures. U.S. National Institute of Standards and Technology, 2004. Versão online .
  2. Data structure. Encyclopædia Britannica (2009) Online
  3. http://pt.wikipedia.org/wiki/Estrutura_de_dados
  4. http://www.dca.fee.unicamp.br/cursos/EA876/apostila/HTML/node10.html
  5. http://www.univasf.edu.br/~marcelo.linder/arquivos_ed1/aulas/aula1.pdf

Lista Encadeada

Uma lista encadeada é um modelo conceitual para a representação de uma sequência de informações armazenadas de forma dinâmica na memória de um computador. Cada informação é armazenada em uma célula ou nó da lista: o primeiro elemento na primeira célula, o segundo na segunda e assim por diante. A estrutura de uma lista encadeada é geralmente representada por uma caixa divida em dois espaços, um para armazenar a informação e o outro para guardar o endereço da próxima caixa.

Existem vários tipos de listas encadeadas disponíveis na literatura, só para citar:

  • Lista encadeada
  • Lista duplamente encadeada
  • Lista circular
  • Pilha
  • Fila
  • Árvores Binárias

A principal diferença entre essas estruturas são as regras e restrições de acesso que elas possuem. Logo, o programador deve analisar as características de cada uma e ver qual se adapta melhor na resolução do problema. Eu poderia apontar aqui um conjunto vasto de vantagens e desvantagens de cada uma, mas isso seria uma discussão um pouco extensa. Vou deixar essa discussão para os próximos posts. Se desejar observar um exemplo de implementação de algumas dessas estruturas, consulte este repositório de código com implementações em C.

Programa que Identifica Palindromes

/* Data: 24/02/2011
 * Programador: Valberto Carneiro
 * Objetivo: Faça um programa que leia uma string do teclado e diga se ela é
   palíndrome. Uma string é palíndrome quando pode ser lida tanto
   de trás pra frente quanto de frente para trás e possui exatamente
   a mesma seqüência de caracteres. Ex.: ASA, SUBI NO ONIBUS.
   Desconsidere os espaços.
   Defina uma função chamada Palindrome que receba uma string como
   parâmetro e retorne um boolean no seu programa.
   Dica: Use a função do exercício 1.
 */

#include<stdio.h>
const int FALSE = 0;
const int TRUE = -1;

int is_palindrome(char *texto) {
  int palindrome = TRUE, tamanho = strlen(texto), y = 0, x = 0;

  //elimina brancos
  while(x < tamanho) {
    if(texto[x] == ' ') for(y=x; y < tamanho; y++) texto[y] = texto[y+1];
    x++;
  }

  tamanho = strlen(texto);

  //compara os caracteres
  for(x = 0; x < tamanho ; x++) {
    //printf("%c = %c\n", texto[x], texto[tamanho-1-x]);
    if (texto[x] != texto[tamanho-1-x]) {
      palindrome = FALSE;
      break;
    }
  }
  return palindrome;
}
int main(){
  char texto[100];
  printf("Escreva uma string para sabermos se ela é palindrome: ");
  gets(texto);
  printf("Resultado: %s", is_palindrome(texto) == FALSE ? "nao" : "sim");
  getch();
}

Strings em C

Introdução

A línguagem C é considerada de nível médio, ou seja, uma linguagem de programação que se aproxima da linguagem humana, mas que também utiliza explicitamente características de “linguagem de máquina”. As Strings em C não trazem abstrações e facilidades que escondem alguns detalhes como:

  • contagem de caracteres
  • tamanho da variável que armazenará a string
  • caractere de terminação entre outros.

Como é uma string em C?

“Uma string de caracteres em C é apenas uma matriz de caracteres” [1], ou seja, para se conseguir armazenar uma string em C, é preciso declarar um array de char com o tamanho máximo que a sua string pode ter.

char variavel[100];

É importante saber que na string acima, você pode armazenar até 99 caracteres. Mas por que? Em C, um dos espaços string guarda o caractere de terminação que serve também para contar o tamanho da string na matriz de caracteres. “As operações de I/O de strings de caracteres (gets, puts, etc.) são implementadas em <stdio.h> e um conjunto de funções de manipulação de strings de caracteres bastante simples é implementado em <string.h>.” [1]

Ler strings em C

Há mais de uma maneira de se ler strings em C, uma delas é utilizando o comando scanf. Veja algumas características:

  • Lê até o primeiro espaço em branco – Você pode digitar uma frase inteira, porém o que a variável armazenará será a primeira sequência de caracteres até o espaço em branco. Use o scanf quando necessitar armazenar strings sem espaços como: logins, senhas, e-mails, urls etc. Abaixo há um exemplo comum de utilização:
  • Não precisa indicar o “&” antes da variável, como se faz quando queremos ler inteiros, por exemplo,  pois o vetor de caracteres já é um endereço de memória que aponta para a primeira posição. Veja o exemplo. [4].
  • Aceita vários tipos de parâmetros para formatar, delimitar ou restringir a leitura de determinados caracteres.
scanf("%s", texto); //lê uma string
scanf("%d", &valor); //lê um inteiro
scanf("%[A-Z]s", frase); //lê apenas caracteres entre A a Z. Para no primeiro caractere fora desse intervalo
scanf("%[^\n]s", frase); //lê qualquer caractere inclusive espaços (igual ao comando gets();)
scanf("%50[^\n]s", frase);// lê apenas 50 caracteres

strcpy

é usado sempre que se deseja copiar uma string em outra. Esse comando é necessário, pois como as duas strings são arrays de caracteres, cada caractere de uma string é copiada para a outra string. Uma por uma. Trabalho árduo.

strcpy(destino, origem);

strcmp

é usado quando se deseja comparar strings. Aqui, o valor de retorno pode ser:

  • zero (0): caso as duas strings sejam iguais
  • negativo (-1): caso a primeira string seja menor que a segunda
  • positivo (1): caso a primeira string seja maior que a segunda

Esse valor usado na comparação para determinação de maior menor ou igual é o código ASCII do caractere comparado. Esse comando varre toda a string comparando caractere  por caractere.

#include
#include

int main() {
  char s1[100],s2[100];
  gets(s1);
  gets(s2);
  if (strcmp(s1,s2)==0)
    printf("igual\n");
  else if (strcmp(s1,s2)<0)
    printf("s1 menor que s2\n");
  else
    printf("s1 maior que s2\n");
  return 0;
}

strlen

esta função retorna o tamanho da sua string. Ele identifica o tamanho da sua string assim que encontra o caractere de terminação, o “contra-barra zero”.

char nome[] = "Maria da Silva";
int s = strlen (nome);
// s conterá o valor 14

strcat

concatena duas strings, adicionando o conteúdo da segunda ao final da primeira, além do terminador (). Note que a primeira string deve ter espaço suficiente para conter a segunda, para que não ocorra um “estouro de buffer” [2].

char nome[50] = "Maria";
char sobrenome[] = " da Silva";
strcat (nome, sobrenome);
// agora nome contém "Maria da Silva"

Exercícios

[3] possui uma excelente lista de exercícios.

Referências

[1] Marshall Brain. String de Caracteres. <http://informatica.hsw.uol.com.br/programacao-em-c35.htm&gt;

[2] ___. Programar em C/Strings. <http://pt.wikibooks.org/wiki/Programar_em_C/Strings&gt;

[3] Unicamp. Algoritmos e Programação de Computadores. <http://www.ic.unicamp.br/~rodolfo/Cursos/mc102/1s2003/exercicios4.html&gt;

[4] Islene Calciolari Garcia. Manipulação de Strings.  <http://www.ic.unicamp.br/~islene/mc102/aula17/aula17.pdf&gt;

Estrutura de um programa em C com loop de reexecução

Revendo alguns conceitos de C e pesquisando nuns sites por aí, encontrei um exeplo que acredito ser pático pra quem quer fazer rapidamente um programa em C.

Aqui é uma estrutura básica, copie e cole no seu arquivo.c, edite da forma como desejar e compile. Pronto, vc terá um programa que só para quando vc quer. 😀

#include<stdio.h>
#include<conio.h>

void main(void) {
  short int rodando;
  do {
    // DIGITE SEU CÓDIGO AQUI.
    printf("\nDigite 1 para manter o programa rodando. ");
    scanf("%d", &amp;rodando);
  } while(rodando==1);
}