Programming

"The only way to learn a new programming language is by writing programs in it." - Dennis Ritchie

Raspberry Pi

“Genius is one percent inspiration and ninety-nine percent perspiration.” -Thomas Edison

Artificial Intelligence

“The pace of progress in artificial intelligence (I’m not referring to narrow AI) is incredibly fast. Unless you have direct exposure to groups like Deepmind, you have no idea how fast—it is growing at a pace close to exponential. The risk of something seriously dangerous happening is in the five-year time frame. 10 years at most.” —Elon Musk wrote in a comment on Edge.org

Electronics

“The five essential entrepreneurial skills for success are concentration, discrimination, organisation, innovation and communication.” -Michael Faraday

Crypto Currency

"Blockchain is the tech. Bitcoin is merely the first mainstream manifestation of its potential." – Marc Kenigsberg

12 Apr 2021

Smart Attendance System - Python GUI Application

The whole code for the program is given below. Detailed description will be given in the upcoming blogs. 
import tkinter as tk
from cv2 import cv2
import time
import datetime as dt
from PIL import Image,ImageTk
import argparse
import numpy
import os
import pandas as pd

class App:    
    def __init__(self,window,video_source=0):
        self.window=window
        self.window.title("Smart Attendance System")
        self.window.config(bg="black")
        self.video_source=video_source
        self.ok=False
        
        self.vid=VideoCapture(self.video_source)
        self.canvas=tk.Canvas(window,width=self.vid.width,height=self.vid.height)
        self.canvas.grid(row=0,column=0,padx=20,pady=(20,0))
        self.timer=ElapsedTimeClock(self.window)

        self.button_frame=tk.Frame(self.window,bg="gray",width=self.vid.width)
        self.button_frame.grid(row=2,column=0,padx=10,pady=10)
        self.btn_snapshot=tk.Button(self.button_frame,text="Add Student",command=self.add_student)
        self.btn_snapshot.grid(row=0,column=0,ipadx=10)
        self.btn_snapshot=tk.Button(self.button_frame,text="Train Model",command=self.train_model)
        self.btn_snapshot.grid(row=0,column=1,ipadx=10)
        self.btn_snapshot=tk.Button(self.button_frame,text="Start Class",command=self.start_class)
        self.btn_snapshot.grid(row=0,column=2,ipadx=10)
        self.btn_snapshot=tk.Button(self.button_frame,text="Get Attendance",command=self.get_attendance)
        self.btn_snapshot.grid(row=0,column=3,ipadx=10)
        self.btn_snapshot=tk.Button(self.button_frame,text="Snapshot",command=self.snapshot)
        self.btn_snapshot.grid(row=0,column=4,ipadx=10)    
        self.btn_snapshot=tk.Button(self.button_frame,text="Start Recording",command=self.start_recording)
        self.btn_snapshot.grid(row=0,column=5,ipadx=10)
        self.btn_snapshot=tk.Button(self.button_frame,text="Stop Recording",command=self.stop_recording)
        self.btn_snapshot.grid(row=0,column=6,ipadx=10)
        self.btn_snapshot=tk.Button(self.button_frame,text="Quit",command=quit)
        self.btn_snapshot.grid(row=0,column=7,ipadx=10)
        self.window.iconbitmap("resources/icons/ai.ico")
        

        self.get_time()
        self.window.mainloop()


    def snapshot(self):
        ret,frame=self.vid.get_frame()
        if ret:
            path="snapshots/{}".format(str(dt.datetime.now().date()))
            if (not os.path.isdir(path)):
                os.mkdir(path)
            path="snapshots/{}/{}".format(str(dt.datetime.now().date()),subject_now)
            if (not os.path.isdir(path)):
                os.mkdir(path)
            cv2.imwrite(path+"/image"+time.strftime("%d-%m-%Y-%H-%M-%S")+".jpg",cv2.cvtColor(frame,cv2.COLOR_RGB2BGR))

    def start_recording(self):
        self.ok=True
        self.timer.start()


    def stop_recording(self):
        self.ok=False
        self.timer.stop()

    def update(self):
        self.delay=10
        ret,frame=self.vid.get_frame()
        if self.ok:
            self.vid.out.write(cv2.cvtColor(frame,cv2.COLOR_RGB2BGR))

        if ret:
            self.photo=ImageTk.PhotoImage(image=Image.fromarray(frame))
            self.canvas.create_image(0,0,image=self.photo,anchor=tk.NW)
            
        self.window.after(self.delay,self.update)

    def get_attendance(self):
        present_students=[]
        path="attendance/{}".format(str(dt.datetime.now().date()))
        if (not os.path.isdir(path)):
            os.mkdir(path)
        path="attendance/{}/{}".format(str(dt.datetime.now().date()),subject_now)
        if (not os.path.isdir(path)):
            os.mkdir(path)


        attendance_sheet=open(path+"/attendance_"+time.strftime("%d-%m-%Y-%H-%M-%S")+".txt","a")
        attendance_sheet.write("\nAttendance for "+ subject_now + "\n")
        attendance_sheet.write("Timestamp: " + str(dt.datetime.now()) + "\n-------------------------------------\n")
        for k,v in marking.items():
            if v>=100:
                present_students.append(k)
                attendance_sheet.write(k+"\n")
        attendance_sheet.close()
        attendance_display=tk.Toplevel()
        attendance_display.geometry("300x583+"+ str(self.window.winfo_x()+768) + "+" + str(self.window.winfo_y()))
        try:
            attendance_display.title("Attendance for "+ subject_now)
        except:
            attendance_display.title("Attendance Sheet")

        label=""
        for student in present_students:
            label=label+"\n"+student
        attendance_label=tk.Label(attendance_display,text=label)
        attendance_label.pack()
        




    def start_class(self):
        self.train_model()
        self.get_subject()
        self.update()

    def get_time(self):
        time_now=int(dt.datetime.now().strftime("%H"))
        if ((time_now <= 17) and (time_now >= 9)):
            if(time_now>=12):
                time_now=time_now%12
            self.get_subject()
        else:
            self.get_subject()

            
    def get_subject(self):     
        global subject_now
        now=dt.datetime.today().weekday()  #0 for monday, 6 for sunday
        df = pd.read_excel("timetable/timetable.xlsx",engine='openpyxl')
        hour_now=int(dt.datetime.now().strftime("%H"))
        if ((int(hour_now)>12) and (int(hour_now)<=17)):
            hour_now=hour_now%12
            session="{} to {}".format(int(hour_now),int(hour_now)+1)
            today_timetable=df.iloc[now]
            subject_now=today_timetable[session]
        if ((int(hour_now)<12 and="" hour_now="" int="">=9)):
            today_timetable=df.iloc[now]
            subject_now=today_timetable[session] 
        if (int(hour_now)==12):
            session="{} to 1".format(int(hour_now))
            today_timetable=df.iloc[now]
            subject_now=today_timetable[session]      
        if((int(hour_now)>17) or (int(hour_now)<9 .format="" _="" __del__="" __init__="" add_student="" ake="" alg="haarfront.xml" ame="" app="" apture="" args.name="" args.type="" args="CommandLineParse().args" attendance="" avi="" bg="black" bold="" break="" cam.release="" cam="cv2.VideoCapture(0)" clearly="" command="lambda:" commandlineparse:="" completed="" count="" count_student="" create_database="" cv2.color_rgb2bgr="" cv2.cvtcolor="" cv2.destroyallwindows="" cv2.font_hershey_plain="" cv2.imread="" cv2.imshow="" cv2.imwrite="" cv2.puttext="" cv2.rectangle="" cv2.videowriter_fourcc="" d-="" datasets="" date="" dd="" def="" dirs:="" dirs="" dt.datetime.now="" elapsedtimeclock:="" else:="" esolution="" f="" face="gray[y:y+h,x:x+w]" face_cascade="cv2.CascadeClassifier(haar_file)" face_resize="cv2.resize(face,(width,height))" faces:="" faces="face_cascade.detectMultiScale(gray,1.3,4)" fg="white" filename="" files="" folder="self.student_enroll.get()" font="(" for="" frame="" get_all_student_names="" get_frame="" global="" gray="cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)" grayimg="cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)" h="" haar="cv2.CascadeClassifier(alg)" haar_file="haarfront.xml" height="" id="" ideo="" if="" images.append="" images="" img="" in="" int="" is="" k="" key="=27:" label="" labels.append="" labels="" lis="" m-="" main="" mark_student="" marking="" mart="" model.train="" model="cv2.face.LBPHFaceRecognizer_create()" mp4="" nable="" name="" name_stu="" names="" nargs="1,default=[" nknown="" no="" not="" nroll="" numpy.array="" o="" one="" onlyface="grayImg[y:y+h,x:x+w]" open="" os.listdir="" os.mkdir="" os.path.isdir="" os.walk="" p="" parent="students" parser.add_argument="" parser="argparse.ArgumentParser(description=" path="" pre="" prediction="" print="" raining="" raise="" res="" resizeimg="" ret:="" ret="" return="" row="1,column=0)" s-="" s.jpg="" s="" select="" self.args="parser.parse_args()" self.capture_pic.grid="" self.capture_pic="tk.Button(self.student_data_window,text=" self.check_subject="" self.count_student="" self.create_database="" self.elapsedtime="dt.datetime(1,1,1).now()-self.zeroTime" self.enroll_label.grid="" self.enroll_label="tk.Label(self.student_data_window,text=" self.fourcc="" self.get_all_student_names="" self.get_subject="" self.height="res" self.lasttime:="" self.lasttime="self.time2" self.mark_student="" self.name="" self.name_label.grid="" self.name_label="tk.Label(self.student_data_window,text=" self.now="dt.datetime(1,1,1).now()" self.out.release="" self.out="cv2.VideoWriter(path+" self.running:="" self.running="0" self.student="stu_name" self.student_data_window.destroy="" self.student_data_window.geometry="" self.student_data_window.title="" self.student_data_window="tk.Toplevel()" self.student_enroll.grid="" self.student_enroll="tk.Entry(self.student_data_window)" self.student_name.grid="" self.student_name="tk.Entry(self.student_data_window)" self.t.after_cancel="" self.t.config="" self.t.grid="" self.t="tk.Label(window,text=" self.tick="" self.time2="self.elapsedTime" self.upwin="" self.vid.isopened="" self.vid.release="" self.vid.set="" self.vid="cv2.VideoCapture(video_source)" self.width="" self.window.after="" self.window.winfo_x="" self.window.winfo_y="" self.zerotime="dt.datetime(1,1,1).now()-self.elapsedTime" self="" source="" start="" std_dimensions="{" stop="" str="" stu_name="" student="" student_list.append="" student_list="" subdir="" subject_now="Free-time" subjectpath="" sure="" system="" t="time.localtime()" text="self.time2)" that="" the="" tick="" time.strftime="" times="" tk.tk="" to="" train_model="" type="str,help=" unknown="" utput="" valueerror="" video="" video_source="" video_types="{" videocapture:="" visible="" w="" while="" width="" window="" x-10="" x200="" x="" y-10="" y="" your="">

26 Mar 2021

Peer to Peer Network (P2P network)

What is a client-server network

Client-Server networks are those kinds of networks in which a device have the permission only to act as either a client device or as a server device. The client device will only have the permission to receive data from the server device and the server will only have the permission to provide data to the client device. Client devices will have client software on it like the web browsers and the server devices will have server software running on them.

What is a peer to peer network

A peer-to-peer (P2P) network is created when two or more PCs are connected and share resources without going through a separate and dedicated server computer. In this kind of networks, a single device will have both client and server software running on them. It can be said as a network, created by systems, which acts as both client and server at the same time. It usually occurs in home networks and in small businesses. All the systems or end-devices in a Peer to Peer network are linked together with equal permissions and responsibilities for processing data. Unlike the traditional client-server network, no devices in a Peer to Peer network are designated solely to serve or to receive data. Peer to Peer network can be abbreviated by P2P network for simplicity. 

Here in the below figure, the PC-01 has a Universal Serial Bus connection to the printer for print sharing and a network connection to PC-02 , using the Network Interface Card for File Sharing purpose. In effect, every connected PC is at once a server and a client. There's no special network operating system residing on a robust machine that supports special server-side applications like directory services (specialized databases that control who has access to what).

Peer to peer network illustration

A Peer to Peer network can be:

  • an ad hoc connection—a couple of computers connected via a Universal Serial Bus to transfer files. 
  • a permanent infrastructure that links a half-dozen computers in a small office over copper wires. 
  • a network on a much grander scale in which special protocols and applications set up direct relationships among users over the Internet.


In general, office and home P2P networks operate over Ethernet (10M bit/sec.) or Fast Ethernet (100M bit/sec.) and employ a hub-and-spoke topology. Category 5 (twisted-pair) copper wire runs among the PCs and an Ethernet hub or switch, enabling users of those networked PCs access to one another's hard drives, printers or perhaps a shared Internet connection. Peer to Peer network allows you to easily share data without having to use a separate server for your file-sharing. Each end-computer that connects to this network becomes a 'peer' and is allowed to receive or send files to other computers in its network. This enables you to work collaboratively to perform certain tasks that need group attention, and it also allows you to provide services to another peer. 

24 Mar 2021

Mesh Topology

What is a Network Topology

Network topology is the way in which the nodes and the associated links (or connections) in a network is arranged. It can be of many types:
  • Star Topology
  • Bus Topology
  • Ring Topology
  • Tree Topology
  • Mesh Topology
  • Hybrid Topology

What is Mesh Topology

A mesh topology is a network topology (arrangement of nodes in a network) in which each node is individually connected to all or most of the other nodes in the network. It is one of the key network architectures in which nodes are connected with many redundant interconnections between them. This kind of topology allows for most transmissions to be distributed even if one of the connections goes down. In Mesh topology, if any cable or node fails, there are many other ways for two nodes to communicate, making it a reliable network topology. This topology is commonly used for wireless networks. There is no concept of a central hub (as in a Star Topology) nor that of a backbone cable (as in the Bus Topology). Even though they are easy to troubleshoot and offers increased reliability, Mesh networks are expensive to install as they require a lot of cabling. 

Mesh topologies involve the concept of routes. Messages sent on a mesh network can take any of the several possible paths from source to destination. The mesh topology accounts for having highest number of  physical connections per device. Unlike other network topologies, Mesh Topology can be divided as: Fully connected mesh topology and Partially connected mesh topology


Different types of mesh topology

  • Fully connected mesh topology 
  • Partially connected mesh topology

Fully connected mesh topology 

A mesh network in which every node is connected to each and every other nodes of the network. The number of connections in this network can be calculated using the following formula: n(n-1)/2, where 'n' is the number of nodes. Full mesh is very expensive to implement and yields the greatest amount of redundancy, so in the event that one of those nodes fails, network traffic can be directed to any of the other nodes. Full mesh is usually reserved for backbone networks. 

    Number of connections = n(n-1) /2    
Fully connected mesh topology illustration

Partially connected mesh topology

A partially connected mesh topology does not have all the nodes connected to each other. At least one of the node in the network will not have connection to all the other nodes of the network. It is an inexpensive way to implement redundancy in a network. If one of the primary computers or connections in the network fails, the rest of the network continues to operate normally.

If any node is not fully connected to all other nodes of the network, then that Mesh Topology can be termed as Partially connected Mesh Topology. With partial mesh, some nodes are organized in a full mesh scheme but others are only connected to one or two nodes in the network. Partial mesh topology is commonly found in peripheral networks connected to a full meshed backbone. It is less expensive to implement and yields less redundancy than full mesh topology.
Partially connected mesh topology illustration

Advantages of a mesh topology

  • Able to manage high amounts of traffic (since multiple devices can transmit data simultaneously)
  • A failure of one device does not cause a break in the network
  • Adding additional devices does not disrupt data transmission between other devices.
  • Increased reliability
  • Each connection can carry its own data load
  • Robust in nature
  • Easy to diagnose
  • Provides security and privacy (since point to point connection exists between each pair of nodes)
  • Easy of troubleshoot
  • Data can be transmitted from different devices simultaneously.
  • Even if one of the components fails, there is always an alternative present,
  • Expansion and modification in topology can be done without disrupting other nodes.

Disadvantages of a mesh topology

  • Overall cost of this network is way too high as compared to other network topologies.
  • Building and maintaining the topology is difficult and time consuming.
  • The chance of redundant connections is high, which adds to the high costs and potential for reduced efficiency.
  • Cabling cost is more and the most in case of a fully connected mesh topology
  • Bulk wiring is required
  • Installation and configuration are difficult if the connectivity gets more.
  • There are high chances of redundancy in many of the network connections.


Implementation of Mesh Topology in Cisco Packet Tracer

Mesh Topology implementation in Cisco Packet Tracer 8.0



Feel free to contact me, if you face any kind of problem regarding the above topic.

20 Feb 2021

Simple Message Encrypter - Python Tkinter project

 Introduction

This project is aimed at making a Simple Message Encrypter using Python Tkinter. The application will be using a simple Symmetric Key algorithm.  Symmetric key algorithms are algorithms for which we use the same cryptographic keys for both encryption of plaintext and decryption of ciphertext (ie. we should use the same password, which the sender used at the time of encryption, for retrieving the message back to its original form). 

Pre-requisites

  • Basic knowledge of python
  • Understanding of tkinter

Project Demo Image




Final Output



Programming

The first step of creating application, is to create a folder for our program. Inside that folder, create a python file(.py extension). Open the python file in any text editor or any python IDE. 
The program begins by importing the tkinter module and defining the main window for the application.
import tkinter
root = tkinter.Tk()
root.title("Message Encrypter")
root.iconbitmap("resources/icons/encrypter.ico")

root.mainloop()

  • Import the Tkinter module, for making the GUI for the application. All we need to do, inorder to use Tkinter is a single import statement
  • initialize an instance of tkinter named "root". You can use your own specific names for this.
  • specify a title for our "root" window.
  • specify the icon. This icon will appear on the top left corner of our application. Even if you didn't specify anything, tkinter will give a default icon.
  • tkinter works by continuously looping through the code, which is specified by the mainloop(). If you forget to mention this line, your program will run without any error. But you will not be able to see it, since it will execute and close, within a fraction of second. If you run the code(at this instance), the application window will look like this. You can see the title of the application and the icon.

Make sure that you have specified the path of the icon (.ico file) correctly.
Get the icon used by me: Get Icon
If you would like to use a different icon, feel free to download an icon from any trusted source. Now its the time to define our frames and other widgets for the application. You must insert the code before the line "root.mainloop()" 
#Defining frames
input_frame = tkinter.Frame(root)
button_frame = tkinter.Frame(root,bg=button_frame_color)
input_frame.pack()
button_frame.pack(fill=BOTH,expand=True)

#Defining widgets for frames
input_data = tkinter.Entry(input_frame,width=80)
output_data = tkinter.Label(input_frame,text="Your output will appear here",bg=output_bg,fg=button_color,width=50,wraplength=200)
copy_button = tkinter.Button(input_frame,text="Copy",bg=button_color)
passwd_label = tkinter.Button(button_frame,text="Password",bg=button_frame_color,borderwidth=0)
passwd_data = tkinter.Entry(button_frame)
encrypt_button = tkinter.Button(button_frame,text="Encrypt",bg=button_color)
decrypt_button = tkinter.Button(button_frame,text="Decrypt",bg=button_color)

input_data.grid(row=0,column=0,columnspan=2,padx=10,pady=10,ipady=50)
output_data.grid(row=1,column=0,padx=10,pady=10,ipady=40,sticky="we")
copy_button.grid(row=1,column=1,pady=10,ipady=10,ipadx=20,padx=(0,10))
passwd_label.grid(row=0,column=0,pady=10,padx=(100,0),ipadx=20,ipady=10)
passwd_data.grid(row=0,column=1,pady=10,padx=(0,10),ipadx=50,ipady=10)
encrypt_button.grid(row=1,column=0,pady=10,padx=(80,0),ipadx=40,ipady=10)
decrypt_button.grid(row=1,column=1,pady=20,ipadx=40,ipady=10)


Our application is mainly divided into two frames: an input frame and  a button frame. The button frame is the gray portion and the input frame is the upper white region. 
  • Define two Frames for the application
  • Place it on to the root window, using the pack() method.
  • Input frame will have message entry region, output region and a copy button.
    • Define an Entry widget (named "input_data") to get the message from user.
    • Place it on the input frame using grid().
    • Define a display region, for outputting the result after processing, using a Label widget from tkinter. Wraplength specifies the length of the line after which a new line character is to be inserted.
    • Place a button widget for copying the content after encrypting/decrypting. Th efunction to be performed while clicking the button will be described below.
  • Button frame will have two buttons : one for encrypting and other for decrypting the message, along with an entry widget for getting the password from the user.
This will give you the basic layout for the application. The layout should look like the below image.

Now, as the layout is over, we should focus our mind to the functioning of the application. Each and every "Buttons" should be attached with a specific function, so that the function will run, once we click on the button. 
expected_char="qazwsxedcrfvtgbyhnujmikolp!@#$%^&*()1234567890POIUYTREWQASDFGHJKLMNBVCXZ~`<,>.?/:;'[{]}+=_-| "
expected_char+='"'
Our application is focused on a simple Symmetric Key Encryption algorithm. Symmentric Key Encryption means that the same Key (Password) which is used at the time of encryption, is needed for decrypting the message. 
Shift cipher concept is implemented here. In shift cipher: 
Cipher text = (Plain text + Password) mod <number of characters>
Inorder to include almost all the characters, that we use normally, I have added a string variable named "expected_char", which contains 94 different characters.
def encrypt():
    cipher_text=''
    plain_text=input_data.get()

    if passwd_data.get()!='':
        passwd=int(passwd_data.get())
        for i in plain_text:
            index=expected_char.find(i)
            updated_index=(index+passwd)%94
            cipher_text+=expected_char[updated_index]
        output_data.config(text=cipher_text)
        #input_data.delete(0,END)
    else:
        messagebox.showerror("Invalid Password","You must enter a password")
For encrypting purpose, we defined a function named encrypt. In-order to store the store the result, we initialized a variable named "cipher_text". It is defined as a local variable, so that we can use the same name in the decrypt function. Get the user input from the Entry widget and store it to the variable "plain_text". For encryption, a password id required. If the user fails to provide a password, the application will throw up an error message. We should update the output Label widget to display the encrypted message.
def decrypt(): 
    plain_text=''
    cipher_text=input_data.get()
    
    if passwd_data.get()!='':
        depasswd=int(passwd_data.get())
        for i in cipher_text:
            new_index=expected_char.find(i)
            new_updated_index=(new_index-depasswd)%94
            plain_text+=expected_char[new_updated_index]
        output_data.config(text=plain_text)
        #input_data.delete(0,END)
    else:
        messagebox.showerror("Invalid Password","You must enter a password inorder to decrypt the message")
Decrypt function will also do the same initial steps of retrieving the user input and initializing an empty string variable. Decryption is based on the formula:
Plain text = (Cipher text - Password) mod <number of characters>
We should update the output label to display the decrypted message.
def copy_data():
    pyperclip.copy(output_data['text'])
Copy_data function will be used to copy the result from the output Label widget, so that the user can send it through any other messaging platform like WhatsApp, Instagram, Snapchat, Twitter, etc.. Copying is done with the help of "pyperclip" module. Add this codes before the section which defines the frames. Link your functions with the appropriate buttons. 
Now your application is completely functional. 

Complete Source Code

GitHub: source code

'''
    program: Simple Message Encrypter
    author : akr
    github : a-k-r-a-k-r
'''

#import necessary modules
import tkinter
import pyperclip
from tkinter import DISABLED,messagebox,BOTH,END


#Defining root window
root=tkinter.Tk()
root.title("Message Encrypter")
root.iconbitmap("resources/icons/encrypter.ico")


#mostly used characters
expected_char="qazwsxedcrfvtgbyhnujmikolp!@#$%^&*()1234567890POIUYTREWQASDFGHJKLMNBVCXZ~`<,>.?/:;'[{]}+=_-| "
expected_char+='"'


#colors
button_frame_color="grey"
button_color="green"
output_bg="black"


#Defining functions
def encrypt():
    cipher_text=''
    plain_text=input_data.get()

    if passwd_data.get()!='':
        passwd=int(passwd_data.get())
        for i in plain_text:
            index=expected_char.find(i)
            updated_index=(index+passwd)%94
            cipher_text+=expected_char[updated_index]
        output_data.config(text=cipher_text)
        #input_data.delete(0,END)
    else:
        messagebox.showerror("Invalid Password","You must enter a password")


def decrypt(): 
    plain_text=''
    cipher_text=input_data.get()
    
    if passwd_data.get()!='':
        depasswd=int(passwd_data.get())
        for i in cipher_text:
            new_index=expected_char.find(i)
            new_updated_index=(new_index-depasswd)%94
            plain_text+=expected_char[new_updated_index]
        output_data.config(text=plain_text)
        #input_data.delete(0,END)
    else:
        messagebox.showerror("Invalid Password","You must enter a password inorder to decrypt the message")


def copy_data():
    pyperclip.copy(output_data['text'])


#Defining frames
input_frame=tkinter.Frame(root)
button_frame=tkinter.Frame(root,bg=button_frame_color)
input_frame.pack()
button_frame.pack(fill=BOTH,expand=True)

#Defining widgets for frames
input_data=tkinter.Entry(input_frame,width=80)
output_data=tkinter.Label(input_frame,text="Your output will appear here",bg=output_bg,fg=button_color,width=50,wraplength=200)
copy_button=tkinter.Button(input_frame,text="Copy",bg=button_color,command=copy_data)
passwd_label=tkinter.Button(button_frame,text="Password",bg=button_frame_color,borderwidth=0)
passwd_data=tkinter.Entry(button_frame)
encrypt_button=tkinter.Button(button_frame,text="Encrypt",bg=button_color,command=encrypt)
decrypt_button=tkinter.Button(button_frame,text="Decrypt",bg=button_color,command=decrypt)

input_data.grid(row=0,column=0,columnspan=2,padx=10,pady=10,ipady=50)
output_data.grid(row=1,column=0,padx=10,pady=10,ipady=40,sticky="we")
copy_button.grid(row=1,column=1,pady=10,ipady=10,ipadx=20,padx=(0,10))
passwd_label.grid(row=0,column=0,pady=10,padx=(100,0),ipadx=20,ipady=10)
passwd_data.grid(row=0,column=1,pady=10,padx=(0,10),ipadx=50,ipady=10)
encrypt_button.grid(row=1,column=0,pady=10,padx=(80,0),ipadx=40,ipady=10)
decrypt_button.grid(row=1,column=1,pady=20,ipadx=40,ipady=10)


root.mainloop()


Stand-alone Executable

In-order to run the application from your Window's desktop, just by clicking the icon, you will need to convert the program to a standalone executable. To achieve this 
pip install auto-py-to-exe

Open "auto-py-to-exe" by typing "auto-py-to-exe" in command prompt or in PowerShell. GUI for the same will appear.

  • Click on the "Browse" button and choose the ".py" file for the program.
  • Choose "One Directory". You can also choose to go with "One File". But in most cases, it will give errors. 
  • Choose to create Window Based instead of Console based
  • In the Icon field, browse the ".ico" file (this will appear on the exe file as the icon)
  • Add the Additional files. Since we have our icon in the resources folder, add the folder, using "Add Folder" button. This icon will appear on the application window's top left corner.
  • Now click on convert
  • Once complete, open the output folder and find the ".exe" file.
  • Make a shortcut of it and send it to desktop, for easy access.

Contributions

Feel free to contribute to the GitHub repository. Happy Hacking. If you have any weird ideas, comment below. Let's make it a reality.
                                                                                                      -akr