Building a Customized

Personal Assistant with Python

PyCon JP 2017

2017.09.08 (Fri) Room 201

Iskandar Setiadi


Iskandar Setiadi

Github: freedomofkeima

Personal Website:

  • 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 :)



Customized Personal Assistant

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


Available at

Deep Photo Style Transfer

Available at

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 = [
            '-i',  # input file
            os.path.join(image_path, filename),
            '-o',  # output file
            '-n',  # number of iteration
        # Execute
        p = subprocess.Popen(args, stdout=subprocess.PIPE, shell=False)
        (output, err) = p.communicate()
        if err:
    return generate_gif_file_from_primitive(image_path, filename)


Daily Lesson

Learning Basic Japanese

Step 1: Prepare the Data

Download it from

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



Automatic Translation

Language Preference




Available at

shlex - Simple Lexical Analysis

  import shlex
      elements = shlex.split(query.encode('utf-8'))
      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("")  # Yahoo Page
  soup = BeautifulSoup(r.content, "html.parser")
  soup_attrs ='div.trouble table tr td')







$ pip install chatterbot

  from chatterbot import ChatBot

  chatbot = ChatBot(
      'Ron Obvious',

  # Train based on the english corpus

  # 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(
      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)
      storage_adapter=""  # Can be stored in JSON file, MongoDB, or even SQL Alchemy

      "chatterbot.corpus.maidcorpus"  # Train from a custom corpus

RSS Aggregator




$ pip install 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.

* * *

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)

Infinite Possibilities (General)

  • Location-aware features: Recommendation list, weather forecast, etc
  • IoT integration: Surveillance camera, air conditioner, etc
  • Better NLP: (Facebook), IBM Watson, Google Cloud Speech, LUIS (Azure), Amazon Lex, etc

Start building your own bot!


Project available at

Presentation slide available at

Thank you!

Profile Picture


* * *