Loan Managing App

import sqlite3

from tkinter import *

from tkinter import ttk, messagebox

class LoanManager:

    def __init__(self, root):

        self.root = root

        self.root.title("Loan Managing app")

        self.root.geometry("1350x720+0+0")

        title = Label(self.root, text="Loan Managing App", font=(

            "Comic Sans MS", 20, ), bd=8,  bg='black', fg='white')

        title.pack(side=TOP, fill=X)

        self.LoanId = StringVar()

        self.name = StringVar()

        self.mob = StringVar()

        self.aadhar = StringVar()

        self.add = StringVar()

        self.pin = StringVar()

        self.amount = StringVar()

        self.year = StringVar()

        self.rate = StringVar()

        self.mpay = StringVar()

        self.tpay = StringVar()

        Detail_F = Frame(self.root, bd=4, relief=RIDGE, bg='light blue')

        Detail_F.place(x=10, y=90, width=520, height=620)

        lbl_id = Label(Detail_F, text="Loan Id", font=("Comic Sans MS", 12, ))

        lbl_id.grid(row=0, column=0, pady=10, padx=20, sticky="w")

        txt_id = Entry(Detail_F, font=("Comic Sans MS", 10, ),

                       bd=3,  textvariable=self.LoanId)

        txt_id.grid(row=0, column=1, pady=10, sticky="w")

        lbl_name = Label(Detail_F, text="Full Name",

                         font=("Comic Sans MS", 12, ))

        lbl_name.grid(row=1, column=0, pady=10, padx=20, sticky="w")

        txt_name = Entry(Detail_F, font=("Comic Sans MS", 10, ),

                         bd=3,  textvariable=self.name)

        txt_name.grid(row=1, column=1, pady=10, sticky="w")

        lbl_mob = Label(Detail_F, text="Mobile No.",

                        font=("Comic Sans MS", 12, ))

        lbl_mob.grid(row=2, column=0, pady=10, padx=20, sticky="w")

        txt_mob = Entry(Detail_F, font=("Comic Sans MS", 10, ),

                        bd=3,  textvariable=self.mob)

        txt_mob.grid(row=2, column=1, pady=10, sticky="w")

        lbl_aa = Label(Detail_F, text="Aadhar No.",

                       font=("Comic Sans MS", 12, ))

        lbl_aa.grid(row=3, column=0, pady=10, padx=20, sticky="w")

        txt_aa = Entry(Detail_F, font=("Comic Sans MS", 10, ),

                       bd=3,  textvariable=self.aadhar)

        txt_aa.grid(row=3, column=1, pady=10, sticky="w")

        lbl_add = Label(Detail_F, text="Address", font=("Comic Sans MS", 12, ))

        lbl_add.grid(row=4, column=0, pady=10, padx=20, sticky="w")

        txt_add = Entry(Detail_F, font=("Comic Sans MS", 10, ),

                        bd=3,  textvariable=self.add)

        txt_add.grid(row=4, column=1, pady=10, sticky="w")

        lbl_pin = Label(Detail_F, text="PinCode", font=("Comic Sans MS", 12, ))

        lbl_pin.grid(row=5, column=0, pady=10, padx=20, sticky="w")

        txt_pin = Entry(Detail_F, font=("Comic Sans MS", 10, ),

                        bd=3,  textvariable=self.pin)

        txt_pin.grid(row=5, column=1, pady=10, sticky="w")

        lbl_amount = Label(Detail_F, text="Amount of Loan",

                           font=("Comic Sans MS", 12, ))

        lbl_amount.grid(row=6, column=0, pady=10, padx=20, sticky="w")

        txt_amount = Entry(Detail_F, font=(

            "Comic Sans MS", 10, ), bd=3,  textvariable=self.amount)

        txt_amount.grid(row=6, column=1, pady=10, sticky="w")

        lbl_time = Label(Detail_F, text="Number of years",

                         font=("Comic Sans MS", 12, ))

        lbl_time.grid(row=7, column=0, pady=10, padx=20, sticky="w")

        txt_time = Entry(Detail_F, font=("Comic Sans MS", 10,

                                         ), bd=3,  textvariable=self.year)

        txt_time.grid(row=7, column=1, pady=10, sticky="w")

        lbl_rate = Label(Detail_F, text="Interest Rate",

                         font=("Comic Sans MS", 12, ))

        lbl_rate.grid(row=8, column=0, pady=10, padx=20, sticky="w")

        txt_rate = Entry(Detail_F, font=("Comic Sans MS", 10,

                                         ), bd=3,  textvariable=self.rate)

        txt_rate.grid(row=8, column=1, pady=10, sticky="w")

        lbl_Mp = Label(Detail_F, text="Monthly Payment",

                       font=("Comic Sans MS", 12, ))

        lbl_Mp.grid(row=9, column=0, pady=10, padx=20, sticky="w")

        txt_Mp = Label(Detail_F, font=("Comic Sans MS", 10, ),

                       bd=3,  state=DISABLED, textvariable=self.mpay)

        txt_Mp.grid(row=9, column=1, pady=10, sticky="w")

        lbl_tp = Label(Detail_F, text="Total Payment",

                       font=("Comic Sans MS", 12, ))

        lbl_tp.grid(row=10, column=0, pady=10, padx=20, sticky="w")

        txt_tp = Label(Detail_F, font=("Comic Sans MS", 10, ),

                       bd=3,  state=DISABLED, textvariable=self.tpay)

        txt_tp.grid(row=10, column=1, pady=10, sticky="w")

        recordFrame = Frame(self.root, bd=5, relief=RIDGE)

        recordFrame.place(x=535, y=100, width=810, height=530)


        yscroll = Scrollbar(recordFrame, orient=VERTICAL)

        self.employee_table = ttk.Treeview(recordFrame, columns=(

            "empId", "name", "years", "rate", "Mpayment", "Tpayment", "mobile"), yscrollcommand=yscroll.set)

        yscroll.pack(side=RIGHT, fill=Y)

        yscroll.config(command=self.employee_table.yview)

        self.employee_table.heading("empId", text="customer Id")

        self.employee_table.heading("name", text="Name")

        self.employee_table.heading("years", text="Number of Years")

        self.employee_table.heading("rate", text="Interest Rate")

        self.employee_table.heading("Mpayment", text="Monthly Payment")

        self.employee_table.heading("Tpayment", text="Total Payment")

        self.employee_table.heading("mobile", text="Mobile No.")

        self.employee_table['show'] = 'headings'

        self.employee_table.column("empId", width=100)

        self.employee_table.column("name", width=100)

        self.employee_table.column("years", width=100)

        self.employee_table.column("rate", width=100)

        self.employee_table.column("Mpayment", width=110)

        self.employee_table.column("Tpayment", width=100)

        self.employee_table.column("mobile", width=100)

        self.employee_table.pack(fill=BOTH, expand=1)

        self.fetch_data()

        self.employee_table.bind("<ButtonRelease-1>", self.get_cursor)

        btnFrame = Frame(self.root, bd=5, relief=RIDGE)

        btnFrame.place(x=700, y=630, width=480, height=60)

        btn1 = Button(btnFrame, text='Add record', font='arial 12 bold',

                      bg='black', fg='white', width=9, command=self.addrecord)

        btn1.grid(row=0, column=0, padx=10, pady=10)

        btn2 = Button(btnFrame, text='Update', font='arial 12 bold',

                      bg='black', fg='white', width=9, command=self.update)

        btn2.grid(row=0, column=1, padx=8, pady=10)

        btn3 = Button(btnFrame, text='Delete', font='arial 12 bold',

                      bg='black', fg='white', width=9, command=self.delete)

        btn3.grid(row=0, column=2, padx=8, pady=10)

        btn4 = Button(btnFrame, text='Reset', font='arial 12 bold',

                      bg='black', fg='white', width=9, command=self.reset)

        btn4.grid(row=0, column=3, padx=8, pady=10)

    def total(self):

        p = int(self.amount.get())

        r = int(self.rate.get())

        n = int(self.year.get())

        t = (p*r*n*10)/100

        m = (p+t)/(n*10)

        self.mpay.set(str(round(m, 2)))

        self.tpay.set(str(t+p))

    def addrecord(self):

        if self.LoanId.get() == '' or self.name.get() == '' or self.mob.get() == '' or self.aadhar.get() == '' or self.add.get() == '' or self.pin.get() == '':

            messagebox.showerror('Error', 'Please enter details ?')

        else:

            self.total()

            con = sqlite3.connect('loanDetails.db')

            cur = con.cursor()

            cur.execute("Select * from customer")

            rows = cur.fetchall()

            for row in rows:

                if row[0] == self.LoanId.get():

                    messagebox.showerror(

                        'Error', 'Duplicates not allowed')

                    return

            cur.execute("insert into customer values(?,?,?,?,?,?,?,?,?,?,?)", (

                self.LoanId.get(),

                self.name.get(),

                self.mob.get(),

                self.aadhar.get(),

                self.add.get(),

                self.pin.get(),

                self.amount.get(),

                self.year.get(),

                self.rate.get(),

                self.mpay.get(),

                self.tpay.get(),

            ))

            con.commit()

            self.fetch_data()

            con.close()

    def fetch_data(self):

        con = sqlite3.connect('loanDetails.db')

        cur = con.cursor()

        cur.execute("select Loan_Id , Name , Year , Rate , Monthly_Payment , Total_Payment , MobileNumber , AadharNumber , Address , Pincode , Amount from customer")

        rows = cur.fetchall()

        if len(rows) != 0:

            self.employee_table.delete(*self.employee_table.get_children())

            for row in rows:

                self.employee_table.insert('', END, values=row)

        con.commit()

        con.close()

    def update(self):

        if self.LoanId.get() == '':

            messagebox.showerror('Error', 'Select a record to update !')

        else:

            self.total()

            con = sqlite3.connect('loanDetails.db')

            cur = con.cursor()

            cur.execute("update customer set Name = ?, MobileNumber = ?, AadharNumber = ?, Address = ?, Pincode = ?, Amount = ?, Year = ?, Rate = ?, Total_Payment = ?, Monthly_Payment = ? where Loan_Id = ?", (

                self.name.get(),

                self.mob.get(),

                self.aadhar.get(),

                self.add.get(),

                self.pin.get(),

                self.amount.get(),

                self.year.get(),

                self.rate.get(),

                self.tpay.get(),

                self.mpay.get(),

                self.LoanId.get()

            ))

            messagebox.showinfo(

                'Info', f'Record {self.LoanId.get()} Updated Successfully')

            con.commit()

            con.close()

            self.fetch_data()

            self.reset()

    def delete(self):

        if self.LoanId.get() == '':

            messagebox.showerror(

                'Error', 'Enter customer ID to delete the records')

        else:

            con = sqlite3.connect('loanDetails.db')

            cur = con.cursor()

            cur.execute("delete from customer where Loan_Id = ?",

                        (self.LoanId.get(),))

            con.commit()

            con.close()

            self.fetch_data()

            self.reset()

    def reset(self):

        self.LoanId.set('')

        self.name.set('')

        self.mob.set('')

        self.aadhar.set('')

        self.add.set('')

        self.pin.set('')

        self.amount.set('')

        self.year.set('')

        self.rate.set('')

        self.mpay.set('')

        self.tpay.set('')

    def get_cursor(self, ev):

        cursor_row = self.employee_table.focus()

        content = self.employee_table.item(cursor_row)

        row = content['values']

        self.LoanId.set(row[0])

        self.name.set(row[1])

        self.year.set(row[2])

        self.rate.set(row[3])

        self.mpay.set(row[4])

        self.tpay.set(row[5])

        self.mob.set(row[6])

        self.aadhar.set(row[7])

        self.add.set(row[8])

        self.pin.set(row[9])

        self.amount.set(row[10])

class Login():

    def __init__(self, root):

        self.root = root

        self.root.title("Loan Managing app")

        self.username = StringVar()

        self.password = StringVar()

        Label(self.root, text="Username:").grid(

            row=0, column=0, padx=10, pady=10)

        Entry(self.root, textvariable=self.username).grid(

            row=0, column=1, padx=10, pady=10)

        Label(self.root, text="Password:").grid(

            row=1, column=0, padx=10, pady=10)

        Entry(self.root, textvariable=self.password,

              show="*").grid(row=1, column=1, padx=10, pady=10)

        Button(self.root, text="Login", command=self.login).grid(

            row=2, column=1, padx=10, pady=10)

    def login(self):

        if self.username.get() == "root" and self.password.get() == "root":

            root.destroy()

            nroot = Tk()

            LoanManager(nroot)

        else:

            messagebox.showerror("Error", "Invalid username or password")

con = sqlite3.connect('loanDetails.db')

cur = con.cursor()

cur.execute('create table if not exists customer(Loan_Id varchar(20) primary key,Name varchar(20),MobileNumber varchar(20),AadharNumber varchar(20),Address varchar(20),Pincode varchar(20),Amount varchar(20),Year varchar(20),Rate varchar(20),Monthly_Payment varchar(20),Total_Payment varchar(20))')

root = Tk()

obj = Login(root)

root.mainloop()

Watermark on images

import cv2

import numpy as np

import glob

import os

from numpy._distributor_init import filename

logo = cv2.imread("logo.jpg")

h_logo, w_logo, _ = logo.shape

images_path = glob.glob("flowers/*.*")

print("Adding watermark")

for img_path in images_path:

    img = cv2.imread(img_path)

    h_img, w_img, _ = img.shape

    center_y = int(h_img / 2)

    center_x = int(w_img / 2)

    top_y = center_y - int(h_logo / 2)

    left_x = center_x - int(w_logo / 2)

    bottom_y = top_y + h_logo

    right_x = left_x + w_logo

      roi = img[top_y:bottom_y, left_x:right_x]

    result = cv2.addWeighted(roi, 1, logo, 0.3, 0)

    img[top_y:bottom_y, left_x:right_x] = result

    filename= os.path.basename(img_path)

    cv2.imwrite("watermarked_images/watermarked_" + filename, img)

print("Watermark added to all images") 

Document checker

import hashlib

from difflib import SequenceMatcher

def hash_file(fileName1, fileName2):

    h2 = hashlib.sha1()

with open(fileName1, "rb") as file:

chunk = 0

while chunk != b'':

chunk = file.read(1024)

h1.update(chunk)

with open(fileName2, "rb") as file:

chunk = 0

while chunk != b'':

chunk = file.read(1024)

h2.update(chunk)

return h1.hexdigest(), h2.hexdigest()

msg1, msg2 = hash_file("pd1.pdf ", "pd1.pdf")

if(msg1 != msg2):

print("These files are not identical")

else:

print("These files are identical")


Expense Tracker

import datetime

import sqlite3

from tkcalendar import DateEntry

from tkinter import *

import tkinter.messagebox as mb

import tkinter.ttk as ttk

connector = sqlite3.connect("Expense Tracker.db")

cursor = connector.cursor()

connector.execute(

'CREATE TABLE IF NOT EXISTS ExpenseTracker (ID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, Date DATETIME, Payee TEXT, Description TEXT, Amount FLOAT, ModeOfPayment TEXT)'

)

connector.commit()

def list_all_expenses():

global connector, table

table.delete(*table.get_children())

all_data = connector.execute('SELECT * FROM ExpenseTracker')

data = all_data.fetchall()

for values in data:

table.insert('', END, values=values)

def view_expense_details():

global table

global date, payee, desc, amnt, MoP

if not table.selection():

mb.showerror('No expense selected', 'Please select an expense from the table to view its details')

current_selected_expense = table.item(table.focus())

values = current_selected_expense['values']

expenditure_date = datetime.date(int(values[1][:4]), int(values[1][5:7]), int(values[1][8:]))

date.set_date(expenditure_date) ; payee.set(values[2]) ; desc.set(values[3]) ; amnt.set(values[4]) ; MoP.set(values[5])

def clear_fields():

global desc, payee, amnt, MoP, date, table

today_date = datetime.datetime.now().date()

desc.set('') ; payee.set('') ; amnt.set(0.0) ; MoP.set('Cash'), date.set_date(today_date)

table.selection_remove(*table.selection())

def remove_expense():

if not table.selection():

mb.showerror('No record selected!', 'Please select a record to delete!')

return

current_selected_expense = table.item(table.focus())

values_selected = current_selected_expense['values']

surety = mb.askyesno('Are you sure?', f'Are you sure that you want to delete the record of {values_selected[2]}')

if surety:

connector.execute('DELETE FROM ExpenseTracker WHERE ID=%d' % values_selected[0])

connector.commit()

list_all_expenses()

mb.showinfo('Record deleted successfully!', 'The record you wanted to delete has been deleted successfully')

def remove_all_expenses():

surety = mb.askyesno('Are you sure?', 'Are you sure that you want to delete all the expense items from the database?', icon='warning')

if surety:

table.delete(*table.get_children())

connector.execute('DELETE FROM ExpenseTracker')

connector.commit()

clear_fields()

list_all_expenses()

mb.showinfo('All Expenses deleted', 'All the expenses were successfully deleted')

else:

mb.showinfo('Ok then', 'The task was aborted and no expense was deleted!')

def add_another_expense():

global date, payee, desc, amnt, MoP

global connector

if not date.get() or not payee.get() or not desc.get() or not amnt.get() or not MoP.get():

mb.showerror('Fields empty!', "Please fill all the missing fields before pressing the add button!")

else:

connector.execute(

'INSERT INTO ExpenseTracker (Date, Payee, Description, Amount, ModeOfPayment) VALUES (?, ?, ?, ?, ?)',

(date.get_date(), payee.get(), desc.get(), amnt.get(), MoP.get())

)

connector.commit()

clear_fields()

list_all_expenses()

mb.showinfo('Expense added', 'The expense whose details you just entered has been added to the database')

def edit_expense():

global table


def edit_existing_expense():

global date, amnt, desc, payee, MoP

global connector, table

current_selected_expense = table.item(table.focus())

contents = current_selected_expense['values']


connector.execute('UPDATE ExpenseTracker SET Date = ?, Payee = ?, Description = ?, Amount = ?, ModeOfPayment = ? WHERE ID = ?',

                  (date.get_date(), payee.get(), desc.get(), amnt.get(), MoP.get(), contents[0]))

connector.commit()

clear_fields()

list_all_expenses()

mb.showinfo('Data edited', 'We have updated the data and stored in the database as you wanted')

edit_btn.destroy()

return

if not table.selection():

mb.showerror('No expense selected!', 'You have not selected any expense in the table for us to edit; please do that!')

return

view_expense_details()

edit_btn = Button(data_entry_frame, text='Edit expense', font=btn_font, width=30,

                  bg=hlb_btn_bg, command=edit_existing_expense)

edit_btn.place(x=10, y=395)

def selected_expense_to_words():

global table

if not table.selection():

mb.showerror('No expense selected!', 'Please select an expense from the table for us to read')

return

current_selected_expense = table.item(table.focus())

values = current_selected_expense['values']

message = f'Your expense can be read like: \n"You paid {values[4]} to {values[2]} for {values[3]} on {values[1]} via {values[5]}"'

mb.showinfo('Here\'s how to read your expense', message)

def expense_to_words_before_adding():

global date, desc, amnt, payee, MoP

if not date or not desc or not amnt or not payee or not MoP:

mb.showerror('Incomplete data', 'The data is incomplete, meaning fill all the fields first!')

message = f'Your expense can be read like: \n"You paid {amnt.get()} to {payee.get()} for {desc.get()} on {date.get_date()} via {MoP.get()}"'

add_question = mb.askyesno('Read your record like: ', f'{message}\n\nShould I add it to the database?')

if add_question:

add_another_expense()

else:

mb.showinfo('Ok', 'Please take your time to add this record')

dataentery_frame_bg = 'light blue'

buttons_frame_bg = 'light blue'

hlb_btn_bg = 'light pink'

lbl_font = ('Georgia', 13)

entry_font = 'Times 13 bold'

btn_font = ('Gill Sans MT', 13)

root = Tk()

root.title('Expense Tracker')

root.geometry('1200x550')

root.resizable(0, 0)

Label(root, text='EXPENSE TRACKER', font=('Noto Sans CJK TC', 15, 'bold'), bg=hlb_btn_bg).pack(side=TOP, fill=X)

desc = StringVar()

amnt = DoubleVar()

payee = StringVar()

MoP = StringVar(value='Cash')

data_entry_frame = Frame(root, bg=dataentery_frame_bg)

data_entry_frame.place(x=0, y=30, relheight=0.95, relwidth=0.25)

buttons_frame = Frame(root, bg=buttons_frame_bg)

buttons_frame.place(relx=0.25, rely=0.05, relwidth=0.75, relheight=0.21)

tree_frame = Frame(root)

tree_frame.place(relx=0.25, rely=0.26, relwidth=0.75, relheight=0.74)

Label(data_entry_frame, text='Date (M/DD/YY) :', font=lbl_font, bg=dataentery_frame_bg).place(x=10, y=50)

date = DateEntry(data_entry_frame, date=datetime.datetime.now().date(), font=entry_font)

date.place(x=160, y=50)

Label(data_entry_frame, text='Payee\t             :', font=lbl_font, bg=dataentery_frame_bg).place(x=10, y=230)

Entry(data_entry_frame, font=entry_font, width=31, text=payee).place(x=10, y=260)

Label(data_entry_frame, text='Description           :', font=lbl_font, bg=dataentery_frame_bg).place(x=10, y=100)

Entry(data_entry_frame, font=entry_font, width=31, text=desc).place(x=10, y=130)

Label(data_entry_frame, text='Amount\t             :', font=lbl_font, bg=dataentery_frame_bg).place(x=10, y=180)

Entry(data_entry_frame, font=entry_font, width=14, text=amnt).place(x=160, y=180)

Label(data_entry_frame, text='Mode of Payment:', font=lbl_font, bg=dataentery_frame_bg).place(x=10, y=310)

dd1 = OptionMenu(data_entry_frame, MoP, *['Cash', 'Cheque', 'Credit Card', 'Debit Card', 'Paytm', 'Google Pay'])

dd1.place(x=160, y=305)     ;     dd1.configure(width=10, font=entry_font)

Button(data_entry_frame, text='Add expense', command=add_another_expense, font=btn_font, width=30,

       bg=hlb_btn_bg).place(x=10, y=395)

Button(data_entry_frame, text='Convert to words before adding', font=btn_font, width=30, bg=hlb_btn_bg).place(x=10,y=450)

Button(buttons_frame, text='Delete Expense', font=btn_font, width=25, bg=hlb_btn_bg, command=remove_expense).place(x=30, y=5)

Button(buttons_frame, text='Clear Fields in DataEntry Frame', font=btn_font, width=25, bg=hlb_btn_bg,

       command=clear_fields).place(x=335, y=5)

Button(buttons_frame, text='Delete All Expenses', font=btn_font, width=25, bg=hlb_btn_bg, command=remove_all_expenses).place(x=640, y=5)

Button(buttons_frame, text='View Selected Expense\'s Details', font=btn_font, width=25, bg=hlb_btn_bg,

       command=view_expense_details).place(x=30, y=65)

Button(buttons_frame, text='Edit Selected Expense', command=edit_expense, font=btn_font, width=25, bg=hlb_btn_bg).place(x=335,y=65)

Button(buttons_frame, text='Convert Expense to a sentence', font=btn_font, width=25, bg=hlb_btn_bg,

       command=selected_expense_to_words).place(x=640, y=65)

table = ttk.Treeview(tree_frame, selectmode=BROWSE, columns=('ID', 'Date', 'Payee', 'Description', 'Amount', 'Mode of Payment'))

X_Scroller = Scrollbar(table, orient=HORIZONTAL, command=table.xview)

Y_Scroller = Scrollbar(table, orient=VERTICAL, command=table.yview)

X_Scroller.pack(side=BOTTOM, fill=X)

Y_Scroller.pack(side=RIGHT, fill=Y)

table.config(yscrollcommand=Y_Scroller.set, xscrollcommand=X_Scroller.set)

table.heading('ID', text='S No.', anchor=CENTER)

table.heading('Date', text='Date', anchor=CENTER)

table.heading('Payee', text='Payee', anchor=CENTER)

table.heading('Description', text='Description', anchor=CENTER)

table.heading('Amount', text='Amount', anchor=CENTER)

table.heading('Mode of Payment', text='Mode of Payment', anchor=CENTER)

table.column('#0', width=0, stretch=NO)

table.column('#1', width=50, stretch=NO)

table.column('#2', width=95, stretch=NO)  #Date column

table.column('#3', width=150, stretch=NO)  # Payee column

table.column('#4', width=325, stretch=NO)  # Title column

table.column('#5', width=135, stretch=NO)  # Amount column

table.column('#6', width=125, stretch=NO)  # Mode of Payment column

table.place(relx=0, y=0, relheight=1, relwidth=1)

list_all_expenses()

root.update()

root.mainloop()

Webcam Sketch

import cv2

import numpy as np

def webcam_sketch(image):

    img_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    img_gray_blur = cv2.GaussianBlur(img_gray, (5,5), 0)

    canny_edges = cv2.Canny(img_gray_blur, 10, 70)

    ret, mask = cv2.threshold(canny_edges, 70, 255, cv2.THRESH_BINARY_INV)

    return mask

cap = cv2.VideoCapture(0)

while True:

    ret, frame = cap.read()

    cv2.imshow('Sketch', webcam_sketch(frame))

    if cv2.waitKey(1) == 13: 

        break

cap.release()

cv2.destroyAllWindows()