Currency Converter with GUI using Python

Introduction

The Real-Time Currency Converter is a Python application that allows users to convert amounts from one currency to another using real-time exchange rates. The application features a graphical user interface (GUI) built with tkinter, and it fetches current exchange rates using an API.

Prerequisites

  • Before you begin, ensure you have the following prerequisites:

    • Basic understanding of Python programming.
    • Python 3.x installed on your machine.
    • Internet connection to fetch exchange rates from the API.

Learning Objectives

  • By the end of this project, you will:

    • Understand how to build a GUI application using tkinter.
    • Learn how to make HTTP requests to an external API.
    • Be able to parse JSON data in Python.
    • Gain experience in error handling and debugging.

Installation Guide

To run this project on your machine, ensure you have Python installed. Follow these steps:

  1. Download and Install Python: Visit the official Python website to download and install Python if you haven’t already.
  2. Set Up a Python Environment: Use a code editor like Visual Studio Code or an IDE like PyCharm to write and run your code.
  3. Clone or Copy the Code: Copy the project code provided below into a new Python file in your development environment.

Project Steps

  1. Design the GUI Layout: Use tkinter to create the layout for the currency converter, including labels, entry boxes, and dropdown menus.
  2. Fetch Exchange Rates: Use the requests library to get the latest currency exchange rates from a public API.
  3. Implement Conversion Logic: Create a function to convert the amount from the source currency to the target currency using the fetched exchange rates.
  4. Handle User Input: Implement functions to take user input from the GUI and perform currency conversion.
  5. Display Results: Show the converted amount on the GUI.

Code

				
					import requests
from tkinter import *
import tkinter as tk
from tkinter import ttk

class RealTimeCurrencyConverter():
    def _init_(self,url):
            self.data = requests.get(url).json()
            self.currencies = self.data['rates']

    def convert(self, from_currency, to_currency, amount): 
        initial_amount = amount 
        if from_currency != 'USD' : 
            amount = amount / self.currencies[from_currency] 
  
        # limiting the precision to 4 decimal places 
        amount = round(amount * self.currencies[to_currency], 4) 
        return amount

class App(tk.Tk):
    def _init_(self, converter):
        tk.Tk._init_(self)
        self.title = 'Currency Converter'
        self.currency_converter = converter

        #self.configure(background = 'blue')
        self.geometry("500x200")
        
        # Label
        self.intro_label = Label(self, text = 'Welcome to Real Time Currency Convertor',  fg = 'blue', relief = tk.RAISED, borderwidth = 3)
        self.intro_label.config(font = ('Courier',15,'bold'))

        self.date_label = Label(self, text = f"1 Indian Rupee equals = {self.currency_converter.convert('INR','USD',1)} USD \n Date : {self.currency_converter.data['date']}", relief = tk.GROOVE, borderwidth = 5)

        self.intro_label.place(x = 10 , y = 5)
        self.date_label.place(x = 160, y= 50)

        # Entry box
        valid = (self.register(self.restrictNumberOnly), '%d', '%P')
        self.amount_field = Entry(self,bd = 3, relief = tk.RIDGE, justify = tk.CENTER,validate='key', validatecommand=valid)
        self.converted_amount_field_label = Label(self, text = '', fg = 'black', bg = 'white', relief = tk.RIDGE, justify = tk.CENTER, width = 17, borderwidth = 3)

        # dropdown
        self.from_currency_variable = StringVar(self)
        self.from_currency_variable.set("INR") # default value
        self.to_currency_variable = StringVar(self)
        self.to_currency_variable.set("USD") # default value

        font = ("Courier", 12, "bold")
        self.option_add('*TCombobox*Listbox.font', font)
        self.from_currency_dropdown = ttk.Combobox(self, textvariable=self.from_currency_variable,values=list(self.currency_converter.currencies.keys()), font = font, state = 'readonly', width = 12, justify = tk.CENTER)
        self.to_currency_dropdown = ttk.Combobox(self, textvariable=self.to_currency_variable,values=list(self.currency_converter.currencies.keys()), font = font, state = 'readonly', width = 12, justify = tk.CENTER)

        # placing
        self.from_currency_dropdown.place(x = 30, y= 120)
        self.amount_field.place(x = 36, y = 150)
        self.to_currency_dropdown.place(x = 340, y= 120)
        #self.converted_amount_field.place(x = 346, y = 150)
        self.converted_amount_field_label.place(x = 346, y = 150)
        
        # Convert button
        self.convert_button = Button(self, text = "Convert", fg = "black", command = self.perform) 
        self.convert_button.config(font=('Courier', 10, 'bold'))
        self.convert_button.place(x = 225, y = 135)

    def perform(self):
        amount = float(self.amount_field.get())
        from_curr = self.from_currency_variable.get()
        to_curr = self.to_currency_variable.get()

        converted_amount = self.currency_converter.convert(from_curr,to_curr,amount)
        converted_amount = round(converted_amount, 2)

        self.converted_amount_field_label.config(text = str(converted_amount))
    
    def restrictNumberOnly(self, action, string):
        regex = re.compile(r"[0-9,]?(\.)?[0-9,]$")
        result = regex.match(string)
        return (string == "" or (string.count('.') <= 1 and result is not None))

if _name_ == '_main_':
    url = 'https://api.exchangerate-api.com/v4/latest/USD'
    converter = RealTimeCurrencyConverter(url)

    App(converter)
    mainloop()
				
			

Code

				
					import requests
from tkinter import *
import tkinter as tk
from tkinter import ttk

class RealTimeCurrencyConverter():
    def _init_(self,url):
            self.data = requests.get(url).json()
            self.currencies = self.data['rates']

    def convert(self, from_currency, to_currency, amount): 
        initial_amount = amount 
        if from_currency != 'USD' : 
            amount = amount / self.currencies[from_currency] 
  
        # limiting the precision to 4 decimal places 
        amount = round(amount * self.currencies[to_currency], 4) 
        return amount

class App(tk.Tk):
    def _init_(self, converter):
        tk.Tk._init_(self)
        self.title = 'Currency Converter'
        self.currency_converter = converter

        #self.configure(background = 'blue')
        self.geometry("500x200")
        
        # Label
        self.intro_label = Label(self, text = 'Welcome to Real Time Currency Convertor',  fg = 'blue', relief = tk.RAISED, borderwidth = 3)
        self.intro_label.config(font = ('Courier',15,'bold'))

        self.date_label = Label(self, text = f"1 Indian Rupee equals = {self.currency_converter.convert('INR','USD',1)} USD \n Date : {self.currency_converter.data['date']}", relief = tk.GROOVE, borderwidth = 5)

        self.intro_label.place(x = 10 , y = 5)
        self.date_label.place(x = 160, y= 50)

        # Entry box
        valid = (self.register(self.restrictNumberOnly), '%d', '%P')
        self.amount_field = Entry(self,bd = 3, relief = tk.RIDGE, justify = tk.CENTER,validate='key', validatecommand=valid)
        self.converted_amount_field_label = Label(self, text = '', fg = 'black', bg = 'white', relief = tk.RIDGE, justify = tk.CENTER, width = 17, borderwidth = 3)

        # dropdown
        self.from_currency_variable = StringVar(self)
        self.from_currency_variable.set("INR") # default value
        self.to_currency_variable = StringVar(self)
        self.to_currency_variable.set("USD") # default value

        font = ("Courier", 12, "bold")
        self.option_add('*TCombobox*Listbox.font', font)
        self.from_currency_dropdown = ttk.Combobox(self, textvariable=self.from_currency_variable,values=list(self.currency_converter.currencies.keys()), font = font, state = 'readonly', width = 12, justify = tk.CENTER)
        self.to_currency_dropdown = ttk.Combobox(self, textvariable=self.to_currency_variable,values=list(self.currency_converter.currencies.keys()), font = font, state = 'readonly', width = 12, justify = tk.CENTER)

        # placing
        self.from_currency_dropdown.place(x = 30, y= 120)
        self.amount_field.place(x = 36, y = 150)
        self.to_currency_dropdown.place(x = 340, y= 120)
        #self.converted_amount_field.place(x = 346, y = 150)
        self.converted_amount_field_label.place(x = 346, y = 150)
        
        # Convert button
        self.convert_button = Button(self, text = "Convert", fg = "black", command = self.perform) 
        self.convert_button.config(font=('Courier', 10, 'bold'))
        self.convert_button.place(x = 225, y = 135)

    def perform(self):
        amount = float(self.amount_field.get())
        from_curr = self.from_currency_variable.get()
        to_curr = self.to_currency_variable.get()

        converted_amount = self.currency_converter.convert(from_curr,to_curr,amount)
        converted_amount = round(converted_amount, 2)

        self.converted_amount_field_label.config(text = str(converted_amount))
    
    def restrictNumberOnly(self, action, string):
        regex = re.compile(r"[0-9,]?(\.)?[0-9,]$")
        result = regex.match(string)
        return (string == "" or (string.count('.') <= 1 and result is not None))

if _name_ == '_main_':
    url = 'https://api.exchangerate-api.com/v4/latest/USD'
    converter = RealTimeCurrencyConverter(url)

    App(converter)
    mainloop()
				
			

Pseudo Code explaining this Python Project

				
					Here is a simplified version of the code in pseudo code form:
1.	Initialize API Request:
o	Send HTTP request to get exchange rates.
o	Parse response as JSON.
2.	Initialize GUI Application:
o	Set window title and size.
o	Create labels for instructions and exchange rate info.
3.	Create Entry and Dropdown Widgets:
o	Create input field for amount.
o	Create dropdowns for selecting from and to currencies.
4.	Define Conversion Logic:
o	Function to convert amount based on selected currencies.
o	Display converted amount on the GUI.
5.	Run Application:
o	Initialize and start the main event loop.

				
			

Pseudo Code explaining this Python Project

				
					Here is a simplified version of the code in pseudo code form:
1.	Initialize API Request:
o	Send HTTP request to get exchange rates.
o	Parse response as JSON.
2.	Initialize GUI Application:
o	Set window title and size.
o	Create labels for instructions and exchange rate info.
3.	Create Entry and Dropdown Widgets:
o	Create input field for amount.
o	Create dropdowns for selecting from and to currencies.
4.	Define Conversion Logic:
o	Function to convert amount based on selected currencies.
o	Display converted amount on the GUI.
5.	Run Application:
o	Initialize and start the main event loop.

				
			

Flow Chart

Code Explanation

  • RealTimeCurrencyConverter Class: Handles the fetching of real-time exchange rates from an API and contains the logic for converting currencies.
  • App Class: Inherits from tk.Tk and sets up the GUI, including widgets like labels, entry fields, dropdowns, and buttons. It also handles user interactions.
  • Conversion Logic: Takes the amount and currency inputs, performs conversion using exchange rates, and updates the result on the GUI.

Challenges and Solutions

1. API Request Failures:

    • Challenge: The API request may fail due to network issues or API downtime.
    • Solution: Implement error handling using try-except blocks to catch exceptions and provide user feedback.

try:

    self.data = requests.get(url).json()

except requests.exceptions.RequestException as e:

    print(“Error fetching data:”, e)

2. Handling Invalid User Input:

    • Challenge: Users may enter invalid data in the amount field.
    • Solution: Use validation commands in tkinter to restrict input to numbers only.

Testing

To ensure the application functions correctly:

  1. Test API Connectivity: Verify that exchange rates are fetched correctly from the API.
  2. Test Currency Conversion: Test the conversion logic with different currencies and amounts.
  3. Test GUI Interaction: Ensure all GUI components respond correctly to user actions.

Additional Resources

FAQs

  1. What if the API changes or becomes unavailable?
    You can switch to another currency exchange API by updating the API endpoint URL in the code and adjusting any differences in the JSON response structure.
  1. How can I add more currencies to the dropdown?
    The application automatically includes all currencies provided by the API. If new currencies become available, they will automatically appear in the dropdowns.
  1. Can I change the GUI theme or style?
    Yes, you can customize the GUI appearance using tkinter styles and themes. Modify the widget configurations or use ttk styles for advanced theming options.

Project by Nimisha Agrawal and Documented by Aakarsh Pandey, Team edSlash.