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!
* * *