Meu primeiro canal: Osvaldice

Oi Pessoal, hoje eu estou aqui pra anunciar a criação do meu primeiro canal de Youtube: Osvaldice.

Ele começa pequeno e ainda sem um formato bem claro mas eu pretendo colocar lá algumas reflexões que tenho e até mesmo algumas coisas da minha vida pessoal e profissional.

O nome do canal é Osvaldice porque é um trocadalho ruim mesmo 🙂

Vídeo de estreia

Pretendo lançar vídeos semanais mas ainda não consigo garantir a regularidade das publicações porque estou em processo de mudança para o Brasil e as coisas estão meio bagunçadas por aqui.

O canal vai começar com 3 vídeos que gravei na última semana e fiz todos eles em uma situação meio improvisada aqui na Alemanha por motivos de “meu equipamento principal está indo para o Brasil”.

Estou criando esse canal para experimentar e aprimorar minhas habilidades de produtor de vídeo para viabilizar meu segundo canal: Cômputos. Já faz vários meses que estou trabalhando no Cômputos mas ainda não consegui encaixar o formato dentro de algo que me deixe feliz. Então o Osvaldice pode me ajudar nessa tarefa e me deixar mais “acostumado” com a câmera.

O canal Cômputos vai ser destinado à apresentar a computação como algo lúdico e divertido. Computação como hobby.

Quando o canal sair eu volto aqui pra avisar.

PS. O blog continua, ok? Se o assunto for mais denso e cheio de referências eu provavelmente vou postar aqui no blog. Se o assunto for mais rápido e informal eu posto lá no Osvaldice.

publicado
Categorizado como Geral

Aprendendo a Programar

Dentre vários assuntos que tenho interesse na computação um deles é sobre o aprendizado de programação. Principalmente para crianças e jovens. Já li muita coisa e ouvi opiniões muito distintas sobre as melhores formas de se ensinar e aprender a programar um computador.

Existe muita discussão sobre se ensinar crianças a programar seria algo bom ou não, mas não pretendo descer muito nesse aspecto do debate. Para fins práticos vou partir da premissa de que ensinar crianças e jovens a programar não faria mal para eles e acrescentaria algumas habilidades úteis aos seus repertórios.

Lembrando sempre que ensinar programação para crianças não tem nada a ver com encaminhar crianças para a profissão de programador.

Como ensinar programação?

Nas minhas conversas sobre esse assunto, com diversas pessoas, eu já vi abordagem bem variadas para ensinar alguém a programar. O nível de convicção desses interlocutores sobre sua abordagem favorita variava muito. Alguns “achavam” que sua abordagem era boa e outros tinham “certeza” de que a sua abordagem era a melhor.

Um padrão que eu detectei foi: quando mais fácil foi para o interlocutor aprender a programar, mais certo ele estava de que o método usado com ele é o mais adequado.

Isso complica muito a discussão porque faz parecer que reproduzir um desses métodos vai funcionar pra todo mundo. E isso não é assim.

O que esses bons resultados, com abordagens diferentes revelam é justamente o oposto. Revelam que o que dá certo é usar abordagens diferentes com pessoas diferentes.

Abordagens

Eu me deparei com sugestões para os mais diversos tipos de abordagens para ensinar programação para iniciantes.

Existe uma abordagem que busca ensinar teoria e “lógica de programação”. Com computadores de verdade ou com computadores de papel. Alguns sugerem escrever código em “Portugol” em um pedaço de papel para fazer os famigerados “teste de mesa” e só depois ir para o computador. Outros sugerem usar Portugol direto no computador (ou Pascal).

Outras pessoas já me disseram que programador tem logo que começar a aprender a programar em C pra já ficar mais próximo da máquina. Eles sugerem C porque seria uma espécie de “assembly multiplataforma”.

Estou lendo um livro muito bom que sugere ensinar computação (e não só programação) partindo de portas lógicas NAND até implementar um jogo de Tetris.

Por outro lado outros amigos imaginam que o melhor mesmo seria usar alguma linguagem de nível mais alto mas que ainda são linguagens de uso geral como Python, Javascript, Processing, Arduino/C++, etc.

Alguns outros adoram ver seus filhos se divertindo com plataformas especificamente criadas para crianças como Scratch.

O que eu acho dessas abordagens? Na verdade não importa o que eu acho porque não estamos falando do meu aprendizado. Eu já aprendi a programar (eu acho?) e cada uma dessas abordagens funcionou para algumas pessoas e também falhou com outras.

Qual abordagem é melhor?

Ok. Então significa que não existe uma abordagem que funcione para ensinar programação? Não exatamente. Não existe uma abordagem que funcione. Existem várias.

Pessoas diferentes aprendem de modo diferente e isso precisa ser respeitado. Então o certo seria iniciar o ensino com uma das abordagens apresentadas e ir iterando sobre ela para ir ajustando o curso. E focar muito nas práticas e atividades que funcionam melhor para aquele aluno ou para a média daquela turma (caso não seja possível individualizar o ensino).

Dentre várias práticas observadas por cientistas que já se debruçaram sobre o assunto as que mais se mostram positivas para facilitar o aprendizado são aquelas que apresentam o feedback mais amplo e rápido para o aluno.

Quando um aluno experimenta algo no computador e vê o resultado daquilo surgindo instantaneamente o cérebro dele dispara recompensas que ajudam muito a fixação do aprendizado. Por outro lado se ele observa o feedback com a visão, com o olfato, com o tato, com a interação com pessoas, etc o efeito dessa recompensa é potencializada ainda mais.

Essa potencialização do feedback é que fez com que o Seymour Papert, criador do ambiente LOGO para ensino de programação para crianças, disponibilizasse uma tartaruga robô no ambiente que ele desenvolveu. O robô existia para reforçar o feedback das crianças quando ela digitava um comando “PARAFRENTE 10” (ou “FRENTE 10” na variante Microsol LOGO) e via aquele robozão andando sozinho obedecendo à instrução fornecida pela criança. Isso tudo está descrito em seus dois livros.

A ideia de feedback rápido também é explorada nesse artigo incrível do Brett Victor chamado Learnable Programming que serviu de referência para a Apple criar o ambiente Swift Playgrounds.

Então, se voltarmos para as abordagens propostas que descrevi acima, podemos trabalhar com várias delas desde que seja possível obter feedback amplo e rápido nas atividades desenvolvidas.

Tanto o Seymour Papert quanto o Brett Victor apresentam outras práticas úteis no ensino de programação (e, acredito, de qualquer outro tipo de conteúdo). Sugiro a leitura de ambos para se preparar para a tarefa de ensinar programação.

Qual abordagem funcionou pra mim?

Eu sou um privilegiado sortudo. Tive pais que tinham uma boa condição de vida (aka classe média) e nunca pouparam grana e esforço em me apoiar.

Eu já contei um pouco essa história aqui mas resumidamente eu era uma criança de 9 anos que brincava com Eletrônica junto com um amigo e esse amigo ganhou um computador de natal. Eu fiquei completamente entusiasmado com aquilo e pedi um computador pro meu pai.

Demorou um pouco pro meu pai conseguir comprar o meu primeiro computador (MSX Expert) usado de um tio mas ele chegou lá e eu comecei a estudar com os livros que acompanhavam a máquina. Mas aí eu travei em um ponto do aprendizado e passei a usar a máquina só pra jogar.

Meu pai viu aquilo e me cobrou: poxa filho… investimos uma grana alta nesse computador pra você aprender a usar ele e você fica só jogando? Você já tinha um videogame pra jogar (um Atari), não precisava de um computador caro pra isso.

Expliquei pra ele que eu já tinha lido todos os livros e feito todos os experimentos que vinham nele e “não tinha mais pra onde ir”.

Ele entendeu o problema e perguntou se eu queria fazer um curso de computação? “- Claro!”.

Ele encontrou uma escola de computação no bairro onde eu morava através da lista telefônica (é… anos 80/90…) e me matriculou lá. Meu pai não entendia nada de tecnologia e me matriculou nessa escola só porque eu poderia ir sozinho até ela (bairro Boa Vista em São José do Rio Preto – SP).

E até aqui mostra como fui/sou uma pessoa privilegiada. Mas agora vem a parte onde eu fui sortudo…

Essa escola perto de casa, no interior de SP, era de um casal que tinha ganhado uma grana alta em um desses de plano de demissões voluntárias e foram para os Estados Unidos, no MIT, estudar no grupo LOGO do próprio Seymour Papert, pra trazer o método pro Brasil. Eles montaram essa escola usando essa abordagem.

E é aqui que eu ganhei na loteria.

No curso eu aprendi LOGO (variante Microsol LOGO) e BASIC em máquinas Apple II (TK3000 e Exato Pro). Eu saia da aula todo dia e tentava refazer tudo o que aprendi no meu MSX Expert (que não tinha LOGO e tinha um dialeto diferente de BASIC).

Depois eu ia para a casa daquele meu amigo que tinha um Apple II (um raríssimo Spectrum ED) onde ele já estava ralando pra aprender Assembly de 6502 (e eu ali do lado me aventurando junto).

Em dezembro de 1989 eu concluí o curso na “Escola Inteligente” (é… era o nome da escola) e me formei em programação LOGO e BASIC aos 12 anos de idade. Alguns meses depois eu comecei a trabalhar como programador em uma imobiliária da cidade, mas isso é outra história.

Conclusão

Depois desse tempo todo eu acho que não importa se você vai ensinar programação com Scratch, Python, C/C++, Arduino ou pela eletrônica. O importante é que você consiga produzir feedback rápido e amplo por todo o caminho do aprendizado.

publicado
Categorizado como Geral

Pai

Me deu vontade falar do meu pai. Mas acho melhor escrever porque sempre acabo chorando quando falo dele. Não é aniversário dele nem nada. Só deu vontade mesmo.

Eu me chamo Osvaldo (Neto), meu pai se chamava Osvaldo (Júnior). E meu avô, adivinhem?, chamava Osvaldo. Só Osvaldo mesmo.

Pra escrever sobre meu pai eu acho pertinente falar do pai dele. Meu avô me adorava. Eu era “O” neto que carregava o nome dele na dinastia da família e isso era muito importante pra ele. Quando eu era criança e não entendia muito as coisas da vida eu gostava dele também.

Mas a gente cresce e as pessoas que conheciam ele nos contam como ele era. E ele era horrível. Uma pessoa monstruosa. Com tudo e com todos. Meu avô apoiava os militares durante a ditadura e provavelmente não comandou sessões de tortura porque não devem ter dado essa oportunidade para ele. Porque sei que ele espancava os filhos ao ponto de pararem no hospital. Meu pai foi a maior vítima do meu avô. Todos os meus tios contam. E acho até que foi uma das razões para que os irmãos cuidassem do meu pai até mesmo quando ele não merecia.

Quando minha mãe ficou grávida (de mim) meu avô ofereceu ao meu pai a opção de pagar pelo aborto. Meu pai recusou e, por conta disso, teve que sair de casa. Minha mãe me conta que esse começo foi bem difícil mas eles tiveram muito suporte das minhas avós e de alguns tios (sempre que falo tios aqui são os irmãos do meu pai porque minha mãe é filha única).

A relação do meu pai com o meu avô sempre foi simbiótica. Eles se amavam e se odiavam. Eles queriam se afastar mas não conseguiam viver afastados. Meu pai acompanhou a vida do meu avô até a morte dele.

Lembro que no velório do meu avô os irmãos e filhos (meus primos) se encontraram e, logo depois, no mesmo dia, estavam todos bebendo, contando piadas e rindo. Eu não entendia porque estavam felizes naquele dia. Mas hoje eu entendo.

Meu pai é um homem do tempo dele. Criado com esse tipo de valores. Ele certamente teria se tornado um monstro pior do que o meu avô se a minha avó não fosse o ser humano mais iluminado que já habitou esse planetinha aqui. Minha avó já tinha falecido anos antes.

Meu avô era um monstro. Mas por causa da minha avó o meu pai se tornou humano. Mas não aquele humano que carrega só virtudes. Ele era humano, humano mesmo. Complexo. Caótico.

Ele era uma figura magnética. Ele era atraente e sedutor. As pessoas queriam estar com ele. Ele era inteligente e apaixonante. Até as pessoas que ele maltratava precisavam estar com ele. Ele conversava sobre qualquer coisa (porque lia muito) e sempre virava o centro das atenções.

Mas ele ainda tinha aquela parte “monstro”. Ele era infiel à minha mãe (no que os tios passavam pano ao culpar minha mãe por não ser uma boa esposa carinhosa). Minha mãe, admito, não é fácil. Mas ela nunca foi desleal ou infiel à ele.

Ele era violento. Lembro de uma cena quando tinha uns 8 ou 9 anos em que ele brigou com a minha mãe e num ato de violência suspendeu ela pelo pescoço com um cabo de vassoura contra a parede. Eu lembro de pular em cima dele pra afastar dela. E depois eu não lembro mais nada.

Mas ele era o cara forte. Ele era minha figura paterna. O cara que sabia desmontar e montar qualquer coisa. Sabia usar as ferramentas todas.

Aprendi a usar ferramentas com ele. Não foram aulas tipo: “olha, filho, essa daqui é uma chave de fenda”. Tava mais para “me dá a chave de fenda… Essa não idiota, você é burro? Já te disse que essa é a Philips”. Mas ele ainda era meu pai. O superherói, saca? Ele estava certo. Eu devia ser burro mesmo.

Mas esse cara aí, em toda a sua complexidade, também patrocinou várias empreitadas minhas. Ele comprou e montou todo meu laboratório de eletrônica quando disse que gostava daquilo. Assinou revista de eletrônica e tudo.

Também vendeu um dos nossos carros e fez vaquinha na família pra comprar meu primeiro computador. E me defendeu quando minha mãe ficou full-pistola comigo porque gastei meu primeiro salário em livros de computação.

Lembro de um dia que estava lendo uma revista de eletrônica para entender como um transistor funcionava. Eu já devia ter 9 anos (em alguns meses eu veria um computador pela primeira vez). Ele passou pela sala várias vezes e eu estava lá compenetrado na leitura da revista.

Ele ficou encafifado com a cena e perguntou: “— Filho, você tá gostando mesmo desse negócio de eletrônica, né?”. E eu respondi: “— Tô sim pai, mas é muito difícil… o meu colega lá aprende isso tudo rapidinho e eu to sofrendo pra entender.” e ele então responde, despretensiosamente, algo que carrego no coração: “— Olha filho, ele pode ser muito inteligente e aprender rápido, mas eu vejo que você é muito esforçado e isso é muito melhor”.

Eu adorava ficar com ele. Tinha noites que ele ia pro quartinho da casa, pegava o revolver Taurus .38 que ele tinha, colocava na mesa, e começava a desmontar tudo. Limpava e lubrificava. E depois montava novamente. No dia seguinte a gente ia para a fazenda do meu tio para dar tiros em latinhas. Minha mãe detestava isso. Mulheres são sempre mais sensatas.

Eu olhava para o meu pai e pensava: “cara, quando crescer eu quero ser assim!”. Tudo o que eu fazia na vida era com o objetivo de impressionar ele. Deixar ele orgulhoso de mim. Mostrar pra ele que eu não era burro nem idiota. Mas eu ainda falhava. Sempre falhava.

Mas meu pai também abandonou a gente. Lembro de quando ele simplesmente foi embora e não voltou. Eu, minha mãe, e minha irmã de 2 anos saímos do MS rumo ao interior de SP com um empréstimo da minha avó materna que pagava só a mudança mas não as passagens. Então viajamos na boléia do caminhão de mudanças.

E aí a minha mãe que não trabalhava se associou com minha avó e uma tia-avó e montaram um negócio de bijuterias que funcionou muito bem. Bem o suficiente para que meu pai ficasse com vontade de voltar. E ele voltou. E minha mãe aceitou ele de volta todo arrependido.

Eu já estava maiorzinho e até começaria a trabalhar com computação algum tempo depois que ele voltou. Mas eu ainda era tímido, introvertido, e bastante inseguro. Lembram? Eu era o menino burro.

Nessa época minha avó, mãe do meu pai, a pessoa mais maravilhosa que já conheci, faleceu. O cigarro levou ela da gente. E junto com ela levou a alma do meu pai. Daquele dia em diante meu pai oscilou, e oscilou, e se afundou, e se reergueu, e afundou de novo, e sumiu, e apareceu, e se separou da minha mãe, e voltou pra ela.

Minha avó, meus primos e eu vestido de quindim.

Lembro de ouvir ele discutindo com minha mãe no quarto. Eles falavam tão alto que eu conseguia ouvir do lado de fora. Lembro dele falar: “Esse menino é um mole. Ele é lerdo… parece desconectado do mundo. Não aprende as coisas”.

E eu fui crescendo. E agora eu ainda queria mostrar pra ele que eu não era burro. Mas agora era com ódio. Era “vou mostrar pra esse filha da puta quem é o burro”.

E a vida foi passando… e passando… e passando… eu aqui e ele lá.

Encontrei uma companheira para compartilhar minha vida e decidimos nos casar. Mas não sem fazer uma festa de noivado para as nossas famílias. E assim fizemos.

A festa foi muito bacana com direito à minha mãe ficar triste porque o filho dela iria se casar. Mas a conversa que eu ouvi do meu pai com outra pessoa foi: “— Netinho? (me chamam assim) Casamento? Isso aí é fogo de palha. Não dura um ano.” Estou junto com a Elaine desde então e já são quase 20 anos assim. Temos 2 filhos: Matheus e Mariana. Um menino e uma menina. Tal como eu e minha irmã mais nova.

Vovô com Matheus

Mas a vontade de mostrar pra ele que eu não era burro, lento e idiota estava lá. E agora eu acrescentei toda a família. Todos os tios precisavam entender que eu não era o filho burro de pais desajustados, que não tinha nenhum futuro.

E essa foi a bosta da minha vida. Levei minha vida inteira tentando provar algo para as outras pessoas e acabei esquecendo de mim mesmo. Isso derreteu minha alma.

E pra piorar, na ausência de uma figura paterna, eu projetei tudo o que eu queria ser em um dos meus tios. E ele se mostrou igual ao meu pai. Mas uma versão com muito mais desbotada e com muito menos charme.

Aos pouco e com muita terapia fui conseguindo acomodar esses sentimentos e me aproximando do meu pai. Dava pra conversar várias coisas exceto alguns tópicos mais políticos, afinal, eu era o petistinha da família.

Fui visitar ele algumas vezes onde ele morava. Conversávamos o dia todo. A saúde dele já não estava boa. Pressão alta, cigarro, bebida, sedentarismo e obesidade faziam parte do cardápio. A fórmula perfeita para um desastre.

Ele morreu enquanto dormia em casa na véspera do feriado do Natal de 2018. Encontraram o corpo dele alguns dias depois. Aparentemente ele teve um AVC enquanto dormia e não resistiu. A gente demorou pra saber que ele havia morrido porque ele tinha dito que estaria pescando no rio durante o feriado. E celular não pega lá onde ele estaria. No celular dele estavam todas as minhas mensagens desejando um Feliz Natal. Infelizmente ele não leu.

Quando fui buscar as coisas que ele tinha deixado minha tia me disse: “— A maior decepção da vida do seu pai foi você ter se tornado petista.” Ou seja, aparentemente eu falhei em deixar ele orgulhoso até a morte dele.

Pais e Filhos

Você culpa seus pais por tudo, isso é absurdo
São crianças como você
O que você vai ser
Quando você crescer?

– Legião Urbana

Quando eu estava pra me tornar pai eu pensei: “— Vou ser muito melhor do que meu pai foi pra mim.”

Hoje eu entendo como é complicado. Meu avô destruiu com a cabeça do meu pai. Ele, por sua vez, não fez tão bem assim pra minha cabeça também. Eu tenho total clareza que não passei nem perto de superar esses problemas. No máximo cheguei ao ponto de saber que eles existem.

O jeito mais fácil de me fazer chorar é falar sobre relacionamento pai e filho.

Eu olho pro meu filho e sinto um medo de gelar os ossos de decepcionar ele. Ao mesmo tempo não queria que ele olhasse pra mim com o mesmo tipo de idolatria que eu sentia pelo meu pai. Não quero esse sentimento dele porque tenho certeza que vou decepcioná-lo.

Queria dizer pra ele que eu acho ele fodapracaralho. Queria dizer pra ele que vai ser bem difícil me decepcionar. Que eu sinto orgulho dele até quando ele falha tentando. Ou melhor, eu já sinto orgulho dele quando eu vejo ele tentando. Não importa o resultado.

Queria que ele não depositasse admiração em mim. Não guiasse a vida dele com esse tipo de admiração. Quero que ele entenda rapidamente que ele tem um pai humano. Humano como todo pai.

Meu pai, filhos, netos e agregados da família.
publicado
Categorizado como Geral

Raspberry Pi 400

No artigo anterior vocês viram que comprei um Raspberry Pi 400. Quando enviei o artigo pro meu Twitter algumas pessoas pediram um review. Então esse post aqui é uma tentativa de mostrar o computador com mais detalhes.

Especificações

O Raspberry Pi 400 tem as configurações muito parecidas com a do Raspberry Pi 4 Model B de 4GB de RAM. As únicas diferenças estão no clock mais rápido (1.8GHz vs 1.5GHz) e a adição de uma porta USB 2.0 extra. Diferente do que se possa pensar não é um Raspberry Pi 4 montado dentro de um case com teclado. Todo o desenho da placa de circuito foi refeito e levou em consideração aspectos como temperatura de operação do circuito.

  • Broadcom BCM2711 com 4 núcleos Cortex-A72 (ARM v8) 64-bit SoC @ 1.8GHz
  • 4GB LPDDR4-3200
  • Wi-Fi Dual-band (2.4GHz e 5.0GHz) IEEE 802.11b/g/n/ac
  • Bluetooth 5.0, BLE
  • Gigabit Ethernet
  • 2 × USB 3.0 and 1 × USB 2.0 ports
  • Conector Horizontal 40-pin GPIO
  • 2 × micro HDMI (com suporte até 4Kp60). O kit que comprei já acompanha um cabo micro-HDMI/HDMI com aproximadamente 1m.
  • H.265 (4Kp60 decode); H.264 (1080p60 decode, 1080p30 encode); OpenGL ES 3.0
  • Entrada para cartão MicroSD (o kit que comprei acompanha um cartão de 16GB da Sandisk já com o SO instalado e pronto pra usar)
  • Teclado compacto 78/79-teclas (dependente do layout)
  • Conector para fonte 5V DC com conector USB-C (o kit que comprei já acompanha uma fonte compatível com pinos US
  • Dimensões máximas 286 mm × 122 mm × 23 mm

Eu adquiri o kit completo com layout US no teclado com a fonte também US (depois descobri que tem a opção US com fonte européia que certamente funcionaria com as tomadas brasileiras também). O kit também inclui cabos, cartão MicroSD com Raspberry Pi OS, e uma cópia impressa do livro The Official Raspberry Pi Beginner’s Guide 4th Edition (o link aponta para a terceira edição).

O kit completo aqui na Alemanha, onde moro, saiu por 97,38 € + 5,80 € de frete (total de 103,18 €).

Conectividade

O Raspberry Pi 400 oferece conexão para quase tudo o que você precisa.

Todas as conexões ficam dispostas na parte traseira do case e, conforme podemos ver na foto acima, temos (da esquerda pra direita):

  1. Conexão GPIO de 40 pinos no formato já padronizado pelas outras versões de placas Raspberry Pi.
  2. Slot para MicroSD.
  3. 2 x conectores Micro-HDMI para usar com até 2 monitores. Eu ainda não usei ele com 2 monitores mas consegui resolução de 3840 x 1080 no meu monitor Samsung Ultrawide 8k.
  4. Conector USB-C para carregador (não serve para dados).
  5. 2 x conectores USB-A 3.0.
  6. 1 x conector USB-A 2.0 para o mouse. Na internet as pessoas reclamam que o mouse fica ligado do lado esquerdo do computador e o fio é um tanto curto para alcançar o lado direito. Como eu sou canhoto e uso o mouse com a mão esquerda eu não senti o problema que parece ser real.
  7. 1 x conector Ethernet Gigabit.
  8. Wireless: ele disponibiliza Wi-Fi e Bluetooth 5.0 BLE.

Uso

Eu usei o meu Raspberry Pi 400 apenas 1 vez por algumas horas. Conectei todos os cabos, liguei, e logo já pude ver o splash screen com a framboesa na tela. Em poucos segundos a interface gráfica carregou e um aplicativo de configuração inicial começou a executar.

O aplicativo pergunta coisas sobre qual idioma você pretende usar, qual o layout do teclado, configuração de rede e por último pergunta se você quer atualizar o software.

Fiz a atualização de software que demorou uns bons minutos e então comecei a usar normalmente.

A primeira coisa que me impressionou bastante foi o fato de que ele conseguiu usar toda a tela do meu monitor com boa resolução (3840 x 1080). E olha que não é “qualquer” monitor.

Desculpem a bagunça 🙂

Experimentei vários aplicativos que acompanham o Raspberry OS. Dos mais leves (Terminal) aos mais pesados (LibreOffice e Chromium). Naveguei por vários sites e assisti videos no Youtube. A máquina se comportou bem e se mostrou bastante usável como uma máquina para o dia-a-dia.

Mas atualizar pacotes e usar IDEs mais pesadas mostraram que ela não é uma máquina destinada à um uso profissional para programadores. É importante lembrar que se trata de uma máquina com processador ARM, logo, vários softwares proprietários distribuídos em formato binário para Linux (ex. Zoom) não vão rodar nela. Lembre-se disso ao pensar em comprar um.

Um teste que infelizmente não consegui fazer é o de som. O Raspberry Pi 400 não possui auto-falante interno mas, em teoria, transmite audio pelo sistema HDMI (em teoria porque só testei em meu monitor que não tem sistema de audio). Eu conectei meu fone de ouvido Bluetooth nele e consegui assistir um video com audio no Youtube sem nenhum problema.

Quando liguei ele pela primeira vez o meu monitor não reconheceu ele de imediato (meu monitor é meio enjoado com conexões HDMI enquanto ele está ligado) e por isso pensei em resetar o Raspberry Pi 400 pra forçar a inicialização da conexão HDMI. Mas… descobri que ele não tem botão de Reset e nem botão de Liga/Desliga. Essa talvez seja a única coisa que senti falta no conjunto todo. A outra coisa que eu achei ruim foi precisar de um adaptador de tomadas para o formato US, mas descobri que foi erro meu em não ver a opção de tomada européia no site.

Resumo

Enfim, como eu disse no meu artigo anterior, eu curti a sensação de usar o Raspberry Pi 400 e fiquei muito feliz com a compra. Pretendo usar ele na minha bancada de eletrônica assim que comprar um monitor pra conectar nele. Mas certamente não servirá como uma máquina principal.

Eu também não recomendaria ele para usuários de outros Raspberry Pi’s se você usa esses dispositivos como proxy, roteador, NAS, media player, ou emulação de consoles. Pra esses casos eu ainda ficaria com as placas convencionais. Não vale a pena gastar dinheiro extra por um computador que tem um case com teclado se você não vai usar ele como um computador.

publicado
Categorizado como Geral

Gostinho de infância

Frente em close up de um computador MSX Expert Cinza 1.0/1.1 da Gradiente vendido durante os anos 80

Comecei a mexer com computador quando era criança. Antes disso a brincadeira era com eletrônica.

Quando falo essas coisas nos dias de hoje as pessoas ficam pensando: “credo! que nerdão”, ou ainda “coitado, ao invés de estar brincando…”, ou “tadinho! que infância mais triste”.

Mas o que as pessoas não sabem é que na década de 80, quando eu era criança, computadores pessoais eram vendidos para o público infantil. Era assim porque não dava pra fazer muita “coisa de adulto” com máquinas de 8 bits, poucos kilobytes de memória e processadores limitados.

As fabricantes anunciavam os computadores como “brinquedos que deixariam seus filhos mais inteligentes”. As crianças queriam computadores porque eles tinham jogos muito legais mas usavam o argumento da inteligência para convencer o pai e o Papai Noel da necessidade dessa máquina de criar gênios.

Mas os computadores não foram os primeiros brinquedos que foram vendidos ou comprados com esse argumento. Naquele tempo a gente tinha uma infinidade de kits de química, kits de eletrônica, ferramentas de brinquedo, revistas, livros e enciclopédias para os pais poderem gastar seu dinheiro e deixar seus filhos mais espertos.

No mercado editorial existiam revistas específicas para crianças e jovens aprenderem eletrônica. Li muito a coleção da Divirta-se com Eletrônica, Be-a-Bá da Eletrônica e cheguei a ganhar uma assinatura da Experiências e Brincadeiras com Eletrônica Júnior do meu pai. A primeira vez que vi um computador e entendi mais ou menos para quê eles serviam foi na revista Informática Eletrônica Digital.

Eu não tenho dados para darem suporte à minha suposição mas eu imagino que uma geração inteira de engenheiros, cientistas, professores, pesquisadores, etc “escolheram suas profissões” brincando com essas coisas.

Sei que escolher uma profissão tão novo não é algo muito legal, mas acreditem, até essa “escolha da profissão” era uma brincadeira em si. Eu já fui empresário do ramo de elevadores à dono de emissora de rádio passando pelo tão sonhado (até hoje) cargo de desenvolvedor de jogos de Atari. Não fui nada disso mas hoje estou aqui: programador.

Computadores dos anos 80

Como disse os computadores dos anos 80 não eram providos de muito poder computacional. Eles tinham formatos que variavam entre um case com um teclado e todo o circuito eletrônico do computador era montado dentro desse mesmo case. Alguns modelos (como o meu MSX Expert) tinha um teclado destacado da “CPU” em si mas no geral ficava tudo em um único lugar.

Foto de um computador TK85 Preto da Microdigital. O computador era montado em um case junto com o teclado com teclas pequenas de borracha.

Monitores eram caros na época mas todo mundo já tinha um televisor em casa. Então essas máquinas frequentemente eram ligadas nas TVs da sala. Isso tornava a gente bem produtivo porque precisava terminar tudo o que queria antes da novela da mãe (e do pai). Minha ascensão social começou quando meu pai me deu uma TV PB exclusiva pra usar com meu computador.

Nas minhas primeira interações com um computador a gente copiava os programas dos manuais, executava, corrigia os erros de digitação (prova de que aprendemos primeiro a depurar e só depois aprendemos a programar), executava com sucesso, brincava com o programa e perdia tudo desligando a máquina. Não tinha onde gravar o programa.

Mais adiante tive acesso à um computador com gravador cassete que deixava a gente gravar os programas em fita. O barulhinho gravado na fita é muito parecido com o barulho dos Modems da época da Internet discada. O princípio por trás dos dois sistemas é o mesmo.

Nessa época algumas pessoas mais abastadas já tinham drives de disquete (5 1/4″) mas eu fiquei na fita cassete até minha ida para o mundo dos PCs IBM/Intel. Quando a computação deixou de ser brinquedo. Deixou de ser brincadeira.

Computação e Programação

Naqueles tempos a gente não tinha acesso à Internet. Pra falar a verdade a Internet era acessível, talvez, apenas para militares e algumas universidades.

Os “civis” do lado de fora do muro da Reserva de Mercado até já tinham acesso à BBSs ou Videotexto (esse até apareceu no Brasil pela Telesp e Telemig mas eram caros e praticamente desconhecidos).

Por conta disso, se você quisesse estudar e aprender a usar os computadores você tinha um número limitado de opções: revistas, livros, poucos cursos, prática.

Os pais daquela época gastavam um dinheirão em um brinquedo (computador) para os filhos. As crianças ligavam essas máquinas e… uma tela preta com um cursos esperando comandos aparecia. E é isso.

Alguns modelos adicionavam um ou outro cartucho com jogo ou demo no pacote para distrair a criança (e os pais). Mas ainda assim não justificava o investimento no aparelho. Um videogame custaria bem menos.

Prevendo isso as fabricantes mais ricas investiam pesado no mercado editorial e lançavam seus produtos com belos manuais e livros que ensinavam programação. Alguns fabricantes fundaram editoras só pra publicar revistas no mercado.

Os manuais do meu Expert eram editados pela Editora Aleph. A maior editora de ficção científica nacional.

Foto com dois manuais do MSX Expert com encadernação espiral. O livro da esquerda se chama Dominando o Expert e o da direita se chama Linguagem BASIC MSX

Quando o nossos pais compravam um computador eles realmente recebiam um pacote de coisas que permitiam o uso daquele computador por uma criança e tudo o que estava ali tinha o objetivo de fazer você aprender a usar um computador do jeito mais pleno: programando.

Eu queria fazer jogos. E fiz alguns. Era uma delícia trazer os amigos do bairro pra jogarem os jogos que eu havia criado. Meus jogos, para os padrões gerais da época, eram razoavelmente divertidos.

Era possível usar aquela máquina para criar coisas que quase se igualavam àquelas coisas que você tanto curtia.

Hoje

Hoje eu sou pai. E vejo meus filhos na Internet. Ou jogando. Ou jogando na Internet. E só. Sempre com um computador. Seja ele no formato de um computador, tablet ou smartphone.

Meu filhos gostam de jogar e, certo dia, resolvi sentar com eles pra fazer um joguinho. Um jogo simples, claro. Um tubarão controlado pelo mouse que tinha que comer peixinhos no mar e desviar dos inimigos. Usamos o Scratch na brincadeira.

Legal! Jogaram um pouco e… valeu pai!… Nunca mais tentaram outra vez. Foram jogar os joguinhos que eles gostam… todos em 3D, com gráficos realistas e ação ininterrupta.

Não dá pra competir. Como falar pra uma criança que ficou 2~3hs trabalhando no “jogo do tubarãozinho” que ela consegue criar seus próprios jogos de verdade? Os jogos que eles jogam são quase inalcançáveis para uma criança.

Hoje eu sei que os jogos da Konami que eu jogava na década de 80 também eram ‘inalcançáveis’ pra mim. Mas na época não pareciam. E não sabendo que era impossível, fui lá, e tentei… sem sucesso. Mas tentei. 🙂

Algumas vezes me pego pensando se seria possível recriar a experiência que uma criança da década de 80 teve com computadores em uma criança dos dias de hoje.

Não tenho resposta pra essa pergunta e nem sei se vale a pena tentar. Talvez seja só uma porção grande de saudosismo da minha infância. Foi tão gostoso que gostaria que meus filhos sentissem o mesmo.

Não sei se vou conseguir mas vou seguir tentando. E nessa tentativa vi o lançamento do RaspberryPi 400. Parece que os ingleses que trabalham nesse projeto compartilham alguns sentimentos que descrevi aqui.

Os ingleses investiram pesado nessa brincadeira de computador pra crianças lá nos anos 80. E o projeto dos Raspberry e Microbit parecem estar tentando criar uma releitura modernizada dessa experiência. Torço muito por eles. E já comprei o meu porque bateu uma baita saudade e ninguém é de ferro.

Foto com um computador RaspberryPi 400 na mesa. O computador vem montado em um case com o teclado. O teclado é branco com detalhes em preto e rosa. Do lado do computador tem um mouse branco e rosa e um monte de cabos que acompanham o kit.
RaspberryPi 400 Desktop

publicado
Categorizado como Geral

NULL

foto do buraco negro Messier 87 que parece com um círculo de fogo desfocado sobre fundo preto

Quase todo desenvolvedor profissional vai ter que lidar com um banco de dados relacional ao longo de sua carreira. Os bancos de dados relacionais são uma daquelas ideias boas que a computação trouxe para o mundo.

Obviamente esses sistemas possuem limitações e essas limitações se dão tanto no nível conceitual como nas várias implementações de SGBD exitentes.

A limitação do modelo relacional existe porque não dá pra modelar o mundo que nos cerca usando conceitos tão “bidimensionais” como tabelas.

Ok, eu sei que dá pra modelar 3D, séries temporais, hierarquia, graphos, etc em bancos de dados relacionais, mas você vão concordar que as coisas começam a ter que ser ligeiramente “enjambradas” nas tabelas pra isso funcionar. E o funcionar ainda pode trazer algumas limitações.

Também tem as limitações de implementações do modelo. Os SGBDs ainda precisam saber se aquela coluna vai armazenar um texto ou um número e qual o tamanho esse dado vai ter.

Mas tem um negócio que é praticamente onipresente nos bancos de dados relacionais. O NULL.

O NULL serve para dizer que aquele dado, daquela coluna, naquela linha “não existe”. Não importa se essa célula de informação é um texto, uma data ou uma chave primária/estrangeira.

Ele também é um tipo de dado “complementar”, ou seja, você não diz que uma coluna da tabela é do tipo NULL. Você diz que aquela coluna é do tipo X e também pode guardar um NULL. Ou seja, o valor NULL não é um tipo mas também serve a todos os tipos.

O NULL também é usado para modelar as relações entre os objetos de duas tabelas. É ele que vem como resposta ou influencia o resultado dos famigerados LEFT|RIGHT|INNER|OUTER|... JOINs que tanto demoram pra entrar na cabeça dos desenvolvedores.

O NULL é tão esquisito que força os programadores, tão acostumados com a lógica binária, a pensar em uma lógica com três estados.

Esses problemas mencionados até aqui podem ser extendidos aos nil, None de várias linguagens de programação, portanto, a dica que eu vou dar pode se aplicar em outros contextos: se você puder evitar usar NULL, faça isso.

Um exemplo do tipo de discussão sobre NULL causa aconteceu na nossa equipe. A gente está trabalhando em um sistema que cadastra perfis de cavalos. Então teremos nesse cadastro o nome do cavalo, a cor dele, a árvore genealógica, gênero, etc. Algumas dessas informações podem mudar ao longo do tempo (ex. um cavalo pode nascer de uma cor e mudar de cor na vida adulta). Outro problema que temos que lidar é com a fragmentação e qualidade dos dados das nossas fontes (ex. algumas base de dados que temos não informam a cor do animal).

Considerando esses requisitos e limitações é bastante comum que programadores, por reflexo, saiam colocando várias dessas colunas como NULLABLE no banco de dados. Mas isso trás alguns problemas que eu pretendo demonstrar (provavelmente de forma incompleta) abaixo.

Perda de Otimizações

Alguns SGBD podem perder otimizações em cenários onde temos colunas NULLABLE. Esse artigo aqui (inglês) tem uma explicação mais detalhada de um desses problemas.

O tipo de problema de otimização causado por colunas NULLABLE variam de SGBD pra SGBD, então recomendo que você faça uma busca por “nullable optimization [seu banco de dados]” no seu buscador favorito para entender o impacto do NULL no seu SGBD.

Pobreza Semântica

Quando usamos NULL no lugar de um valor real sabemos apenas que não temos aquele valor. Mas o que isso significa de fato? Não dá pra saber.

Vou dar um exemplo bem simplificado para ilustrar melhor… Imagine que temos um site de e-commerce e na nossa tabela de produtos (ex. Product) a gente tenha uma coluna para guardar o diâmetro do produto (ex. diameter). Na sua loja virtual você tem produtos com essa característica (ex. parafusos, canos, etc) e produtos que não tem essa característica (ex. caixa decorativa, piso porcelanato, furadeira).

A gente pensaria: esse campo é NULLABLE porque ele não precisa ser preenchido para todos os produtos.

Mas o que o não-valor NULL significa de verdade nesse contexto? significa que eu “não sei o valor” porque ainda não medi o objeto que está cadastrado no meu banco de dados? Significa que o valor diâmetro não se aplica àquele produto porque ele é uma caixa? Significa que ele ainda está aguardando a informação porque ela é preenchida de forma assíncrona por outro serviço ou equipe?

Não existe uma solução específica para adicionar mais semântica para esses dados. Existe um conjunto de técnicas e práticas que podem ser usadas pra resolver esse problema.

No caso da cor do cavalo que comentei acima, temos uma Foreign Key (FK) para uma tabela de cores oficiais de cavalo (sim, isso existe), o ideal seria criar uma cor NOT_AVAILABLE na tabela de cores e referenciar ela quando não conseguirmos determinar a cor do animal. Mas a mesma solução não serviria para a data de nascimento dele.

Como temos diferentes tipos de informação que podem ou não estar disponíveis precisamos criar uma modelagem específica para lidar com isso.

Coalescing

Quando dizemos que uma coluna é de um tipo específico podemos fazer nossas queries e nosso código sempre assumindo que o dado retornado é daquele tipo.

Saber disso diminui a complexidade do nosso código porque não precisamos ficar lidando com um cenário excepcional onde o tipo do dado muda nem ficar convertendo esse dado de um formato para outro.

NULL é inevitável

Infelizmente nem sempre é possível evitar o uso de NULL. Eventualmente precisamos recorrer à ele ou preferir ele à outras opções.

Se eu tenho uma coluna birthdate e nem sempre eu terei essa informação para preencher no meu banco de dados é preferível usar NULL do que armazenar uma data inválida tipo 00/00/0000. Usar uma data inválida só vai servir pra mudar a complexidade de lugar (quando precisar calcular a idade da pessoa preciso excluir datas zeradas pra não ter alguém com 2020 anos).

No caso do diâmetro que eu mencionei acima, podemos usar um 0 pra sinalizar que o objeto não tem diâmetro. Mas fazer isso pode trazer problemas e complexidades para o sistema de shipping fazer o cálculo da volumetria do objeto pra calcular o frete. Nesse caso usar NULL pode fazer mais sentido (e usar uma segunda coluna pra adicionar semântica à esse NULL).

Conclusão

NULL não é inerentemente ruim e não estou desaconselhando ele. O objetivo desse artigo é só “desligar o automático” na cabeça dos desenvolvedores na hora de tornar uma coluna NULLABLE.

E quando estiver usando NULL é importante redobrar a atenção com seu código e com seus dados.

PS. NULL significa Zero em Alemão. Então eu abro exceção e tomo Coca-Cola Null Zucker (zero açucar) por aqui. 😉

publicado
Categorizado como Geral

Ensinando Testes

Depois de algum tempo escrevendo código com testes automatizados eu comecei a considerar que cursos e livros sobre esse assunto fossem sempre um tipo de “falcatrua”. Achava que ensinar a fazer testes não fazia muito sentido.

Mas quando abri minha empresa de consultoria e treinamento eu recebia vários pedidos de clientes para ministrar um “Curso de TDD” para suas equipes. Então resolvi desenvolver esse curso.

Só uma observação: eu uso teste automatizado e não ao longo desse texto porque é importante saber que TDD é uma técnica de desenho e modelagem de código que usa testes automatizados mas tem muito software com testes automatizados que não foram criados com TDD.

Voltando para o curso…

O curso ficou bem legal e os slides estão disponíveis gratuitamente hoje em dia, já que não vendo mais ele e nem tenho mais a minha empresa.

Ter desenvolvido esse curso mudou a minha visão sobre ensinar testes com cursos e livros? Não mudou.

Prática vs. Perfeição

Eu continuo achando que só é possível aprender a escrever testes na prática. E durante o curso, como vocês podem ver nesse slide, eu menciono isso para não alimentar falsas expectativas de que cada aluno ali seria um “mestre dos testes” após concluir o meu treinamento.

Eu estabeleci um paralelo entre aprender escrever testes com aprender uma arte marcial. E usei a figura do Sr. Miyagi ensinando caratê pro Daniel San (ok, eu sei que sou velho mas me recuso a usar a figura do tira-casaco/coloca-casaco que ensinava Kung-Fu).

E, tal como nas artes marciais, você não aprende a escrever testes em livros e cursos.

Resolvi estabelecer uma proposta “ousada” para o curso: não ensinar a escrever testes.

No lugar disso o curso daria uma fundamentação sobre o que é teste, pra que servem, a importância deles, e desmistificaria algumas bobagens que dizem sobre eles (ex. cobertura de 100% é essencial, código com testes não tem bugs, etc). Depois a gente teria algumas atividades práticas controladas (as tão temidas “dinâmicas”).

Em uma dessas dinâmicas eu criava uma atividade parecida com a de um Coding Dojo com os alunos. O problema em todas as turmas era sempre o mesmo: converter números para algarismos romanos.

Essa dinâmica baseada em Coding Dojo servia muito bem no processo seletivo de uma outra empresa onde trabalhei mas isso é assunto para outro artigo.

Eu observava a dinâmica mas não trabalhava no problema. Eu tomava nota de algumas coisas da atividade e, no final, a gente discutia o que havia acontecido de errado, o que tinha dado certo e eu ia encaixando os tópicos de TDD para serem ilustrados pelo que eles experimentaram.

Depois disso a gente passava por mais alguns fundamentos e retornávamos para a prática.

A segunda atividade era escrever um encurtador de URLs completo na linguagem/framework que a empresa usava ou com o qual a maior parte da equipe estava mais familiarizada.

Nesse momento a gente aprendia como organizar melhor os testes, como usar as ferramentas de teste e até como fazer TDD. Essa atividades levava de 1 a 2 dias e eram feitas em duplas (pair programming) que eram trocadas a cada 2 horas (o critério de troca era misturar abordagens das diferentes duplas com programadores(as) diferentes).

Por fim eu indicava alguma literatura complementar (majoritariamente como referência) porque obviamente eles aumentam a sua compreensão sobre testes automatizados mesmo não sendo a fonte principal de aprendizado.

Uma curiosidade sobre a dinâmica do Coding Dojo com o problema dos algarísmos romanos: eu ministrei esse treinamento para 5 turmas diferentes. Das cinco turmas que trabalharam no problema, cada uma delas entregou solução completamente diferente umas das outras. Todas funcionavam e atenderiam tranquilamente requisitos de performance, uso de memória, etc. Engraçado notar como pessoas e times possuem perspectivas tão distintas sobre os problemas apresentados.

Não é fácil mas é possível

Infelizmente é impossível aprender a escrever testes sem praticar. Mas eu garanto que vale a pena tentar.

Vai ser frustrante e lento no início mas depois as coisas aceleram.

E entenda que o seu “caratê” vai ser bem ruim no começo e, talvez, no futuro, ele fique ótimo. Você pode até chegar à faixa preta mas atingir a perfeição é impossível.

Por conta dos seus testes serem ruins no começo eles vão gerar um grande esforço de manutenção. Aquele refactoring ou bugfix “trivial” vai te garantir horas de reescrita de testes. Desistir vai parecer uma ótima ideia nessas horas. E é aí que você vai precisar perseverar. Entenda que isso acontece porque seus testes ainda não estão muito bons (ou ainda que o seu código sendo testado precise de algumas melhorias).

E quando você não conseguir mais programar sem testes você vai ver que valeu a pena.

Python Raiz

Logotipo antigo do Python onde se lê "Python Powered" com uma fonte pontilhada em branco com uma borda preta. Esse logotipo fica sobre uma elipse azul

Como todos sabem sou programador Python a quase duas décadas e boa parte da minha carreira foi construída em torno desta linguagem. E isso mostra como ela é excelente. Pra uma pessoa como eu, que adora aprender e estudar linguagens de programação, significa muito priorizar uma só linguagem por quase metade da vida.

Mas o que me motivou a escrever esse texto aqui foram as adições recentes (ou nem tão recentes) à linguagem. Coisas como suporte para desenvolvimento assíncrono (async, await, etc), anotações de tipos, f-strings, operador “walrus” (:=), e a mais recente delas (cuja PEP ainda está em “Draft”): Pattern Matching.

Python Nutella

O conceito de Pattern Matching já existe a bastante tempo (Prolog?) mas ficou mais popular com a recente adoção da excelente linguagem Elixir por muitos desenvolvedores.

O uso mais básico de Pattern Matching pode ser visto nas instruções switch/case presente em várias linguagens de programação estruturadas. Mas Pattern Matching não é “só” um switch/case. Nos tradicionais comandos de switch/case as linguagens avaliam uma expressão (switch expr) e dependendo do resultado da expressão ele busca um bloco de código que dê “match” com esse resultado (case constant-expr).

Mas em linguagens como Elixir (que é a que usarei como exemplo por conhecer melhor) esse “match” pode ser feito com regras muito mais elaboradas e usar estruturas de dados completas no lugar de apenas um valor constante, como nas linguagens que mencionei acima.

Abaixo vou colocar um exemplo de código pseudo-Python que demonstra como uma função pode ser implementada sem e com Pattern Matching:

Esse caso mostra como o conceito é poderoso e prático para resolver uma série de problemas. E a sintaxe parece razoavelmente natural. Mas parece que essa “naturalidade” some quando avançamos pelos exemplos da PEP e começamos a ver coisas como:

O que me assusta em tudo isso são as invenções de coisas que nunca estiveram no Python:

  • _ como caracter coringa: o caracter _ sempre foi usado, por convenção, como uma variável cujo valor pode ser descartado. Um exemplo disso seria fazer coisas como: name, url, *_ = 'name,url,extra,data'.split(','). Porque não usar a cláusula else: com o match?
  • Dotted-names: Os casos de Constant Value Patterns onde tiveram que inventar uma sintaxe nova com dotted-names é outra coisa que nunca vi no Python. Essa sintaxe foi descartada anteriormente para coisas muito mais simplórias como quando pediram algo parecido com with do Pascal.
  • | como operador de alternativa: | já existe em Python e ele faz as vezes de OR bit-a-bit. Também temos o or que faz as vezes de OR lógico. Me parece que, mesmo não sendo semanticamente a mesma coisa, o segundo OR lógico faz mais sentido do que o OR bit-a-bit. Uma opção aceitável, por familiaridade, seria o uso de || que também é usado como OR lógico em diversas linguagens.

Mas o que mais me desagrada nessas recentes adições à linguagem é a preocupação que tenho com “legibilidade natural da linguagem“. E não, essa legibilidade não tem relação direta com escrever código limpo e organizado para programadores Python. Tem relação com a capacidade de um código ser compreendido até mesmo por algum desenvolvedor que não conhece a linguagem.

Aprendendo Python

Python não foi minha primeira linguagem. Já conhecia outras antes dela. Essas linguagens eram majoritariamente estruturadas mas eu já tinha brincado um pouco com desenvolvimento orientado à objetos com Object Pascal do Turbo Pascal 6 e 7 (com Turbo Vision e tal).

Meu primeiro contato com Python se deu por volta do ano 2000 na extinta e saudosa Conectiva (aquela do Conectiva Linux que depois se juntou com a Mandrake pra formar a Mandriva que também sumiu… enfim… uma bagunça 🙂).

Eu estava trabalhando em um projeto de “compilador de configuração para interfaces gráficas”. Esse é o nome chique que dei agora… na época era só um programa escrito em C que geraria os arquivos texto de configuração para Gnome, KDE e WindowMaker à partir de um conjunto de configurações centralizadas.

Mas o importante para a discussão de agora é a parte do “escrito em C” e “arquivos texto”. Todos sabem que C e texto não se harmonizam muito bem, certo? Então… no final tudo daria certo. Só demoraria mais tempo pra ficar pronto.

Certo dia meu chefe me trouxe um artigo que ensinava Python. Ele havia traduzido o artigo original para o português e pediu pra que eu desse uma revisada (acho que a intenção dele era outra já nem sabia inglês direito). O artigo original não está mais no ar mas tenho uma cópia dele (a tradução se perdeu).

A versão do Python, naquela época, era 1.5.2 (o artigo foi atualizado depois que eu li para acrescentar coisas do Python 2). E lendo só esse artigo eu aprendi Python em 1, uma, UMA f*cking noite! Com um artigo de blog!

Eu aprendi Python em uma noite porque eu sou inteligente? Esperto? Super-humano? Não! Dêem uma olhada no post.

Eu espero.

Viram como a linguagem do artigo é simples? Ela é legível, as construções dela são intuitivas: v = 1 atribui valor 1 pra v, v == 2 compara valor v com 2, v[0] acessa o primeiro elemento de um array/lista, class Person: ... define uma classe, e assim se segue. Ou seja, para uma pessoa que programa minimamente em algo conseguia aprender a linguagem muito rápido.

Tinham pouca coisa estranha nessa linguagem que não existia em outras. Talvez o fato de usar indentação pra delimitar os blocos de código e aquele parâmetro self nos métodos de instância. Mas tirando isso é tudo bem normalzinho.

Agora imaginem uma pessoa aprendendo Python com coisas como:

Imagina esbarrar com um código desses logo de primeira? O cara volta pro Perl 🙂 Just kidding…

Eu sei que o código do artigo é praticamente o mesmo para rodar no Python de hoje (talvez só o uso de print() e input() tenha mudado com o Python 3).

Também sei que o artigo não ensina tudo sobre a linguagem (mesmo naquela versão da época). Ele é só uma introdução. E de fato, quando decidi me aprofundar mais no aprendizado da linguagem eu fui atrás de outros materiais. Li o The Python Tutorial que vem com a própria linguagem e na seqüencia importei um livro que realmente ensinava a linguagem toda: Learning Python da editora O’Reilly.

Naquela época eu comprei a primeira edição do livro que, hoje, já está na quinta edição que cobre até o Python 3.3.

Finalmente eu pude estudar tudo o que Python tinha. E até hoje eu recomendo esse livro. Mas vou falar uma curiosidade sobre ele: a 1ª edição tinha 384 páginas. A 5ª edição tem 1648 páginas! Mais de 4 vezes maior. E nem descrevem as (muitas) novidades do Python 3.4, 3.5, 3.6, 3.7, etc.

Ou seja, se você realmente pretende dominar tudo o que a linguagem oferece vai levar uma vida. Além do Learning Python eu ainda recomendo o Fluent Python (assim que a segunda edição sair eu atualizo o link) do meu querido amigo Luciano Ramalho.

Python para não-programadores

Todo mundo sabe que Python tem crescido muito na comunidade científica. Isso aconteceu muito graças à iniciativas como SciPy e de projetos que nasceram dentro dessa iniciativa e ganharam vida própria como o Jupyter, matplotlib, pandas, scikit-learn, etc.

Por outro lado Python também se tornou uma linguagem muito usada no ensino de programação de diversas escolas e universidades em todo o mundo. Usam ela para ensinar programação para todo mundo e não só para alunos dos cursos de computação e afins.

E essas duas coisas estão relacionadas. Se você ensina programação com Python para um aluno de biologia qual linguagem ele vai usar para escrever uma ferramenta que auxilia num trabalho de genética?

Porque essas escolas escolheram Python para ensinar programação Porque projetos como SciPy e Jupiter escolheram usar Python? Porque não escolheram outras linguagens?

Eu suspeito de que seja um conjunto de atributos da linguagem, entre eles:

  1. Educacional: Python nasceu de um projeto de linguagem educacional (ABC), mas também nasceu porque seu criador (Guido van Rossum) acreditava que linguagens educacionais não precisavam ser de brinquedo (toy languages) e que deveria ser possível usá-las no dia-a-dia.
  2. Multiplataforma: instalação, implementação e uso fácil nas principais plataformas disponíveis.
  3. Multipropósito: você consegue desenvolver software de linha de comando mas também consegue implementar uma interface gráfica ou um servidor Web.
  4. Multiparadigma: sabe programação estruturada? ok. Sabe modelagem OO? ok também. Sou craque em lambda functions? tá lá também um básico pra você usar.
  5. Facilidade de integração com bibliotecas em de outras linguagens como C, Fortran, etc. Vocês devem imaginar o imenso número de bibliotecas científicas implementadas em outras linguagens. Porque reescrever tudo?

Mas o que eu acho mais importante para essa escolha é a de que todos os cientistas que já programaram alguma coisa para seu trabalho conseguem ver um código Python e ter uma ideia, mesmo que superficial, do que aquilo faz. É a tal “legibilidade natural da linguagem” que já mencionei.

Multipropósito

Se você quer um carro que comporte toda a família, seja potente, veloz, econômico, tenha porta-malas grande, seja espaçoso, confortável, etc você provavelmente vai acabar com isso aqui:

Python nasceu pra ser fácil de aprender e usar. Ter uma sintaxe limpa, clara e familiar. Sem coisas esdrúxulas como símbolos em excesso ou coisas menos convencionais como a sintaxe object message do Smalltalk (que inspira a sintaxe do Ruby).

Python também nasceu sem tipos ou anotações de tipos. Tudo nela foi pensada para abstrair esse conceito “mundano” da computação. Isso facilita o aprendizado das pessoas.

Python nunca pretendeu ter uma performance absurda. Só a performance necessária para permitir o seu uso em problemas reais. Se você precisasse de performance absurda você provavelmente escreveria código em C ou Assembly e “colaria” ele com Python.

Python nunca foi pensada para concorrência ou paralelismo. Então não dá pra “competir” com linguagens como Go ou Elixir (Erlang) nesse quesito. Essas linguagens nasceram pra lidar com esse tipo de problema. Acrescentar um punhado de palavras reservadas e algumas bibliotecas não torna Python ideal para esse propósito.

Python não nasceu como linguagem funcional. Mesmo ela tendo ferramentas que te permitam expressar algumas ideias de modo funcional ela não é uma linguagem funcional de verdade. Python nasceu como linguagem majoritariamente orientada à objetos.

Colocar um map() aqui e um lambda acolá não torna a linguagem própria para resolver problemas que são mais facilmente solucionáveis com linguagens funcionais. Python tem objetos mutáveis. Python não tem suporte nativo à tail-recursion. Macros? O próprio Guido já disse que “nem morto” (não achei a referência, mas acredite, eu vi isso).

Guarda-Chuva

Python já não é mais uma linguagem de nicho ou underground. Python já é mainstream e centenas ou milhares de empresas de diversos portes já usam ela em seus negócios.

Como consequência disso o número de vagas de emprego e trabalhos com Python cresceu vertiginosamente nos últimos anos e por isso, inevitavelmente, programadores de outras linguagens acabam tendo que lidar com Python em algum momento de suas carreiras.

Por conta dessa situação eu tenho a sensação de que a necessidade de adicionar certas funcionalidades no Python vem do desejo desses programadores de usar parte favorita da outra linguagem também em Python porque eles não conseguem pensar “do jeito Python”.

Lembro bem quando Java estava na moda e todo programador Python criava getters/setters nas classes. Inventavam mil maluquices como Interfaces (no Zope), protocols, … para terem algo parecido com o que Java oferecia. Um baita esforço pra programar Java em Python.

Hoje em dia parece que tá todo mundo querendo programar Elixir em Python, JS/Node em Python, …

Sem Conclusão

Vocês devem estar imaginando que estou ficando desgostoso com a linguagem ou que vou abandoná-la. Não estou não. As coisas novas que não gosto de usar irei ignorar (ex. operador :=). Outras que me fizeram até torcer o nariz mas passei a gostar entraram pro meu repertório (ex. f-strings).

Tem aquelas funcionalidades que me fazem torcer o nariz, e quando dei uma chance pra elas descobri que podem ser úteis se forem usadas com muita moderação (ex. type annotation) serão usadas com moderação.

Enfim… Vou continuar a usar e a gostar de Python. Até porque ela tem tantas qualidades que me deixou preguiçoso para mudar. Mas pretendo continuar a programar Python em Python. Daquele jeito raiz. Daquele jeito moleque… aquela programação Python de várzea.

Update: corrigido um erro no operador “OR lógico” para or e adicionei uma sugestão de uso do ||.

Mercado saturado: isso importa?

Como me envolvi em vários eventos voltados para empreendedores nos últimos anos recebo e-mails de várias pessoas que pretendem desenvolver seus próprios empreendimentos. O perfil dessas pessoas geralmente é formado por programadores ou freelancers que tiveram uma idéia e querem desenvolve-la até que ela se torne um negócio.

Recebo vários tipos de perguntas mas tem um tipo que me chama a atenção: “Você não acha que esse mercado está saturado?”.

Essa pergunta me chama a atenção porque, por trás dessa aparência inocente, ela tem várias subquestões importantes como: mercado “oceano azul” vs “oceano vermelho”, mercado global vs local, ineditismo vs copycat, etc.

Ineditismo

Dia desses um amigo chegou com uma ideia interessante e disse que ia começar a desenvolve-la. Algum tempo depois eu fui perguntar pra ele como estava o andamento do projeto e ele me respondeu: “Ih! Desisti da ideia. O Google implementou um produto ‘igualzinho’.”.

Eu achei a resposta interessante porque parece que as pessoas se esquecem que já existiam buscadores antes do Google 🙂 O que o Google fez para alcançar o domínio nas buscas foi criar um produto que funcionava melhor que os concorrentes.

Mesmo com esse ótimo produto eles tem os seus concorrentes em buscas específicas como busca de ofertas (ex. Buscapé no Brasil), busca de estabelecimentos locais, etc. Eles tem concorrência até mesmo para o produto principal: DuckDuckGo (a participação de mercado é menor mas mesmo assim a empresa já é lucrativa).

Quando uma grande empresa grande e poderosa resolve atacar no mesmo mercado e com um produto parecido com o seu significa que você, provavelmente, está com um bom projeto nas mãos! Essa concorrência deve ser encarada como uma validação positiva da sua idéia e não uma coisa para se lamentar. Eu sempre desconfio de empreendedores com idéias “que ninguém mais teve”.

Outro exemplo: nós, programadores, conhecemos os serviços de hosting de código Github e Bitbucket, certo? Eles são os mais famosos e o Github é o maior player nesse mercado. Quando o Github nasceu o Google já tinha o Google Code Hosting.

Mesmo assim colega resolveu criar um serviço desses e cobrar $9/mês para as pessoas usarem. Nasceu o Codeplane. O Codeplane nasceu porque ele tinha uma necessidade que não era atendida pelo Bitbucket/Github de forma satisfatória: ter dezenas de projetos pequenos para hospedar em repositórios privados.

O Github cobra por cada repositório privado, logo, o custo seria enorme. O Bitbucket, na época, limitava o número de repositórios privados em apenas 5 por usuário. No Codeplane não. Você poderia ter quantos repositórios privados precisasse. O único limite era o espaço de armazenamento total.

Ele criou um serviço útil para ele e para várias pessoas e ganhou dinheiro com isso. Independentemente dos “cachorros grandes” desse mercado.

Diferenciais

Uma coisa que é importante ter num mercado onde existe concorrência é o diferencial. O Google tinha como diferenciais a qualidade nos resultados das buscas e a velocidade com que elas eram feitas. O Codeplane tinha uma forma de cobrar diferente dos concorrentes. O DuckDuckGo também tem seus diferenciais.

O simples fato de ter um serviço adaptado para a realidade brasileira, por exemplo, pode criar um diferencial. Mas tenha em mente que esse diferencial pode ser pequeno demais para impedir seus concorrentes de atacarem seu mercado.

Copycats

Criar um produto similar à outro pré-existente e colocar alguns diferenciais nele é bacana. O “copycat” puro e simples não é.

O problema do copycat é que os seus clientes usarão o seu serviço até descobrirem o “original”. Se a empresa que fez o original for mais “poderosa”, provavelmente, terá condições de melhorar o produto deles num ritmo muito mais acelerado que o seu. Isso te deixaria para trás muito rápido na corrida pelo mercado.

Oceano Azul vs Oceano Vermelho

Existe um livro chamado “A Estratégia do Oceano Azul” (W. Chan Kim, Renee Mauborgne) que descreve o mercado como oceanos. Existe um oceano cheio de tubarões (concorrência) onde a briga entre eles é tão grande que tinge as águas de vermelho. E existem outros oceanos bem menos concorridos onde as águas ainda são azuis.

O objetivo de todos os empreendedores que estão começando deveria ser o de navegar por oceanos azuis. Com pouca concorrência. Para fazer isso o livro sugere que segmente o mercado de maneiras diferentes e ofereça valores também diferentes para esse mercado.

Analise os atributos de valor que os seus concorrentes oferecem para os clientes e tente realçar/eliminar alguns deles de modo a ter um produto único e diferente que sirva para pessoas que estão em mercados ainda inexplorados.

Global vs Local

Em vários artigos que falam sobre como começar um negócio você vai ler sobre “a necessidade de adaptar o produto para a realidade brasileira”. Não tem nada de errado com essa estratégia e ela pode até ser boa porque, inicialmente,  diminui os riscos do negócio.

Mas eu acho que devemos nos arriscar mais e parar com esse pensamento pequeno. Com a Internet e os negócios voltados para tecnologia o custo de iniciar certos serviços em escala nacional ou global é muito parecido. E, me perdoe pela obviedade, o mercado global é muito maior que o brasileiro.

Se a gente falar de um negócio que só adapta um que já existe em outro país a coisa fica ainda pior. Pode ser questão de (pouco) tempo para que a empresa global adapte o seu produto para a realidade brasileira e venha competir com você aqui no Brasil.

E aí será uma briga de uma empresa local contra uma empresa global. É bem mais difícil ganhar essa briga, não acham?

publicado
Categorizado como Geral

Programador Freelancer

foto de um programador de costas trabalhando em seu notebook com um monitor externo. A foto está tratada para deixar toda a imagem exceto a tela do monitor externo em preto-e-branco.

Durante muito tempo da minha vida eu trabalhei como programador freelancer. Eu até tive empresa, sócio, etc. mas o fato é que eu era um freelancer como qualquer outro. Afinal eu vendia o serviço, elaborava proposta, negociava, executava o projeto, cobrava, emitia nota fiscal, e dava suporte. Durante esse tempo eu aprendi algumas coisas que gostaria de compartilhar.

Freelancing não escala

Trabalhar como freelancer é divertido e dificilmente enfrentamos problemas com a rotina quando trabalhamos desta forma. Não temos que lidar com a rotina porque cada projeto é único.

Essa variedade de projetos é legal mas tem algumas desvantagens. Como eles são razoavelmente diferentes fica difícil reaproveitar o conhecimento adquirido durante a execução de um deles.

Como o freelancer precisa aprender coisas novas em quase todos projeto perde-se boa parte do “ganho de escala” do negócio. E é o ganho de escala que permite reduzir custos que geram margens de ganho maiores ou preços menores para o cliente. Isso não é bom nem ruim. É uma característica inerente do trabalho do freelancer.

Se o freelancer opta por “crescer” o negócio e montar uma empresa com vários funcionários (ou freelancers) precisa observar que ele pode até ganhar escala mas esse ganho será praticamente linear: para fazer 1 projeto precisa de 1 pessoa e para fazer 2 projetos provavelmente precisará de 2 pessoas.

Você pode até mudar a inclinação do gráfico projetos x pessoas mas ele dificilmente se curvará.

Você vende horas? Cobre por horas

Uma armadilha bastante comum para freelancers iniciantes é a de negociar um contrato com um escopo fechado. A coisa piora se o escopo não estiver muito detalhado.

Essa armadilha é mortal porque na imensa maioria dos casos o contrato vincula o pagamento do serviço à entrega do escopo. E, acredite, os clientes vão expandir esse escopo ao ponto de tornar o projeto prejudicial para o freelancer.

Eu sei que é difícil negociar um contrato baseado em horas de trabalho mas você tem que negociar nesses termos. É melhor não pegar o projeto do que negociá-lo por escopo e/ou vincular o pagamento ao escopo.

Sei que isso é bem complicado porque as contas para pagar chegam todos os meses sem piedade e aquele contrato com escopo fechado oferece uma oportunidade de ter dinheiro para pagar essas contas. Mas no médio prazo você pode acabar se tornando um escravo do projeto e ficar trabalhando de graça nele (ou até pagando para trabalhar).

O melhor para você e para seu cliente é trabalhar com entregas parciais em intervalos curtos e rápidos. Isso nos leva ao próximo ponto…

Atualização: logo depois que enviei O Melhor da Internet o meu amigo Elvis enviou um link para um artigo que ele escreveu onde ele ressalta o fato de que um freelancer raramente consegue vender 100% das suas horas disponíveis.

Atualização 2: Depois que o artigo foi publicado me lembrei de uma outra dica importante relacionada à esse tópico. Quando você está elaborando a proposta e negociando o projeto é importante incluir o tempo usado nesse processo no valor final do projeto. Se você não fizer isso essas horas sairão “de graça” para seu cliente. Para isso funcionar direito as propostas também precisam ter um prazo de validade que permita uma revisão de valores nos casos onde a negociação demora muito.

Não cobre “50% no início e 50% na entrega”

É uma prática bem comum trabalhar dessa forma: o freelancer recebe 50% quando inicia o projeto e o restante quando entrega ele pronto.

Existem duas pegadinhas nesse modelo: uma é o conceito de pronto (veja o tópico anterior) e a outra tem relação com um negócio chamado fluxo de caixa.

Uma das coisas que certamente mata uma empresa é a má gestão do seu fluxo de caixa. E um freelancer é uma empresa de uma pessoa só. Precisa gerenciar seu fluxo de caixa com muita atenção.

Quando você fecha um negócio e recebe por ele 50%+50% fica mais difícil de gerenciar o fluxo de caixa da empresa porque a segunda metade do pagamento vira um alvo móvel. Quando você vai entregar o projeto? Quando ele estará “pronto”?

No lugar de negociar 50%+50% prefira receber parcelas em intervalos regulares (mensalmente? quinzenalmente?). Pode-se até vincular os pagamento às entregas parciais do projeto.

Receber pelo trabalho em intervalos regulares e vincular isso às entregas parciais é o cenário perfeito porque facilita a gestão do fluxo de caixa do freelancer e aumenta a segurança do cliente que pagará por algo que já recebeu.

“Produtize” seus serviços

No primeiro tópico eu falei sobre o problema de escala associado ao freelancing e aqui eu vou apresentar uma forma de amenizar esse problema.

É raro mas acontece: quando um freelancer está trabalhando no seu milésimo projeto ele percebe que certos padrões surgem em todos eles. Exemplo: quase todos os projetos tem um formulário de contato, ou uma página com um mapa mostrando a localização da loja do cliente, ou tem algum sistema de monitoramento, backup, etc.

Quando o freelancer detecta um padrão desses ele pode ter certeza que existe uma oportunidade de transformar essa parte do projeto em um produto que pode ser vendido para vários clientes. Se você fizer isso vai ter um ganho de escala ou até mesmo alguma receita recorrente.

Certos projetos também são genéricos ao ponto de poderem ser transformados em produtos (com a devida anuência do cliente contratante). Um exemplo? Um dos meus clientes solicitaram o desenvolvimento de um sistema de avaliação de funcionários para o RH da empresa.

O sistema usava uma metodologia conhecida como “Avaliação 360°” e gerava relatórios para o RH da empresa avaliar os seus funcionários. O sistema foi desenvolvido para um cliente específico mas, certamente, poderia ser útil para outras empresas. Não foi o caso mas esse projeto poderia ter se transformado em um produto.

Outros tipos de produtos que você pode criar estão na forma de conteúdo. Em meu caso, por exemplo, escrevi um livro e criei um video-curso de programação Python e Django para vender na Internet (que, por não manter mais, acabei disponibilizando gratuitamente).

Crie receitas recorrentes

Todo negócio tem seu risco e com o freelancing não poderia ser diferente. Quando o freelancer está trabalhando e vendendo suas horas de trabalho para alguém as coisas ficam bem. Mas quando, por algum problema, isso não acontece as coisas podem ficar bem complicadas.

Um freelancer pode adoecer, o mercado pode dar uma esfriada, pode acontecer uma entresafra de projetos (ex. o período de novembro a março costuma ser difícil para novos projetos).

Uma maneira de lidar com essas dificuldades é cuidar para poupar nos períodos fartos para ter algo nos períodos difíceis como na fábula da Cigarra e das Formigas. Outro modo de lidar com essa questão é criando formas de se obter receitas recorrentes.

Ofereça serviços de manutenção, suporte, apoio, etc para os clientes que desenvolveram projetos com você. Crie mecanismos (honestos) para continuar recebendo dinheiro deles mesmo depois que o projeto tenha terminado. Ou crie algum produto (tópico anterior) que seja vendido na modalidade de assinatura.

Recuse clientes ruins

Essa é uma das coisas mais difíceis de colocar em prática porque, a menos que alguém nos avise, é quase impossível saber se um cliente novo é bom ou ruim. Mas alguns indícios podem ser observados:

  • Cliente que questiona demais os preços – pode ser uma preocupação legítima mas geralmente não é. Mostra que é um cliente mais preocupado com preços do que com qualidade. Ele vai apertar os seus ganhos e vai te trocar por outro mais barato na primeira oportunidade.
  • Cliente que não sabe o que quer e não te ouve – existem muitos clientes que não sabem exatamente o que querem e isso isoladamente não é um problema. Mas se você tentar ajudá-lo a descobrir e ele recusar a sua ajuda isso pode virar um problema.
  • Cliente que descumpre o combinado – você estabelece com o cliente que ele te pagará mensalmente e no dia do pagamento você tem que ficar lembrando e cobrando. Ou cliente que simplesmente te dá um calote. Eu costumava fazer um teste: eu “esquecia” de cobrar os meus clientes algumas vezes. É engraçado mas os meus melhores clientes sempre me enviavam e-mail avisando sobre meu “esquecimento”.
  • Cliente que oferece uma “oportunidade única” de trabalhar para ele – tem muito cliente que pede um precinho camarada em um primeiro projeto com a promessa de valores maiores em projetos futuros. Não caia nessa armadilha porque esse cliente não é fiel à você. Ele é fiel ao teu preço baixo. E não se engane… tem muita empresa grande e famosa que usa o próprio nome para obter essas vantagens. Se usarem o discurso do “você vai colocar a nossa empresa no teu portifólio!” respondam de forma sarcástica: “eu já gastei a minha verba de marketing para esse ano”.

Para clientes pré-existentes é sempre importante gastar algumas horas do mês para reavaliar a sua carteira de clientes e projetos. Cliente bom é aquele que cumpre com suas obrigações, gera bons projetos, indica você para novos clientes e te dá um bom lucro.

Automatize as tarefas chatas

Coisas chatas que freelancers precisam fazer e precisam ser automatizadas o mais rápido possível:

Responder e-mails de sondagem

Eu recebia muitos e-mails assim: “Oi, Meu nome é Fulano e gostaria de saber quanto você cobraria por um projeto assim e assado”. Você tem que responder à esses e-mails mas 80% deles são de aventureiros. Pessoas que não tem dinheiro para te contratar, não sabem o que querem e não vão fechar negócio contigo.

O problema é que não dá pra você diferenciar as boas oportunidades daquelas que vão fazer você perder tempo.

Um das coisas que funcionou razoavelmente bem comigo foi colocar informações detalhadas sobre o tipo de projeto que eu desenvolvia e um valor aproximado para minha hora de trabalho no site da empresa. Colocava destaque na informação: “Esses valores são negociáveis”.

Com essas informações a pessoa já consegue ter uma idéia se ele consegue contratar o seu serviço. A outra informação (valores negociáveis) filtrava os aventureiros daqueles que realmente queriam realizar o projeto.

O cara pode até não ter o dinheiro para te contratar mas se ele quiser muito realizar o projeto ele vai entrar em contato contigo para tentar negociar o prazo de pagamento, os valores, o escopo, etc. E isso, por si só, mostra que ele pode ser um bom cliente e gerar negócios.

Algumas pessoas (por medo ou desconhecimento) acreditam que essas informações no site afugentam clientes. Pode ser que sim. Mas pergunte-se: “Que tipo de cliente eu estou afastando?”.

Produzir e enviar propostas

Depois que você entende melhor o projeto é o momento de enviar uma proposta para seu cliente.

Se você ainda estiver negociando projetos com escopo fechado fica impossível automatizar essa etapa porque cada proposta será única e precisará ser bem detalhada, mas se você negociar em termos de horas a proposta fica bem mais simples. Você precisa apenas preencher os milestones do projeto (entrego X na data Y, …) e fazer uma multiplicação de horas pelo teu valor/hora.

Eu tinha um template no meu editor de textos onde eu só alterava os dados, gerava um PDF, e enviava para o cliente. Se o cliente já era antigo, muitas vezes, eu só mandava um e-mail: “imagino que dê pra gente trabalhar nisso em uma semana por R$X”. E o cliente respondia: “Ok, pode fazer”. Esse é o tipo de relação de confiança que você precisa construir com seus clientes.

Cobrança e NFe.

Cobrar o cliente e ver se ele pagou é uma daquelas coisas que nunca consegui automatizar 100% mas cheguei à um ponto onde isso não atrapalhava o resto das atividades.

Eu criei uma conta de cobrança sem registro na conta da empresa no banco (dica: não misture sua conta pessoal com a conta usada para seu trabalho) e emitia boletos para meus clientes pagarem. Cerca de 5 dias depois da emissão dos boletos eu puxava um extrato e conciliava os pagamentos na mão. No site da prefeitura eu emitia as NFe daqueles que haviam pagado o boleto.

Comecei com um software que só emitia os boletos e depois migrei para outro que emitia os boletos e a NFe.

Seja parceiro dos bons clientes

É provável que você não consiga resolver todos os problemas de seus clientes e, nestes casos, você deve ajudá-lo a encontrar as soluções para esses problemas. Mesmo que para isso você tenha que encaminhá-lo para um outro prestador de serviços (freelancer, empresa, etc).

Se você fizer isso o cliente criará um modelo mental muito positivo sobre você: “quando eu tenho um problema é só eu entrar em contato com esse cara que ele resolve ou me ajuda a resolver”. Esse modelo mental é poderosíssimo para gerar novos negócios.

Cumpra combinados e faça com qualidade

Deveria ser o primeiro item mas resolvi deixá-lo para o final para que fique mais fresco na sua memória.

É da mais absoluta importância para um profissional que ele cumpra aquilo que foi combinado com o cliente. E mais do que isso… é importante que tudo seja feito com a maior qualidade.

Cumprir com o combinado manterá o seu cliente fiel à você. Fazer isso com qualidade transformará ele num canal de vendas.

publicado
Categorizado como Geral