sexta-feira, 28 de dezembro de 2018

2019 - Ano Novo!

Mesmo que 2018 não tenha sido um bom ano, eu gostaria de agradecer:

- Aos meus amigos e colegas que me ajudaram, de uma forma ou de outra, a me recuperar de meu orgulho de ser um programador (muito obrigado!);

- De aprender, com todos, sobre o que é a vida e como vive-la;

- Da vida que, por mais que ela seja difícil algumas vezes, é essencial para nossa experiência;

- Da morte, pois devemos saber que tudo tem um fim;

- E da minha família, que esta em primeiro lugar, sempre;

Ah.. E de meus leitores, que sem eles, eu não teria ganhado US$19,55 depois de 8 anos:


Obs.: Putz, deveria ter sido Youtuber quando dava... (acho que blog saiu meio de moda) :P

[Atualização]

Para ajudar as pessoas: aqui esta o código-fonte em Java que gera números para apostar na Mega Sena:

import java.util.*;

public class MegaSena {

public static void main(String... args) throws Exception {
int max = 6;
if (args.length > 0) {
max = Integer.parseInt(args[0]);
if (max > 15) {
throw new Exception("Invalid number");
}
}
for (int i = 0; i < max; i++) {
System.out.print(Math.round(Math.random() * 59.0 + 1.0) + (i == (max - 1) ? "\n" : ","));
}
}
}

Depois de compilado, para executar basta usar o seguinte comando:
java MegaSena

Se quiser quinze (15) números, aí faça:
java MegaSena 15

[Fim da atualização]

Até mais e boa sorte!

sexta-feira, 21 de dezembro de 2018

Feliz Natal!


Sabe, este ano foi um ano difícil para mim... Não vou falar do que me aconteceu, mas foi algo profissional, que não desejo a ninguém que esteja na minha idade (a meia-idade).

Mas foi um ano de aprendizado: aprender a recomeçar, aprender que as coisas não são para sempre e, principalmente, que eu não agrado todo mundo por ser eu mesmo.

E, aprendi, neste último mês, o quanto a vida é preciosa demais para desperdiça-la.

Sim, como sempre, em Dezembro, mando um e-mail de Natal para as pessoas que conheci no trabalho, na escola e em outros lugares. (meio besta? é... mas, sei lá, eu acho legal)

E em um e-mail destes, um pessoal me respondeu de uma forma bem carinhosa e me fez refletir com o que cada um me escreveu. (sim, eu leio todos os e-mails... só não respondo a todos -- yep, preguiça mesmo :P)

Sei que, nesta vida corrida e agitada que todos nós vivemos, onde todo mundo pede tudo para ontem, queremos dar o melhor, principalmente, para mostrar o nosso trabalho e dedicação aos outros (ou para nós mesmos).

Mas será que, algumas vezes, não exageramos um pouco?

Será que precisamos disso para tornarmos felizes? Será que precisamos, realmente, ir para o exterior? Ganhar muito dinheiro? Comprar um carro de luxo?

Ou será que ter mais tempo para sua família e seus amigos seria melhor?

Hum... Cada um tem sua verdade, então, acho que para estas questões não haveria uma resposta certa... :P

Obs.: Não sou de esquerda, nem de direita, sou eu mesmo. :)
Obs. 2: E, sim, preciso de dinheiro, gosto de comprar coisas para mim e tenho que trabalhar. (só não tenho que trabalhar de cara fechada todo o dia :P)

Feliz Natal a todos!

Até mais!

sexta-feira, 14 de dezembro de 2018

Dicas de Programação: Parâmetros nomeados em C#

Sabe aquelas funções que tem n parâmetros que tem que passar, mas que você só quer passar uma e todas as outras são nulas (ou valores "default").

Então, dá para fazer isso em C#, com parâmetros nomeados na função. Por exemplo:

using System;

public class Program
{
  public static int soma(int i = 2, int j = 1) {
    return i + j;
  }

  public static void Main()
  {
    Console.WriteLine("Soma: " + soma(10));
    Console.WriteLine("Soma: " + soma(10, 5));
    Console.WriteLine("Soma: " + soma(i: 10));
    Console.WriteLine("Soma: " + soma(j: 10));
  }
}

Se você ver, ao passar um valor nomeado (seja "i" ou seja "j") a outra variável vai estar atribuído com o valor default (o que esta depois do igual, na função).

Legal, né? (Ah... Sim, isso funciona no Swift e no Kotlin)

Até mais!

terça-feira, 11 de dezembro de 2018

Dicas de Programação: Saindo de dois loops (for, for) em Java

Uma vez me perguntaram: como sair de dois loops dando um break?

Bem, eu sei que em Java é bem simples... É só dar um "labeling break":

public class Main {
    public static void main(String[] args) {
        saidaqui: for (int i = 0; i < Integer.MAX_VALUE; i++) {
            for (int j = 0; j < Integer.MAX_VALUE; j++) {
                System.out.println(i + ":" + j);
                if (j % 10 == 9) {                    
                    break saidaqui;
                }
            }
        }
    }
}

Com isso, quando o break executar, ele irá parar os dois loops (pois o label indica para ele sair do loop mais externo).

A mesma coisa pode ser feita em um loop/switch:

public class Main {
    public static void main(String[] args) {
        saidaqui: for (int i = 0; i < Integer.MAX_VALUE; i++) {            
            switch (i) {                
                case 9:
                System.out.println("Vai sair");
                if (true) {
                    break saidaqui;
                } 
                break;
                default:
                System.out.println("Index: " + i);
            }
        }
    }
}

Estranho, não?

Obs.: Acabei de ver que isso também funciona em Swift (iOS)!

import Foundation 

var i: Int = 0;
var j: Int = 0;
saidaqui: for i in 0...10 {
for j in 0...10 {
  print(String(format: "%d:%d", i, j));
if (j == 9) {                    
break saidaqui
}
}
}

Até mais!

Lembrando dos Natais Passados: Monark BMX

Bem... Eu nunca fui bom com "coisas com rodas", mas teve uma conversa com um pessoal sobre os tempos de criança e falou-se sobre uma tal de BMX Monark:


Me lembro de ter visto estas propagandas nas revistinhas da Turma da Mônica, quando ainda era publicada na Editora Abril...

Mas não me lembro desta bicicleta ter marcha, nem que dava para pular assim, quase no céu, sem se espatifar no asfalto (a bicicleta e quem estava nela...).

Quem diria que a gente era tão inocente de achar que essa era "a" bicicleta (tempo que a TV era o mais rápido meio de comunicação...).

Bons tempos! (eu acho... :P )

Até mais!

quinta-feira, 6 de dezembro de 2018

Tartarugas Ninjas na vida real

E se, as Tartarugas Ninjas fossem gente de verdade, como é que seria um treinamento entre eles? 

Hum... Sinceramente, acho que seria mais ou menos assim:


Aonde será que esta a April? :P

Até mais!

segunda-feira, 19 de novembro de 2018

Isso é MVP (Model-View-Presenter)? Reflexão e questões

Hum... Fiquei pensando em algumas coisas após ter terminado o tutorial (se é que é um tutorial :P) ...

Uma das coisas é colocar o "assincronismo" na parte "Model" da coisa.

Pensando bem, se é a tela do Android (por exemplo) que trava por causa da resposta do serviço, por que diabos tenho que colocar o "assincronismo" no lado do serviço?

Eu poderia resolver com alguma coisa assim, no lado da View:

this.startLoading();
this.callAsync(presenter.callLogin, (returned: Object) throws Exception -> {
       this.finishLoading();
      if (object is User) {
            ...
      } else if (object is Error) {
           ...
      }
});


E colocar o Model e o Presenter síncronos.

E por que pensei nisso? Por causa que nem todas as aplicações pedem coisas assíncronas (por exemplo, um serviço de API que, na teoria, ao receber uma requisição, não seria necessário executar o serviço assíncrono).

Mas, se em todo o caso, os serviços (Models) são assíncronos (seja por que foi pensado assim, ou esteja utilizando uma biblioteca assíncrona) e você estiver precisando usar em alguma coisa síncrona, dependendo da linguagem, é possível fazer algo assim:

public function onRequest(request: Request, response: Response) {
      ...
      presenter.callLogin();
     this.wait();
     if (this.user != null) {
          ...
    } else if (this.error != null) {
         ...
     }
     ...
}

public function onLogin(user: User) {
     this.user = user;
     this.notify();
     ...
}

public function onLoginFail(error: Error) {
      this.error = error;
      this.notify();
      ...
}


Tomara que, desta vez, eu tenha acertado! :P

Até mais!

sexta-feira, 16 de novembro de 2018

Isso é MVP (Model-View-Presenter)? Terceira (e acho que última) parte - Presenter

Como muita gente viu, eu arrumei a parte dois (realmente, fazer as coisas com pressa dá nisso...).

Vamos a última parte (eu acho), a implementação da classe Presenter.

Esta classe tem como característica juntar a parte View (da segunda parte deste artigo) com a Model (da primeira parte deste mesmo).

Então temos:

//Classe de Presenter que implementa a delegação do Modelo (ILoginModelDelegate) e da View (ILoginViewDelegate)
public class LoginPresenter implements ILoginModelDelegate, ILoginViewDelegate  {

         //Propriedades privadas
         private property model: ILoginModel;
         private property view: ILoginView;

         //Construtor da classe
         public constructor(view: ILoginView) {
                   //Cria o model através de uma Fábrica (Factory)
                  model = Factory::instance.getModel(ILoginModel.class);
                  model.delegate = this;
                  view.delegate = this;
         }

         //Função de login
         private function login() {
                  model.login(view.username, view.password);
        }

        @implementation
         public function onLoginSuccess(user: User) {
                  view.onLogin(user);
         }

         @implementation
         public function onLoginError(error: Error) {
                 view.onLoginFail(error);
         }

        @implementation
         public function callLogin() {
                 login();
         }
}

E, assim, temos a junção de tudo. Por exemplo, se fosse uma "página web":

public class LoginPageView: Page, ILoginView, OnClickListener {
       private property presenter: LoginPresenter;
       private property @UI okButton: UIButton;
       ...
       public constructor() {
              ...
              presenter = new LoginPresenter(this);
             okButton.setOnClickListener(this);
             ...
       }
      ...
       @implementation
       public function OnClick(sender: UIObject) {
              presenter.callLogin();
       }
       ....
}

Se fosse uma "Activity do Android":

public class LoginActivity: Activity, ILoginView, OnClickListener {

       private property presenter: LoginPresenter;
       private property okButton: Button;
       ...
       @override
       public function onCreate(savedInstanceState: Bundle) { 
              ...
              presenter = new LoginPresenter(this);
             okButton.setOnClickListener(this);
             ...
       }
      ...
       @implementation
       public function OnClick(sender: View) {
              ...
              presenter.callLogin();
              ...
       }
       ....
}

Ou se fosse um "serviço JSON":

public class LoginJSONView: JSON, ILoginView {

       private property presenter: LoginPresenter;
       ...
       public constructor { 
              ...
              presenter = new LoginPresenter(this);
             ...
       }
      ...
      @override
       public onPost(request: Request, response: Response) {
               ...
               presenter.callLogin();
              ...
       }
       ....
}

Acho que é isso... Se eu esquecer de alguma coisa, depois eu arrumo. (errar é humano, ainda mais depois dos 40... :P )

Até mais!

quarta-feira, 31 de outubro de 2018

Isso é MVP (Model-View-Presenter)? Segunda parte - View

Bem, tenho que corrigir uma coisa anteriormente: o método "login" esta síncrono, seria melhor se ele fosse assincrono, ou usando callbacks:

public function login(username: string, password: string, callback: function(user: User?, error: Error)) {
}

ou usando métodos de delegação de uma interface (que será implementada na classe de Presenter):

public interface ILoginModelDelegate {
      public function onLoginSuccess(user: User);
      public function onLoginError(error: Error);
}

Beleza, agora podemos continuar! (se eu não me lembrar de nada até lá...)

Se para Model, a gente fez uma interface para ela (para facilitar a mudança da origem de dados -- seja serviços REST, SOAP ou banco de dados), a gente faz a mesma coisa para a View.

Por que? -- você deve perguntar...

Pelo mesmo motivo: desacoplamento, ou seja, para que a nossa "tela" possa mudar de HTML para um serviço que retorna json ou para outro que retorna XML:

public interface ILoginView {
        public property (readonly) username: string;
        public property (readonly) password: string;
        public function onLogin(user: User);
        public function onLoginFail(error: Error);       
}

public class LoginPageView: Page, ILoginView {
        public property (readonly) username: string {
                 return txtUserName.text;
        }
        ...
}

public class LoginRestView: Rest, ILoginView {
        public property (readonly) username: string {
                 return request.getParameter("username");
        }
        ...
}

Legal, né?

Bem, acho que é isso... Na próxima fica faltando só a Presenter. :)

Até mais!

quarta-feira, 24 de outubro de 2018

Isso é MVP (Model-View-Presenter)? Primeira parte - Model

Sabe aquele tipo de cara que aprende somente na prática? Então, este sou eu (por isso, eu não tenho certeza se isso é MVP).

MVP é uma sigla para Model-View-Presenter (modelo, visão e apresentação), que é um tipo de modelo de arquitetura de software, como o MVC.

Como este, seguimos o padrão de separar o "negócio" (regras, cálculos, verificações, dados, etc.), o "M" da sigla, da tela (bem, tela é tela :P), o "V" da sigla.

Se separamos, existe alguém que junta, certo? Sim, e este "juntador" é representado pela letra "P" (o Presenter).

Bem, melhor que explicar, vamos a codificação (programador entende melhor "programando"). Primeiramente, vamos entender as classes de modelo:

public interface IUserModel {
        //Função que verifica se o usuário é válido.
        //@param username string que contém o nome do usuário (obrigatório) 
        //@param password string que contém a senha do usuário (obrigatório)
        //@return se os valores foram válidos, retorna um objeto da classe User, com as informações do usuário, caso o contrário, retorna null
        public function login(username: string, password: string): User?;
}

//Implementação da interface IUserModel que usa banco de dados
public class UserDatabaseModel: IUserModel {
        @implementation
        public function login(username: string, password: string): User? {
             ...
        }
}

Por que temos uma interface em modelo? Por causa da teoria de "baixo acoplamento", e por que podemos, em vez de usar uma classe que conecta em banco de dados, usar uma classe que conecta em serviços REST, por exemplo:

//Implementação da interface IUserModel que usa serviços REST
public class UserRESTServiceModel: IUserModel {
        @implementation
        public function login(username: string, password: string): User? {
             ...
        }
}

Na hora de usar essas, em vez de instanciar um objeto da própria classe:
public property model: UserRESTServiceModel = new UserRESTServiceModel();

Podemos instanciar um objeto da interface:
public property model: IUserModel = new UserRESTServiceModel();

E, assim, utilizar um serviço ou outro, só mudando a instância:
public property model: IUserModel = new UserDatabaseModel();

Acho que a primeira parte esta concluída, na próxima, veremos a "V" de view (não de vingança). :)

Até mais!

terça-feira, 23 de outubro de 2018

Gigante guerreiro Daileon!


Ontem, um colega meu falou sobre um provável "remake" do Jaspion...

Bem, pelo que ouvi de boatos, sei que a SATO Company tem os direitos da série e que a Toei Company autorizou que esta possa fazer um filme de sua personagem.

Mas são só especulações, nada muito confirmado ou feito...

Porém, parece que tem um pessoal que esta animado! Tipo seu Rafael Segnini, que fez a transformação do gigante guerreiro Daileon em 3D:


Ficou bem legal, não? :)

Até mais!

sexta-feira, 21 de setembro de 2018

Dicas de programação: Escrevendo operadores de "cast" em C#

No C#, dá para escrever operadores para conversão de tipos. Por exemplo:

    //Estrutura Pessoa 
    struct Pessoa
    {
        //Propriedade Nome
        public String Nome
        {
            get; set;
        }

        //Propriedade Idade
        public int Idade
        {
             get; set;
        }

        //Converte o objeto pessoa para String (de maneira implicita, sem precisar fazer "(String)pessoa")
        public static implicit operator String(Pessoa pessoa)
        {
            return pessoa.Nome;
        }

        //Converte o objeto pessoa para int(de maneira explicita, precisando fazer "(int)pessoa")
        public static explicit operator int(Pessoa pessoa)
        {
            return pessoa.Idade;
        }

    }

    static void Main(string[] args)
    {
          //Crio o objeto pessoa
          Pessoa pessoa = new Pessoa();
          //Seto o nome e a idade
          pessoa.Nome = "Ricardo";
          pessoa.Idade = 100;
          //Converto os valores
          String nomePessoa = pessoa;
          int idadePessoa = (int) pessoa;
         //Exibo na tela
          Console.WriteLine("Nome: " + nomePessoa + " Idade: " + idadePessoa);
    }

Até mais!

terça-feira, 18 de setembro de 2018

Mercado Municipal de Campinas

Você não sabe aonde comprar chá de quebra-pedra? Ou nori? Ou feijão-fradinho por quilo?

Pois é, existe um lugar em Campinas que tem tudo isso e muito mais... E, este espaço, nós chamamos carinhosamente de Mercadão:


Oxê... Me deu uma saudade do comércio no Centro de Campinas... (para quem não sabe, já "trabalhei" lá :P )

Até mais!

Dicas de Programação: Enumeração em Swift

Uma coisa meio estranha no Swift, é que dá para colocar parâmetros dentro das "constantes" enumeradas e trabalhar com elas:

import Foundation

enum Log {
    //Constante debug com um parâmetro String
    case debug(String)
    //Constante warning com um parâmetro String
    case warning(String)
    //Constante error com um parâmetro String
    case error(String)
    //Função do enumerador que escreve no console/terminal
    func write() {
        //Obtém a data atual
        let now = Date()
        switch (self) {
         //Caso o enumerador seja debug 
        case Log.debug(let d):
           //Escreve na tela a data atual, a palavra [DEBUG] e o parâmetro "d" passado na constante
           print("\(now) [DEBUG] \(d)")
        //Caso o enumerador seja warning 
        case Log.warning(let w):
           //Escreve na tela a data atual, a palavra [WARNING] e o parâmetro "w" passado na constante
           print("\(now) [WARNING] \(w)")
        //Caso o enumerador seja error
        case Log.error(let e):
           //Escreve na tela a data atual, a palavra [ERROR] e o parâmetro "e" passado na constante
           print("\(now) [ERROR] \(e)")
        //Caso não seja nenhum deles, dá um erro
        default:
            fatalError("Unsupported")
        }
    }
//Exemplo de uso
Log.error("Ocorreu um erro").write()
Log.warning("Variavel é nula, utilizando valor 0 como default").write()
let pi = 3.14
Log.debug("Valor da constante pi=\(pi)").write()

Bizarro, não?

Até mais!

Black Kamen Rider: original ou dublado?

Qual seria melhor? A abertura original de Black Kamen Rider (sim, isso mesmo, quem canta é o protagonista da história):


Ou a dublada:


Fiquei na dúvida... :P

Até mais!

sexta-feira, 14 de setembro de 2018

Dicas de programação: Reescrevendo operadores em Swift

Para reescrever operadores em Swift é bem simples: basta criar uma função estática com o "nome do operador", seus parâmetros e seu retorno (por exemplo, se for o operador ==, tenho dois parâmetros para comparar e um retorno do tipo booleano):

//Estrutura que guarda os dados de uma pessoa
struct Pessoa {
    //Nome da pessoa
    var nome: String

    //Idade da pessoa
    var idade: Int
    

    //Reescrevendo o operador ==
    static func ==(_ first: Pessoa, _ second:Pessoa) -> Bool {

        //Comparo o nome e a idade, se os dois forem iguais, retorno true, senão, retorno false
        return first.nome == second.nome && first.idade == second.idade
    }


}


//Crio os dados de uma pessoa
let pessoa1 = Pessoa(nome: "Ricardo Takemura", idade: Int.max)
//Crio os mesmos dados (em outro objeto)
let pessoa2 = Pessoa(nome: "Ricardo Takemura", idade: Int.max)

//Comparo um com o outro, se for igual exibo "{dado1} é igual que {dado2}" senão "{dado1} é diferente que {dado2}"
print("\(pessoa1) é \(pessoa1 == pessoa2 ? "igual" : "diferente") que \(pessoa2)")


Legal, não?

Até mais!

quinta-feira, 13 de setembro de 2018

Dicas de programação: Estruturas/Objetos anônimos em Swift

Quantas vezes a gente não teve preguiça de criar um objeto/estrutura para guardar dois ou três dados...

Pois é, existe um jeito de criar um objeto no Swift sem ter que declara-lo! E é muito fácil: basta declarar as "propriedades" dentro de parênteses "()". Por exemplo:

//Função que retorna "meu dados" (nome do tipo String e idade do tipo Int)
func me() -> (nome: String, idade: Int) {

     //Retorno meu nome e idade (estou velho...)
    return (nome: "Ricardo Takemura", idade: Int.max)

}

//Crio uma "constante" x com o retorno da função acima
let x = me()

//Exibo os campos nome e idade na tela
print("Nome: \(x.nome) Idade: \(x.idade)")


Legal, né?

Até mais!

Dicas de programação: Criando e chamando métodos de um "objeto anônimo" em Java

Eu já falei de classe anônima em algum post mais antigo... Geralmente, a gente implementa uma interface ou "herda" uma classe abstrata com a classe anônima e (também) implementa seus métodos. Mas, como seria se, por necessidade, eu quisesse incluir uma nova função em um objeto de uma classe já implementada?

Pois é, dá para fazer isso com o uso da mesma técnica:

import java.util.*;
import java.io.*;


public class Teste {

     //Método principal
     public static void main(String[] args) throws Exception {
          Object objeto = new Object() {


               //Propriedade privada
               private String helloWorld = "Hello World";


               //Método público
               public String talk() {
                        return helloWorld;
               }


               //Método público que existe na classe Object
               public String toString() {
                        return helloWorld;
               }
          };


          //Chamando o método toString da classe Object e exibindo seu resultado
          System.out.println(objeto.toString());

          //Chamando o método que não existe na classe Object mas que existe na "classe anônima"
          String ret = objeto.getClass().getDeclaredMethod("talk").invoke(objeto).toString();


          //Exibindo o resultado
          System.out.println(ret);
    }
}


Loucura, não? :P

Até mais!

Alguém se lembra: Rastan para Master System?

Um guerreiro bárbaro precisando salvar seu mundo de criaturas diabólicas!

"Conan?" -- você pensaria.

"Nope, Rastan para Master System!" -- eu responderia. :)


Rastan é um dos poucos jogos para Master System que não foi reprogramado ou criado pela SEGA e sim pela Taito Corporation.

Baseado em um arcade da própria empresa, consiste em controlar um bárbaro que precisa percorrer sua terra atrás de seres malignos. (Grande estória? Claro que não! Quem, nos anos 90, se importava com estória?)

Com jogabilidade simples (e travada), é um game legal para se jogar em um fim-de-semana.

Vale muito mais pela nostalgia.

Abaixo, uma jogatina feita pelo canal World of Longplays:


Até mais!

terça-feira, 11 de setembro de 2018

Cultura em Campinas?



Bem, eu já fiz um post parecido com este em 2011 (eu acho). Mas só queria atualizar. :)

Museu do esporte de Campinas:
https://www.facebook.com/pages/Museu-Do-Esporte-De-Campinas/186022495197948

Museu aberto de astronomia:
https://www.facebook.com/museuabertodeastronomia/

Museu de arte contemporânea de Campinas:
https://www.facebook.com/MAC-CAMPINAS-1659900337557500/

Museu da imagem e do som de Campinas:
https://www.facebook.com/campinasMIS/

Instituto cultural Nipo Brasileiro:
https://www.facebook.com/nipocampinas

Casa de Portugal:
https://www.facebook.com/casadeportugalcamp/

Instituto CPFL:
http://www.institutocpfl.org.br/

SESC Campinas:
https://www.sescsp.org.br/unidades/16_CAMPINAS/#/uaba=programacao#/fdata=id%3D16

Dicas de programação: Extensões em C#

Uma vez, eu escrevi de como fazer extensões em Swift (iOS).

Pois é, agora eu descobri que dá para fazer algo semelhante em C#:

using System;

///Usado para fazer extensões
using System.Linq;


namespace Teste
{
    /// 


    /// Classe estática para extensão do tipo/classe int
    ///
    public static class IntExtension
    {
        ///
        /// Converte um número decimal em binário (String)
        ///

        /// Número a ser convertido (this)
        /// String com o valor em formato binário
        public static String ToBinary(this int number)
        {
            String str = "";
            do
            {
                int rest = number % 2;
                str = rest.ToString() + str;
                number = number / 2;
            }
            while (number > 0);
            return str;
        }
    }

  
  class Program
    {
        static void Main(string[] args)
        {
            Program p = new Program();
            Console.WriteLine("Dois em binário: {0}", 2.ToBinary());
            Console.ReadKey();
        }
    }
}


Esta certo que converter um número em binário desta forma é meio "arcaico", mas sou um programador raiz. (ou Nutella, em alguns casos... :P)

Até mais!

Dicas de programação: Reescrevendo operadores em C#

A coisa mais estranha e legal é quando uma linguagem deixa sobrescrever operadores (tipo mais [+] ou vezes [*]).

Podemos fazer barbaridades com isso... Por exemplo, dizer que uma mesma variável não é igual a ela mesma!

Sim, dá para fazer isso em C#:

using System;
namespace Teste
{
    class Program
    {
        ///
        /// Reescrevendo o operador de comparação "igual" (==) da classe Program
        ///

        /// O primeiro objeto a ser comparado
        /// O segundo objeto a ser comparado
        /// Sempre false
        public static Boolean operator ==(Program p1, Program p2)
        {
            //Em qualquer situação, retorno false
            return false;
        }


        ///
        /// Reescrevendo o operador de comparação "diferente" (!=) da classe Program
        ///

        /// O primeiro objeto a ser comparado
        /// O segundo objeto a ser comparado
        /// Sempre true
        public static Boolean operator !=(Program p1, Program p2)
        {
            //Em qualquer situação, retorno true
            return true;
        }


        static void Main(string[] args)
        {
            Program p = new Program();
            Console.WriteLine("Este programa é igual a ele mesmo? " + (p == p ? "Sim" : "Não"));
            Console.ReadKey();
        }
    }
}


Ele sempre vai dizer que p não é igual a p (ou seja, p == p dá false).

Bizarro, não?

Até mais!

segunda-feira, 10 de setembro de 2018

Testes automatizados para .Net: SpecFlow

Sabe o Cucumber?

Bem, se você não sabe, é uma ferramenta de automação aonde você escreve os cenários (com linguagem natural) e ele vai executando este conforme seu passo a passo. (mágico? bem, eu diria que nem tanto....)

Então, tem gente que gosta, tem gente que detesta (eu até gostaria, se me pagassem bem para "programar" nele... :P). Mas você sabia que existe uma ferramenta parecida para .Net?

Pois é, e se chama SpecFlow:


Obs.: Se é bom? Então... Depende do gosto (e de quão custoso é configurar ele e o ambiente de teste).
Obs. 2: Hum... Já disse que mudei de linguagem este semana? Agora sou programador .Net! :)

Até mais!

Alguém se lembra: El Hazard?

Sabe aqueles animes que passavam na Band e que mal a gente sabia que passavam (tipo Tenchi Muyo!)?

Pois é, dentre estes, tinha um que era baseado em um tema que não era nada comum para um desenho japonês (tipo, coisas árabes, como as histórias das "Mil e uma noites").

Ele se chamava El Hazard:


É uma animação muito louca (se bem que TODA coisa japonesa é meio LOUCA), que contava a história dos estudantes (e um professor) que foram transportados para um reino cheio de magia, aonde, sem a menor explicação, eles recebem poderes sobrenaturais.

Muitas confusões e aventuras (sim, tipo "Sessão da Tarde") acontecerão com nosso protagonista e seus amigos. (e inimigos -- sendo que um deles é um dos colegas de escola dele!)

Abaixo, a abertura mostrada no saudoso Band Kids:


Obs.: Se é divertido? É. Se dá para entender alguma coisa? Bem, ai você esta pedindo demais... :P

Até mais!

terça-feira, 14 de agosto de 2018

Gosta de HQ? Então, seu canal é o Nerd All Star!

Uma vez, perguntei ao Nerd Ancião o que é ser nerd... E ele me respondeu, com aquela calma que todo ancião tem:

"Nerd que é raiz, é aquele que gosta de HQ, p*rr@!" :P

Se você é um cara que gosta de quadrinhos da Marvel ou da DC (ou de ambos -- pois é, você sabia que não é proibido gostar dos dois? :P), então seu canal do Youtube é o do Nerd All Stars:


É bem legal ver como o apresentador conta as estórias (algumas "clássicas") ou apresenta as personagens da DC e da Marvel. Simples e direto. :)

Obs.: No vídeo acima, ele apresenta o Sandman de Neil Gaiman (as estórias desta personagem são umas das que eu mais gosto, mas apesar do protagonista ser ótimo, a minha personagem favorita desta HQ é a Morte -- sim, é aquela mesma que esta no fim de tudo...).

Recomendo! (o canal e o quadrinho)

Até mais!

quarta-feira, 1 de agosto de 2018

7 Animes para Assistir na Netflix

Gosta de anime? Paga a Netflix? Então, quer um dica?

Pois bem, eu não vou te dar nenhuma, mas o canal Bunka Pop te dá sete (dicas... pô, deixa de pensar besteira... :P ):


Se vale a pena? Só posso dizer que "Fullmetal Alchemist: Brotherhood" é muito legal! :)

Até mais!

quinta-feira, 26 de julho de 2018

Alguém se lembra: Jewel Master?

Esse jogo é meio desconhecido, mas é bem interessante!

Jewel Master é um jogo para Mega Drive de ação e aventura, que conta a história de um mago (ou aprendiz), aonde ele precisa defender sua vila das forças do mal.


História batida? Sim... Mas o interessante é como ele combate "este mal"... Ele usa anéis mágicos (que são obtidos durante o jogo), onde estes possuem poderes de ataque, agilidade e defesa.

O legal é que dá para misturar estes poderes obtendo, assim, novas magias (mais fortes ou mais fracas, conforme a mistura).

Ah... A música também é um ponto forte (pelo menos, para mim).

Vale a pena jogar, só para ver como é que é.

Abaixo, uma jogatina feito pelo canal VGDBbr:


Até mais!

segunda-feira, 9 de julho de 2018

Dicas de Programação: Entendendo extensões em Swift

Extensões em Swift não são as coisas mais fáceis de se entender, mas não é um bicho de sete (7) cabeças. (se bem que bicho de sete cabeças não existe... eu acho... :P )

Extensões são, na prática, adições de métodos em classes já existentes.

Iremos a um exemplo, que isso torna as coisas mais fáceis. :)

Vamos dizer que eu precise, em meu projeto, botões que tenham, em sua característica, um fundo de cor gradiente, conforme ilustração:


Ok, neste caso, eu só tenho uma propriedade backgroundColor que coloca, ou imagem, ou uma cor sólida no botão...

Porém, eu sei que dá para fazer isso com um CAGradientLayer, adicionando esta como uma sublayer de uma UIView:

    override func viewDidAppear(_ animated: Bool) {
        let gradientLayer = CAGradientLayer()
        gradientLayer.colors = [UIColor.yellow, UIColor.green]
        gradientLayer.startPoint = CGPoint(x: 0, y: 0)
        gradientLayer.endPoint = CGPoint(x: 0, y: 1)
        gradientLayer.frame = CGRect(x: 0, y: 0, width: myButton.bounds.width, height:  myButton.bounds.height)
        myButton.layer.insertSublayer(gradientLayer, at: 0)
    }

Contudo, para cada botão que eu tiver na tela (ou telas) que precise de um gradiente, vou precisar usar o mesmo código...

Para evitar isso, que tal "adicionarmos" um método chamado "setGradientColors" em todos os botões (classe UIButton)?

Adicionar? Eureka! Como eu escrevi acima, é para isso que a extensão existe:

extension UIButton
{
    func setGradientColors(startColor: UIColor, endColor: UIColor) {
        let gradientLayer = CAGradientLayer()
        gradientLayer.colors = [startColor.cgColor, endColor.cgColor]
        gradientLayer.startPoint = CGPoint(x: 0, y: 0)
        gradientLayer.endPoint = CGPoint(x: 0, y: 1)
        gradientLayer.frame = CGRect(x: 0, y: 0, width: self.bounds.width, height: self.bounds.height)
        gradientLayer.type = kCAGradientLayerAxial
        if let sublayers = self.layer.sublayers {
            if (sublayers.count > 0) {
                let sublayer = sublayers[0]
                if (sublayer is CAGradientLayer) {
                    sublayer.removeFromSuperlayer()
                }
            }
        }
        self.layer.insertSublayer(gradientLayer, at: 0)
        self.layoutIfNeeded()
    }
}

Agora, para cada botão que precise usar um fundo gradiente, só é preciso chamar o método "setGradientColors":

override func viewDidAppear(_ animated: Bool) {
    myButton.setGradientColors(startColor: UIColor.yellow, endColor: UIColor.green)
}

Entretanto, você pergunta: Mas se eu quiser usar em um UILabel... Vou ter que criar a mesma função para esta classe?

Sim... e não! Se você quiser usar em todas as classes que herdam de UIView (UILabel e UIButton são filhos de UIView), você pode somente trocar a extensão de UIButton para UIView:

extension UIView
{
    func setGradientColors(startColor: UIColor, endColor: UIColor) {
        ...
    }
}

Que tudo vai funcionar! :)

Legal, né? Mas, como você pode ver, extensões são poderosas e, portanto, devem, sem dúvida nenhuma, serem utilizadas com cautela. (como diz tio Ben: "Com grandes poderes....")

Até mais!

Alguém se lembra: CRUJ?

Se existia alguma concorrência para a TV Globo, referente a programação infantil na década de 90, este era a TV CRUJ:


O Comitê Revolucionário Ultra Jovem (CRUJ), era formado pelo Caju (líder do CRUJ), Chiclé e o Macaco (e posteriormente a Maluca, entre outros) que invadiam a programação da tarde do SBT, de segunda a sexta, passando desenhos animados de ótima qualidade. (Timão e Pumba, Marsupilami, 101 Dálmatas, etc.)

Claro, isso era invenção (eles não invadiam a TV aberta... mas bem que seria legal, se fosse verdade... principalmente nos tempos de hoje :P ), o programa, originalmente, se chamava Disney Club e fazia parte da grade de programação da empresa.

Mas deu tão certo, que esta "invasão" durou quase 5 anos!

Deu saudades, certo? Então assista a abertura, publicada pelo canal Programadas Históricas:


Cruj, cruj, cruj, tchau!

Alguém se lembra: Mini games da Tec Toy?

Quem não queria um Game Boy ou um Game Gear na década de 90?

(Querer, eu queria, poder... bem, não nasci rico e nem trabalhava naquela época...)

Se você, assim como eu (não, ninguém come ninguém, é um advérbio não verbo, e... ah, deixa pra lá... :P), não tinha possibilidade nenhuma de ter estas maravilhas para jogar, então, devia ficar fazendo a mesma coisa que eu fazia: ficava insistindo para sua mãe comprar, pelo menos, um mini game do Sonic ou do Mortal Kombat da Tec toy (que eram bem mais em conta -- o que quer dizer, mais barato mesmo).




Se era igual ao do Master System (como dizia)?
Pelo menos, para mim, nem um pouco... Mas isso se resolvia com um pouco de imaginação (como fazia seu Lucas Silva e Silva).

Se tinha 1 Mega?
Acho que não tinha nem 1 K. :P

Se possuía músicas e efeitos sonoros?
Hum... Acho que possuía beeps de tom diferentes (tipo o Papa-Léguas -- entendeu a referência, hein, hein? :P).

Se era divertido?
Ah... Pelo menos, isso era (na época). :)

Obs.: Vídeo acima, feito pelo canal Tectoy Oficial.

Até mais!

Alguém se lembra: Os Wuzzles?

Sabe de um desenho da Disney que passava na Rede Globo no final dos anos 80 (e começo dos 90), junto com os Ursinhos Gummi, que misturava dois bichos em uma coisa só?

Não sabe? Então deixa eu refrescar sua memória:


Os Wuzzles (nome estranho não?) era um desenho animado que possuía seis protagonistas que misturam dois animais em um só, dentre eles, o "chefe" da trupe, um híbrido de leão com abelha, chamado Abeleão (sim, os caras foram muuuuito inventivos com os nomes...).

Divertido, pena que não fez tanto sucesso assim... (acho que passou só em menos de um ano aqui na Brasil...)

Abaixo, a abertura em português:


Até mais!

domingo, 17 de junho de 2018

Alguém se lembra: Vuvuzela?


Eita, que esta é uma das coisas que queria que as pessoas esquecessem... (desde a Copa da África do Sul - 2010) :P

É só isso, pessoal!

Até mais!

Alguém se lembra: Muppet Babies?

Sou da época que passava os Muppets "originais", ou seja, Caco e Piggy eram bonecos de espumas bem... (como direi...) toscos para a época atual.

Mas teve um tempo que eles reapareceram, só que no formato de desenho e bebês, no SBT. O desenho se chamava Muppet Babies:


Era mais "fofinho" e menos comédia que o primeiro, mas eu entendo que era mais (ainda) para crianças. As histórias tinham um lado mais moralista e uma única adulta que dava conselhos a "criançada", era chamada somente de Babá.

Era até que "legalzinho" na época.

Bem... Para quem ficou com saudades, parecem que eles vão voltar:


Será que vai ficar bom? :P

Até mais!

domingo, 20 de maio de 2018

Alguém se lembra: Bucky (anime)?

Sabe aquele anime com uma estória estranha, com um traço estranho, em um horário estranho e em uma emissora estranha (esta bem, até que a TV Bandeirantes não é muito estranha... só de vez em quando :P ), que, de repente, todo mundo gosta e assiste?

Então, este é Bucky:


Sobre a estória, eu "acho" que era sobre reinos (todos muitos diferentes) que tinham uma disputa entre eles, e o nosso protagonista, Bucky, queria brigar e ser o mais forte de todos, para se tornar o rei de tudo e dominar todos eles! (Herói querendo salvar a Terra? Neste caso, é só um nego metido mesmo... :P ).

O desenho era meio tosco (os bichos que acompanhavam nossos guerreiros eram feios de doer...).

E, mesmo assim, eu assistia querendo saber mais da história e do protagonista...

Sei lá, vai ver, meu gosto (e de muita gente) é meio duvidoso...

Abaixo, a abertura brasileira:


Obs.: Medo! :P

Até mais!

Alguém já leu: Os livros da magia (DC)?

Os livros da magia, de Neil Gaiman, é uma HQ do selo Vertigo da DC Comics, que conta a estória de um jovem estudante chamado Timothy Hunter que, de repente, é convidado, por quatro pessoas estranhas, para se tornar o maior mago do mundo.

Bastante parecido com um tal de Harry? Pode até ser... Mas este aqui foi lançado antes. :P


E, claro, este conto é bem mais pesado que os livros da J. K. Rowling (não em número de páginas, claro. :) ).

Gosta das séries Deuses Americanos (Stream), Sandman (quadrinhos) e do filme MirrorMask? Então, provavelmente, você gostará deste também! (afinal, são todos do mesmo autor!)

Só para dizer (para que não entendeu :P ): Eu gostei! Vale muito a pena!

Até mais!

Alguém se lembra: Machineman?

Esta série japonesa que passou aqui, no Brasil, a partir dos anos 90 (na TV Bandeirantes, eu acho...), conta a estória de um herói alienígena (como o Jaspion, Superman e tanto outros...) que vem para a Terra ajudar os terráqueos (quem mora na Terra é? Dãããã :P ), a combater o mal que assola o planeta. (Clichê? Totalmente! :P)


Mas, apesar disso tudo, tinha umas coisas diferentes também! Em vez de uma espada (o que é mais comum em uma série como esta), o herói usava um florete! E, em vez de uma jovem gosto..., quero dizer, bonita, ele tinha uma bola de beisebol (???) como ajudante!

É até que era bem divertido! :)

Abaixo, a abertura original:


Até mais!

Alguém se lembra: Phantasy Star 3?

De toda a série Phantasy Star, o capítulo 3 é, de longe, o mais criticado e o que menos tem em a ver com a história principal...

Mas, fora esse desgosto, não deixa de ser um bom jogo. :)


Phantasy Star 3 conta a trajetória dos habitantes da nave espacial Alisa III, após a explosão do planeta Palma, ocorrida no episódio dois (2).

Nesta nave, os "palmanos" começaram a se separar em dois grandes "povos": os Layans e os Okarios.

Desta separação, gerou-se uma grande guerra.

E, 1000 anos após esta, é que nossa aventura começa.

É um RPG pequeno (terminei em menos de 24 horas :) ), mas tem coisas legais nele, como casamentos! (Que? Você acha que casamento não é legal? Espero, realmente, que sua esposa/seu esposo não esteja por perto...)

Obs.: Para os fãs da série principal: jogue como se não fosse um Phantasy Star... Acredite, melhora sua diversão uns cinqüenta por cento!

Abaixo, uma jogatina feita pelo canal Velberan Adventures:


Até mais!

sexta-feira, 11 de maio de 2018

The Legend of Zelda em mangá?

Pois é, para quem nunca jogou um Zelda (seu sonysta, caixista ou segueiro -- sim, para quem não sabe, a SEGA fazia videogames... :P), mas gostaria de saber por que diabos o pessoal fala tão bem das histórias dos jogos (e, claro, gosta de mangás), que tal começar a franquia lendo? (afinal, jogando, na legalidade, ficaria meio caro... :P).

A Editora Panini lançou dois mangás com as histórias de três jogos (dois deles, pertencente a um mesmo "mundo"). O primeiro é The Legend of Zelda: Oracle of Seasons/Oracle of Ages:


O segundo, e mais aclamado, é o famoso The Legend of Zelda: Ocarina of Time:


Cada um tem a história completa do jogo referido (é uma edição única) e a qualidade do produto esta legal (não tem capa dura, mas é uma capa bonita com um bom papelão).

Recomendo muito para quem tem curiosidade ou para quem é fã e quer saber mais detalhes dos jogos.

Até mais!

Alguém se lembra: Top Gear?

Nunca tive um Super NES, nem gostava de jogos de corrida, mas de tanto ouvir falar, resolvi dar uma chance para Top Gear:


E não é que o jogo é legalzinho! :)

Gostava muito de Out Run do Master System (não que tenha muitas coisas em comum...), mas esse não deixa a desejar (é, algumas vezes, até mais divertido).

Quer saber mais desse jogo inesquecível dos anos 90? Então aproveite, e veja uma jogatina feita pelo canal Velberan:


Obs.: Só não pense que é um Gran Turismo ou um Forza, que, na época, os jogos tinham que ser divertidos, não serem realistas. :P

Até mais!

quarta-feira, 9 de maio de 2018

Dicas de Programação: Como transformar uma imagem colorida em preto e branco (Android)?

A maneira mais na raça é fazendo uma média aritmética entre o vermelho, verde e azul (RGB) de cada pixel da imagem:

Bitmap image = BitmapFactory.decodeStream(new FileInputStream("image.jpg"));
Bitmap grayImage = Bitmap.createBitmap(image.getWidth(), image.getHeight(), image.getConfig());
for (int x = 0; x < image.getWidth(); x++) {
      for (int y = 0; y < image.getHeight(); y++) {
             int color = image.getPixel(x, y);
             int blue = color & 0xFF; //obtém o valor "azul" do RGB (0,0,255)
             int green = (color & 0xFF00) >> 8; //obtém o valor "verde" do RGB (0,255,0), para isso, se desloca o valor 8 bits para direita
             int red = (color & 0xFF0000) >> 16; //obtém o valor "verde" do RGB (255,255,0), para isso, desloca o  valor 16 bits para direita
             int mid = (blue + green + red) / 3; //média aritmética
             int gray = Color.argb(0xFF, mid, mid, mid);
             grayImage.setPixel(x, y, gray);
      }
}
grayImage.compress(Bitmap.CompressFormat.JPEG, 75, new FileOutputStream("image_gray.jpg"));

A maneira mais fácil (e mais performática), seria mais ou menos esta:

ColorMatrix colorMatrix = new ColorMatrix();
colorMatrix.setSaturation(0f);
ColorMatrixColorFilter filter = new ColorMatrixColorFilter(colorMatrix);
Canvas canvas = new Canvas(grayImage);
Paint paint = new Paint();
paint.setColorFilter(filter);
canvas.drawBitmap(image, 0, 0, paint);


Até mais!

segunda-feira, 7 de maio de 2018

Alguém se lembra: Out Run?

Sabe um jogo de corrida que não é um jogo de corrida?

Confuso, mas é mais ou menos isso que é Out Run:


Out Run é um jogo de "dirigir" (como o próprio produtor do jogo costuma definir), feito pela Sega, onde você viaja entre vários cenários em uma Ferrari Testarossa conversível.

O legal é que, como não é um jogo de corrida, não existe posição (classificação) e, assim, pode-se ficar admirando as paisagens de 16 bits do jogo (acho que ele utilizava a placa Sega System 16) -- na época, eu achava o máximo. :P

Só não fica admirando demais, pois existe um tempo para completar o "circuito". :)

Ah... Saudades das maravilhas que o 16 bits proporcionava... :P

Abaixo, uma jogatina feita pelo canal World of Longplays:


Até mais!

quinta-feira, 25 de janeiro de 2018

Alguém se lembra: Dick Tracy para Mega Drive?

Sabe de um jogo baseado em um personagem de HQ que era gostoso de se jogar, mas que o final é decepcionante? (né, seu Shinobi para Master System...)

Esse jogo era Dick Tracy para Mega Drive.


Putz, era um ótimo jogo de tiro/ação, com gráficos decentes, boa jogabilidade e um alto desafio.

Pena que o final era um maldito "game over"! (não me lembro de nem ter visto créditos!) :(


Se vale a pena jogar? Pela diversão, sim! Agora, se você espera satisfação ao terminar... Bem..., quem disse que o mundo (dos games) é perfeito... :P

Obs.: Vídeo do canal DAZZYVANDAM RETRO GAMING.

Até mais!

Dicas de programação: Como gerar um Dictionary através de dois Arrays (Swift)?

Bem simples! Com o comando zip (a partir do iOS 8):

let fields = ["nome","sobrenome"]
let data = ["Ricardo", "Takemura"]
let union = zip(fields,data)
let dict = Dictionary(uniqueKeysWithValues: union)

Fácil, não? :P

Até mais!

Dicas de Programação: Como abrir um PDF no WebView do Android?

De uma maneira fácil, é usar o viewer do Google. Por exemplo, quero abrir o seguinte pdf:

https://www.portal.ufpr.br/tutoriais_normaliza/pagina_texto.pdf

Basta usar a url "https://docs.google.com/gview?embedded=true&url=[url_do_pdf]" no loadUrl do objeto WebView do Android:

...
private WebView webView;
...
webView = (WebView) findViewById(R.id.webView)
...
webView.loadUrl("https://docs.google.com/gview?url=https://www.portal.ufpr.br/tutoriais_normaliza/pagina_texto.pdf&embedded=true")
...

Simples assim! :)

Até mais!