Ofereço ajuda em Java, C/C++, Python, C#, LISP, AutoLisp, AutoCAD
Ofereço ajuda em PHP, Python, C#, JavaScript, Laravel, Google Ads e SEO

Planilha Web - Planilhas e Calculadoras online para estudantes e profissionais de Engenharia Civil, Engenharia Elétrica e Engenharia Mecânica.

C ::: Dicas & Truques ::: Rotinas de Conversão

Como converter uma string em um valor de ponto-flutuante usando a função atof() da linguagem C

Quantidade de visualizações: 9188 vezes
Em algumas situações, pode ser necessário converter uma string em um valor numérico de ponto-flutuante. Para isso podemos usar a função atof().

Esta função recebe uma matriz de caracteres e tenta transformá-la em um valor de ponto-flutuante. Se a conversão não for possível, o valor 0 é retornado. Os sinais "+" e "-", o ponto decimal e uma parte exponencial, representada por "e" ou "E" são válidos na string a ser convertida. Veja um exemplo:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
  // valor de ponto-flutuante em forma de string
  char valor_str[] = "34.5";

  // A linha abaixo causa um comportamento estranho
  //float res = 10 + valor_str;

  // temos que converter a string em um valor de ponto-flutuante válido
  float res = 10 + atof(valor_str);

  printf("O resultado e: %f", res);

  puts("\n");
  system("pause");
  return 0;
}



Java ::: Classes e Componentes ::: JList

Java Swing para iniciantes - Como adicionar itens a uma JList em tempo de execução

Quantidade de visualizações: 23008 vezes
Este exemplo mostra como inserir itens em uma JList do Java Swing em tempo de execução. O valor a ser inserido é informado em um JTextField. Veja que estamos usando a classe DefaultListModel e seu método addElement() para adicionar os novos itens.

Veja a janela JFrame e os componentes usados para exemplificar esta funcionalidade:



E agora veja o código Java Swing completo para o exemplo:

package arquivodecodigos;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
 
public class Estudos extends JFrame{
  JList lista;
  JTextField campo;  
 
  public Estudos() {
    super("A classe JList");
     
    Container c = getContentPane();
    c.setLayout(new FlowLayout(FlowLayout.LEFT));
     
    // Cria um novo DefaultListModel
    DefaultListModel modelo = new DefaultListModel();
     
    // Cria a JList
    lista = new JList();
  
    // Atribui o DefaultListModel à JList
    lista.setModel(modelo);
  
    // Um botão que permite adicionar itens na JList
    JButton btn = new JButton("Adicionar na JList");
    btn.addActionListener(
      new ActionListener(){
        public void actionPerformed(ActionEvent e){
          String valor = campo.getText();
           
          if(valor.length() != 0){
            ((DefaultListModel)(lista.getModel()))
               .addElement(valor);
            campo.setText("");
            campo.requestFocus();
          }
        }
      }
    );
 
    // Adiciona a lista à janela
    c.add(new JScrollPane(lista));
 
    // Cria um JTextField e o adiciona à janela
    campo = new JTextField(10);
    c.add(campo);
 
    // Adiciona o botão à janela
    c.add(btn);  
 
    setSize(350, 250);
    setVisible(true);
  }
   
  public static void main(String args[]){
    Estudos app = new Estudos();
    app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  }
}



C# ::: Desafios e Lista de Exercícios Resolvidos ::: Matemática e Estatística

Exercícios Resolvidos de C# - Como calcular juros simples em C# - Um programa C# que lê o valor principal, o tempo

Quantidade de visualizações: 738 vezes
Pergunta/Tarefa:

Saber como escrever um programa C# que recebe o valor principal, o tempo e a taxa de juros e retorna os juros simples a serem pagos ou recebidos é uma habilidade que todo programador deve aprender em algum ponto de sua carreira.

Sendo assim, escreva um algoritmo em C# que pede para o usuário informar um valor a ser pago ou recebido, o tempo em dias, meses ou anos e a taxa de juros (sem dividi-la por 100) e retorne os juros simples a serem pagos ou recebidos. Note que, se você quiser mostrar o valor total a ser pago ou recebido, basta somar os juros ao valor principal.

Antes, porém, veja a fórmula do cálculo de juros simples:

\[\text{Juros} = \frac{\text{C} \times \text{i} \times \text{t}}{100}\]

Onde:

C é o valor a ser pago ou a ser recebido;
i é a taxa de juros (sem dividir por 100);
t é o tempo em dias, meses, anos, etc.

Sua saída deverá ser parecida com:

Informe o valor principal: 600
Taxa de juros: 12
Informe o tempo: 5
Juros a serem pagos ou recebidos: 360.0
Resposta/Solução:

Veja a resolução comentada deste exercício usando C#:

using System;

namespace Estudos {
  class Principal {
    // função principal do programa C#
    static void Main(string[] args) {
      // vamos ler o valor principal
      Console.Write("Informe o valor principal: ");
      double principal = Double.Parse(Console.ReadLine());

      // agora vamos ler a taxa de juros
      Console.Write("Taxa de juros: ");
      double taxa = Double.Parse(Console.ReadLine());

      // finalmente o tempo em dias, meses, anos, etc
      Console.Write("Informe o tempo: ");
      int tempo = Int32.Parse(Console.ReadLine());

      // vamos calcular os juros
      double juros = (principal * taxa * tempo) / 100;

      // e mostramos o resultado
      Console.WriteLine("Juros a serem pagos ou recebidos: " + juros);
      
      Console.WriteLine("\nPressione uma tecla para sair...");
      Console.ReadKey();
    }
  }
}



Java ::: Java para Engenharia ::: Física - Mecânica

Como calcular a velocidade de um corpo dado sua massa e sua energia cinética usando a linguagem Java

Quantidade de visualizações: 1244 vezes
A Energia cinética é uma das formas da energia mecânica e definida como a energia de movimento, pois está relacionada com o estado de movimento de um corpo.

Variando de acordo com o movimento e a massa do corpo, esse tipo de energia tem sua existência condicionada à velocidade, uma vez que nos corpos em repouso ela não existe, pois a velocidade é nula.

Essa vertente de energia depende da relação entre corpo e o ponto referencial do observador. Se houver velocidade, haverá energia cinética. Portanto, não trata-se de uma energia invariável, mas sim de um tipo de energia mecânica que é determinada em função da massa do corpo em movimento, medida em quilogramas (kg), e da velocidade desenvolvida por ele, medida em metros por segundo (m/s).

A fórmula para obtenção da velocidade de um corpo, quando temos a sua energia cinética e a sua massa é:

\[\text{v} = \sqrt{\frac{E_c}{\frac{1}{2}\text{m}}}\]

Onde:

m ? massa do corpo (em kg).

Ec ? energia cinética (em joule, J).

v ? velocidade do corpo (em m/s).

Vamos ver um exemplo agora? Observe o seguinte enunciado:

1) Determine qual é a velocidade em que se move um corpo de 20kg cuja energia cinética é igual a 400J.

Note que o exercício já nos dá os valores em suas unidades de medidas no SI (Sistema Internacional de Medidas). Tudo que temos a fazer é converter a fórmula para código Java. Veja:

package arquivodecodigos;

public class Estudos{
  public static void main(String args[]){
    // energia cinética
    double energia_cinetica = 400; // em joule
    // massa do corpo
    double massa = 20; // em kg
    
    // e então calculamos a velocidade do corpo
    double velocidade = Math.sqrt(energia_cinetica / (0.5 * massa));
  
    // mostramos o resultado
    System.out.println("A velocidade do corpo é: " + velocidade + "m/s");     
  }
} 

Ao executar este código Java nós teremos o seguinte resultado:

A velocidade do corpo é: 6.324555320336759m/s

Não se esqueça de que a velocidade retornada estará em metros por segundo.


Java ::: Dicas & Truques ::: Strings e Caracteres

Como excluir uma substring de uma string usando o método delete() da classe StringBuffer do Java - Revisado

Quantidade de visualizações: 334 vezes
Em algumas situações nós gostaríamos de excluir parte de uma palavra ou texto, ou seja, remover uma substring de uma string. Para isso nós podemos usar o método delete() da classe StringBuffer da linguagem Java. Lembrando que a classe StringBuffer, do pacote java.lang, é usada em vez da classe String quando precisamos fazer muitas concatenações e adições ou remoções no conteúdo da string.

Veja um exemplo de código no qual removemos parte do conteúdo de um StringBuffer:

package arquivodecodigos;

public class Estudos{
  public static void main(String[] args){
    StringBuffer frase = new StringBuffer("Gosto muito de Java");
    
    // mostra o conteúdo original
    System.out.println("Frase original: " + frase);
    
    String remover = "muito ";
    // vamos obter o índice inicial do conteúdo a ser removido
    int pos = frase.indexOf(remover);
     
    // e agora vamos remover
    frase.delete(pos, pos + remover.length());
    
    // com a remoção
    System.out.println("Depois da remoção: " + frase);
     
    System.exit(0);
  }
}

Após a execução deste código nós teremos o seguinte resultado:

Frase original: Gosto muito de Java
Depois da remoção: Gosto de Java


Python ::: Dicas & Truques ::: Strings e Caracteres

Como converter uma string para float ou double em Python usando a função float()

Quantidade de visualizações: 1675 vezes
Em algumas situações nós temos um valor numérico representado por uma string e gostaríamos de convertê-lo para um valor float ou double na linguagem Python. Para isso nós podemos usar a função float(), disponível por padrão na linguagem.

Note o uso da função type() para exibirmos o tipo da variável antes e depois da conversão.

Veja o código Python completo para o exemplo:

# método principal
def main():
  # vamos pedir para o usuário informar o preço de um produto
  # note que o preço será lido como uma string
  preco = input("Informe o valor do produto: ")

  # vamos exibir o valor lido e o tipo da variável
  print("Você informou o valor: {0}".format(preco))
  print("O tipo da variável é: {0}".format(type(preco)))

  # agora vamos converter a string para o tipo float
  preco = float(preco)
  
  # vamos mostrar o novo tipo da variável
  print("O novo tipo da variável é: {0}".format(type(preco)))

if __name__== "__main__":
  main()

Ao executar este código Python nós teremos o seguinte resultado:

Informe o valor do produto: 45.92
Você informou o valor: 45.92
O tipo da variável é: <class 'str'>
O novo tipo da variável é: <class 'float'>

É preciso, no entanto, ter cuidado ao informar a string que será convertida para float. Se, em vez de informar o ponto separador de decimal, nós informarmos a vírgula, o seguinte erro será apresentado:

Informe o valor do produto: 45,21
Você informou o valor: 45,21
O tipo da variável é: <class 'str'>
Traceback (most recent call last):
File "c:\estudos_python\estudos.py", line 18, in <module>
main()
File "c:\estudos_python\estudos.py", line 12, in main
preco = float(preco)
ValueError: could not convert string to float: '45,21'


LISP ::: Dicas & Truques ::: Matemática e Estatística

Como testar se um número é par ou ímpar em Lisp

Quantidade de visualizações: 1069 vezes
Muitas vezes precisamos saber se um determinado número é par ou ímpar. Isso pode ser feito em Common Lisp usando-se a função REM, que retorna o resto de uma divisão por inteiros.

Veja o exemplo a seguir:

; variáveis que vamos usar no programa
(let ((num))
  ; Vamos ler um número inteiro
  (princ "Informe um valor inteiro: ")
  ; talvez o seu compilador não precise disso
  (force-output)
  ; atribui o valor lido à variável num
  (setq num (read))
   
  ; vamos testar se o número informado é par ou ímpar 
  (cond
    ((= 0 (rem num 2))
      (princ "Você informou um número par"))
    (T (princ "Você informou um número ímpar"))
  )
)

Ao executar este programa Common Lisp nós teremos o seguinte resultado:

Informe um valor inteiro: 8
Você informou um numero par

É importante observar que a maioria das implementações Lisp fornecem as funções EVENP e ODDP que permitem testar se um número é par ou ímpar. O objetivo dessa dica foi fazer uma comparação entre a Common Lisp e outras linguagens de programação na realização desta tarefa.


Revit C# ::: Dicas & Truques ::: Tratamento de Erros

Como corrigir o erro OperationCanceledException em macros e add-ins do Revit C# API

Quantidade de visualizações: 406 vezes
Nesta dica mostrarei como podemos tratar a exceção OperationCanceledException em macros e plug-ins feitos para o Revit usando a Revit C# API. Esta exceção está no namespace Autodesk.Revit.Exceptions e deve ser declarada por seu nome completo, para não ser confundida com System.OperationCanceledException.

O erro OperationCanceledException ocorre quando uma operação é cancelada de forma inesperada. Por exemplo, no código abaixo nós pedimos para o usuário selecionar um grupo e, em seguida, informar um ponto na área de desenho do Revit para que o grupo seja copiado e colocado no ponto indicado.

Se o usuário clicar com o botão direito ou pressionar Esc, a operação é cancelada automaticamente. O tratamento da exceção OperationCanceledException nos permite reagir a isso, indicando ao usuário o melhor caminho a ser seguido.

O código apresentado aqui já foi visto em dicas e truques sobre a criação e manipulação de grupos de elementos no Revit usando a Revit C# API. No entanto, no código apresentado eu não fiz o tratamento de exceções.

Veja o código Revit C# API completo para o exemplo:

using System;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Structure;
using Autodesk.Revit.UI.Selection;
using System.Collections.Generic;
using System.Linq;
 
namespace Estudos {
  [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.
    TransactionMode.Manual)]
  [Autodesk.Revit.DB.Macros.AddInId("ED8EC6C4-9489-48F7-B04E-B45B5D1BEB12")]
  public partial class ThisApplication {
    private void Module_Startup(object sender, EventArgs e) {
      // vamos obter uma referência ao Document ativo
      Document doc = this.ActiveUIDocument.Document;
      
      // Vamos definir um objeto Reference para guardar
      // o elemento selecionado pelo usuário
      Reference ref_selecionado = null;
  
      // pedimos para o usuário selecionar um grupo
      Selection selecao = this.ActiveUIDocument.Selection;
      
      try {
        ref_selecionado = selecao.PickObject(ObjectType.Element,
          "Selecione um grupo");
        Element elem = doc.GetElement(ref_selecionado);
        Group group = elem as Group;
      
        // vamos pedir para o usuário selecionar um ponto na área de
        // desenho do Revit
        XYZ ponto = selecao.PickPoint(
          "Selecione um ponto para posicionar o grupo");
      
        // criamos uma nova transação e posicionamos a cópia do
        // grupo nas coordenadas indicadas pelo usuário
        Transaction transacao = new Transaction(doc);
        transacao.Start("Copiar Grupo no Revit");
        doc.Create.PlaceGroup(ponto, group.GroupType);
        transacao.Commit();
      
        // mostramos o resultado
        TaskDialog.Show("Aviso", "O grupo foi copiado com sucesso.");
      }
      // Se o usuário clicar com o botão direito ou pressionar Esc
      catch (Autodesk.Revit.Exceptions.OperationCanceledException ex) {
        TaskDialog.Show("Aviso", "Erro: Operação cancelada pelo usuário");
      }
      catch (Exception ex) {
        TaskDialog.Show("Aviso", "Erro: " + ex.Message);
      }
    }
    
    private void Module_Shutdown(object sender, EventArgs e) {
      // para fazer alguma limpeza de memória ou algo assim
    }
 
    #region Revit Macros generated code
    private void InternalStartup() {
      this.Startup += new System.EventHandler(Module_Startup);
      this.Shutdown += new System.EventHandler(Module_Shutdown);
    }
    #endregion
  }
}

Se o usuário cancelar a operação, ou seja, não selecionar nenhum grupo (talvez pressionando a tecla Esc), o código reagirá e mostrará a mensagem:

Erro: The user aborted the pick operation.

Se, em vez de selecionar um grupo, o usuário selecionar um outro elemento, então a mensagem de erro será:

Erro: Referência de objeto não definida para uma instância de um objeto.


Java ::: Desafios e Lista de Exercícios Resolvidos ::: Arrays e Matrix (Vetores e Matrizes)

Exercícios Resolvidos de Java - Verifique se as componentes de um vetor de 10 componentes inteiros lidos pelo teclado formam uma progressão aritmética

Quantidade de visualizações: 1734 vezes
Pergunta/Tarefa:

Verifique se as componentes de um vetor de 10 componentes inteiros lidos pelo teclado formam uma progressão aritmética, informando se sim ou se não. Caso forme, imprima o termo inicial e a razão.

Resposta/Solução:

Para a entrada do usuário, nós vamos usar um objeto da classe Scanner. Veja a resolução comentada:

package arquivodecodigos;

import java.util.Scanner;

public class Estudos{
  public static void main(String[] args){
    // vamos usar a classe Scanner para leitura
    Scanner entrada = new Scanner(System.in);

    // declara e constrói um vetor de 10 inteiros
    int valores[] = new int[10];
    
    // vamos ler os valores dos elementos do vetor
    for(int i = 0; i < valores.length; i++){
      System.out.print("Informe o valor: ");
      valores[i] = Integer.parseInt(entrada.nextLine());
    }
    
    // já temos o vetor. Agora vamos verificar se temos
    // uma progressão geométrica
    boolean progressao = true;
    // vamos obter a razão
    int razao = valores[1] / (valores[0]);
    
    // vamos varrer os elementos do vetor e verificar se todos
    // possuem a mesma razão
    for(int i = 1; i < valores.length; i++){
      if((valores[i] / (valores[i - 1])) != razao){
        progressao = false;
        break;
      }
    }
    
    if(progressao){
      System.out.println("Formam uma progressão geométrica.");
      System.out.println("A razão é: " + razao);
      System.out.println("O primeiro termo é: " + valores[0]);
    }
    else{
      System.out.println("Não formam uma progressão geométrica.");
    }
  }
}

Ao executar este código Java nós teremos o seguinte resultado:

Informe o valor: 1
Informe o valor: 2
Informe o valor: 4
Informe o valor: 8
Informe o valor: 16
Informe o valor: 32
Informe o valor: 64
Informe o valor: 128
Informe o valor: 256
Informe o valor: 512
Formam uma progressão geométrica.
A razão é: 2
O primeiro termo é: 1


C# ::: Coleções (Collections) ::: List<T>

Como usar a classe genérica List<T> do C# em suas aplicações

Quantidade de visualizações: 15751 vezes
A classe genérica List<T> da linguagem C# representa uma lista fortemente tipada de objetos que podem ser acessados por índices. Esta classe fornece métodos para pesquisar, ordenar e manipular seus elementos. Veja sua posição na hierarquia de classes da plataforma .NET:

System.Object
  System.Collections.Generic.List<T>
    System.ServiceModel.Install.Configuration.
  ServiceModelConfigurationSectionCollection
    System.ServiceModel.Install.Configuration.
  ServiceModelConfigurationSectionGroupCollection
    System.Workflow.ComponentModel.ActivityCollection
    System.Workflow.Activities.WorkflowRoleCollection
    System.Workflow.Activities.OperationParameterInfoCollection
    System.Workflow.ComponentModel.Design.
  ActivityDesignerGlyphCollection
    System.Workflow.Runtime.Tracking.ExtractCollection
    System.Workflow.Runtime.Tracking.TrackingAnnotationCollection
    System.Workflow.Runtime.Tracking.TrackingConditionCollection
    System.Workflow.Runtime.Tracking.ActivityTrackingLocationCollection
    System.Workflow.Runtime.Tracking.UserTrackingLocationCollection
    System.Workflow.Runtime.Tracking.ActivityTrackPointCollection
    System.Workflow.Runtime.Tracking.UserTrackPointCollection
    System.Workflow.Runtime.Tracking.WorkflowTrackPointCollection

Esta classe implementa também as interfaces IList<T>, ICollection<T>, IEnumerable<T>, IList, ICollection e IEnumerable.

A classe List<T> é a equivalente genérica da classe ArrayList. Ela implementa a interface genérica IList<T> usando um array (matriz) cujo tamanho é dinamicamente aumentado de acordo com a necessidade. Esta classe usa tanto um comparador de igualdade quanto um de ordenação.

Os métodos tais como Contains(), IndexOf(), LastIndexOf() e Remove() usam um comparador de igualdade para os elementos da lista. O comparador de igualdade padrão para o tipo T é definido segundo as seguintes regras: Se o tipo T implementar a interface genérica IEquatable<T>, então o comparador de igualdade é o método Equals(T) dessa interface. Caso contrário, o comparador de igualdade padrão é Object.Equals(Object).

Os métodos tais como BinarySearch() e Sort() usam um comparador de ordenação para os elementos da lista. O comparador padrão para o tipo T é definido da seguinte forma: Se o tipo T implementar a interface genérica IComparable<T>, então o comparador padrão é o método CompareTo(T) dessa interface. Caso contrário, se o tipo T implementar a interface não-genérica IComparable, então o comparador padrão é o método CompareTo(Object) dessa interface. Se o tipo T não implementar nenhuma destas duas interfaces, então não haverá comparador padrão, e um comparador ou delegate de comparação deve ser fornecido explicitamente.

Uma lista List<T> não fornece garantias quanto à sua ordenação. Devemos ordená-la por conta própria antes de efetuar algumas operações (tais como BinarySearch) que exigem que a List<T> esteja ordenada. Os elementos em uma coleção do tipo List<T> podem ser acessados usando índices (que começam a partir de 0). Uma List<T> aceita o valor null como valor válido para tipos referência e aceita elementos duplicados.

Em relação à performance, a documentação do .NET afirma que, embora List<T> e ArrayList possuam funcionalidade semelhante, a classe List<T> possui uma performance melhor na maioria dos casos, além de ser type safe (oferece segurança de tipos).

Veja um trecho de código no qual criamos uma List<T> de inteiros, inserimos alguns valores e usamos o laço foreach para percorrer a lista e exibir os valores dos elementos:

static void Main(string[] args){
  // vamos criar um objeto da classe List<T>
  List<int> valores = new List<int>();

  // vamos inserir três valores na lista
  valores.Add(5);
  valores.Add(2);
  valores.Add(9);

  // vamos usar o laço foreach para percorrer os elementos
  // na lista
  foreach(int v in valores){
    Console.WriteLine(v);    
  }

  // vamos pausar a execução
  Console.ReadKey();
}


Carregar Publicações Anteriores


Nossas 20 dicas & truques de programação mais populares

Você também poderá gostar das dicas e truques de programação abaixo

Nossas 20 dicas & truques de programação mais recentes

Últimos Projetos e Códigos Fonte Liberados Para Apoiadores do Site

Últimos Exercícios Resolvidos

E-Books em PDF

E-Book 350 Exercícios Resolvidos de Java - PDF com 500 páginas
Domine lógica de programação e a linguagem Java com o nosso E-Book 350 Exercícios Exercícios de Java, para você estudar onde e quando quiser.

Este e-book contém exercícios resolvidos abrangendo os tópicos: Java básico, matemática e estatística, programação dinâmica, strings e caracteres, entrada e saída, estruturas condicionais, vetores e matrizes, funções, laços, recursividade, internet, arquivos e diretórios, programação orientada a objetos e muito mais.
Ver Conteúdo do E-book
E-Book 650 Dicas, Truques e Exercícios Resolvidos de Python - PDF com 1.200 páginas
Domine lógica de programação e a linguagem Python com o nosso E-Book 650 Dicas, Truques e Exercícios Exercícios de Python, para você estudar onde e quando quiser.

Este e-book contém dicas, truques e exercícios resolvidos abrangendo os tópicos: Python básico, matemática e estatística, banco de dados, programação dinâmica, strings e caracteres, entrada e saída, estruturas condicionais, vetores e matrizes, funções, laços, recursividade, internet, arquivos e diretórios, programação orientada a objetos e muito mais.
Ver Conteúdo do E-book

Linguagens Mais Populares

1º lugar: Java
2º lugar: Python
3º lugar: C#
4º lugar: PHP
5º lugar: C
6º lugar: Delphi
7º lugar: JavaScript
8º lugar: C++
9º lugar: VB.NET
10º lugar: Ruby


E-Book 350 Exercícios Resolvidos de Java - PDF com 500 páginas
Domine lógica de programação e a linguagem Java com o nosso E-Book 350 Exercícios Exercícios de Java, para você estudar onde e quando quiser. Este e-book contém exercícios resolvidos abrangendo os tópicos: Java básico, matemática e estatística, programação dinâmica, strings e caracteres, entrada e saída, estruturas condicionais, vetores e matrizes, funções, laços, recursividade, internet, arquivos e diretórios, programação orientada a objetos e muito mais.
Ver Conteúdo do E-book Apenas R$ 19,90


© 2025 Arquivo de Códigos - Todos os direitos reservados
Neste momento há 37 usuários muito felizes estudando em nosso site.