segunda-feira, 3 de dezembro de 2012

Spring MVC 3 - parte 4 - Mapeando Requisições

Usa-se @RequestMapping para mapear URLs para uma classe ou um método tratador particular. O seguinte exemplo apresenta a aplicação Petcare, que é uma das aplicações de exemplo da Spring:
   @Controller
   @RequestMapping("/appointments")
   public class AppointmentsController {

      private final AppointmentBook appointmentBook;

      @Autowired
      public AppointmentsController(AppointmentBook appointmentBook) {
         this.appointmentBook = appointmentBook;
      }

      @RequestMapping(method = RequestMethod.GET)
      public Map<String, Appointment> get() {
         return appointmentBook.getAppointmentsForToday();
      }

      @RequestMapping(value="/{day}", method = RequestMethod.GET)
      public Map<String, Appointment> getForDay(
         @PathVariable @DateTimeFormat(iso=ISO.DATE) Date day, 
         Model model {
          return appointmentBook.getAppointmentsForDay(day);
      }

      @RequestMapping(value="/new", method = RequestMethod.GET)
      public AppointmentForm getNewForm() {
         return new AppointmentForm();
      }

      @RequestMapping(method = RequestMethod.POST)
      public String add(@Valid AppointmentForm appointment, 
         BindingResult result) {
         if (result.hasErrors()) {
            return "appointments/new";
         }

         appointmentBook.addAppointment(appointment);
         return "redirect:/appointments";
      }
   }  
Neste exemplo, @RequestMapping é usada em vários lugares. Primeiro, é usada em nível de classe, indicando que todos os métodos tratadores neste controle são relativos ao path /appointments. O método get() tem um melhor refinamento: aceita requisições do tipo GET, quer dizer, qualquer HTTP GET para /appointments invocará este método. O método add() é similar: aceita requisições do tipo POST, quer dizer, qualquer HTTP POST para /appointments invocará este método. O método getNewForm() combina a definição de método HTTP e path, então, qualquer requisição do tipo GET para appointments/new será tratada por esse método. O método getForDay() apresenta outro uso para @RequestMapping e será detalhado posteriormente.

quarta-feira, 14 de novembro de 2012

Spring MVC 3 - Índice

Estou escrevendo uma série de artigos sobre o framework Web Spring MVC 3. 
Estarei disponbilizando esses artigos conforme for escrevendo.
Até a parte 3 já está disponível no blog.
Espero que seja útil para a comunidade de desenvolvedores. 

  • Parte 1 - Introdução - clique aqui para leitura
  • Parte 2 - Configuração - clique aqui para leitura
  • Parte 3 - Controladores - clique aqui para leitura
  • Parte 4 - Mapeando Requisições - clique aqui para leitura
  • Parte 5 - Views
  • Parte 6 - Interceptando Requisições
  • Parte 7 - Internacionalizando a Aplicação
  • Parte 8 - View Resolver
  • Parte 9 - Exceções
  • Parte 10 - Tratando Formulários
  • Parte 11 - Bean Validation
  • Spring MVC 3 - Parte 3 - Controladores

    Uma classe de Controle do Spring MVC possui métodos tratadores para requisições de usuário. Utiliza a anotação de classe @Controller e possui a anotação @RequestMapping que pode ser aplicada em nível de classe ou método. Em nível de classe mapeia uma URL para a classe de controle e, então, um método particular HTTP mapeia para cada método do controle. Controle interpreta a entrada do usuário e a transorma dentro de um modelo que é apresentado ao usuário através de uma view.
        package ... ;
    
        ...
        import org.springframework.stereotype.Controller;
        import org.springframework.web.bind.annotation.RequestMapping;
        import org.springframework.web.bind.annotation.RequestMethod;
        import org.springframework.web.servlet.ModelAndView;
        import org.springframework.ui.Model;
    
        @Controller
        @RequestMapping("/welcome")
        public class WelcomeController {
        
            @RequestMapping(method = RequestMethod.GET)
            public String welcome(Model model) {
                Date today = new Date();
                model.addAttribute("today", today);
                return "welcome";
           }
        }
    
    
    O exemplo acima é um controle do Spring MVC, mapeado com a anotação @Controller. O primeiro @RequestMapping é usado em nível de classe para especificar que qualquer requisição recebida para /welcome será atendida por este controle. O segundo @RequestMapping é usado em nível de método e, nesse caso, atende qualquer requisição HTTP GET. No caso, este método é o método default para este controle e toda requisição recebida para /welcome será direcionada para o método welcome(Model model). No caso deste controle, se nenhum método HTTP GET default fosse declarado, a exceção ServletException seria lançada. Uma variação deste comportamento seria declarar ambos os valores no método:
        @Controller
        public class WelcomeController {
    
            @RequestMapping(value = "/welcome", method=RequestMethod.GET)
            public String welcome(Model model) {
            ...
    
    
    Um outro exemplo de método tratador no controle pode ser visto abaixo. Ele recebe todas as requisições HTTP POST enviadas para o controle, normalmente enviadas pelo usuário após submeter um HTML form, além de dois parâmetros de entrada. O primeiro é @RequestParam("courtName") String courtName, usado para extrair o parâmetro de requisição chamado courtName. O segundo parâmetro é Model model, usado para definir um objeto que podemos passar dados e retornar para a view. Na execução do método, uma variável chamada reservations é adicionada ao objeto Model, tornando-se disponível para retornar a visão para ser apresentada ao usuário e o método finaliza com um retorno para a view reservationQuery, indicada pela string de retorno.
        
        @RequestMapping(method = RequestMethod.POST)
        public String sumbitForm(@RequestParam("courtName") String courtName, Model model) {
            List reservations = java.util.Collections.emptyList();
            if (courtName != null) {
                reservations = reservationService.query(courtName);
           }
           model.addAttribute("reservations", reservations);
           return "reservationQuery";
        }
    
    
    Para habilitar auto detecção das classes de controle anotadas na sua aplicação, é necessário configurar o contexto do Spring informando o pacote base das classes de controle, conforme pode ser visto ne exemplo abaixo:
     
       <?xml version="1.0" encoding="UTF-8"?>
       <beans xmlns="http://www.springframework.org/schema/beans"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns:p="http://www.springframework.org/schema/p"
            xmlns:context="http://www.springframework.org/schema/context"
            xsi:schemaLocation="
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    
            <context:component-scan base-package=
                  "org.springframework.samples.petclinic.web"/>
    
            <!-- ... -->
       </beans>
    

    Spring MVC 3 - Parte 2 - Configurações

    Usando Maven, é preciso informar as dependências abaixo para desenvolver uma aplicação com Spring MVC:
        
            org.springframework
            spring-webmvc
            ${spring.version}
        
        
            org.springframework
            spring-web
            ${spring.version}
        
    
    É necessário configurar o servlet do Spring MVC no arquivo web.xml:
        
            ...
       
            
                aplicacao
                
                    org.springframework.web.servlet.DispatcherServlet
                
                1
            
            
                aplicacao
                /
            
        
    
    É necessário criar um arquivo xml do Spring para carregar as configurações para o Spring MVC. Por default, esse arquivo terá o nome do servlet, informando no arquivo web.xml, acrescido de -servlet.xml. Usando como exemplo a configuração do web.xml acima, o nome do arquivo seria aplicacao-servlet.xml. É possível especificar um outro nome utilizando o parâmetro contextConfigLocation no arquivo web.xml. Para carregar outros arquivos de configuração do Spring, ao lado do arquivo do Spring MVC, neste caso aplicacao-servlet.xml, é necessário definir o listener ContextLoaderListener no web.xml. Por default, ele carrega o arquivo /WEB-INF/applicationContext.xml, mas pode-se especificar outros arquivos, usando o parâmetro contextConfigLocation. Os arquivos de configuração devem ser separados por vírgula ou espaços.
        
            ...
    
            
                contextConfigLocation
                /WEB-INF/aplicacao-service.xml
            
            
                
                    org.springframework.web.context.ContextLoaderListener
                
            
        
    
    É necessário configurar a aplicação para escanear a presença de anotações nas classes de controle do Spring MVC, como @Controller e @RequestMapping. Para isso, é preciso habilitar o Spring para detectar as anotações através do elemento informando o pacote base da aplicação, que será a raiz para procurar pelas anotações. Em adição, a anotação @RequestMapping mapeia requisições URLs para classes controladoras e respectivos métodos. Por isso, é preciso registrar também as classes DefaultAnnotationHandlerMapping e AnnotationMethodHandlerAdapter. A primeira, para processar requisições em nível de classe e a segunda, em nível de método. A seguir, encontra-se um exemplo dessas configurações, que podem ser incluídas no arquivo de configuração do Spring MVC.
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/
                                               spring-context-3.0.xsd">
    
           <context:component-scan
                base-package="com.apress.springrecipes.court.web" />
            
           <bean class="org.springframework.web.servlet.mvc.annotation.
                                   DefaultAnnotationHandlerMapping" />
    
           <bean class="org.springframework.web.servlet.mvc.annotation.
                                    AnnotationMethodHandlerAdapter" />
    </beans>
    

    terça-feira, 13 de novembro de 2012

    Spring MVC 3 - Parte 1 - Introdução

    O componente central do Spring MVC é um controlador (controller) que é um servlet configurado no web.xml chamado Dispatcher Servlet. Este servlet segue o padrão Front Controller. Quando uma requisição web é enviada para uma aplicação Spring MVC, um controlador recebe esta requisição e faz o tratamento necessário. Para se definir uma classe de controle, a classe precisa ser anotada com @Controlller. Quando esta classe recebe uma requisição, ela procura por um apropriado método para tratar esta requisição. Então é necessário mapear cada requisição para um método da classe de controle, usando um ou mais mapeamentos. Para fazer isso, os métodos são decorados com a anotação @RequestMapping. A assinatura desses métodos pode ter qualquer nome, uma variedade de argumentos e pode ter qualquer um de uma série de retornos, como exemplo, String ou void. A seguir encontra-se uma lista parcial de argumentos válidos para os métodos do controlador:
    • HttpServletRequest ou HttpServleResponse
    • Parâmetros de Requisição anotados com @RequestParam
    • Atributos de Modelo anotados com @ModelAttribute
    • Cookies incluídos na requisição anotados com @CookieValue
    • Map ou ModelMap, para o método adicionar atributos ao modelo
    • Errors ou BindingResult, para o método fazer o “binding” e validar o resultado de de objetos
    • SessionStatus, para notificações de completude de processamento de sessão
    Depois que o método do controle finaliza seu processamento, ele delega o controle para a view, que é representada pelo valor de retorno do método, no caso uma String. Esse valor de retorno é um valor lógico (ex: user ou report) e não uma implementação da view (ex: user.jsp ou report.pdf). Se o retorno é void, um valor default lógico é usado. Os objetos dos argumentos do método recebidos como parâmetros, como por exemplo um Map ou SessionStatus estarão acessíveis na view, tendo sido modificados ou não pelo método do controlador. Um bean do Spring do tipo ViewResolver, configurado na aplicação, resolve o valor lógico de retorno do método para uma implementação.

    sexta-feira, 17 de agosto de 2012

    Os filhos querem colo

    Na sexta feira, dia 12 de maio 2006, uma amiga do meu filho, a Isa, pulou do 8º andar do prédio onde morava em Joinville -SC. Tinha acabado de almoçar, estava com o uniforme do colégio Bom Jesus, e a mochila nas costas, o que indicava que iria retornar ao colégio, pois nas quartas e sextas eles têm aula o dia todo. Foi um choque para todos os colegas! Aí vem a pergunta: Por quê? Ela tinha apenas 15 anos. Que problemas uma menina de 15 anos pode ter? Fiz esta pergunta ao meu filho, e a resposta me deixou chocada... Ele me disse: Mãe, eu acho que era falta de colo! Questionei: Como assim? E ele me disse: Hoje em dia, os pais trabalham praticamente o dia todo, sempre com a mesma desculpa de que querem dar aos filhos tudo aquilo que nunca tiveram e, na maioria das vezes, eles estão conseguindo. Eles estão dando um estudo no melhor colégio, cursos de idiomas, dinheiro pra gastar no shopping, um computador de última geração pro filho ficar enfiado em casa durante o pouco tempo livre que sobra, roupas, tênis, celular, tudo muito caro, etc... E sempre cobrando da gente boas notas, pois estão investindo muito... Não era melhor então ter comprado ações, depositado na poupança, ou sei lá onde? Na maioria das vezes, os pais não têm mais tempo para os filhos, não conversam mais, não fazem um carinho... Quando a gente chega em casa, o que mais quer é o colo da mãe quando vai mal nas provas, ou quando acontece alguma coisa ruim. Por que você acha que hoje os adolescentes são quase todos revoltados? Na maioria das vezes, eles estão querendo chamar a atenção, ser notados, só que no lugar errado e de forma errada: na rua e com violência. Espero que a morte da Isa não tenha sido em vão, pois quem sabe desta forma muitos pais vão repensar suas atitudes para com seus filhos! Não somos máquinas, não somos todos iguais. Não é porque o filho da vizinha tira só dez que todos nós vamos tirar 10... Talvez, nem todos nós queiramos falar inglês! Depois de me falar tudo isso em prantos, ele me abraçou e disse, olhando nos meus olhos: Mãe, obrigado por você estar tão presente em minha vida, por eu poder contar sempre com você nos bons e nos maus momentos... Obrigado, também, pelas broncas, pois sei que mereço. O tempo e o amor são os melhores investimentos que vocês fazem pelos seus filhos, o resto é conseqüência. (Texto anônimo, circulando na Internet)

    quinta-feira, 3 de novembro de 2011

    Funções em Python

    Funções em Python são definidas com a palavra def, seguidas pelo seu nome, além de parênteses. Dentro dos parênteses, existe a possibilidade de se incluir uma lista de parâmetros. No início do corpo da função, é uma boa prática fazer um comentário, chamado de docstrings. Usando docstrings, ferramentas podem utilizar o comentário para a documentação do sistema. Funções em Python podem ter a opção de retornar algum valor, uma lista, um objeto, etc ou podem não retornar nada, se portando como um procedimento.
    >>> def fib(n): 
    ...     """Imprime uma série de Fibonacci para o parâmetro n."""
    ...     a, b = 0, 1
    ...     while a < n:
    ...         print a,
    ...         a, b = b, a+b
    ...
    >>> # Chamando a função
    ... fib(2000)
    
    >>> def fib2(n): 
    ...     """Returnondo uma lista contendo uma série de Fibonacci para n."""
    ...     result = []
    ...     a, b = 0, 1
    ...     while a < n:
    ...         result.append(a)   
    ...         a, b = b, a+b
    ...     return result
    ...
    >>> f100 = fib2(100) 
    
    Podemos ter um variável número de argumentos na lista, com valores default ou não. Para valores default, não existe a necessidade de se passar esse valor para a função. Além disso, não é necessário passar os argumentos para a função na ordem dos parâmetros, desde que utilizemos um par nome=valor.
    >>> def funcaoComArgumento(arg1, arg2="valor_default", arg3="valor_default")
           ...
    
          #chamadas a função
          funcaoComArgumento(100)
          funcaoComArgumento(arg2="qualquercoisa", arg1=100)
          # ocorrerá um erro para a chamada a seguir pois não existe um valor default para arg1 
          funcaoComArgumento(arg2="qualquercoisa")  
    
    Finalizando, parâmetros com a forma **name recebem um dicionário e com a forma *name recebem tuplas. Os parâmetros que recebem dicionários devem, obrigatoriamente serem os últimos parâmetros da função.
    def cheeseshop(kind, *arguments, **keywords):
        print "-- Do you have any", kind, "?"
        print "-- I'm sorry, we're all out of", kind
        for arg in arguments:
            print arg
        print "-" * 40
        keys = sorted(keywords.keys())
        for kw in keys:
            print kw, ":", keywords[kw]
    
    cheeseshop("Limburger", "It's very runny, sir.",
               "It's really very, VERY runny, sir.",
               shopkeeper='Michael Palin',
               client="John Cleese",
               sketch="Cheese Shop Sketch")
    
    -- Do you have any Limburger ?
    -- I'm sorry, we're all out of Limburger
    It's very runny, sir.
    It's really very, VERY runny, sir.
    ----------------------------------------
    client : John Cleese
    shopkeeper : Michael Palin
    sketch : Cheese Shop Sketch
    

    sábado, 22 de outubro de 2011

    Mais Estruturas de Controle através de exemplos

    Como estruturas de controle são praticamente parecidas nas linguagens, abaixo encontram-se exemplos e pequenas observações sobre o assunto:

    1 - If:
    >>> x = int(raw_input("Please enter an integer: "))
    Please enter an integer: 42
    >>> if x < 0:
    ...      x = 0
    ...      print 'Negative changed to zero'
    ... elif x == 0:
    ...      print 'Zero'
    ... elif x == 1:
    ...      print 'Single'
    ... else:
    ...      print 'More'
    ...
    More
    
    2 - For:
    >>> a = ['cat', 'window', 'defenestrate']
    >>> for x in a:
    ...     print x, len(x)
    
    Abaixo, um exemplo que altera a lista enquanto ocorre o loop:
    >>> a = ['cat', 'window', 'defenestrate'] 
    ...for x in a[:]: # utilizando uma cópia da lista
    ...    if len(x) > 6: a.insert(0, x)
    ...
    >>> a
    ['defenestrate', 'cat', 'window', 'defenestrate']
    
    3 - Função Range:

    Itera sobre uma sequência de números.
    >>> range(5, 10)
    [5, 6, 7, 8, 9]
    >>> range(0, 10, 3) # entre 0 e 10, de 3 em 3
    [0, 3, 6, 9]
    >>> range(-10, -100, -30) # entre -10 e -100, de -30 em -30
    [-10, -40, -70]
    
    Utilizando a função em um for:
    >>> a = ['Mary', 'had', 'a', 'little', 'lamb']
    >>> for i in range(len(a)):
    ...     print i, a[i]
    
    4 - Break e Else:
    >>> for n in range(2, 10):
    ...     for x in range(2, n):
    ...         if n % x == 0:
    ...             print n, 'equals', x, '*', n/x
    ...             break
    ...     else:
    ...         print n, 'is a prime number'
    .
    5 - Continue:
    >>> for n in range(2, 10):
    ...     for x in range(2, n):
    ...         if n % x == 0:
    ...             continue'
    .
    6 - Pass:
    >>> while True:
    ...     pass  # aguarda por interrupção  (Ctrl+C)
    ...
    >>> class MyEmptyClass:
    ...     pass
    
    No próximo post, falaremos sobre funções em Python.

    Até lá.

    quinta-feira, 20 de outubro de 2011

    Listas e Estruturas de Controle em Python

    Python possui algumas estruturas usadas para agrupar tipos e List é o mais versátil deles, não sendo necessário que uma lista possua tipos iguais.

    >>> a = ['spam', 'eggs', 100, 1234]
    >>> a
    ['spam', 'eggs', 100, 1234]
    

    Como strings, listas também utilizam índices, porém, são mutáveis:

    >>> a[0]
    'spam'
    >>> a[3]
    1234
    >>> a[-2]
    100
    >>> a[1:-1]
    ['eggs', 100]
    >>> a[:2] + ['bacon', 2*2]
    ['spam', 'eggs', 'bacon', 4]
    >>> 3*a[:3] + ['Boo!']
    ['spam', 'eggs', 100, 'spam', 'eggs', 100, 'spam', 'eggs', 100, 'Boo!']
    >>> a[:]
    ['spam', 'eggs', 100, 1234]
    >>> a[2] = a[2] + 23
    >>> a
    ['spam', 'eggs', 123, 1234]
    >>> # Substituir alguns itens:
    ... a[0:2] = [1, 12]
    >>> a
    [1, 12, 123, 1234]
    >>> # Remover alguns:
    ... a[0:2] = []
    >>> a
    [123, 1234]
    >>> # Inserir alguns:
    ... a[1:1] = ['bletch', 'xyzzy']
    >>> a
    [123, 'bletch', 'xyzzy', 1234]
    >>> # Inserir a própria lista:
    >>> a[:0] = a
    >>> a
    [123, 'bletch', 'xyzzy', 1234, 123, 'bletch', 'xyzzy', 1234]
    >>> # Limpar a lista:
    >>> a[:] = []
    >>> a
    []
    

    Também temos a funão len():

    >>> a = ['a', 'b', 'c', 'd']
    >>> len(a)
    4
    

    Para mostrar como listas em Python é versátil, também podemos criar listas contendo outras listas:

    >>> q = [2, 3]
    >>> p = [1, q, 4]
    >>> len(p)
    3
    >>> p[1]
    [2, 3]
    >>> p[1][0]
    2
    >>> p[1].append('xtra')     # See section 5.1
    >>> p
    [1, [2, 3, 'xtra'], 4]
    >>> q
    [2, 3, 'xtra']
    

    Fluxo de Controle

    >>> # Fibonacci series:
    ... # the sum of two elements defines the next
    ... a, b = 0, 1
    >>> while a < 10:
    ...     print a
    ...     a, b = b, a+b
    
    A primeira estrutura que veremos é o While.
    Em Python, zero é considerado como falso e outros números é considerado verdadeiro. A condição a ser testada pelo loop pode ser também uma string ou uma lista, qualquer sequência. Podemos utilizar <, >, ==, <=, >=, != para realizar o teste da condição.
    A primeira linha do loop, que é a linha de teste, é finalizado com dois pontos(:). O corpo do loop é identado e pode-se utilizar tab ou espaços para identar a linha. Identação em Python é a forma que o ele possui para agrupar comandos. As linhas dentro do bloco precisam ficar identadas com o mesmo número de espaços ou tabs e o Python é rígico com esta questão. Quando utilizamos o ambiente interativo, é necessário uma linha em branco para indicar o fim do corpo do loop. O comando print imprime o valor na saída padrão. Strings são impressas sem aspas e espaço é inserido entre items:
    >>> i = 256*256
    >>> print 'The value of i is', i
    The value of i is 65536
    
    A vírgula no final do comando print evita imprimir em uma nova linha:
    >>> a, b = 0, 1
    >>> while a < 1000:
    ...     print a,
    ...     a, b = b, a+b
    ...
    1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
    

    No próximo post, continuaremos falando sobre outras estruturas de controle.

    Primeiros Passos em Python

    Para início, é muito interessante utilizar uma shell para invocar o interpretador do Python e digitar alguns comandos básicos da linguagem. Para isso, apenas se faz necessário digitar, na shell, o comando python. Como no Linux, o Python costuma vir instalado e configurado, não é necessário fazer nada. Porém, se estiver usando o Windows, é importante colocar o caminho da pasta onde o Python foi instalado no path.

    Para trabalhar com números, temos os operadores +, -, *, /, como em qualquer outra linguagem.
    Podemos atribuir um número a uma variável utilizando o sinal = e podemos associar um número a várias variáveis ao mesmo tempo.

    >>> width = 20
    >>> height = 5*9
    >>> width * height
    900
    
    >>> x = y = z = 0  # Zero x, y and z
    >>> x
    0
    >>> y
    0
    >>> z
    0
    

    Assim como números, temos as strings:

    >>> 'spam eggs'
    'spam eggs'
    >>> 'doesn\'t'
    "doesn't"
    >>> "doesn't"
    "doesn't"
    >>> '"Yes," he said.'
    '"Yes," he said.'
    >>> "\"Yes,\" he said."
    '"Yes," he said.'
    >>> '"Isn\'t," she said.'
    '"Isn\'t," she said.'
    

    Podemos ter strings por mais de uma linha de duas formas:

    hello = "This is a rather long string containing\n\
    several lines of text just as you would do in C.\n\
        Note that whitespace at the beginning of the line is\
     significant."
    
    print hello
    
    print """
    Usage: thingy [OPTIONS]
         -h                        Display this usage message
         -H hostname               Hostname to connect to
    """
    

    Strings podem ser contatenadas com o operador + e repetida com *. Podemos trabalhar com Strings utilizando índices:

    >>> word = 'Help' + 'A'
    >>> word
    'HelpA'
    >>> '(' + word*5 + ')'
    '(helpahelpahelpahelpahelpa)'
    
    >>> word[4]
    'A'
    >>> word[0:2]
    'He'
    >>> word[2:4]
    'lp'
    
    >>> word[:2]    # Os primeiros dois caracteres
    'He'
    >>> word[2:]    # Tudo menos os primeiros dois caracteres
    'lpA'
    
    >>> word[-1]     # O último caracter
    'A'
    >>> word[-2]     # O penúltimo caracter
    'p'
    >>> word[-2:]    # Os últimos dois caracteres
    'pA'
    >>> word[:-2]    # Tudo menos os dois caracteres
    'Hel'
    

    Também temos a função len():

    >>> s = 'supercalifragilisticexpialidocious'
    >>> len(s)
    

    No próximo post, estarei falando sobre estruturas de controle em Python.

    sábado, 5 de fevereiro de 2011

    O que é Ruby on Rails e Instalação

    Ruby on Rails é um framewok que é fácil para desenvolver, fazer deploy e manter aplicações web.

    Tem sido escolhido por muitos para desenvolvimentos para a Web 2.0.

    Rails implementa uma arquitetura MVC, cria automaticamente stubs para testes, é fácil para testar aplicações.

    Rails é escrito em Ruby, uma linguagem moderna, de scripts e OO. Em Ruby, pode-se expressar idéias naturalmente e com um código limpo. Porém, Rails estendeu a linguagem, para uma programação ainda mais fácil.

    Um exemplo de uma classe Modelo chamada Project.

    class Project < ActiveRecord::Base
      belongs_to :portfolio
      has_one :project_manager
      has_many :milestones
      has_many :deliverables, :through => :milestones
    
      validates :name, :description, :presence => true
      validates :non_disclosure_agreement, :acceptance => true
      validates :short_name, :uniqueness => true
    end
    

    A filosofia do Rails é: convenção sobre configuração, DRY (Don't repeat yourself) e Rest.

    Além disso, Rails é Agil. Ele segue as práticas dessa metodologia.

    Instalação

    Aqui será explicado como instalar o Rails no Ubuntu 10.10, que possui um pouco mais de detalhes. Para instalar no Windows, siga as orientações encontradas em http://rubyonrails.org/download.

    execute os comandos abaixo no terminal:

    sudo apt-get install build-essential libopenssl-ruby libfcgi-dev
    sudo apt-get install ruby irb rubygems ruby1.8-dev
    sudo apt-get install sqlite3 libsqlite3-dev
    sudo gem install rails
    sudo gem install sqlite3-ruby
    

    A versão do Rails que está executando por default pode ser verificada com o comando:

    rails -version
    

    Se não for encontrado, execute o seguinte comando:

    export PATH=/var/lib/gems/1.8/bin:$PATH
    

    Com o comando abaixo, é possível verificar quais versões estão instaladas:

    gem list --local rails
    

    Pode-se instalar outra versão do Rails, através do comando abaixo. Existem situações onde isso possa ser necessário.

    gem install rails -- version 3.0.1
    

    Agora é possível verificar as versões instaladas:

    gem list --local rails
    rails _3.0.1_ --version
    

    sexta-feira, 21 de janeiro de 2011

    Por onde começar no Ruby

    Após as orientações de instalação das linguagens, encontradas no post sobre linguagens dinâmicas - Ruby e Python, precisamos de material e livros para estudar e aprofundarmos nessas linguagens. Se você, como eu, tem esse interesse e está um pouco perdido, vou deixar algumas dicas abaixo.

    Sobre Ruby, existe bons materiais na internet e, por isso, não vou ficar aqui reinventando a roda, se já escreveram para nós, vamos poupar tempo e digitação.

    Mas, antes de tudo, Ruby é
    Uma linguagem dinâmica, open source com foco na simplicidade e na produtividade. Tem uma sintaxe elegante de leitura natural e fácil escrita.
    Esta é a definição encontrada em http://www.ruby-lang.org/pt/

    No livro Why's (Poignant) Guide to Ruby, existe uma citação interessante que demonstra a simplicidade (não significa que não seja poderosa) da linguagem, em comparaçao ao Java:
    Na livraria perto de casa, existe uma enorme estante cheia de livros de Java só esperando para tombar e cair em cima de mim algum dia. E um dia isto vai acontecer. Da forma como as coisas estão indo, um dia esta estante será tão grande que se tombar vai esmagar todos nós. Pode até mesmo dar a volta ao mundo várias vezes, esmagando as edições anteriores dos mesmos livros de Java, e as novas edições atropelando estas também.
    .

    Aprenda a Programar

    Este é um bom material, básico sobre o Ruby, e com uma versão em português, para quem se sentir mais a vontade para ler na nossa língua. O legal que a tradução foi feita por profissionais da área, que conhecem a linguagem, como Fabio Akita. Então, você não vai encontrar traduções bizonhas, sem sentido. Tudo foi feito com cuidado. Vale a pena começar por aqui. É uma leitura agradável e rápida e já lhe dá uma visão global da linguagem.

    Para quem optar pela versão em inglês, pode acessar aqui.


    O Guia (comovente) de Ruby do Why

    É um material diferente, divertido e você vai se aprofundar mais na linguagem. Também vale a leitura.

    Para ler o material em inglês, clique aqui.

    Ruby 101 – O básico de Ruby para poder utilizar tanto o Rails quanto o Cucumber

    Este é um tutorial recente e muito bom encontrado no blog do Urubatan. É um tutorial extenso, mas vale muito a pena. Recomendo.

    Livros

    Minha dica em livros são essas:

    Para a versão 1.8 do Ruby:
    - Programming Ruby (2nd edition): The Pragmatic Programmers' Guide

    Para a versão 1.9 do Ruby:
    - Programming Ruby 1.9 (3rd edition): The Pragmatic Programmers' Guide

    Esses livros, conhecidos como Pickaxe book, devido a uma imagem de uma ferramenta na capa, é considerado o guia definitivo da linguagem. O único problema que vejo é que ele traz a referência da linguagem em quase metade do livro. Porém, até chegar lá, você já terá lido mais de 400 páginas. Então, entendo esse guia como um plus.

    O importante neste estudo é você aprender e ter uma base de Ruby antes de estudar Ruby on Rails. O livro pode ser utilizado como um livro de consulta, se preferir.

    Cursos

    Recomendo o curso da Caelum. para quem mora numa cidade que tem uma filial ou parceiro. Já fiz alguns cursos de Java, na Caelum Rio e foram ótimos. Tem dois cursos, na grade, sobre Ruby on Rails.

    terça-feira, 18 de janeiro de 2011

    Linguagens Dinâmicas - Ruby e Python

    Ano passado, tive meu primeiro contato profissional com linguagens dinâmicas. Na época, tive a oportunidade de dar manutenção em uma aplicação Ruby on Rails. No começo, sofri um pouco com os novos paradigmas, até conseguir fazer alguma coisa útil. Depois desse breve contato, eu acabei ficando um tempo só trabalhando e estudando Java.

    Porém, no final de 2010, voltei a me dedicar ao estudo dessas linguagens e tenho dedicado meu tempo a duas dessas linguagens: Python e Ruby. Claro que o tempo é escasso, mas tenho focado para tirar o melhor proveito eme aprofundar cada dia mais.

    Ruby e Python tem se tornado um grande vício em minha vida. Da mesma forma que o pessoal vai pra casa a noite para ficar horas jogando, estou me viciando de ir pra casa estudar Ruby e Python que, para mim, é uma grande diversão. Fico fascinado com a facilidade de, por exemplo, lidar com listas, iteraçoes, etc. Creio que essas duas linguagens, com seus frameworks web Rails e Django, vieram para ficar.

    Então, quero compartilhar com aqueles que desejam , sobre essa apaixonante viagem. Claro que não vou ficar aqui detalhando sobre as linguagens, mas dando algumas dicas que achei interessante e onde estudar, afinal, material na internet não falta.


    Para começar, você pode me perguntar: Ruby ou Python? Sinceramente, ainda não consegui nenhuma resposta. As duas, para mim, são ótimas. Já ouvi algumas pessoas defendendo uma em detrimento da outra, mas, no meu caso, não cheguei a nenhuma conclusão, quer dizer, cheguei sim: as duas. Pode ser que no futuro eu tenha uma escolha ou resposta.

    Iniciando ...

    A primeira coisa que precisamos fazer, é claro, instalar o interpretador para essas linguagens.


    Python no Linux
    Se você tem o privilégio de usar uma distro Linux, como Ubuntu, então, o python já está instalado.

    Python no Windows

    Usuários do Windows precisam fazer o download do Python e instalá-lo.
    Visite a página de downloads do Python em http://www.python.org/download/ e escolha o instalador para sua arquitetura, além de escolher a versão do Python desejada, no caso, existe a possibilidade de instalar a versão 2.7.1 ou 3.1.3.

    Neste momento, tanto faz qual versão você vai instalar, porém, o framework web Django, ainda não foi atualizado para a versão 3.1.3 do Python.


    Ruby no Linux
    No Linux, como super usuário, instale o Ruby.
    No ubuntu faça:

    sudo bash
    apt-get install ruby-full



    Ruby no Windows
    Acesse http://www.ruby-lang.org/pt/downloads/ e siga as orientações em Ruby em Windows.


    Sugiro utilizar a versão do Linux. Caso não conheça o Linux, recomendo instalar a versão 10.10 do Ubuntu e aprender a usar esse sistema operacional.


    Nos próximos posts, vamos nos aprofundar nessas linguagens.
    A idéia é após detalhar sobre elas, falar um pouco sobre Rails e Django.

    domingo, 27 de setembro de 2009

    Gerência de Processos

    Infelizmente, devido a correria do dia-a-dia, fiquei mais de um mês sem conseguir postar no meu blog. Além do trabalho, estudos e um curso que fiz, faltou foi tempo. Não faltaram idéias e pensamentos que gostaria que tivessem parado aqui, mas a vida continua e estou de volta. Nesse post, estou colocando algumas fotos de uns exercícios feitos em sala de aula, em uma disciplina de gerência de processos, de um curso que estava fazendo. Tirei as fotos dos exercícios dos grupos em que a turma foi dividada e fiquei com a responsabilidade de permitir que todos pudessem ter acesso a essas fotos. Mesmo com um pouquinho de atraso, aí estão elas, com os exercícios de cada grupo.