diff --git a/chatmaths.py b/chatmaths.py new file mode 100644 index 0000000..f0df289 --- /dev/null +++ b/chatmaths.py @@ -0,0 +1,124 @@ +from word2number.w2n import word_to_num +import re +import inflect + +""" recevies the full sentence and change it in order to be compatible with the following operations. Calls others functions depeding on the operations needed.""" +def entre(sentence): + acum = [] + num = 0 + if "plus" in sentence: + sentence = sentence.replace("plus", "+") + if "minus" in sentence: + sentence = sentence.replace("minus", "-") + if "times" in sentence: + sentence = sentence.replace("times", "*") + if "divided by" in sentence: + sentence = sentence.replace("divided by", "/") + if "power" in sentence: + sentence = sentence.replace("power", "^") + if "powers" in sentence: + sentence = sentence.replace("powers", "^") + if "what is " in sentence: + sentence = sentence.replace("what is ", "") + if "what" in sentence: + sentence = sentence.replace("what", "") + if "is" in sentence: + sentence = sentence.replace("is", "") + word = "" + final = "" + for k in sentence: #loop to check if there are any letters left in the sentence + cnf = (bool(re.match('[a-zA-Z]', k))) #returns True or False if letters in sentence + if cnf: + break + try: + if cnf: #if returned True, may be numbers in full english, change them to numbers + for i in sentence: #checks every indexex of the string to make the necessary treatment + if i in "+" or i in "-" or i in "*" or i in "/" or i in "^": #if this indexex has the value of an operation, the number must be completed + word = word_to_num(word) #if number is in english, becames a number + final += str(word) #add the number to the final string + final += i #add the operation to the final string + word = "" + continue + if i in " ": + continue + else: + word += i #keeps adding the letter/number to have the full word or full number wanted + + word = word_to_num(word) #adds the final number to the final string (initial string ended so it is needed to add again since it was not added before + final += str(word) + sentence = final #finally the initial string, having numbers in it in english, becames only numbers. + except: + print("Only full english or just numbers!") + + if " " in sentence: + sentence = sentence.replace(" ", "") + try: + for i in sentence: #loop to insert full numbers into a list + if i in "+" or i in "-" or i in "*" or i in "/" or i in "^": + acum.append(num) #appends the number wanted to the list + acum.append(i) #appends the operation wanted to the list + num = 0 + continue + else: + num = num * 10 #if the indexex is still a number, the previous numbers are multiplied by 10 -> example: if num was 3, now is 30 + num = num + float(i) #now, add the number in the indexex -> example: if the number in this indexex is 2, now the full number is 32 + + acum.append(num) #adds the final number wanted to the list one last time + acum = mults(acum, 0) + acum = sums(acum, 0) + if cnf: #if there was letters in the initial sentence + p = inflect.engine() + acum = p.number_to_words(acum[0]) #the final result becames in full english + if "point zero" in acum: + acum = acum.replace("point zero", "") + print("Easy, the answer is ", acum) + else: #if not, prints the final result + print("Easy, the answer is ", acum[0]) + except: + print("Try again") + +""" checks if there is any multiplication/division/power to do because they have priority. + if so the operation is done - gets as parameters the list acum and the indexex number - returns the result of this operations""" +def mults(acum, index): + if index < len(acum): + if acum[index] == "*": + tot = float(acum[index - 1]) * float(acum[index + 1]) + working(tot,acum, index, "mult") + elif acum[index] == "^": + tot = float(acum[index - 1]) ** float(acum[index + 1]) + working(tot,acum, index, "mult") + elif acum[index] == "/": + tot = float(acum[index - 1]) / float(acum[index + 1]) + working(tot,acum, index, "mult") + else: + mults(acum, index + 1) #if index is a number, using recursion we call the function again with to check the following indexex + return acum + +""" checks if there is any sums/subtractions to do. + if so the operation is done - gets as parameters the list acum and the indexex number - returns the final result""" +def sums(acum, index): + if index < len(acum): + if acum[index] == "+": + tot = float(acum[index - 1]) + float(acum[index + 1]) + working(tot,acum, index, "sum") + elif acum[index] == "-": + tot = float(acum[index - 1]) - float(acum[index + 1]) + working(tot,acum, index, "sum") + else: + sums(acum, index + 1) + return acum + + + +def working(tot, acum,index,type): + if "sum" in type: + acum[index - 1] = tot # replaces the indexex before with the result of the operation + acum.remove(acum[index + 1]) # removes the other indexexes involved in the operation + acum.remove(acum[index]) # "" "" + sums(acum, index) # calls the function again, with the same indexex since we removed two indexexes from the list + else: + acum[index - 1] = tot # replaces the indexex before with the result of the operation + acum.remove(acum[index + 1]) # removes the other indexexes involved in the operation + acum.remove(acum[index]) # "" "" + mults(acum, index) # calls the function again, with the same indexex since we removed two indexexes from the list + diff --git a/confirmDB.py b/confirmDB.py new file mode 100644 index 0000000..75b8de3 --- /dev/null +++ b/confirmDB.py @@ -0,0 +1,19 @@ +import pymysql #allows connection to databases with sql + + +"""Connect to the database""" +def connection(): + connect = pymysql.connect(host="localhost", + user="root", + passwd="", + database="users") + return connect + + + + + + + + + diff --git a/info.py b/info.py new file mode 100644 index 0000000..84bde20 --- /dev/null +++ b/info.py @@ -0,0 +1,57 @@ +import random #this package allows to choose randomly an index of a list +from confirmDB import connection +from Setup import load_setting + + +""" prints a random answer to question about favourite things """ +def informations(sentence): + answer = ["I don't want to share this with you", "If i tell you I would have to kill you", "I just don't know yet", + "Good question!"] + final = random.choice(answer) + print(final) + ownInfo(sentence) + + +""" gets information about favourites of the user""" +def ownInfo(sentence): + sep = 'favourite ' + info = sentence.split(sep, 1)[0] #gets the words before the word "favourite" in a sentence to isolate "favourite" and the key word + info = info + sep #adds the word "favourite" to the already filtered sentence + info = sentence.replace(info, "") #gets the key word by removing all the words previous to "favourite" and "favourite" included + info = info.replace(" ", "") + nick = load_setting(0) #get the nick of current user + nick = nick.lower() + nick = nick[:-1] + """--------------------------------------------""" + try: + connect = connection() # gets the details to the database + cursor = connect.cursor() # establish a cursor to fetch the results wanted from the databse + sql = 'SELECT ' + info + ' FROM favourite WHERE NICKNAME = "' + nick + '"' #sql gets the order to select all info from the table favourite in the current user row + cursor.execute(sql) # order to select executed + myresult = cursor.fetchall() # gets all the rows of nicknames where the nickname == nick + l = str(myresult[0]) # l = ('favourite food',) / (None,) + if "None" in l: + final = (l[1:]) + final = final[:-2] + else: + final = (l[2:]) + final = final[:-3] + if final == "None": + getInfo(nick, info) + else: + print("Your favourite ", info.lower() , " is ", final) + except: + getInfo(nick, info) + + +""" "add" new values to table favourite """ +def getInfo(nick, info): + print("I don't know yours, what is it? ") + ans = input("") + connect = connection() # gets the details to the database + cursor = connect.cursor() # establish a cursor to fetch the results wanted from the databse + sql = 'UPDATE favourite SET '+info+'="'+ans+'" WHERE NICKNAME="'+ nick + '"' #sql gets the order to update all info from the table favourite in the current user row + cursor.execute(sql) # order to select executed + connect.commit() # tell the database to save all the changes + print("Ok, I will try not to forget!") + diff --git a/play.py b/play.py new file mode 100644 index 0000000..cee4bcd --- /dev/null +++ b/play.py @@ -0,0 +1,72 @@ +import webbrowser # +import glob #allows to have a list +import os #provides a portable way of using operating system functionalities +import random #allows to choose randomly an index of a list + + +def play(sentence): + mlist = (glob.glob("music/*.mp3")) #gets all the names of the musics inside the folder music, in the same directory as the python files + if "show" in sentence or "list" in sentence: + if "my" not in sentence: + if "all" in sentence: + filt = sentence + if "show" in sentence: + if "all" in sentence: + filt = filt.replace("show all music of ", "") #filters sentence to get the name to identify the music + else: + if "all" in sentence: + filt = filt.replace("list all music of ", "") #filters sentence to get the name to identify the music + filt = filt.lower() + print("All music of :", filt.upper() ," \n") + attp = 0 + for i in mlist: + top = i.lower() + i = i[6:] #filter the value in order to get only the name of the music/artist + if filt in top: + print(i) #prints the songs with the name user wanted + attp = 1 + if attp < 1: + print("You have no songs with that name") + else: + print("Your music: \n") + for i in mlist: + i = i[6:] #filter the value in order to get only the name of the music/artist + print(i) #prints the song + + + elif "random" in sentence or "shuffle" in sentence: + shuffle = random.choice(mlist) #chooses one random song + os.startfile(shuffle) #execute the song with that name + shuffle = shuffle[6:] #filters the name of the song to print only the name of the song and artist + print("Playing ", shuffle) + else: + if "play " in sentence: + counter = 0 + newS = sentence.replace("play ", "") #gets the name of the song + for i in mlist: + top = i.lower() + newS = newS.lower() + if newS in top: #if finds the name of the song wanted + print("Playing ", i[6:]) + os.startfile(i) #plays the music qanted + break + else: + if counter < (len(mlist)-1): #allows to continue searching while there are still musics to search + counter += 1 + continue + else: #if doesn't find the song wanted in the list: + uOpen(sentence) + break + + +def uOpen(sentence): + sentence = sentence[5:] #sentence is sentence after play + print("Playing " + sentence) + url = "https://www.youtube.com/results?search_query=" + sentence + webbrowser.open(url) #opens google with that url + +def uGoogle(sentence): + sentence = sentence[5:] #sentence is sentence after open + print("Opening " + sentence) + url = "https://www." + sentence + webbrowser.open(url) # opens google with that url diff --git a/send_email.py b/send_email.py new file mode 100644 index 0000000..b9add1e --- /dev/null +++ b/send_email.py @@ -0,0 +1,31 @@ +import smtplib # implements the SMTP protocol to be able to send emails + +""" sends an email to new users with the details of the account + https://www.geeksforgeeks.org/send-mail-gmail-account-using-python/ +""" +def email(nick, password, mail): + try: + server = smtplib.SMTP('smtp.gmail.com', 587) #declaration of gmail SMTP server settings + server.starttls() #For security, this start the SMTP connection in the Transport Layer Security mode that encrypts all the SMTP commands + server.login("theforeignersgroup@gmail.com", "wearethebest101") #information of the account which will send the email + msg = "Thank you for joining our CHATBOT!\nDont lose these email.\nYour account details to access our " \ + "chatbot:\nLogin Username: " + nick + "\nPassword: " + password + server.sendmail("theforeignersgroup@gmail.com", mail, msg) + server.quit() #closes the SMTP session + except: + print("Something went wrong. Probably your wiki connection it is not the best for this service") + + +""" Allows the user to send emails to everyone he wants, using our email""" +def create_email(): + try: + server = smtplib.SMTP('smtp.gmail.com', 587) #declaration of gmail SMTP server settings + server.starttls() #For security, this start the SMTP connection in the Transport Layer Security mode that encrypts all the SMTP commands + mail = input("Email: ") + server.login("theforeignersgroup@gmail.com", "wearethebest101") #information of the account which will send the email + msg = input("Message: ") + server.sendmail("theforeignersgroup@gmail.com", mail, msg) + server.quit() #closes the SMTP session + print("Done! What can I help you now?") + except: + print("Something went wrong. Probably your wiki connection it is not the best for this service") diff --git a/thanks.py b/thanks.py new file mode 100644 index 0000000..cd33c1e --- /dev/null +++ b/thanks.py @@ -0,0 +1,8 @@ +import random #this package allows to choose randomly an index of a list + + +""" prints random answers to compliments """ +def thanks(): + answer = ["Thank you! :)", "I know, I know..", "I have never heard that before, thank you!", + "Probably you are right :)", "I don't care about what you think."] + print(random.choice(answer)) diff --git a/users.py b/users.py new file mode 100644 index 0000000..9fef27f --- /dev/null +++ b/users.py @@ -0,0 +1,95 @@ +from confirmDB import connection +from send_email import email + +"""checks if there is any registered user with that nickname""" +def checkUnique(nick): + try: + exist = False + connect = connection() # gets the details to the database + cursor = connect.cursor() # establish a cursor to fetch the results wanted from the databse + nick = nick.lower() + sql = 'SELECT NICKNAME FROM users WHERE NICKNAME = "' + nick + '"' #sql gets the order to select all nicknames from the table users with the nickname == nick + cursor.execute(sql) # order to select executed + myresult = cursor.fetchall() # gets all the rows of nicknames where the nickname == nick + for x in myresult: + if nick in x: #check if there is already a nickname == nick + exist = True + break + if exist: + check = input("I already know one " + nick + ", is that you? ") + check = check.lower() + if check in ["yes", "y", "of course", "yap", "obviously", "indeed", "that is correct", "affirmative"]: + LOGIN(nick) + return True + else: + return False + else: + return False + except: + print("Sorry, seems that you are not connected to my databse.") + return "off" + +""" process to login the user""" +def LOGIN(nick): + try: + password = input("Password: ") + ckpassword = userDetails(nick, "PASSWORD") + if password == ckpassword: + print("Logged in Successfully!") + else: + print("Failed to Login!") + LOGIN(nick) + except: + print("Sorry, seems that you are not connected to my databse.") + +"""gets all the info wanted in the table users""" +def userDetails(nick, info): + try: + connect = connection() + cursor = connect.cursor() + sql = 'SELECT ' + info + ' FROM users WHERE NICKNAME = "' + nick + '"' #sql selects the info wanted about the user with nickname==nick from the table user + cursor.execute(sql) # order to select executed + myresult = cursor.fetchall() # gets all the rows of nicknames where the nickname == nick + l = str(myresult[0]) # l = ('nickname',) + final = (l[2:]) + final = final[:-3] + return final + except: + pass + +""" Adds new friends, collectiong and storing the information needed """ +def newFriend(): + try: + firstName = input("What is your first name? ") + lastName = input("What is your last name? ") + nickname = input("How should I treat you? ") + nickname = nickname.lower() + connect = connection() + cursor = connect.cursor() + sql = 'SELECT NICKNAME FROM users WHERE NICKNAME = "' + nickname + '"' #sql gets the order to select all nicknames from the table users with the nickname == nick + cursor.execute(sql) # order to select executed + myresult = cursor.fetchall() # gets all the rows of nicknames where the nickname == nick + for x in myresult: + if nickname in x: + print("I already call that to a friend. Please start again with a diferent nickname.") + return False + age = input("How old are you? ") + city = input("Where do you live? ") + mail = input("What is your email? ") + password = input("Define your password: ") + sql = "INSERT INTO users (FIRST_NAME, LAST_NAME, AGE, CITY, PASSWORD, NICKNAME, EMAIL) VALUES (%s, %s, %s, %s, " \ + "%s, %s, %s) " #sql gets the order to insert all these values into the table users + val = (firstName, lastName, age, city, password, nickname, mail) + cursor.execute(sql, val) #order executed + connect.commit() # tell the database to save all the changes + sql = "INSERT INTO favourite (NICKNAME) VALUE (%s) " #sql gets the order to add the user nickname into the table favourite + val = (nickname) + cursor.execute(sql, val) #order executed + connect.commit() # tell the database to save all the changes + print(cursor.rowcount, " more friend! That's great!\n\n") + email(nickname, password, mail) #Works depending on the wifi connection / does not work with public wifi connections + return nickname + except: + print("Something went wrong") + + diff --git a/what.py b/what.py index 4dfe60a..b729efa 100644 --- a/what.py +++ b/what.py @@ -1,46 +1,25 @@ import random from wiki import wikiSearch -def sentence_what(ck): - operations = ["+", "plus", "-", "minus", "/", "devised", "divided", "*", "x", "times"] +from chatmaths import entre +from info import informations, ownInfo + + +""" prepered answers to what questions """ +def sentence_what(sentence): """ Function to get ChatBot information related to WHAT questions """ - if "your" in ck: - # name related questions - if "last name" in ck: + if "your" in sentence: + if "last name" in sentence: answer = ["My last name is Foreigners", "My last name is B", "My last name is C", "My last name is D"] print(random.choice(answer)) - elif "middle name" in ck: + elif "middle name" in sentence: print("My middle names are Made By The") - elif "full name" in ck: + elif "full name" in sentence: print("My name is ChatBot Made By The Foreigners") - elif "name" in ck: + elif "name" in sentence: print("My name is ChatBot") - # personal related questions - elif "favourite" in ck: - if "colour" in ck: - word = "colour" - answer = ["obviously red.", "red.", " for the 100 time, red! You have a memory of a fish."] - print("My favourite " + word + " is " + random.choice(answer)) - elif "song" or "music" in ck: - if "type" or "kind" or "genre" in ck: - answer = ["I love all of them", "I don't want to share this with you", - "If i tell you I would have to kill you"] - print(random.choice(answer)) - else: - answer = ["I don't listen to music very often, so I can't answer to that question.", "I just don't know yet", "Good question!"] - print(random.choice(answer)) - elif "food" in ck: - answer = ["I just can't eat.", "I don't even have a mouth, seems impossible to know.", "Good question! I would love to have a answer to that question."] - print(random.choice(answer)) - elif "film" in ck: - if "type" or "kind" or "genre" in ck: - answer = ["I love all of them", "I don't want to share this with you", "If i tell you I would have to kill you"] - print(random.choice(answer)) - else: - answer = ["I love many films, I can't choose one.", "I don't want to share this with you", "If i tell you I would have to kill you"] - print(random.choice(answer)) else: - print("I am not sure if I understand what you mean.") - elif "plus" in ck or "+" in ck or "minus" in ck or "-" in ck or "*" in ck or "times" in ck or "x" in ck or "divided" in ck or "/" in ck: - detectFunction(ck) + informations(sentence) #calls other answers about the chatbot + elif "my" in sentence: + ownInfo(sentence) #calls other questions and answers about the user else: - wikiSearch(ck) \ No newline at end of file + wikiSearch(sentence) #if there are no "personal" questions, calls wikiSearch to search in wikipedia for meanings