Building a Customized
Personal Assistant with Python
PyCon JP 2017
2017.09.08 (Fri) Room 201
Iskandar Setiadi
#pyconjp_201


Iskandar Setiadi
Github: freedomofkeima
Personal Website: https://freedomofkeima.com
Software Engineer at HDE, Inc. - Shibuya, Japan
From Jakarta, Indonesia
Graduated from Institut Teknologi Bandung (Indonesia) 2 years ago
On the Map: Indonesia

Why Python?
Started using Python ~3 years ago from an internship in HDE, Inc.
Python is very easy to learn!
The community is nice and friendly :)

Prologue





Maid-chan Overview

Why Facebook Messenger?
-
Multi-platforms
Our bots can be accessed everywhere without developing own client-side interface.
-
Huge number of users
Facebook has more than 1 billion of users, which allows us to share our bots with our friends easily.
Deep Learning for Images
Deep Learning Drawbacks
Speed & Initial Setup
Deep Learning requires a lot of dependencies, such as Caffee, Torch, CUDA backend (GPU), etc. It also takes several minutes to generate result from a model, which makes it not usable with mobile devices.

Primitive: Configure Once, Execute Everywhere
def create_primitive_image(image_path, filename): for i in xrange(0, 3): # Generate 3 different images output_path = os.path.join(image_path, "output{}.png".format(i)) args = [ 'primitive', '-i', # input file os.path.join(image_path, filename), '-o', # output file output_path, '-n', # number of iteration '175' ] # Execute p = subprocess.Popen(args, stdout=subprocess.PIPE, shell=False) (output, err) = p.communicate() if err: logging.error(err) return generate_gif_file_from_primitive(image_path, filename)
Showcase



Daily Lesson
Learning Basic Japanese



Step 2: Retrieve the Data
Python csv module to help!
with open(filename, 'rb') as fobj: reader = csv.reader(fobj, delimiter=',', encoding='utf-8') ... # get random Kanji & Vocabulary based on level choice here
Step 3: Create a Generic Daily Scheduler
while True: current_mt = int(time.time()) metadata = redis_client.get_schedules() if metadata["next_mt"] < current_mt: metadata["kanji_n4"] = get_random_kanji(level=4) ... # Store any other daily information metadata["next_mt"] += 86400 # every 1 day redis_client.set_schedules(metadata)
Subscribe

Showcase

Automatic Translation
Language Preference

Examples

Examples

shlex - Simple Lexical Analysis
import shlex try: elements = shlex.split(query.encode('utf-8')) except: elements = [query.encode('utf-8')] # Input : Translate "I am going to Pycon" to 日本語 # Output : ['Translate', 'I am going to Pycon', 'to', '日本語']
trans-shell to Google Translate
... # Use trans online language detection if not source_language_key: source_language_key = get_trans_language_prediction(source_text) # "trans -id {text}" handling if not target_language_key: target_language_key = Constants.TRANSLATION_MAP[source_language_key] args = ["trans", "-b", "{}:{}".format(source_language_key, target_language_key), source_text] p = subprocess.Popen(args, stdout=subprocess.PIPE, shell=False) (output, _) = p.communicate() return output
Train Status
Train Accident


requests + BeautifulSoup + Google Translate
import requests from bs4 import BeautifulSoup # Retrieve page r = requests.get("https://transit.yahoo.co.jp/traininfo/area/4/") # Yahoo Page soup = BeautifulSoup(r.content, "html.parser") soup_attrs = soup.select('div.trouble table tr td')
Chatbot
Showcase

Showcase

Showcase

Showcase

ChatterBot
$ pip install chatterbot
from chatterbot import ChatBot chatbot = ChatBot( 'Ron Obvious', trainer='chatterbot.trainers.ChatterBotCorpusTrainer' ) # Train based on the english corpus chatbot.train("chatterbot.corpus.english") # Get a response to an input statement chatbot.get_response("Hello, how are you today?") # Response: "I am doing well."
Custom Corpus
self.chatbot = ChatBot( 'Maid-chan', trainer='chatterbot.trainers.ChatterBotCorpusTrainer', # Can also be trained with Twitter or Ubuntu dialog corpus output_adapter="chatterbot.output.OutputFormatAdapter", # Output can be integrated with other framework (MS Bot) output_format='text', storage_adapter="chatterbot.storage.MongoDatabaseAdapter" # Can be stored in JSON file, MongoDB, or even SQL Alchemy ) self.chatbot.train( "chatterbot.corpus.indonesia.conversations", "chatterbot.corpus.indonesia.greetings", "chatterbot.corpus.english.conversations", "chatterbot.corpus.english.greetings", "chatterbot.corpus.maidcorpus" # Train from a custom corpus )
RSS Aggregator
Examples

Examples

feedparser
$ pip install feedparser # https://github.com/kurtmckee/feedparser
import feedparser response = feedparser.parse(url) if 'bozo_exception' in response: # invalid response, not a valid RSS return False for entry in response.get("entries", {}): title = entry.get("title") ...
Bonus: Daily Greetings

Daily Greetings
Make your bot more fun!
With generic scheduler (daily lesson), Maid-chan is equipped with daily greetings feature.
* * *
FB Messenger Bot: Configure

Documentation: https://developers.facebook.com/docs/messenger-platform/getting-started
Caveat & Lesson Learned
- Facebook has 20 seconds timeout
- Facebook will keep sending the message until a response is given
- Timezone handling for better user experience
- Friends can be added as Application Tester (pre-release)
- Users are prone to make mistakes
- Don't trust user input for learning (Chatbot)
Infinite Possibilities

Optimus Prime Bot (Example: Location x Yelp) https://github.com/hungtraan/FacebookBot
Infinite Possibilities (General)
- Location-aware features: Recommendation list, weather forecast, etc
- IoT integration: Surveillance camera, air conditioner, etc
- Better NLP: Wit.ai (Facebook), IBM Watson, Google Cloud Speech, LUIS (Azure), Amazon Lex, etc
Start building your own bot!
Closing
Project available at https://github.com/freedomofkeima/messenger-maid-chan

Presentation slide available at https://freedomofkeima.com/pyconjp2017/
Thank you!

* * *