terça-feira, dezembro 23, 2008

Merry Christmas with Bash


Júlio Neves wrote a shell script that draws a Christmas Tree decorated with Christmas lights.

He wishes "muito suSHELLso em 2009" that means in a free translation "much sucSHELLcess in 2009".

It is very funny. I hope you like it.

You can see the source code here: http://www.dicas-l.com.br/cantinhodoshell/cantinhodoshell_20081222.php.

Merry Christmas to Everyone.

Note: The site is written in Brazilian Portuguese, but you can just pick the code.

quinta-feira, dezembro 04, 2008

I am not afraid anymore

Have you ever been afraid of changing some code? Even one that you've developed?

I have. Many times. Why this happened to me? Well, that is because I could not be 100% confident that my changes would not break any other part of the program.

My life changed when I learned the Test Driven Development methodology (aka TDD).

The idea behind TDD is that you must write automated tests before writing your code. This methodology will not only help you design better software by catching bugs at the same time you are coding, but (IMHO) it is also a great way to assure your code will keep working after maintenances.

Managers love to say they want you to deliver fully tested software. They even say that TDD is a wonderful idea. But things change when you need to fix a bug or insert new features into a product that do not have automated tests. At this moment, managers complain that there is no time to let you write a test suite to cover the entire software.

To be totally honest we need to agree that being able to fix problems and / or insert new features into your company's products in a timely manner is essential in the global market competition.

- I can not write an entire test suite to the program, and take the risk to not deliver it in a time it must be delivered. And if I do not write tests how can I assure that everything will keep working after I put my hands in it?

In this case I write tests to the part of the software that I will alter. Moreover, whenever I have a bug to fix I write tests to fully cover that part I'm working on.

Yes, I know that to be considered effective, tests must cover 100% of the program, but you must have a fresh view about it:

This approach significantly reduces the number of tests I should write to be able to check if my changes did not affect anything else. So, it will take less time and effort than the ideal situation (which my manager probably would not allow let me to do).

I will be able to write them little by little, during my development activities. The product did not have any test at all so if I write a little number of tests each time that I am working on it is better than nothing.

What you think? Is my approach good? I would like to listen to your opinion.

segunda-feira, outubro 20, 2008

Blind Programmer

I used to complain almost every day about my tendonitis.

Today I was reading a post named Programador Cego (Blind Programmer) at Aurélio's blog (It is written in Brazilian Portuguese).

This post talks aboit Ângelo Beck. He is 27 years old and he is completely blind.

Ângelo uses a screen reader and a method he developed to help him see the source code. So he is able to develop in PHP.

Ângelo proved that a blind person can do almost anything and changed my mind. He is a hero!

From now on I will never complain about my tendonitis again.

segunda-feira, março 17, 2008

How to load debug symbols with GDB - Another Approach

I wrote in the post How to load debug symbols with GDB one way do debug a stripped version of an application with full access to debug symbols.

In this post I will explain another way you can do it.

We are going to load debuging information from a file that was generated by our executable just before it was stripped off..

I am going to use the same source and environment settings that I used in my earlier post:
  • released.c: source code of the program we wish to debug (listing 1).
  • ~/estudo/: Source code of our program will be put here.
  • ~/local/bin: The stripped off version of binary program will stay here.
  • ~/local/symbols: In this place are all files that contain debugging information.
#include <stdio.h>
#include <stdlib.h>

int division(int a, int b);

int m;

int main(void)
int i;
int j;

printf("vou setar i\n");
i = 10;

printf("vou setar j\n");
j = 1;

printf ("i = %d, j = %d\n", i, j);
m = division(i, j);

printf("m = %d / %d = %d\n", i, j, m);

return 0;

int division(int a, int b)
return a / b;

Listing 1 - sample program source code

Let's start:

1 - Create your program with debug information. In our sample:
gcc -g -o release release.c <ENTER>

2 - Now we will generate a file that will contain only debug informations. You generate this file by issuing this command:
objcopy --only-keep-debug <ENTER>
In our sample:
objcopy --only-keep-debug release release.sym <ENTER>

The choice of .sym as an extension for the debug info file is totally arbitrary. You can use whatever you wish to.

3 - You remove debugging information:
strip -s release <ENTER>

4 - Move file release to ~/local/bin/:
mv release ~/local/bin <ENTER>

5 - Move file released.sym to ~/local/symbols/
mv release.sym ~/local/symbols <ENTER>

6 - Go to directory ~/local/bin
cd ~/local/bin <ENTER>

7 - Run GDB:
gdb ./release <ENTER>

8 - Try list command to see that release executable file doesn't have symbols in it.

Figure 1 shows us what I said.

Figure 1 - executable file named release is loaded by GDB.

9 - Let GDB to load symbols from symbols file named release.sym. This file has all symbols that we need to debug. You achieve this by issuing the following command:
add-symbol-file ~/local/symbols/release.sym <ENTER>

From now on you can debug your program as usual.

Figure 2 shows us that debugging symbols where imported successfully and that now the list command shows us the program source code.

Figure 2 - now our GDB session has debuging symbols

As you can see in figure 3, I set a break point at line 17 and I ran the program that stopped there. Then I printed i variable. It is possible just because symbols were loaded.

Figure 3 - debugging session.

You can see that this method to load debug symbols is easier than the previous one presented in the post How to load debug symbols with GDB.

My friend Jumpi complained that it is not the unix way to debug applications that just don't have debug information by loading a separated file. We have core files to help us to debug the application in our host.

I agree with him that it is unusual to debug this way, but it may be useful.

The idea behind this method (and behind the previous one) is similar to that used by MS with .pdb files.

It will allow you to save disk space on your host because you can keep only stripped versions of your applications and libraries in it. It is especially important to embedded systems.

At the same time it let you have a collection of symbol files stored at some place (say, a DVD disc or another server). When (and if) you need to do a debug session

I hope this post will make your life easier.

domingo, março 16, 2008

Precision Resistors

A lot of hobbyists want to make their own circuits but they face a problem: precision resistors.

There are many projects where the ratio between resistances is more important than the actual values. In these case we can measure our resistors to select the most appropriated.

Let me show an example. Suppose we have an inverter amplifier as shown in figure 1.

Figure 1 - Inverter Amplifier

Gain is determined by equation

We can see that the circuit's gain is determined by the ratio between Rf and Ri.

Suppose we want a gain of X.

If Rf = 10,000 ohms and Ri = 5,000 ohms the gain is -2.

If Rf = 20,000 ohms and Ri = 10,000 ohms the gain is -2 too.

If we use resistors with tolerance (precision) of 5% the gain could vary between -1.81and -2.21 depending on real values of resistors Rf and Ri.

If we use resistors with tolerance (precision) of 2% the gain could vary between -1.92 e -2.08 what is much better.

What if we don't have precision resistors? What can we do?

We can use our ordinary resistors (tolerance of 5%). Take a bunch of them and measure each one until you find two resistors with a resistance ratio as near as possible of the value we wish (It is 2 in our sample).

Let me illustrate with an example. Say we take a bunch of resistors of 20K and 10K ohms (nominal values) to measure.

Suppose we found some resistors of 20,900 and 10,400 ohms. So we could do Rf = 20,900 ohms and Ri = 10,400. With these values, the gain would be -2.01 that is a better result than estimated with 2% tolerance resistors.

If we found Rf = 21,000 and Ri = 10,500 than the gain would be exactly 2.

The method, presented in this post, to use ordinary resistors instead of precision resistors is suitable only in prototype development. In commercial scale it is not feasible and the use of precision resistors is mandatory.

Note: As Maurício de Oliveira wrote in his answer to the brazilian portuguese version of this article, precision resistors are manufactured in a way that they take in account changes in their resistance by changes in temperature and manufacturers to their best to minimize it.

So, there are differences between precision resistors and ordinary resistors.

In this article (that I wrote to hobbyists), I am not taken this in account because hobbyists don't design professional circuits and then it will not cause too much trouble. Then it is a valid approuch for a experimental circuit.

sábado, março 08, 2008

How to load debug symbols with GDB

My friend Wanderley asked me if it is possible to tell GDB to load debuging symbols from some file and use it to help debuging a program that doesn't have them.

Yes. It is.

There are two solutions to this question.

I going to explain the first solution in this post. The other solution I will explain in the next post.

You can load debuging information from an debug enabled version of executable file.

In order to better explain the first solution, I will setup my sample environment as follows:
  • released.c: source code of the program we wish to debug (listing 1).
  • ~/estudo/: Source code of our program will be put here.
  • ~/local/bin: The stripped off version of binary program will stay here.
  • ~/local/symbols: In this place are all files that contain debuging information.
#include <stdio.h>
#include <stdlib.h>

int division(int a, int b);

int m;

int main(void)
int i;
int j;

printf("vou setar i\n");
i = 10;

printf("vou setar j\n");
j = 1;

printf ("i = %d, j = %d\n", i, j);
m = division(i, j);

printf("m = %d / %d = %d\n", i, j, m);

return 0;

int division(int a, int b)
return a / b;
Listing 1 - sample program source code

I have two versions of the program: with and without debuging information.

1 - You compile your program with debug information. In our sample:
gcc -Wall -g -release release.c <ENTER>

2 - You make a copy of your program. In our sample:
cp release release.full <ENTER>

3 - You strip off debuging information:
strip -s release <ENTER>

As you can see on Figure 1, we have two programs. released.full has debuging symbols but release doesn't have them.

Figure 1

4 - Move file release to ~/local/bin/:
mv release ~/local/bin <ENTER>

5 - Move file released.full to ~/local/symbols/
mv release.full ~/local/symbols <ENTER>

6 - Go to directory ~/local/bin
cd ~/local/bin <ENTER>

7 - Run GDB:
gdb ./release <ENTER>

8 - Try list command to see that release executable file doesn't have symbols in it.

Note: if the program was already running you could get its PID then attach GDB to it.

Figure 2 shows us two windows. The first one shows that our executable file has no debug information. In the other window we can see that release is not yet loaded.

Figure 2 - executable file named release is loaded by GDB but it is not yet running.

9 - Let GDB to load symbols from executable file named release.full. This binary version of our program has all symbols that we need to debug.

Please notice that GDB will not replace the release executable by release.full version of our program. It will just import symbols from release.full into release debugging session.

But GDB needs to know in advance where it must put the symbols it will load. How can you determine the correct memory address?

It is quite simple. You issue command maint inside GDB:
maint info sections

Then you look for .text section. The address that is in the first column is what you want. In our sample, it is 0x08048320. See figure 3.

Figure 3 - looking for .text section address

10 - The next step is to instruct GDB to load debug symbols into .text section. To achieve it you do this:
add-symbol-file ~/local/symbols/release.full <.text section address>

In our sample it means to type:
add-symbol-file ~/local/symbols/release.full 0x08048320

From now on you can debug your program as usual.

Figure 4 shows us that debugging symbols where imported successfully and that now the list command (abbreviated as l) shows us the program source code.

Figure 4 - now our GDB session has debuging symbols

As you can see in figure 5, I set a break point at line 17 and I ran the program that stopped there. Then I printed i variable.

In the other terminal I issued ps command. It was done just to show you that the only program running was release executable. There is no instance of release.full program.

Figure 5 - debugging session.

I hope this post will make your life easier. In the next time I will teach you another way to import debugging symbols.

sexta-feira, fevereiro 29, 2008

Using Mutt with Gmail

Gmail is the best e-mail service and Firefox is the best browser. But if you keep Gmail's page open for a long time then Firefox will waste a lot of memory of your computer.

If you have an old machine like me, you know that each byte is important. So, I decided to come back to my old mail client: Mutt (http://www.mutt.org/).

Here I'm showing some steps you need to let mutt access Gmail with IMAP protocol.

I'm using Ubuntu 7.04 with mutt 1.5.13, but it should work with other distros.

You must replace my_mail@gmail.com and my_password occurrences with real values.

  1. First of all you must enable IMAP access to your Gmail account. To enable IMAP in your Gmail account:
    1.1. Log in to your Gmail account.
    1.2. Click Settings at the top of any Gmail page.
    1.3. Click Forwarding and POP/IMAP.
    1.4. Select Enable IMAP.

  2. Install mutt, msmtp and ssl. I won't show you how to do it because it is different for each distro.

  3. Create msmtp configuration file (~/.msmtprc) as shown:

    account default
    host smtp.gmail.com
    port 587
    from my_mail@gmail.com
    tls on
    tls_starttls on
    auth on
    user my_mail@gmail.com
    password my_password
    logfile ~/.msmtp.log

  4. Create mutt configuration file (~/.muttrc) as shown:

    set imap_user = "my_mail@gmail.com"
    set imap_pass = "my_password"

    set from = "my_mail@gmail.com"
    set realname = "Your Real Name"

    set folder = "imaps://imap.gmail.com:993"
    set spoolfile = imaps://imap.gmail.com:993/INBOX
    set record=""
    set postponed="imaps://imap.gmail.com/[Gmail]/Drafts"

    set header_cache="~/.mutt/cache/headers"
    set message_cachedir="~/.mutt/cache/bodies"
    set certificate_file=~/.mutt/certificates
    set move = no
    set imap_check_subscribed="yes"
    set imap_list_subscribed="yes"
    set mbox="imaps://imap.gmail.com/[Gmail]/All Mail"
    # this line instructs mutt to refresh my IMAP mailbox every 60 seconds
    set mail_check=60
    #I'm using ^ character to instruct mutt to update e-mail list immediately
    bind index "^" imap-fetch-mail

And that's all folks.

quinta-feira, fevereiro 07, 2008

Primeiro Salto de Paraglider

No dia 27/01/2008, eu, Meine Liebe e os tios dela (Jfefe e Rosa) fomos passear nas praias de São Vicente.

Além de muito banho de mar, muita comida gostosa, andamos no teleférico.

Uma vez lá em cima, no morro xyz, aproveitei para realizar o meu primeiro salto de para-glider.

E quase que eu perco a oportunidade! A muito tempo que eu quero saltar, mas sempre alguma coisa me impedia: falta de tempo, falta de dinheiro, o pessoal só aceitava cheque ou dinheiro, os saltos estavam restritos aos competidores...

Dessa vez nada atrapalhou... fui lá, paguei, disse pra patroa "grave meu salto" e saltei.

Rapaz... é uma sensação indescritível. Muito legal ficar parado lá em cima, vendo a cidade lá embaixo... as pessoas parecendo formiguinhas.

"O vídeo vai ficar legal" - pensei.

Legal, ao invés de ficar aqui só falando, digo, escrevendo, eu poderia te mostrar o vídeo para veres como foi o meu salto de para-glider.

Poderia, mas não vou... minha mulher ficou com tanto medo, que ao invés de me filmar, virou o rosto para não ver nada!!!!!!!!!

Caramba! Vou ter que saltar de novo (legal, hein?) e pedir pra alguém gravar (e ela não vai ser esse alguém). Aí eu posto o vídeo aqui.

quarta-feira, janeiro 30, 2008

Looking for many words at once

I use Vim daily and my admiration for it always is renewed. It has so may features that I doubt any one can use 100% of its capacity.

One of the Vim's features I like too much is its ability to search different words at once in text.

When we want to find a word we enter in command mode and we type:

/word <ENTER>

- But what if we want to find two or more words ? Do we need to do separate searches?

No! We do just one search in command mode with each word separated by escaped pipes (\|) :

/word1\|word2\|word3 <ENTER>

Figure 1 shows a search for four words. Notice that spaces are considered as part of the word we are looking for.

Figure 2 shows the result of the search.

I hope this tip will be as useful for you as it is for me.

quinta-feira, janeiro 24, 2008

Livros que eu já li

Aqui estão alguns dos livros que eu já li (técnicos ou não).

terça-feira, janeiro 22, 2008

Procurando várias palavras ao mesmo tempo

Uso o Vim todos os dias e minha admiração por ele sempre se renova. Ele é tão cheio de recursos que duvido que exista alguém que consiga utilizar 100% das suas capacidades.

Um dos recursos que o Vim possui que mais me agrada é a sua capacidade de procurar por várias palavras diferentes ao mesmo tempo no texto.

Normalmente, quando queremos procurar uma palavra, entramos no modo de comando e digitamos:

/palavra <ENTER>

- Mas e quando queremos procurar duas ou mais palavras? Vamos ter que fazer as buscas separadamente?

Não! Nós efetuamos a busca, no modo de comando, com as palavras separadas pelo pipe escapado (\|) :

/palavra1\|palavra2\|palavra3 <ENTER>

A figura 1 abaixo ilustra o comando de busca para quatro palavras. Observe que os espaços são considerados como parte da palavra que se procura.

A figura 2 mostra o resultado da busca.

Espero que esta dica seja tão útil para ti quanto é para mim.

terça-feira, janeiro 15, 2008

Entendendo o Mercurial (2)

Fiz as correções na tradução do artigo Understanding Mercurial. A versão traduzida encontra-se aqui.

Aproveito para agradecer ao meu amigo Wanderley pelas correções e sugestões.

segunda-feira, janeiro 14, 2008

Entendendo o Mercurial

Hoje eu praticamente terminei a tradução do artigo Understanding Mercurial para o português. Falta eu fazer uma revisão e corrigir uns pequenos erros (que não atrapalham em nada o entendimento do assunto).

A tradução está no wiki do Mercurial. Podes visitá-la clicando aqui.

sábado, janeiro 12, 2008

Controle de Versões: Tão importante quanto o compilador!

Se tu desenvolves software, independente de qual seja a linguagem, então deves fazer o controle das modificações de algum modo.

Quando estava iniciando na programação, o controle que eu fazia era bem primitivo. Se eu tivesse apenas um arquivo, após finalizar as alterações, eu salvava uma cópia do mesmo com o seguinte formato: <nome>.<extensão><anomêsdia_horaminuto>.

Por exemplo, se eu tivesse um arquivo chamado meu arquivo.c e tivesse finalizado uma alteração do arquivo no dia 10/01/2008 às 18:30h, a cópia do mesmo teria o nome arquivo.c_20081001_1830.

Se por acaso fossem vários arquivos correlacionados, ao invés de copiar os arquivos em si, eu aplicava este método à pasta.

Por exemplo, se eu tivesse uma pasta chamada meuprograma e dentro desta pasta eu tivesse os arquivos meu_fonte.c, meu_fonte.h e LEIAME.TXT, após concluir as alterações nestes arquivos,supondo que elas tivessem ocorrido no dia 11/01/2008 às 09:30h, seria gerada uma cópia da pasta chamada meuprograma_20080111_0930.

Com o passar do tempo este tipo de controle torna-se ineficiente.

- Por quê? Porque eu não conseguia saber, por exemplo, que modificações foram feitas em que versão das cópias. Se eu tivesse um trabalho compartilhado com um ou mais colegas, tornava-se difícil dividir as tarefas e depois unir os trabalhos.

Procurando uma solução para estes problemas, encontrei o CVS. Durante anos ele foi uma ferramenta indispensável no meu trabalho. O CVS não evolui como deveria e, com o tempo, foi substituído com muitas vantagens pelo Subversion.

O Subversion, bem como o CVS e outros programas de controle de versão, possuem um repositório centralizado. Isto tem inumeras vantagens.

Um dia desses, meu amigo Wanderley me falou de um sistema de controle de versões (SCM) com repositório distribuído.

- Repositório distribuído? - Perguntei espantado. - Isso deve ser uma m...

Após ouvir atentamente (mesmo achando que seria perda de tempo), mudei de idéia e resolvi experimentar este programa. Afinal, o Wanderley é um programador muito experiente e não iria dar seu aval para uma solução meia-boca.

O Mercurial (este é o seu nome) é um sistema de controle de versões muito leve e ocupa pouco espaço disco.

Em SCMs com repositório centralizado, todos os arquivos ficam em um único local (servidor), sendo que os desenvolvedores baixam uma cópia dos mesmos para o seu diretório de trabalho. Certamente isto não é novidade para ti.

O Mercurial, por usar repositório distribuído, não possui um servidor central. Cada desenvolvedor tem ao mesmo tempo o repositório e o diretório de trabalho.

- Não parece nem seguro, nem prático. E qual a vantagem disso?

É seguro. O projeto já está bem estável e a cada release vários bugs são corrigidos .

É prático, pois por meio de comandos simples de exportação e importação podemos sincronizar nosso repositório com o repositório de outros desenvolvedores.

Além disso, o Mercurial possui várias extensões / contribuições da comunidade que ampliam e facilitam seu uso. Por exemplo, sua integração com o Bugzilla.

A vantagem de se utilizar o repositório distribuido verifica-se quando tu tens arquivos ou projetos que desenvolves na tua casa, no trabalho, nos computadores da faculdade, etc e não tens como instalar o Subversion, por exemplo, para controlar a versão dos mesmos (ou não tens acesso à rede).

Usando o Mercurial, podes manter o controle de versões onde for necessário, sem problemas. Não é preciso nem do acesso à rede. É só executares uma exportação / importação das modificações e pronto.

Isso sem abrir mão de controle de versões, habilidade de efetuar os diffs, ver logs, uso de tags, entre outras coisas que já nos acostumamos com o Subversion.

Já estou utilizando o Mercurial em 3 projetos (faz menos de um mês que comecei a usá-lo) e estou completamente satisfeito.

Estou pensando em traduzir para o Português os tutorias que se encontram no site oficial como uma forma de ajudar a ampliar o seu número de usuários.

Se tu usas o Subversion, o CVS ou outro sistema de versões, experimente o Mercurial. Com toda a certeza vais gostar muito de trabalhar com ele.

E se tu ainda não usas nenhum sistema destes, já passou da hora de começares. Vá no site do Mercurial e comece a utilizá-lo. Com o tutorial fornecido, em menos de 20 minutos já estarás dominando o programa.

Tu não vais te arrepender.

sábado, janeiro 05, 2008

Mecatrônica Fácil ameaçada por piratas

Ontem, recebi um e-mail da editora Saber Eletrônica. A editora informava que devido aos altos custos de produção de uma revista, dos impostos e à pirataria, eles não estão conseguindo manter a revista Mecatrônica Fácil.

- Pirataria?

Isso mesmo. Pirataria. Estão disponibilizando o conteúdo da revista na internet. Por causa desse tipo de gente (lixo é o termo mais apropriado), os esforços para que tenhamos uma elevação na qualidade técnica dos nossos estudantes e profissionais fica comprometida.
Resultado: a versão impressa da revista será cancelada. A editora vai disponibilizar o conteúdo apenas em mídia digital para os assinantes, via portal web que está em desenvolvimento, como uma tentativa de manter a revista viva.

Eu não sei se isso realmente vai dar resultados. Muita gente não gosta de ler no computador (por exemplo, eu).

Se o número de assinantes aumentasse de modo substancial, acredito que eles manteriam a versão impressa da revista.

Se tu és um aficcionado por Eletrônica e Mecatrônica e ainda não és assinante da Mecatrônica Fácil, entre em contato com a editora e faça a tua assinatura.

sexta-feira, janeiro 04, 2008

Pense bem onde investir seu dinheiro

Eu recentemente comecei a investir no mercado de ações. Como não gosto de perder dinheiro, antes de, efetivamente, botar meu dinheiro no fogo, fiz minha lição de casa: comprei livros e pesquisei sites e blogs sobre o assunto.

Sou leigo no que se refere ao mercado financeiro. Assim, comprei os livros que apareciam nos blogs que tratam de finanças (por sinal, todos excelentes).

Quando compro um livro sobre um assunto que desconheço e a obra se propõe a ensinar o básico, espero que o autor segure na mão do leitor, ou seja, que ele explique as coisas do modo mais fácil do mundo, entrando nos mínimos detalhes, por mais idiotas ou diretos que possam parecer.

- Por quê?

Quando nós conhecemos um assunto algumas coisas podem parecer óbvias, mas para um leigo não. Além disso, espero que o material tenha uma qualidade mínima que me permita ver claramente onde o autor quer chegar (especialmente quando se trata de gráficos ou códigos).

É responsabilidade do autor chamar a atenção do leitor para todos os detalhes que ele poderia deixar passar despercebidos.

Resolvi falar sobre um livro em especial neste meu post por considerar que ele não cumpre o seu papel.

O livro Aprenda a Investir com Sucesso em Ações, dos autores Gil Ari Deschatre e Arnaldo Majer. Editora Ciência Moderna.

Fiquei extremamente decepcionado com este livro. Abaixo seguem os motivos:
  • a qualidade é ruim. Os gráficos apresentados têm péssima qualidade.

  • o livro é abrangente ao falar da análise técnica, demonstrando vários métodos que podem ser utilizados nas análises. Entretanto, no meu entender, de modo muito superficial.

  • o autor passa uma boa parte do livro repetindo a importância de se utilizar programas de computador para facilitar as análise.
    Certo. Todos sabemos disso. Não é necessário ficar falando sobre isso o tempo inteiro. O espaço gasto com essa repetição exagerada poderia ter sido melhor empregado com um maior aprofundamento nos assuntos apresentados.
Não duvido da capacitação técnica dos autores, mas a didática deles é péssima.

Ao invés de comprar este livro, recomendo que tu estudes o material dos links abaixo:

Além disso, é fundamental que tu leias, diariamente, os blogs de finanças. Abaixo estão alguns que eu acompanho:

    Estes blogs, além da elevada qualidade, apresentam muita didática nos seus artigos.