Programação, diversão e arte. Por Ricardo Giaviti
Posts tagged Programação
Montando ambiente completo Windows + Apache + PHP + MySQL com XAMPP
Jul 26th
Montar um ambiente de desenvolvimento do zero usando o Windows, Apache, PHP e o MySQL sem nenhum pacote pronto, não é tão trivial. Por isso existem esses pacotes prontos que fazem todo o serviço de instalação e configuração para nós e ainda nos fornecem ferramentas úteis.
Uma dessas ferramentas e a melhor que encontrei até agora é o XAMPP. Esse pacote nos fornece um conjunto de ferramentas prontas para nos auxiliar no desenvolvimento de PHP com MySQL. Dentre as ferramentas oferecidas estão:
- Servidor web Apache;
- Banco de dados MySQL;
- Interpretador PHP versão 5 e 4;
- PHPMyAdmin – Administração do MySQL;
- Painel de controle para iniciar e parar os serviços;
- Perl;
- Tomcat – Instalação via add-on;
Existem muito mais coisas que estão disponíveis no site oficial. Visite o site para ter mais informações sobre o que vem mais com o pacote.
Para baixar, acesse o site e baixe a versão .EXE auto-installer. Com essa versão basta clicar Install e você terá seu XAMPP instalado.
A instalação é um pouco demorada. Relaxe. É assim mesmo!
Após a instalação, irá aparecer uma tela de console perguntando se você deseja adicionar atalhos no menu iniciar e na área de trabalho. Aqui você precisará digitar “y” para sim e “n” para não. Sem aspas, claro. Digite sua resposta e tecle Enter.
Depois dessa pergunta, haverá mais uma pergunta em console que você terá que responder “y”. Na outra questão que irá aparecer, será perguntado se você quer transformar o XAMPP em portátil colocando ele em pen-drives. Não é nosso caso, sendo assim, responda “n”.
Feito isso, está quase tudo pronto. O instalador fará alguns procedimentos e levará você para uma outra tela de console onde haverá um menu com várias opções. A única opção que nos interessa, por enquanto, é a opção 1 – Start XAMPP Control Panel. Essa opção iniciará o painel de controle do XAMPP. Nesse painel de controle podemos iniciar o servidor apache e o MySQL por exemplo.
Abaixo está uma figura do Painel de controle do XAMPP. Clique em START para o Apache e para o MySQL. Os dois serviços iniciará e aparecerá a informação Running, ao lado e em verde. Isso significa que os serviços de banco de dados e servidor apache estão rodando.
Feito isso, tudo está pronto. Só vamos validar a instalação abrindo qualquer navegador e digitando na barra de endereço: http://localhost.
Navegador:
Agora, para começar a desenvolver, basta colocar seus scripts PHP em htdocs, que fica dentro da pasta de instalação do Xampp.
Enjoy!
Usando breakpoint condicional no Eclipse
Jul 3rd
Quando estamos debugando uma aplicação Java pelo Eclipse, é muito comum querermos que a thread que se está executando seja suspensa de acordo com o valor de uma variável.
Por exemplo, nossa aplicação está apresentando um NullPointerException. Então desconfiamos que talvez uma variável está com valor null dentro de um loop. Ao invés de ficarmos percorrendo todo o loop até ver se a variável está nula, podemos colocar uma condição no breakpoint que vai dentro do loop que verifica se essa variável é nula. Se a expressão da condição for verdadeira, a thread é suspensa automaticamente no breakpoint.
Veja como usar o breakpoint condicional:
No Eclipse, adicione um breakpoint e depois de adicionado clique sobre esse mesmo breakpoint com o botão direito do mouse. Escolha a opção “Breakpoint Properties”. veja na imagem abaixo a opção:
Na tela que se abrir, marque a opção “Conditional” e digite logo abaixo a condição que você quer que seja verdadeira para que o breakpoint suspenda a thread em execução.
Eu usei um exemplo de comparação equals de uma String. Mas você pode usar qualquer expressão lógica. veja a imagem abaixo:
Pronto. Clique OK e seu breakpoint agora é condicional.
Note-se que usei o Eclipse Helios e Windows XP para o desenvolvimento desse mini-tutorial.
eXtreme Go Horse (XGH)
Jan 15th
Reblogando um post sensacional achado em http://gohorseprocess.wordpress.com.
Todas as vezes que eu leio esse post eu me identifico mais com os projetos que eu participo. Acredito que até daria para fazer uma eXtreme Go Horse Plus Plus (XGH++).
Parabéns ao criador!
1- Pensou, não é XGH.
XGH não pensa, faz a primeira coisa que vem à mente. Não existe segunda opção, a única opção é a mais rápida.
2- Existem 3 formas de se resolver um problema, a correta, a errada e a XGH, que é igual à errada, só que mais rápida.
XGH é mais rápido que qualquer metodologia de desenvolvimento de software que você conhece (Vide Axioma 14).
3- Quanto mais XGH você faz, mais precisará fazer.
Para cada problema resolvido usando XGH, mais uns 7 são criados. Mas todos eles serão resolvidos da forma XGH. XGH tende ao infinito.
4- XGH é totalmente reativo.
Os erros só existem quando aparecem.
5- XGH vale tudo, só não vale dar o toba.
Resolveu o problema? Compilou? Commit e era isso.
6- Commit sempre antes de update.
Se der merda, a sua parte estará sempre correta.. e seus colegas que se fodam.
7- XGH não tem prazo.
Os prazos passados pelo seu cliente são meros detalhes. Você SEMPRE conseguirá implementar TUDO no tempo necessário (nem que isso implique em acessar o BD por um script malaco).
8- Esteja preparado para pular fora quando o barco começar a afundar… ou coloque a culpa em alguém ou algo.
Pra quem usa XGH, um dia o barco afunda. Quanto mais o tempo passa, mais o sistema vira um monstro. O dia que a casa cair, é melhor seu curriculum estar cadastrado na APInfo, ou ter algo pra colocar a culpa.
9- Seja autêntico, XGH não respeita padrões.
Escreva o código como você bem entender, se resolver o problema, commit e era isso.
10- Não existe refactoring, apenas rework.
Se der merda, refaça um XGH rápido que solucione o problema. O dia que o rework implicar em reescrever a aplicação toda, pule fora, o barco irá afundar (Vide Axioma 8).
11- XGH é totalmente anárquico.
A figura de um gerente de projeto é totalmente descartável. Não tem dono, cada um faz o que quiser na hora que os problemas e requisitos vão surgindo (Vide Axioma 4).
12- Se iluda sempre com promessas de melhorias.
Colocar TODO no código como uma promessa de melhoria ajuda o desenvolvedor XGH a não sentir remorso ou culpa pela cagada que fez. É claro que o refactoring nunca será feito (Vide Axioma 10).
13- XGH é absoluto, não se prende à coisas relativas.
Prazo e custo são absolutos, qualidade é totalmente relativa. Jamais pense na qualidade e sim no menor tempo que a solução será implementada, aliás… não pense, faça!
14- XGH é atemporal.
Scrum, XP… tudo isso é modinha. O XGH não se prende às modinhas do momento, isso é coisa de viado. XGH sempre foi e sempre será usado por aqueles que desprezam a qualidade.
15- XGH nem sempre é POG.
Muitas POG’s exigem um raciocínio muito elevado, XGH não raciocina (Vide Axioma 1).
16- Não tente remar contra a maré.
Caso seus colegas de trabalho usam XGH para programar e você é um coxinha que gosta de fazer as coisas certinhas, esqueça! Pra cada Design Pattern que você usa corretamente, seus colegas gerarão 10 vezes mais código podre usando XGH.
17- O XGH não é perigoso até surgir um pouco de ordem.
Este axioma é muito complexo, mas sugere que o projeto utilizando XGH está em meio ao caos. Não tente por ordem no XGH (Vide Axioma 16), é inútil e você pode jogar um tempo precioso no lixo. Isto fará com que o projeto afunde mais rápido ainda (Vide Axioma 8). Não tente gerenciar o XGH, ele é auto suficiente (Vide Axioma 11), assim como o caos.
18- O XGH é seu brother, mas é vingativo.
Enquanto você quiser, o XGH sempre estará do seu lado. Mas cuidado, não o abandone. Se começar um sistema utilizando XGH e abandoná-lo para utilizar uma metodologia da moda, você estará fudido. O XGH não permite refactoring (vide axioma 10), e seu novo sistema cheio de frescurites entrará em colapso. E nessa hora, somente o XGH poderá salvá-lo.
19- Se tiver funcionando, não rela a mão.
Nunca altere, e muito menos questione um código funcionando. Isso é perda de tempo, mesmo porque refactoring não existe (Vide Axioma 10). Tempo é a engrenagem que move o XGH e qualidade é um detalhe desprezível.
20- Teste é para os fracos.
Se você meteu a mão num sistema XGH, é melhor saber o que está fazendo. E se você sabe o que está fazendo, vai testar pra que? Testes são desperdício de tempo, se o código compilar, é o suficiente.
21- Acostume-se ao sentimento de fracasso iminente.
O fracasso e o sucesso andam sempre de mãos dadas, e no XGH não é diferente. As pessoas costumam achar que as chances do projeto fracassar utilizando XGH são sempre maiores do que ele ser bem sucedido. Mas sucesso e fracasso são uma questão de ponto de vista. O projeto foi por água abaixo mas você aprendeu algo? Então pra você foi um sucesso!
22- O problema só é seu quando seu nome está no Doc da classe.
Nunca ponha a mão numa classe cujo autor não é você. Caso um membro da equipe morra ou fique doente por muito tempo, o barco irá afundar! Nesse caso, utilize o Axioma 8.
Fonte: http://gohorseprocess.wordpress.com/extreme-go-horse-xgh/
Configurando ambiente de desenvolvimento C++ no Windows com Eclipse e MinGW
May 11th
O Eclipse é uma das melhores IDEs de desenvolvimento Java no mercado. O que pouca gente sabe, é que ela também pode ser usada para desenvolvimento de aplicações utilizando o C++. Nesse pequeno tutorial, mostrarei como instalar o compilador C++ para Windows (MinGW) e utilizar o Eclipse para trabalhar com esse compilador.
O compilador MinGW (Minimalist GNU for Windows) é uma versão portada para Microsoft Windows do conjunto de ferramentas GNU. Este software inclui um conjunto de arquivos cabeçalho para a API do Windows que permite aos desenvolvedores usar o GCC para criar programas nativos em Windows sem precisar contar com uma emulação em tempo real de um sistema Unix-like.
Ambiente usado nesse tutorial:
- Windows XP SP2
- Eclipse 3.4 – Ganymede C++
O primeiro passo é baixar o Eclipse para C++. Para isso, vá ao site oficial do Eclipse (http://www.eclipse.org), clique em “Download Eclipse” e baixe a última versão do “Eclipse IDE for C/C++ Developers“. O Eclipse vem em uma pacote ZIP (quando Windows) com aproximadamento 68MB. Feito o download do Eclipse, descompacte o arquivo ZIP. Agora vamos ao próximo passo.
Nesse segundo passo, vamos baixar o MinGW, que é o compilador que utilizaremos. Acessem o site do MinGW (http://www.mingw.org), vá em “Downloads” e baixe a última versão do “Automated MinGW Installer“. Enquanto esse artigo esta sendo escrito, a última versão é a MinGW 5.1.4 de 26/04/2008. O arquivo é pequeno porque toda a instalação será feita online. Ele baixará todos os arquivos necessários na hora da instalação.
Existe alguns detalhes para se instalar o MinGW. Duplo clique no instalador e vamos começar a instalação. Você deverá estar conectado a Internet para instalar o MinGW com sucesso. Na primeira tela, clique em “Next“. Na segunda, marque a opção “Download and install“, igual na figura abaixo.
Depois clique em “I Agree” para aceitar a licensa GPL e na tela de escolha de pacote (Choose Package), marque a opção “Current“, para instalar a versão estável atual do MinGW.
- Previous: Versão estável anterior;
- Current: Versão atual estável;
- Candidate: Versão futura porém instável;
Na escolha de componentes (Choose Components), você deverá obrigatoriamente marcar as opções:
- MinGW base tools;
- g++ compiler
As outras opções (g77 compiler, Ada compiler…) são opcionais. Elas não são necessárias para o que pretendemos fazer com esse tutotial. Instale se você quiser.
Clique em “Next” e escolha o diretório de instalação. O diretório padrão e recomendado é o “C:\MinGW“. Avance mais uma vez e o instalador irá começar a fazer o download dos componentes e a instalação dos mesmos.
Após terminar, finalize o instalador e abra o Eclipse (que você descompactou no primeiro passo). Para rodar o Eclipse você irá precisar da JRE instalada. Caso você não tenha a JRE, basta fazer o download aqui: http://java.sun.com/javase/downloads/index.jsp. Selecione a opção: “Java SE Runtime Environment (JRE)“.
Com o Eclipse aberto, teremos a seguinte tela:
Até aí tudo certo? Agora vamos criar o nosso projetinho C++ de exemplo para ver se está tudo OK e se a compilação está funcionando. Para criar o projeto faça: “File > New > C++ Project“. Digite um nome para seu projeto e escolha a opção “Hello World C++ Project“. Verifique se o MinGW aparece no Toolchains. Abaixo segue uma figura para você ter uma referência:
Agora clique em “Finish” e vamos testar. O projeto será criado e você pode fechar essa tela de “Welcome” que aparece quando se inicia o Eclipse. Repare que o projeto criado está no lado esquerdo do Eclipse. Essa janela onde fica os projetos é chamada de “Project Explorer“. Expanda seu projeto, vá na pasta src e duplo clique no arquivo “Teste.cpp“. Você terá um código igual ao abaixo:
//============================================================================ // Name : Teste.cpp // Author : // Version : // Copyright : Your copyright notice // Description : Hello World in C++, Ansi-style //============================================================================ #include <iostream> using namespace std; int main() { cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!! return 0; }
Abaixo segue uma screenshot do Eclipse para você ter uma referência de como estarão as coisas nesse momento.
Agora vamos rodar o projeto. Para compilar e rodar esse projeto, clique no “Play” na barra de ferramentas lá em cima no Eclipse. Se tudo der certo, no console dele irá aparecer “!!!Hello World!!!“. Se aparecer, quer dizer que deu tudo certo e seu Eclipse está prontinho para ser usado como uma IDE de desenvovlimento C++.
Existem muitos livros e muitos tutoriais na Internet sobre C++. De uma pesquisada no Google sobre o assunto e você verá quanta informação você achará. Até a próxima e bons estudos.
Fontes:
Explicação sobre o MinGW: http://pt.wikipedia.org/wiki/MinGW
Como conectar o Java ao MySQL usando o NetBeans
Nov 25th
Pessoal, resolvi fazer esse artigo ensinando como se conectar a uma base de dados MySQL usando o Java porque vi que é uma dificuldade muito comum entre as pessoas que estão iniciando em programação. Espero que esse artigo ajude a todos que estão com essa dificuldade a sanarem suas dúvidas,
Esse artigo parte do pressuposto de que quem for seguir esse tutorial tenha o JDK (Java Development Kit) instalado assim como o MySQL e o NetBeans. Caso você não tenha nenhum deles, você pode baixar e instalar a partir dos sites oficiais. Abaixo segue os sites de cada um deles:
Para esse tutorial eu estou usando o JDK6, MySQL 5.0 e o NetBeans 6.5 rodando tudo em cima do Ubuntu 8.10 Intrepid Ibex.
O NetBeans possui algumas “facilidades” de conexão a banco de dados bem ao estilo “Next > Next > Ok”. Porém o tutorial foi feito na maneira tradicional.
Após tudo instalado hora de começar a colocar a mão na massa. O Java para se conectar a qualquer banco de dados precisa de um driver de conexão, esse driver é chamado de JDBC (Java Database Connectivity). Sem um JDBC não é possível fazer uma conexão a um banco de dados. Cada banco de dados possui seu próprio JDBC. Por exemplo a Oracle fornece um JDBC para ser usado em bancos Oracle, o PostGRESQL também fornece um JDBC para ser usado com o PostGRESQL e assim vai. Não é diferente com o MySQL. O pessoal do MySQL também disponibilizou um JDBC para ser usado em conexão Java – MySQL.
Um pouquinho mais de informação sobre os drivers JDBC pode ser encontrado aqui na Wikipedia.
Como o MySQL também nos fornece um JDBC, vamos baixa-lo do site oficial do MySQL. Endereço do JDBC é: http://dev.mysql.com/downloads/. No menu, clique em Connectors e depois em Connector/J. Agora é só fazer o download do JDBC. Feito o download descompacte o arquivo.
Vai ser descompactado vários arquivos como instruções e documentações mas o arquivo que nos interessa é um que termina com extensão .JAR. Até a finalização desse artigo o nome do JDBC do MySQL é mysql-connector-java-5.1.7-bin.jar
Esse é o JDBC que irá nos conectar a uma base MySQL. Guarde a localização desse arquivo. Agora vamos criar um banco de exemplo com alguns dados.
Se conecte ao MySQL com sua ferramenta favorita ou pelo console mesmo. Para esse artigo eu criei um banco com uma tabela e três colunas. Tudo bem simples. Se quiser seguir esse exemplo abaixo vai os script SQL para a criação. Basta rodar no banco. Fique a vontade para fazer o esquema de banco a sua maneira, só lembre de mais para frente no artigo adaptar o seu esquema de banco ao código.
Script SQL:
CREATE TABLE IF NOT EXISTS 'usuarios' ( 'nome' varchar(50) NOT NULL, 'email' varchar(50) NOT NULL, 'idade' int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; INSERT INTO usuarios (nome, email, idade) VALUES ('Ricardo', 'ricardo@meuemail.com', 23), ('José', 'jose@seuemail.com', 29);
Beleza! Banco criado e alguns dados inseridos. Vamos para o NetBeans!
Abra a NetBeans e teremos uma tela inicial parecida com essa:
Vamos criar nosso projeto. Para isso faça:
- Arquivo > Novo Projeto;
- Escolha categoria: Java. Projeto: Aplicativo Java;
- Clique em Próximo;
- Coloque um nome para o projeto e clique em finalizar;
Próxima tela após clicar no botão Próximo. Aqui é onde definiremos o nome para o projeto e mais algumas configurações.
Nosso projeto foi criado.
Agora vamos adicionar o driver JDBC para que nossa aplicação consiga se conectar ao Banco de Dados. Para isso:
- Clique com o botão direito em cima do Projeto > Propriedades.
- Selecione a opção Bibliotecas e clique no botão Adicionar JARs/pasta.
- Vá até o JDBC que baixamos do site do MySQL selecione o arquivo .jar
- Clique em OK > OK
Pronto. O JDBC já foi adicionado a nossa aplicação. Agora vamos fazer um pouco de código
Nós iremos fazer toda a conexão com banco de dados direto da classe principal que o NetBeans nos forneceu. Logicamente essa metodologia não segue as melhores práticas da programação e todo o resto, mas serve para você ter uma idéia de pelo menos como conectar sua aplicação a uma base MySQL.
O código gerado pelo NetBeans está assim:
package mysqlconnection; public class Main { public static void main(String[] args) { //Nosso código vai aqui } }
Vamos criar a conexão e vamos fazer um select básico no banco. Abaixo segue o código com a conexão, com o envio do select e o tratamento de exceção. O código está comentado com o que cada linha está fazendo:
package mysqlconnection; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class Main { public static void main(String[] args) { String driver = "com.mysql.jdbc.Driver"; //Classe do driver JDBC String banco = "MeuBD"; //Nome do Banco criado String host = "localhost"; //Maquina onde está o banco String str_conn = "jdbc:mysql://" + host + ":3306/" + banco; //URL de conexão String usuario = "root"; //Usuário do banco String senha = ""; //Senha de conexão try { Class.forName(driver); //Carrega o driver //Obtém a conexão com o banco Connection conn = DriverManager.getConnection(str_conn, usuario, senha); //Cria um statement para podermos mandar um SQL para o banco Statement stmt = conn.createStatement(); //Mandamos o SQL para o banco e obtemos um ResultSet String sql = "SELECT * FROM usuarios"; ResultSet rs = stmt.executeQuery(sql); //Percorrendo o ResultSet e obtendo os valores do banco while (rs.next()) { System.out.println(rs.getString("nome")); System.out.println(rs.getString("email")); System.out.println(rs.getInt("idade")); System.out.println("===================================="); } } catch (ClassNotFoundException ex) { System.out.println("Não foi possível carregar o driver."); ex.printStackTrace(); } catch (SQLException ex) { System.out.println("Problema com o SQL"); ex.printStackTrace(); } } }
Repare que na obtenção dos objetos a partir do ResultSet nós usamos como chave o nome da coluna no banco de dados.
Se estiver tudo certo, já podemos executar nosso código. Para isso faça aperta F6 ou clique no “Play”. Se tudo deu certo e se você utilizou o esquema de banco fornecido nesse post, a saída para console será assim:
run: Ricardo ricardo@meuemail.com 23 ==================================== José jose@seuemail.com 29 ==================================== CONSTRUÍDO COM SUCESSO (tempo total: 0 segundos)
Bacana hein?!
É isso pessoal, fizemos uma conexão bem simples a uma base de dados MySQL usando Java e JDBC. Espero que tenham gostado do artigo e até a próxima!
Experimente o Ruby Online
Nov 20th
Se você escuta falar sempre de Ruby (mas nunca testou) e gostaria de experimentar sem ter que instalar o interpretador no seu computador, o site Try Ruby! pode te ajudar. O Try Ruby! é uma interface Web para você testar a linguagem e parte dos seus recursos. É muito parecido com o IRB que o Ruby oferece quando o interpretador é instalado.
No Try Ruby! basta digitar os comandos no console do site e a saída vai sendo gerada. Realmente muito bom para quem quer conhecer.
Além de oferecer a possibilidade de você testar o Ruby em tempo real, você pode digitar help no Try Ruby! que o próprio site irá guiar você por um tutorial bem básico sobre Ruby utilizando o próprio console que o TR fornece.
Vamos começar a testar Try Ruby. Iremos começar com uma soma simples. Acesse o site e no console digite:
>> 4 + 3 => 7
Beleza! Estamos indo, agora digite:
6 * 7 => 42
Legal, agora vamos a um dos conceitos do Ruby que nos diz que tudo em Ruby é um objeto, inclusive os números que usamos. Já que um número é um objeto (fixnum), vamos chamar um método do nosso objeto:
10.next => 11
O Ruby contém diversos métodos para os objetos fixnum. Para ver a documentação completa do fixnum, clique aqui. Abaixo segue mais um exemplo de um método que podemos usar com o objeto fixnum. Esse método irá nos retornar a quantidade de bytes utilizadas pelo nosso objeto.
5.size => 4
Experimente esse número:
100000000000000000.size => 8
Ok. Estamos indo bem com números. Agora, vamos testar um pouco as Strings em Ruby. Vamos começar atribuindo instanciando uma nova String:
meu_nome = "Ricardo" => Ricardo
Vamos testar o que o Ruby nos oferece com relação a Strings:
meu_nome.upcase => RICARDO meu_nome.reverse => odraciR
Há diversos métodos para manipulação de Strings no Ruby. Você pode testar muito mais acessando a documentação oficial do Ruby para Strings aqui.
Você também pode experimentar os Arrays em Ruby. Vamos começar declarando 2 Arrays:
array1 = [1, 2, 3, 4] => [1, 2, 3, 4] array2 = [1, 2, 3] => [1, 2, 3]
Agora vamos somar (ou unir) esses dois array declarados:
array1 + array2 => [1, 2, 3, 4, 1, 2, 3]
Também podemos fazer a subtração deles:
array1 - array2 => [4]
Se você quiser a intersecção dos dois arrays, você pode conseguir isso facilmente assim:
array1 & array2 => [1, 2, 3]
Eu vou ficando por aqui, mas você pode continuar. Faça o guia que o site Try Ruby preparou. Como eu disse no começo do post, basta digitar help no console e o próprio Try Ruby irá guia-lo. Após terminar tudo você pode pegar a documentação do Ruby e ir praticando e vendo o que a linguagem oferece. A documentação oficial e completa de toda a linguagem Ruby você encontra aqui.
Se ainda não estiver satisfeito, você pode acessar o rubylearning.com. Existem diversos tutoriais e exemplos de código nesse site. Porém alguns você não conseguirá fazer no Try Ruby. Nesse caso eu aconselho a instalar o interpretador na sua máquina. Você pode baixar o interpretador no site oficial do Ruby: http://www.ruby-lang.org
Aos que estão chegando ao mundo Ruby, sejam bem vindos e espero que gostem da linguagem. Vejo vocês no próximo post e bons estudos.


















Recent Comments