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, 28 de dezembro de 2018
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!
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!
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!
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!
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();
...
}
....
}
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();
...
}
....
}
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!
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? {
...
}
}
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!
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!
Marcadores:
Japonês,
Jaspion,
SATO Company,
Seriado,
Toei Company,
Tokusatsu
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!
//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!
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:
Bizarro, não?
Até mais!
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!
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!
//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!
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!
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!
"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!
Pois é, agora eu descobri que dá para fazer algo semelhante em C#:
using System;
///Usado para fazer extensões
using System.Linq;
namespace Teste
{
///
public static class IntExtension
{
///
/// Converte um número decimal em binário (String)
///
/// Número a ser convertido (this)
///
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!
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
///
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
///
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!
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!
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!
"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!
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!
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...
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) {
...
}
}
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)
}
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....")
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!
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!
(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.
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!
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á.
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!
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!
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!
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!
Mas, fora esse desgosto, não deixa de ser um bom jogo. :)
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!
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!
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!
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!
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!
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!
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!
Assinar:
Postagens (Atom)