![]() |
|||||
|
Java ::: Tratamento de Erros ::: Passos Iniciais |
Quais as diferenças entre checked exceptions, runtime exceptions e errors na linguagem Java?Quantidade de visualizações: 15644 vezes |
Checked exceptions (exceções verificadas), runtime exceptions (exceções de tempo de execução) e errors (erros) possuem diferenças importantes e devem ser entendidas perfeitamente para tirarmos maior proveito da plataforma Java. Entre as checked exceptions podemos citar FileNotFoundException, ClassNotFoundException e IOException. Agora veja: problemas tais como um arquivo não encontrado, uma classe não encontrada ou problemas com entrada e saída (talvez a impressora parou de responder ou a rede caiu) fogem completamente do domínio da aplicação. Tais exceções não são provocadas por código mal escrito ou mal testado. Desta forma, o Java força que todas as checked exceptions estejam em um bloco try...catch. Vamos ver se isso é verdade? Observe o trecho de código abaixo: import java.io.*; public class Estudos{ public static void main(String[] args){ DataInputStream in = new DataInputStream( new BufferedInputStream( new FileInputStream("conteudo.txt"))); while(in.available() != 0) System.out.print((char) in.readByte()); System.exit(0); } } Se tentarmos compilar este código teremos o seguinte resultado: Estudos.java:7: unreported exception java.io.FileNotFoundException; must be caught or declared to be thrown new FileInputStream("conteudo.txt"))); ^ Estudos.java:9: unreported exception java.io.IOException; must be caught or declared to be thrown while(in.available() != 0) ^ Estudos.java:10: unreported exception java.io.IOException; must be caught or declared to be thrown System.out.print((char) in.readByte()); ^ 3 errors Aqui nós temos uma exceção FileNotFoundException e duas exceções IOException. Vamos nos concentrar na exceção gerada pelo construtor da classe FileInputStream. Folheando a documentação do Java nós encontramos: public FileInputStream(String name) throws FileNotFoundException É aqui que as coisas começam a ficar interessantes. Todos os métodos Java que podem atirar exceções verificadas são marcados com throws e o tipo de exceção lançada. A palavra throws é usada para transferir a responsabilidade do tratamento do erro para o chamador de tais métodos. Outro exemplo é o método readByte() da classe DataInputStream: public final byte readByte() throws IOException Para corrigir as exceções acima, só precisamos usar um bloco try...catch. Veja: import java.io.*; public class Estudos{ public static void main(String[] args){ try{ DataInputStream in = new DataInputStream( new BufferedInputStream( new FileInputStream("conteudo.txt"))); while(in.available() != 0) System.out.print((char) in.readByte()); } catch(IOException e){ System.out.print(e.getMessage()); } System.exit(0); } } Exceções verificadas são todas aquelas que descendem de Exception mas não descendem de RuntimeException. As exceções de tempo de execução (runtime exceptions) são provocadas por código mal escrito ou mal testado, ou seja, são causadas por nós programadores. Entre estas exceções podemos citar ArithmeticException, IndexOutOfBoundsException e NoSuchElementException. De fato, um erro aritmético é responsabilidade do programador, pois cabe a este verificar se os valores estão dentro da faixa permitida por cada tipo de dados. Ao contrário das exceções verificadas, o compilador não força o uso do bloco try...catch para as runtime exceptions. De fato, isso é fácil de compreender, uma vez que tais exceções não deveriam jamais aparecer. Contudo, pode ser desejável usar o bloco try...catch em casos em que os valores de uma operação são definidos pelo usuário. Veja um exemplo: import java.util.*; public class Estudos{ public static void main(String[] args){ Scanner in = new Scanner(System.in); System.out.print("Informe um inteiro: "); int valor = in.nextInt(); System.out.print("Informe outro inteiro: "); int valor2 = in.nextInt(); System.out.println("O resultado é " + valor / valor2); } } Se executarmos este código e informarmos o valor 0 para o segundo inteiro, teremos a seguinte exceção: Informe um inteiro: 4 Informe outro inteiro: 0 Exception in thread "main" java.lang.ArithmeticException: / by zero at Estudos.main(Estudos.java:13) Uma forma de corrigir isso é testando os valores informados para verificar suas faixas ou lançar uma exceção. Veja como usamos esta última alternativa: import java.util.*; public class Estudos{ public static void main(String[] args){ Scanner in = new Scanner(System.in); System.out.print("Informe um inteiro: "); int valor = in.nextInt(); System.out.print("Informe outro inteiro: "); int valor2 = in.nextInt(); try{ System.out.println("O resultado é " + valor / valor2); } catch(ArithmeticException e){ System.out.println("Uma exceção " + "ArithmeticException ocorreu, " + "possivelmente uma tentativa de " + "divisão por zero."); } } } Agora se informarmos zero para o segundo inteiro, teremos: Informe um inteiro: 5 Informe outro inteiro: 0 Uma exceção ArithmeticException ocorreu, possivelmente uma tentativa de divisão por zero. As runtime exceptions (causadas por falha nossa, os programadores) descedem de java.lang.RuntimeException. Além das runtime exceptions e das checked exceptions, temos também os errors, que descedem de java.lang.Error e não devem jamais ser atirados ou tratados em blocos try...catch. Este tipo de erro é reservado para indicar problema na JVM. Entre tais erros temos OutOfMemoryError, que é lançado quando a Java Virtual Machine não consegue alocar um objeto porque sua fatia de memória esgotou e o Garbage Collector ainda não liberou mais memória. Não há razão para tratarmos isso em um bloco try...catch uma vez que, ao contrário de C++, a liberação de memória só é feita pelo GC. O melhor a fazer é deixar mesmo o programa ser encerrado e encontrar alternativas para a correção do problema. |
Python ::: NumPy Python Library (Biblioteca Python NumPy) ::: Números Aleatórios, Números Randômicos, Amostras Aleatórias, Amostras Randômicas |
Como gerar um número randômico em Python usando a função rand() do módulo random da NumPyQuantidade de visualizações: 732 vezes |
Em algumas situações nós precisamos gerar um número aleatório na faixa de 0 e 1 (não incluído). Para isso nós podemos usar a função rand() do módulo random da biblioteca NumPy do Python. Veja um exemplo:# importamos o módulo random da biblioteca NumPy import numpy as np # método principal def main(): # vamos gerar um número decimal aleatório de 0 (incluído) # à 1 (não incluído) valor = np.random.rand() print("O número sorteado foi: {0}".format(valor)) if __name__== "__main__": main() Ao executar este código Python nós teremos o seguinte resultado: O número sorteado foi: 0.2037063569952866 Note que o número retornado pela função rand() é um float com uma precisão semelhante ao double em outras linguagens de programação. Veja agora uma modificação deste código para gerar 10 números aleatórios: # importamos o módulo random da biblioteca NumPy import numpy as np # método principal def main(): # vamos gerar 10 números decimais aleatórios de 0 (incluído) # à 1 (não incluído) for i in range(10): valor = np.random.rand() print("O número sorteado foi: {0}".format(valor)) if __name__== "__main__": main() Ao executar este código Python nós teremos o seguinte resultado: O número sorteado foi: 0.57920714427429 O número sorteado foi: 0.06329414607318185 O número sorteado foi: 0.12184477988071851 O número sorteado foi: 0.5410663009618577 O número sorteado foi: 0.790229323250604 O número sorteado foi: 0.4733277307431061 O número sorteado foi: 0.7669969432159425 O número sorteado foi: 0.6934927410217504 O número sorteado foi: 0.13216036543343856 O número sorteado foi: 0.6958612722883786 |
C++ ::: Desafios e Lista de Exercícios Resolvidos ::: Estruturas de Controle |
Exercício Resolvido de C++ - Como testar se um ano é bissexto em C++ - Um programa que lê um ano com quatro dígitos e informa se ele é bissexto ou nãoQuantidade de visualizações: 486 vezes |
Pergunta/Tarefa: Chama-se ano bissexto o ano ao qual é acrescentado um dia extra, ficando ele com 366 dias, um dia a mais do que os anos normais de 365 dias, ocorrendo a cada quatro anos (exceto anos múltiplos de 100 que não são múltiplos de 400). Isto é feito com o objetivo de manter o calendário anual ajustado com a translação da Terra e com os eventos sazonais relacionados às estações do ano. O último ano bissexto foi 2012 e o próximo será 2016. Um ano é bissexto se ele for divisível por 4 mas não por 100, ou se for divisível por 400. Escreva um programa C++ que pede ao usuário um ano com quatro dígitos e informa se ele é bissexto ou não. Sua saída deverá ser parecida com: Informe o ano: 2024 O ano informado é bissexto. Veja a resolução comentada deste exercício usando C++: #include <iostream> using namespace std; // função principal do programa int main(int argc, char *argv[]){ // variáveis usadas para resolver o problema int ano; // vamos solicitar que o usuário informe um ano cout << "Informe o ano: "; cin >> ano; // vamos verificar se o ano informado é bissexto if(((ano % 4 == 0) && (ano % 100 != 0)) || (ano % 400 == 0)){ cout << "O ano informado é bissexto."; } else{ cout << "O ano informado não é bissexto."; } cout << "\n" << endl; system("PAUSE"); // pausa o programa return EXIT_SUCCESS; } |
MySQL ::: Dicas & Truques ::: Joins (Junções) |
Como agrupar dados de duas ou mais tabelas no MySQL usando LEFT JOIN (ou LEFT OUTER JOIN)Quantidade de visualizações: 14757 vezes |
A junção LEFT JOIN (ou LEFT OUTER JOIN) do MySQL é usada quando queremos agrupar dados de duas ou mais tabelas e exibir todos os registros da tabela à esquerda, mesmo que não haja correspondências (match) de registros na tabela à direita. Vamos ver um exemplo? Considere duas tabelas: jogadores e times. Um jogador pode jogar em nenhum (zero) ou um time e um time pode conter zero ou mais jogadores. Aqui a cardinalidade é de 1 x N. Comece criando a tabela de times: Comando DDL CREATE TABLE para a tabela times: CREATE TABLE times( id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, nome VARCHAR(45) NOT NULL, PRIMARY KEY(id) ) ENGINE = InnoDB; Vá em frente e insira alguns times nesta tabela. Vamos agora criar a tabela de jogadores: Comando DDL CREATE TABLE para a tabela jogadores: CREATE TABLE jogadores( id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, nome VARCHAR(45) NOT NULL, id_time INTEGER UNSIGNED, PRIMARY KEY(id), CONSTRAINT fk_jogadores_times FOREIGN KEY fk_jogadores_times(id_time) REFERENCES times(id) ON DELETE RESTRICT ON UPDATE RESTRICT ) ENGINE = InnoDB; Note que o campo id_time da tabela jogador aceita NULL, ou seja, como é possível haver jogadores sem times, devemos ser capazes de cadastrar os jogadores e só mais adiante definir o time a qual ele pertencerá. Veja: INSERT INTO jogadores VALUES(NULL, 'JORGINHO', NULL); Vá em frente e cadastre alguns jogadores (sem relacioná-los com algum time). Finalizado alguns cadastros de jogadores e times, use a instrução UPDATE para relacionar alguns jogadores com seus respectivos times (deixe alguns jogadores sem time). Veja um exemplo: UPDATE jogadores SET id_time = 3 WHERE id = 2; E aqui já podemos ver um exemplo da junção LEFT JOIN. Nossa tarefa é listar o id, nome do jogador e nome do time a qual ele pertence. Mas, queremos também incluir na listagem os jogadores que ainda não possuem times (o valor do campo id_time ainda é NULL). Veja: SELECT j.id, j.nome, t.nome FROM jogadores j LEFT JOIN times t ON j.id_time = t.id; id jogador time 1 ROBERTO CARLOS ? 2 JORGINHO CRUZEIRO 3 GUSTAVO BORGES ? 4 MARCOS ? Note que o conjunto de dados retornados inclui todos os jogadores, incluindo aqueles para os quais nenhum time foi definido ainda. |
Python ::: Flask Micro Framework ::: Rotas e Roteamento |
Como criar rotas em suas aplicações Flask usando o decorador @app.route() - Tutorial Flask para iniciantesQuantidade de visualizações: 1795 vezes |
Aplicações web modernas usam uma técnica chamada roteamento nomeado, ou, na linguagem do pessoal do SEO, URLs amigáveis. Isso quer dizer que, em vez de termos URLS do tipo /livro.php?id_livro=39 nós temos /livro/39. Neste modelo de roteamento, livro é o nome de uma função Python que será chamada quando o usuário acessar este endereço, e 39 será o argumento passado para o método. Em Flask, as URLs são associadas às funções Python por meio do decorador @app.route(). Veja uma aplicação Flask completa que possui um método index() que é chamado quando o usuário acessa a raiz da aplicação: # vamos importar a biblioteca Flask from flask import Flask # função principal do programa def main(): # vamos criar a aplicação Flask app = Flask(__name__) # definimos a rota para a função index() @app.route("/") def index(): return "Este é o método index()" # e iniciamos a aplicação web na porta 5000 app.run(port=5000, debug=True) if __name__== "__main__": main() Note que a nossa aplicação Flask estará disponível na porta 5000. Assim, ao acessar o endereço http://127.0.0.1:5000 nós teremos o seguinte resultado: Este é o método index() Veja agora como criar uma URL /listar_usuarios e associá-la a uma função listar_usuarios(): # vamos importar a biblioteca Flask from flask import Flask # função principal do programa def main(): # vamos criar a aplicação Flask app = Flask(__name__) # definimos a rota para a função index() @app.route("/") def index(): return "Este é o método index()" # definimos a rota para a função listar_usuarios() @app.route("/listar_usuarios") def listar_usuarios(): return "Este é o método para listar os usuários" # e iniciamos a aplicação web na porta 5000 app.run(port=5000, debug=True) if __name__== "__main__": main() Agora, experimente acessar o endereço http://127.0.0.1:5000/listar_usuarios e veja o resultado. Se tudo estiver correto, você verá o seguinte resultado: Este é o método para listar os usuários Em mais dicas desta seção você verá como criar URLs com parâmetros e passá-los para suas funções Python. |
C# ::: LINQ ::: LINQ to Objects |
Como retornar o maior elemento em um array de int em C# usando a função Max() do LINQQuantidade de visualizações: 1120 vezes |
Nesta dica mostrarei, em um exemplo bem simples, como podemos usar o método Max() do LINQ (Language-Integrated Query) do C# para retornar o maior elemento de um vetor de inteiros. Note que temos um vetor de int com os valores {5, 2, 8, 3, 0, 1} e o valor 8 deverá ser retornado como sendo o maior. Veja o código completo para o exemplo: using System; using System.Linq; namespace Estudos { class Principal { static void Main(string[] args) { // vamos construir um vetor de inteiros int[] valores = {5, 2, 8, 3, 0, 1}; // vamos obter o maior elemento do vetor int maior = valores.Max(); // vamos mostrar o resultado Console.WriteLine("O maior valor é: {0}", maior); Console.WriteLine("\nPressione uma tecla para sair..."); Console.ReadKey(); } } } Ao executar este código C# nós teremos o seguinte resultado: O maior valor é: 8 Fique atento ao fato de que o método Max() pode atirar uma exceção do tipo InvalidOperation se o array ou coleção estiver vazia ou não incluir nenhum elemento que se encaixe nas condições testadas. Veja o resultado ao chamarmos este método em um vetor vazio: System.InvalidOperationException HResult=0x80131509 Message=Sequence contains no elements Source=System.Linq StackTrace: at System.Linq.ThrowHelper.ThrowNoElementsException() at System.Linq.Enumerable.Max(IEnumerable`1 source) at Estudos.Principal.Main(String[] args) in C:\estudos_c#\Estudos\Principal.cs:line 11 |
Python ::: Desafios e Lista de Exercícios Resolvidos ::: Hidrologia e Hidráulica |
Exercícios Resolvidos de Python - FEMPERJ-2012-TCE-RJ: A vazão de dimensionamento de uma galeria de águas pluviais que drena uma área densamente urbanizada de 10 hectaresQuantidade de visualizações: 524 vezes |
Pergunta/Tarefa: 1) FEMPERJ-2012-TCE-RJ: A vazão de dimensionamento de uma galeria de águas pluviais que drena uma área densamente urbanizada de 10 hectares, considerando-se uma chuva de projeto com intensidade de 60 mm/hora, duração igual ao tempo de concentração da bacia e coeficiente de escoamento superficial igual a 0,90, através do Método Racional, é: A) 150 m3/s B) 0,150 l/s C) 1,5 m3/s D) 150 l/s E) 15 m3/s Sua saída deve ser parecida com: Intensidade da chuva em mm/h: 60 Área da bacia em hectares: 10 Coeficiente de escoamento: 0.9 A vazão de dimensionamento é: 1.5 m3/s O primeiro passo para resolver esta questão é relembrar a fórmula da Vazão pelo Método Racional. Apresentado pela primeira vez em 1851 por Mulvaney e usado por Emil Kuichling em 1889, o Método Racional é um método indireto e estabelece uma relação entre a chuva e o escoamento superficial (deflúvio). Usamos esta fórmula para calcular a vazão de pico de uma determinada bacia, considerando uma seção de estudo. Eis a fórmula: \[Q = \frac{C \cdot I \cdot A}{360} \] Onde: Q = vazão de pico (m3/s); C = coeficiente de escoamento superficial que varia de 0 a 1. Coeficiente de Runoff (adimensional). I = intensidade média da chuva (mm/h); A = área da bacia (ha), onde 1 ha = 10.000m2. A [[menor_igual]] 300 ha. Na questão do concurso nós já temos a intensidade da chuva em milímetros por hora e a área já está em hectares. Tudo que temos a fazer é jogar na fórmula. Então, hora de vermos a resolução comentada deste exercício usando Python: # função principal do programa def main(): # vamos ler a precipitação ou intensidade da chuva em mm/h intensidade = float(input("Intensidade da chuva em mm/h: ")) # vamos ler a área da bacia em hectares area_bacia = float(input("Área da bacia em hectares: ")) # vamos ler o coeficiente de escoamento coeficiente = float(input("Coeficiente de escoamento: ")) # e vamos calcular a vazão de pico em metros cúbicos vazao = ((coeficiente * intensidade * area_bacia) / 360.0) # e mostramos o resultado print("A vazão de dimensionamento é: {0} m3/s".format(vazao)) if __name__== "__main__": main() |
Python ::: Python para Engenharia ::: Geometria Analítica e Álgebra Linear |
Como calcular a transposta de uma matriz em Python - Python para Geometria Analítica e Álgebra LinearQuantidade de visualizações: 6968 vezes |
A matriz transposta de uma matriz A é a matriz AT. Tal matriz é obtida quando copiamos os elementos da matriz A para uma outra matriz (ou para ela mesma) e trocamos de posição as linhas e colunas. Dessa forma, a primeira linha da matriz A se transforma na primeira coluna da matriz transposta, a segunda linha da matriz A se transforma na segunda coluna da matriz transposta e assim por diante. Em termos de notação, podemos dizer, de forma algébrica, que: ATji = Aij Onde i representa as linhas e j representa as colunas, tanto na matriz original quanto na matriz transposta. É importante estar atento à quantidade de linhas e colunas na matriz original e na matriz transposta equivalente. Assim, se a matriz original for 3x2, a matriz transposta será 2x3. Antes de vermos o código Python, dê uma olhada na seguinte matriz de duas linhas e três colunas: \[A = \left[\begin{matrix} 3 & 5 & 7 \\ 1 & 2 & 9 \end{matrix}\right] \] Sua matriz transposta correspondente é: \[A^T = \left[\begin{matrix} 3 & 1 \\ 5 & 2 \\ 7 & 9 \end{matrix}\right] \] E agora veja o código Python que declara uma matriz 2x3 e gera a matriz transposta 3x2: # importamos a bibliteca NumPy import numpy as np def main(): # vamos declarar e construir uma matrix # 2x3 (duas linhas e três colunas matriz = np.array([(3, 5, 7), (1, 2, 9)]) # vamos exibir os valores da matriz print("Elementos da matriz:") for i in range(np.shape(matriz)[0]): for j in range(np.shape(matriz)[1]): print("%7.2f" % matriz[i][j], end="") print() # como temos uma matriz 2x3, a transposta deverá ser # 3x2, ou seja, três linhas e duas colunas linhas = np.shape(matriz)[0] # linhas da matriz original colunas = np.shape(matriz)[1] # colunas da matriz original transposta = np.empty((colunas, linhas)) # e agora vamos preencher a matriz transposta for i in range(np.shape(matriz)[0]): for j in range(np.shape(matriz)[1]): transposta[j][i] = matriz[i][j] # vamos exibir os valores da matriz transposta print("\nElementos da matriz transposta:") for i in range(np.shape(transposta)[0]): for j in range(np.shape(transposta)[1]): print("%7.2f" % transposta[i][j], end="") print() if __name__== "__main__": main() Ao executar este código Python nós teremos o seguinte resultado: Elementos da matriz: 3 5 7 1 2 9 Elementos da matriz transposta: 3 1 5 2 7 9 É possível também obter a matriz transposta de um outra matriz usando o método transpose() da biblioteca NumPy da linguagem Python. Veja: # importamos a bibliteca NumPy import numpy as np def main(): # vamos declarar e construir uma matrix # 2x3 (duas linhas e três colunas matriz = np.array([(3, 5, 7), (1, 2, 9)]) # vamos exibir os valores da matriz print("Elementos da matriz:") for i in range(np.shape(matriz)[0]): for j in range(np.shape(matriz)[1]): print("%7.2f" % matriz[i][j], end="") print() # vamos transpor a matriz usando o método transpose() transposta = matriz.transpose() # vamos exibir os valores da matriz transposta print("\nElementos da matriz transposta:") for i in range(np.shape(transposta)[0]): for j in range(np.shape(transposta)[1]): print("%7.2f" % transposta[i][j], end="") print() if __name__== "__main__": main() Ao executar este novo código Python veremos que o resultado é o mesmo. |
C# ::: C# + MySQL ::: MySqlCommand |
Como gravar dados em uma tabela MySQL usando INSERT INTO e o comando ExecuteNonQuery() da classe MySqlCommand do C#Quantidade de visualizações: 1287 vezes |
Nesta dica mostrarei como inserir dados em uma tabela MySQL usando o comando SQL INSERT INTO e o comando ExecuteNonQuery() da classe MySqlCommand do C#. A tabela usada no exemplo contém os campos id, titulo, autor, paginas, data_cadastro. O campo id é auto-incremento e o campo data_cadastro é do tipo DATETIME. Por essa razão eu passei os valores NULL para o campo auto-incremento e o valor NOW() para o campo data_cadastro, de forma que a data e hora atual sejam gravadas. Como se trata de uma operação INSERT, o método ExecuteNonQuery() retorna a quantidade de registros afetados pelo comando. No exemplo eu mostro como obter e exibir este valor. Veja o código completo para o exemplo (incluindo a conexão com o banco de dados MySQL a partir do C#): using System; using System.Data; using System.Windows.Forms; using MySql.Data.MySqlClient; namespace EstudosMySQL { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { // objeto de conexão MySqlConnection conn = null; // string de conexão string connStr = "server=localhost;user id=root; " + "password=osmar1234; database=estudos; pooling=false"; try { conn = new MySqlConnection(connStr); conn.Open(); if (conn.State == ConnectionState.Open) { // primeiro criamos um novo objeto MySqlCommand MySqlCommand comando = new MySqlCommand(); // definimos a conexão para este comando comando.Connection = conn; // definimos o comando SQL a ser executado comando.CommandText = "INSERT INTO livros (id, titulo, " + autor, paginas, data_cadastro) " + "VALUES(NULL, 'JAVA PARA INICIANTES', " + "'OSMAR J. SILVA', 740, NOW())"; // e executamos o comando SQL int res = comando.ExecuteNonQuery(); if (res > 0) { MessageBox.Show("Operação realizada com sucesso. " + res + " linhas afetadas."); } else { MessageBox.Show("Deve ter acontecido alguma coisa. " + res + " linhas afetadas."); } } } catch (MySqlException ex) { MessageBox.Show("Erro: " + ex.Message); } } } } |
Python ::: Pygame ::: Animação, Animações, Técnicas de Animação |
Como criar um relógio analógico no Pygame - Código completo com variáveis e comentários em portuguêsQuantidade de visualizações: 1374 vezes |
Nesta dica mostrarei um código para a criação de um relógio analógico completo em Python, com comentários detalhados e fácil de entender. Veja a imagem:![]() Por simplicidade, eu mantive a mesma cor para todos os elementos da animação e deixei somente o básico mesmo, para que você possa se concentrar nas partes mais importantes. Neste código você aprenderá como definir o tamanho, título e cor de fundo para uma janela do Pygame do Python. Aprenderá também como definir a quantidade de frames por segundo para a animação, assim como controlar os disparos do timer pygame.time.Clock(). Por fim, o código mostra como calcular o ângulo dos ponteiros das horas, minutos e segundos e efetuar o desenho das retas saindo do centro do círculo. Você sabia, por exemplo, que o ângulo de 45 graus corresponde exatamente à hora 1:30hs? Em vários exemplos de relógios analógicos na internet, o ponteiro das horas fica preso à uma determinada hora, aguardando o ponteiro dos segundos completar um giro completo. No código que apresento aqui, eu obtive a hora atual como um decimal, o que faz com que o ponteiro das horas mostre a posição real da hora, como um relógio analógico do mundo real. Para estudantes de matemática, engenharia e física, este código é uma boa aplicação da técnica de se converter coordenadas polares para coordenadas cartesianas. Eis o código completo para o relógio analógico. Boa diversão. # vamos importar as bibliotecas necessárias import pygame, sys from pygame.locals import * import math from datetime import datetime # função que faz a correção dos ângulos def corrigir_angulo(angulo): return abs(angulo % 360) # inicializa a biblioteca pygame.init() # quantidade de frames por segundo FPS = 30 # construímos o timer timer = pygame.time.Clock() # obtém a superfície do jogo e define o tamanho da tela janela = pygame.display.set_mode((600, 400)) # vamos definir o título da janela do jogo pygame.display.set_caption('Relógio Analógico no Pygame') # vamos definir alguns parâmetros fonte = pygame.font.Font(None, 36) VERMELHO = (200, 0, 0) BRANCO = (255, 255, 255) raio = 150 x_inicial = 300 y_inicial = 200 distancia_aro = 20 # e aqui nós entramos no loop do game while True: # vamos pintar a tela toda de branco janela.fill(BRANCO) # monitoramos os eventos for evento in pygame.event.get(): # se o evento foi um pedido para sair if evento.type == QUIT: # fechamos a tela do jogo pygame.quit() # e saimos do programa sys.exit() # vamos desenhar um circulo não preenchido (maior) pygame.draw.circle(janela, VERMELHO, (x_inicial, y_inicial), raio, 2) # vamos desenhar um circulo não preenchido (menor) pygame.draw.circle(janela, VERMELHO, (x_inicial + 1, y_inicial + 1), 5, 0) # vamos desenhar os números do relório (1-12) for n in range(1, 13): # calcula o ângulo dessa hora angulo = math.radians((n * (360 / 12)) - 90) # agora convertemos o ângulo e o raio para coordenadas cartesianas if len(str(n)) > 1: x = math.cos(angulo) * (raio - distancia_aro) - 18 else: x = math.cos(angulo) * (raio - distancia_aro) - 10 y = math.sin(angulo) * (raio - distancia_aro) - 10 texto_numero = fonte.render(str(n), True, VERMELHO) janela.blit(texto_numero, (x_inicial + x, y_inicial + y)) # vamos obter as horas, minutos e segundos atuais hoje = datetime.today() horas = hoje.hour % 12 minutos = hoje.minute segundos = hoje.second # ajustamos as horas para tratar a hora decimal (com frações de horas) horas = horas + (minutos * (1 / 60)) + (segundos * (1 / 3600)) # desenha o ponteiro das horas angulo_horas = corrigir_angulo(horas * (360 / 12) - 90) angulo_horas = math.radians(angulo_horas) hora_x = math.cos(angulo_horas) * (raio - 60) hora_y = math.sin(angulo_horas) * (raio - 60) coord_finais = (x_inicial + hora_x, y_inicial + hora_y) pygame.draw.line(janela, VERMELHO, (x_inicial, y_inicial), coord_finais, 4) # desenha o ponteiro dos minutos angulo_minutos = corrigir_angulo(minutos * (360 / 60) - 90) angulo_minutos = math.radians(angulo_minutos) minutos_x = math.cos(angulo_minutos) * (raio - 40) minutos_y = math.sin(angulo_minutos) * (raio - 40) coord_finais = (x_inicial + minutos_x, y_inicial + minutos_y) pygame.draw.line(janela, VERMELHO, (x_inicial, y_inicial), coord_finais, 3) # desenha o ponteiro dos segundos angulo_segundos = corrigir_angulo(segundos * (360 / 60) - 90) angulo_segundos = math.radians(angulo_segundos) segundos_x = math.cos(angulo_segundos) * (raio - 30) segundos_y = math.sin(angulo_segundos) * (raio - 30) coord_finais = (x_inicial + segundos_x, y_inicial + segundos_y) pygame.draw.line(janela, VERMELHO, (x_inicial, y_inicial), coord_finais, 1) # redesenha a tela continuamente pygame.display.update() # aciona o disparo do timer timer.tick(FPS) |
Nossas 20 dicas & truques de programação mais populares |
C# - Como adicionar ou subtrair dias de uma data em C# usando o método AddDays() da estrutura DateTime Java - Como percorrer uma árvore binária em Java usando o algorítmo depth-first search (DFS) recursivo |
Você também poderá gostar das dicas e truques de programação abaixo |
JavaScript - Como exibir apenas dois dígitos após o ponto decimal em JavaScript usando a função toFixed() do objeto Number |
Nossas 20 dicas & truques de programação mais recentes |
Últimos Projetos e Códigos Fonte Liberados Para Apoiadores do Site |
Python - Como criar o jogo Pedra, Papel, Tesoura em Python - Jogo completo em Python com código comentado |
Últimos Exercícios Resolvidos |
E-Books em PDF |
||||
|
||||
|
||||
Linguagens Mais Populares |
||||
1º lugar: Java |