def process(sentence): """ Process the sentence, and go to Google """ if is_math(sentence): return sentence.forward("math") sentence.replace_it() engines = { "google": "http://www.google.com/search?q={}", "bing": "http://www.bing.com/search?q={}", "yahoo": "http://search.yahoo.com/search?p={}", "duckduckgo": "https://duckduckgo.com/?q={}", "baidu": "http://www.baidu.com/s?wd={}", } engine = paul.get_search_engine().lower() keywords = sentence.keywords(ignore=[engine]) paul.log("KEYWORDS:", keywords) query = "+".join([word.replace(" ", "+") for word, _ in keywords if word not in VERBS + NOUNS]) url = engines[engine].format(query) paul.log("URL: " + url) paul.loading() paul.open_URL(url) return "Here, try this."
def associativity(self, node, symbol): cond1 = lambda n: n.value == symbol cond2 = lambda n: type(n) in [int, float] vals, succ = self.collect_values(node, cond1) if succ: nums, varis = paul.partition(vals, cond2) else: return None if symbol == "*": n = 1 check = 1 for i in nums: n *= i elif symbol == "+": n = 0 check = 0 for i in nums: n += i if check != n: node.value = symbol node.left = Node(n) if varis: paul.log("VARIS:", varis) if len(varis) == 1: node.right = Node(varis[0]) else: varis.sort() oths = [varis[0]] for i in varis[1:]: oths.append(i) oths.append(symbol) node.right = self.create_nodes(oths)
def process(sentence): """ Process the sentence """ keywords = sentence.keywords(include=["VB", "NS"]) paul.log("KEYWORDS:", keywords) if paul.has_one_of(keywords, ["mute", "silence", "silent, " "unmute"]): mute() return "Toggling mute." elif paul.has_one_of(keywords, ["volume", "louder", "quieter"]): return change_volume(keywords) elif paul.has_one_of(keywords, ["brightness", "brighter", "dimmer"]): return change_brightness(keywords) elif paul.has_word(keywords, "screensaver"): screensaver() return "Done!" elif paul.has_word(keywords, "desktop"): desktop() return "Done!" elif paul.has_one_of(keywords, ["lock", "sleep"]): sleep() return "Done!" elif paul.has_one_of(keywords, ["more", "again"]): return repeat() else: return "I couldn't manage that."
def process(sentence): ''' Process the sentence ''' r = paul.PAUL_ROOT modules = [file[:-3] for file in os.listdir(r + "/Modules/") if file[-3:] == ".py" and file not in [ "__init__.py", "importer.py", "personality.py", "loader.py"] ] paul.log("MDLS:", modules) wrd = extract_word(sentence, modules, two_helps=True) if wrd: return get_help(wrd) helping = "I'm more than happy to help! " helping += "I'm able to help with:\n" for m in modules: helping += " " + m[0].upper() + m[1:] + "\n" paul.interact(helping[:-1]) r = paul.interact("Which do you want to know about?", response="arb") s = paul.Sentence(r) if s.has_one_of(["none", "never", "no", "nope", "exit", "stop"]): paul.acknowledge() return wrd = extract_word(s, modules, two_helps=False) if wrd: return get_help(wrd) else: return "I wasn't quite sure what you needed help with..."
def process(sentence): ''' Process the sentence ''' keywords = sentence.keywords(include=["VB", "NS"]) pp = sentence.get_part("PP", indexes=True) if pp: keywords += pp paul.trim_word(keywords, "to") paul.log("KEYWORDS:", keywords) temp_key = get_key(keywords) if temp_key[1]: key = temp_key[0] else: return temp_key[0] temp_val = get_val(keywords, key, sentence) if temp_val[1]: val = temp_val[2] confirm = temp_val[0] else: return temp_val[0] return make_change(key, val, confirm)
def create_postfix(self, expression): ''' Create the postfix version of the expression ''' paul.log("STARTED POSTFIX ON", expression) operators = {"^":3,"\\":3,"*":2,"/":2,"+":1,"-":1,"(":0} stack = [] postfix = [] for item in expression: if item == "(": stack.append(item) elif item == ")": stacked = stack.pop() while stacked != "(": postfix.append(stacked) stacked = stack.pop() elif item not in list(operators.keys()): postfix.append(item) else: prec = operators[item] while len(stack) != 0 and prec <= operators[stack[-1]]: postfix.append(stack.pop()) stack.append(item) while len(stack) != 0: postfix.append(stack.pop()) paul.log("ENDED POSTFIX ON", postfix) return postfix
def choose(list_choices): ''' Choose the item from what we found ''' question = "Which of these do you want? \n" options = "\n".join([str(index + 1) + ". " + "/".join(item.split("/")[3:]) for index, item in enumerate(list_choices)]) choice = paul.interact(question + options, "list") if choice is not None and choice <= 5 and choice > 0: paul.log("CHOICE: " + str(choice)) return list_choices[choice - 1] return None
def process(sentence): ''' Process the sentence ''' keywords = sentence.keywords(include=["NS"]) keywords = [word[0] for word in keywords] new_keys = [] for keyword in keywords: for word in keyword.split(): new_keys.append(word) keywords = new_keys keywords = paul.filter_unless_listed(keywords, DAYS, MONTHS, NOUNS) paul.log("KEYWORDS: " + str(keywords)) return what_keyword(keywords[0])
def scrape_first_paragraph(url): ''' Get the first paragraph of the specified (print-formatted) wikipedia article ''' gross_url = url.replace("/wiki/", "/w/index.php?title=")+"&printable=yes" paul.log("URL ATTEMPT: " + gross_url) d = paul.DOM.fromURL(gross_url) para = d["#mw-content-text"].get_immediate_child('p')[0].extract_raw_text() paul.set_it(url) para = stripIt(para) if para.endswith("may refer to:") or para.endswith("may refer to"): paul.open_URL(url) return "This is a diambiguation page. I'll bring it up now..." return para + "\n\n" + url
def add_mult(self, tokens): i = 0 ops = list("=+-*/()^\\") new_toks = [] while i < len(tokens)-1: new_toks.append(tokens[i]) if tokens[i] not in ops and tokens[i+1] not in ops: new_toks.append("*") elif tokens[i] == ")" and tokens[i+1] == "(": new_toks.append("*") elif tokens[i] not in ops and tokens[i+1] == "(": new_toks.append("*") i += 1 new_toks.append(tokens[i]) paul.log("TOKENS:", new_toks) return(new_toks)
def create_nodes(self, stack): operators = list("^\\*/+-") paul.log("STARTED NODES ON", stack) if len(stack) == 1: return stack[0] if type(stack[0]) == Node else Node(stack[0]) else: pos = 2 for i in range(len(stack)): if stack[i] in operators: pos = i break n = Node(stack[pos]) n.left = stack[pos-2] if type(stack[pos-2]) == Node else Node(stack[pos-2]) n.right = stack[pos-1] if type(stack[pos-1]) == Node else Node(stack[pos-1]) paul.log("STACK NOW", stack[:pos-2] + [n] + stack[pos + 1:]) return self.create_nodes(stack[:pos-2] + [n] + stack[pos + 1:])
def get_val(keywords, key, sentence): ''' Determine the value to set. ''' val = '' flag = True confirm = "Done." if paul.has_one_of(keywords, ["off", "false", "stop"]): val = "False" elif paul.has_one_of(keywords, ["on", "true", "start", "begin"]): val = "True" elif key == "title": if paul.has_word(keywords, "sir"): val = "sir" elif paul.has_word(keywords, "ma'am"): val = "ma'am" else: return ("I don't understand which title " + "you want to go by, sir or ma'am.", False) val = '"{}"'.format(val) elif key == "search_engine": engines = ["Google", "Bing", "Yahoo", "DuckDuckGo", "Baidu"] for engine in engines: if paul.has_word(keywords, engine.lower()): val = '"{}"'.format(engine) if val == '': return ("Sorry, I couldn't work out which " + "search engine you want to use.\n" + "Please choose from Google, Bing, Yahoo, " + "DuckDuckGo and Baidu next time.", False) elif key == "name": if sentence.has_one_of(["i", "me"]): val = paul.join_lists(sentence.get_part("??"), sentence.get_part("XO")) paul.log("VAL[0]", val[0]) val = '"{}"'.format(val[0].capitalize()) confirm = ("Ok, I'll call you " + "{} from now on.".format(val[1:-1])) elif sentence.has_word("you"): return ("My name is Paul.", False) else: return ("Not really sure what you're getting at...", False) else: paul.log("PARAMETER NOT FOUND") return ("I'm not sure how you" + " wanted '{}' set.".format(key), False) return (confirm, flag, val)
def extract_word(sentence, modules, two_helps=False): ''' Extract the module the user wants help with. ''' for word in modules: if sentence.has_word(word): if two_helps: if word == "help": help_count = 0 for w,t in sentence: if w == "help": help_count += 1 if help_count > 1: return "help" else: paul.log("NOT ENOUGH HELPS") else: return word else: return word
def make_equations(sentence): ''' Create a set of equations to work with ''' eqn_string = [] index = 0 for word, _ in sentence: is_eq = (paul.has_one_of(word, "+/^*-=1234567890") or word in list("abcdefghijklmnopqrstuvwxyz")) if not is_eq: if len(eqn_string) != index: index += 1 else: try: eqn_string[index] += word except IndexError: eqn_string.append(word) if eqn_string == []: eqn_string = [make_from_words(sentence.sentence_string)] paul.log("EQN_STRING:", eqn_string, "INDEX:", index) return eqn_string
def make_from_words(string): sym_rep = { "plus": "+", "times": "*", "minus": "-", "take away": "-", "over": "/", "divided by": "/", "divide": "/", "to the power of": "^", "power": "^", "squared": "^ 2", "cubed": "^ 3", "double": "* 2", "triple": "* 3", "root": "\\", "square root": "\\ 2", } symbs = list("+*-/^\\") + list("1234567890") new = [] num = [] newstring = string for old, rep in sym_rep.items(): newstring = newstring.replace(old, rep) paul.log("NEWSTR:", newstring) for word in newstring.split(): paul.log(" WORD:", word) if word in NUMBER_WORDS(): num.append(word) elif word in symbs: s = " ".join(num) if s.strip(): n = paul.parse_number(s) new.append(n) num = [] new.append(word) if num: s = " ".join(num) n = paul.parse_number(s) new.append(n) return " ".join([str(j) for j in new])
def join_digits(self, expression): ''' Join two-or-more digit numbers together. Also spots pi and e ''' numbers = list("1234567890.") letters = list("abcdefghijklmnopqrstuvwxyz") ops = list("(+*-^\\/") paul.log("DIGITIZING", expression) new_expression = [] i = 0 neg = False while i < len(expression): paul.log(expression[i], new_expression) if expression[i] == " ": i += 1 elif expression[i] in letters: if expression[i] == "e": new_expression.append(e) i += 1 elif expression[i] == "p" and expression[i+1] == "i": new_expression.append(pi) i += 2 else: new_expression.append(expression[i]) i += 1 elif expression[i] == "-" and new_expression[-1] in ops: neg = True i += 1 elif expression[i] not in numbers: new_expression.append(expression[i]) i += 1 else: number = "" j = i while j < len(expression) and expression[j] in numbers: number += expression[j] j += 1 i = j if neg: number = "-" + number neg = False new_expression.append(float(number)) return new_expression
def get_help(module): ''' Given the name of a module as a string, return the help for this module, also as a string. If the module does not have a help function, say so. ''' def clean(string): string = string.replace("\n", " ") while " " in string: string = string.replace(" ", " ") return string.strip() if module == "help": return clean(manual()) try: m = importlib.import_module("Modules." + module) paul.log(m) try: return clean(m.manual()) except: return "I couldn't find any help for this, I'm afraid. " except: return "Hmm... I couldn't find that module."
def find(params="", look_in=False): ''' Find the item that was searched for with necessary paramenters ''' home = look_in if look_in else "~" avoiders = [ "Library", "Cache", ".log", ".properties", ] command = 'mdfind -onlyin {}/ "{}"'.format(home.strip("\n"), params) results = paul.run_script(command, response=True).split("\n")[:-1] filtered_results = sorted([line.strip() for line in results if not has_one_of_substrings(line.strip(), avoiders)], key=len) paul.log("RESULTS FIRST 5: ", filtered_results[:10]) if len(filtered_results) > 0: if len(filtered_results) > 1: decision = choose(filtered_results[:5]) else: decision = filtered_results[0] paul.log("DECISION: " + str(decision)) it = paul.set_it(decision) paul.log('IT: {}'.format(it)) return decision else: return None
def process(sentence): ''' Process the sentence ''' sentence.replace_it() keywords = sentence.keywords() paul.log("KEYWORDS: " + str(keywords)) ignores = ["i", "wikipedia"] filtered_keywords = [word for word in keywords if word[0] not in ignores] paul.loading() if filtered_keywords == []: return "I don't understand. Sorry!" if filtered_keywords[0][0] in ["joke", "jokes"]: if sentence.has_word("about"): pass else: return sentence.forward("personality") elif filtered_keywords[0][0].startswith("http"): paul.open_URL(filtered_keywords[0][0]) return findIt(filtered_keywords[0][0], sentence)
def make_change(key, val, confirm): ''' Write the changes to the system file. ''' if key in ["VERBOSE", "NOISY", "LOGGING"]: file = "system" else: file = paul.system.flags["USER"]["username"] settings_file = paul.PAUL_ROOT + "/Settings/{}.py".format(file) sub = " \"{}\": {},\n".format(key, val) paul.log("SETTING:", sub) lines = open(settings_file).readlines() backup = lines[:] paul.log(" " + key) for i, line in enumerate(lines): if line.startswith(" \"" + key + "\""): lines[i] = sub open(settings_file, "w").write("".join(lines)) runtime_change(key, val) return confirm open(settings_file, "w").write("".join(backup)) return "Something went wrong changing the setting."
def process(sentence): ''' Process the sentence ''' global mb username = '' password = '' provider = '' if not mb: try: mb = Mailbox(provider) except ConnectionRefusedError: return "Oh no! Check your settings, I couldn't connect for some reason." try: mb.login(username, password) except: return "Hmmm... Check your username and password are correct." keywords = sentence.keywords(include=["VB"]) paul.log("KEYWORDS:", keywords) if paul.has_one_of(keywords, ["read", "check", "have"]): r = mb.get_unread() return r if r else "" elif paul.has_one_of(keywords, ["write", "send", "compose"]): return "I can't quite do that yet. Working on it!"
def get_key(keywords): ''' Decide on the key to use ''' key = '' flag = True if paul.has_one_of(keywords, ["noisy", "noisiness", "talk", "talking"]): key = "NOISY" elif paul.has_one_of(keywords, ["verbose", "verbosity", "debug", "debugging"]): key = "VERBOSE" elif paul.has_word(keywords, "logging"): key = "LOGGING" elif paul.has_one_of(keywords, ["name", "call", "called"]): key = "name" elif paul.has_word(keywords, "title"): key = "title" elif paul.has_word(keywords, "prompt"): return ("You have to change the prompt in settings" + " manually, I'm afraid.", False) elif paul.has_one_of(keywords, ["search", "engine", "search engine"]): key = "search_engine" else: paul.log("FOUND NO FLAG") return ("I'm not sure what you wanted me to set.", False) return (key, flag)
def process(sentence): ''' Process the sentence, act as necessary ''' paul.loading() ignore = [ "weather", "forecast", "rainy", "rain", "raining", "sunny", "temperature", "cold", "hot", "humid", ] keywords = sentence.keywords() paul.log("KEYWORDS: " + str(keywords)) today = datetime.date.today().weekday() paul.log("TODAY: " + str(today)) day_index = 0 weekdays = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'] if (len(keywords) == 0 or paul.has_one_of(keywords, ['today', 'now', "today's"])): day_index = 0 elif paul.has_one_of(keywords, ['tomorrow', "tomorrow's"]): day_index = 2 elif paul.has_one_of(keywords, weekdays): for day in weekdays: if paul.has_word(keywords, day): paul.log("DAY:", day) day_index = (weekdays.index(day) + today) % 7 + 1 if day_index == 1: day_index = 0 paul.log("DAY: " + str(day_index)) return weather(day_index, sentence)
def weather(day_index, sentence): ''' Simply get the weather for any day ''' if day_index > 5 or day_index < 0: return "I can't see that far ahead. Sorry!" try: page = urllib.request.urlopen("http://weather.yahooapis.com/" "forecastrss?u=" + paul.get_temp().lower() + "&w=" + paul.get_woeid()) except urllib.error.URLError: return ("I couldn't retrieve the weather. " + "Are you connected to the internet?") lines = page.readlines() conditions = get_conditions(lines, day_index) paul.log("WEATHER_RAW:", lines) paul.log("CONDITIONS:", conditions) paul.set_it("http://weather.yahoo.com/") if day_index == 0: condition = (", and {}".format(conditions['text'].lower()) if conditions['text'].lower() != "unknown" else "") temp = conditions['temp'] conditions2 = get_conditions(lines, 1) paul.log("CONDITIONS2:", conditions2) condition2 = conditions2['text'].lower() temp2 = "{}".format(conditions2['high']) com = comment(sentence, temp, conditions['text']) return "{0}It's {1}°{2}{3}. The high today is {4}°{2}, {5}.".format( com, temp, paul.get_temp(), condition, temp2, condition2) else: condition = conditions['text'].lower() com = comment(sentence, conditions['high'], conditions['text']) rep = ("{0}It will have a low of " "{1}°{2}, a high of {3}°{2}, and will be {4}.".format( com, conditions['low'], paul.get_temp(), conditions['high'], condition)) return rep
def process(sentence): ''' Process the sentence. ''' sentence.replace_it() eqns = make_equations(sentence) if len(eqns) == 0: return "I'm not sure what you want me try try and solve. Sorry!" subs = sentence.has_one_of(["sub", "substitute", "solve"]) rearrange = sentence.has_one_of(["rearrange", "solve"]) if subs: rearrange = False if (paul.get_it() and paul.Sentence(paul.get_it()).has_one_of("+/^*-=1234567890")): eqns.append(paul.get_it()) if len(eqns) < 2 else 0 paul.log(eqns) eqn_string = eqns[0] if subs: try: eqn_string = eqns[1] except IndexError: eqn_string = eqns[0] if rearrange: for e in eqns: if len(e) > 1: eqn_string = e break paul.log("SUBS:", subs, "REARRANGE:", rearrange) paul.log("EQUATION:", eqn_string) had_equals = True if not paul.has_word(eqn_string, "="): eqn_string = "y=" + eqn_string had_equals = False elif eqn_string.strip()[0] == "=": eqn_string = "y" + eqn_string paul.log("EQUATION:", eqn_string) # try: eqn = Equation(eqn_string) # except: # return "Something went horribly wrong when I tried to math. Oops." # if subs and len(eqns) > 1: eq2 = Equation(eqns[0]) if type(eq2.head.right.value) == float: eqn.substitute((eq2.head.left.value, eq2.head.right.value)) elif type(eqn.head.right.value) == float: eq2.substitute((eqn.head.left.value, eqn.head.right.value)) eqn, eq2 = eq2, eqn else: url = "http://www.wolframalpha.com/input/?i=" query = "sub {} into {}".format(eq2, eqn) query.replace("+", "%2D").replace("=", "%3D").replace("/", "%2F") paul.open_URL(url+query) return '''I was unsuccessful in finding the solution:\n{}\n{}'''.format(eq2, eqn) if rearrange: targ = "x" targets = sentence.keywords() for word, _ in targets: if len(word) == 1: targ = word try: eqn.rearrange_linear_for(targ) except RuntimeError: url = "http://www.wolframalpha.com/input/?i=" query = "rearrange {} for {}".format(eqn, targ) query.replace("+", "%2D").replace("=", "%3D").replace("/", "%2F") paul.open_URL(url+query) return "Oh dear, not a clue. Try this instead." result = str(eqn) if not had_equals: result = result[4:] paul.set_it(result) try: if result[0] == "(" and result[-1] == ")": result = result[1:-1] except IndexError: pass return result
def process(sentence): ''' Process the sentence ''' commands = { 'open': lambda location: get(location), 'get': lambda location: get(location), 'launch': lambda location: get(location), 'show': lambda location: reveal(location), 'find': lambda location: reveal(location), 'search': lambda location: reveal(location), 'reveal': lambda location: reveal(location), 'locate': lambda location: reveal(location), 'be': lambda location: reveal(location), # Catch in case, use safer reveal than get } types = { 'folder': "folder ", 'powerpoint': "presentation ", 'keynote': "presentation ", 'document': "word ", 'word': "word ", 'spreadsheet': "spreadsheet ", 'excel': "spreadsheet ", 'picture': "image ", 'image': "image ", 'movie': "movie ", 'film': "movie", 'video': "movie ", 'audio': "audio ", 'music': "music ", 'email': "email ", 'event': "event ", 'pdf': "pdf", 'preference': "preferences ", 'bookmark': "bookmark ", 'favourite': "bookmark ", 'font': "font ", 'widget': "widget ", "app": "application ", "application": "application ", "program": "application ", "executable": "application ", } apps = ["app", "application", "program", "executable"] replaced = sentence.replace_it() preps = sentence.get_part("PP", indexes=True) paul.log(preps) preps = paul.filter_out(preps, "for") paul.log(preps) try: object = sentence.get_part("NO")[0] except: object = None verb = sentence.get_part("VB")[0] if replaced: return commands[verb](replaced) ignore = list(types.keys()) + list(commands.keys()) keywords = sentence.keywords(ignore=["file"]) paul.log("KEYWORDS: " + str(keywords)) if keywords == []: return "I don't understand. Sorry." filters = generate_filters(keywords, preps) if object in types.keys(): filters.append("kind:{}".format(types[object])) if object in apps: where = "/Applications" params = keywords[0][0] + " kind:application" paul.log("FINDING APP") else: where = False params = " ".join(filters) paul.log("PARAMETERS: " + str(params)) search = filters[0] paul.log(search) if search.startswith("http") or search.startswith("www."): s = search paul.open_URL(s if s.startswith("http") else "http://"+s) return "Opening the website..." elif paul.has_word(keywords, "all"): return show_all(params) else: return commands[verb](find(params, where))
def simplify(self, node=-1): ''' Try and simplify the tree -- at the moment, only basically ''' if node == -1: node = self.head ops = { "+": lambda x, y: x + y, "-": lambda x, y: x - y, "*": lambda x, y: x * y, "/": lambda x, y: x / y, "^": lambda x, y: x ** y, "\\": lambda x, y: x ** (1 / y), "=": lambda x, y: x == y } if node.value in ops.keys(): self.simplify(node.left) self.simplify(node.right) nums = [int, float] val = node.value left = node.left.value right = node.right.value if val in ["+", "-"] and right == "*" and left == "*": self.common_factor(node) #self.simplify() elif val == "/" and not (node.right.is_terminal() and node.left.is_terminal()): self.cancel(node) self.gcd(node) elif val in ["*", "^"]: self.expand(node) elif val in ["+", "-"] and node.left.is_terminal() and left in LETTERS(): node.left = self.create_nodes([1.0, left, "*"]) try: self.common_factor(node) except: self.simplify(node.left) elif val in ["+", "-"] and node.right.is_terminal() and right in LETTERS(): node.right = self.create_nodes([1.0, right, "*"]) try: self.common_factor(node) except: self.simplify(node.right) if val == "*": self.associativity(node, "*") elif val == "+": self.associativity(node, "+") paul.log("SIMPLIFYING", node) paul.log("VAL", val, "LEFT", left, "RIGHT", right) if type(left) in nums and type(right) in nums: paul.log("Simplify Option 1") node.value = ops[val](left, right) if node.value % 1 == 0: node.value = int(node.value) node.left = None node.right = None elif val in ["+", "-"] and left == 0: paul.log("Simplify Option 2") node.value = node.right node.left = None node.right = None elif val in ["+", "-"] and right == 0: paul.log("Simplify Option 3") node.value = node.left node.left = None node.right = None elif val in ["*", "/"] and left == 1: paul.log("Simplify Option 4") node.value = node.right node.left = None node.right = None elif val in ["*", "/"] and right == 1: paul.log("Simplify Option 5") node.value = node.left node.left = None node.right = None elif val == "*" and (left == 0 or right == 0): paul.log("Simplify Option 6") node.value = 0 node.left = None node.right = None elif val == "*" and (node.left == node.right): paul.log("Simplify Option 7") node.value = "^" node.right = Node(2) elif val == "^" and left == 0: paul.log("Simplify Option 8") node.value = 0 node.left = None node.right = None elif val == "^" and right == 0: paul.log("Simplify Option 9") node.value = 1 node.left = None node.right = None if type(node.value) == Node: node.left = node.value.left node.right = node.value.right node.value = node.value.value