Permalink
Browse files

Initiating refactor

Starting over with a hopefully better approach that actually mirrors a
more human decision making process
  • Loading branch information...
1 parent 66b9ef5 commit 7360dded5b93cdb6643580af76ba425ae98ba3df Eric Garside committed Feb 15, 2013
View
@@ -1 +1 @@
-calibrations
+build
View
@@ -0,0 +1,72 @@
+# Zoidberg Solution
+## The problem
+Jane has 14 balloons. She buys another 6 balloons. How many balloons does she have now?
+
+## Parsed problem
+Jane has 14 balloons .
+NNP VBZ CD NNS .
+
+She buys another 6 balloons .
+PRP VBZ DT CD NNS .
+
+How many balloons does she have now ?
+WRB JJ NNS VBZ PRP VB RB .
+
+# Zoidberg Solution
+## The problem
+Mrs. Jones bought some bananas. Her friends ate 5 bananas. She gave the remaining 4 apples to her friend. How many apples did she buy in the beginning?
+
+## Parsed problem
+Mrs. Jones bought some bananas .
+NNP NNP VBD DT NNS .
+
+Her friends ate 5 bananas .
+PRP$ NNS VBP CD NNS .
+
+She gave the remaining 4 apples to her friend .
+PRP VBD DT VBG CD NNS TO PRP$ NN .
+
+How many apples did she buy in the beginning ?
+WRB JJ NNS VBD PRP VB IN DT NN .
+
+# Zoidberg Solution
+## The problem
+Tony has 19 jars. He gives 16 jars to his sister. How many jars does he have now?
+
+## Parsed problem
+Tony has 19 jars .
+NNP VBZ CD NNS .
+
+He gives 16 jars to his sister .
+PRP VBZ CD NNS TO PRP$ NN .
+
+How many jars does he have now ?
+WRB JJ NNS VBZ PRP VB RB .
+
+# Zoidberg Solution
+## The problem
+Lucy has 8 dolls. Ethelle has 4 more dolls than her. How many dolls does Ethelle have?
+
+## Parsed problem
+Lucy has 8 dolls .
+NNP VBZ CD NNS .
+
+Ethelle has 4 more dolls than her .
+NNP VBZ CD JJR NNS IN PRP$ .
+
+How many dolls does Ethelle have ?
+WRB JJ NNS VBZ NNP VB .
+
+# Zoidberg Solution
+## The problem
+Joey has 13 toy cars. Chandler has 6 toy cars. How many fewer toy cars does Chandler have than Joey?
+
+## Parsed problem
+Joey has 13 toy cars .
+NNP VBZ CD NN NNS .
+
+Chandler has 6 toy cars .
+NNP VBZ CD NN NNS .
+
+How many fewer toy cars does Chandler have than Joey ?
+WRB JJ JJR NN NNS VBZ NNP VB IN NNP .
View
@@ -0,0 +1,77 @@
+# Zoidberg
+A word problem solver.
+
+# Requirements
+* Python 2.7+
+* SymPy
+* NumPy
+* NLTK
+
+# How it works
+Zoidberg solves word problems in three distinct steps.
+
+## Interpretation
+Zoidberg uses a triple interpretation approach to parse word problems. The raw
+text of the word problem is iterated over three times, each cycle of the
+iteration designed to pull out or piece together different information about
+the problem at hand.
+
+### Solution inference
+> What implications does the problem make about itself?
+
+The first analysis of the problem uses the Inference engine to make some quick
+judgements on what the problem is about. Without going into any specific detail
+about the problem itself, the Inference engine provides some quick and dirty
+directionality for the query parser.
+
+For example, a word problem containing the word "another" might be an addition
+problem; one containing the word "fewer" might be subtraction. The output of
+the inference engine isn't designed to be right, it's designed to be fast.
+
+This step is intended to model the cognitive process of a rough first
+impression of the question being asked; it is expected the first impression
+will often be wrong or incomplete, but even then should be invaluable to the
+query parser for actually targeting the real question.
+
+### Query parsing
+> What is the question being asked?
+
+The second analysis of the problem uses the Parsing engine to determine the
+question actually being asked. The parser marries the general impressions of
+the Inference engine with specifics about the problem itself.
+
+A properly parsed query will be a mathematical formulation of the question
+being asked, in symbolic notation, which SymPy could then solve for us.
+
+### Data extraction
+> What salient data is proved; what data is missing?
+
+Once the question we need to answer is known, the Extraction engine attempts to
+fill in whatever data is missing from our expression such that it can be
+properly solved.
+
+The Extractor exclusively uses the query, and attempts only to fill in missing
+data from the query. A properly extracted problem will be an expression.
+
+## Solving
+Once an expression has been defined, it can be solved. SymPy is used to handle
+expression solving. To the best of its abilities, Zoidberg will attempt to
+respond with a humanized, textual version of the answer.
+
+An ideal solution is "Jane has 6 balloons" instead of "6" or "6 balloons".
+
+## Learning
+Arguably the most important part of the Zoidberg model is the ability to learn
+new things. A ~/brain.zoidberg.json file will be created in your home directory
+to store learned behaviors.
+
+The learning process is heavily involved in modifying the default functionality
+of all it's engines.
+
+# Why is it named Zoidberg?
+Need a project name? Why not Zoidberg?
+
+# Tagging reference
+PoS Tagging reference list:
+ ftp://ftp.cis.upenn.edu/pub/treebank/doc/tagguide.ps.gz
+
View
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
View
File renamed without changes.
File renamed without changes.
File renamed without changes.
View
View
@@ -0,0 +1,25 @@
+#!/usr/bin/env python
+from argparse import ArgumentParser, FileType
+from zoidberg.problem import Problem
+from sys import exit, stdout
+
+def argparse():
+ desc = "Solves word problems."
+ parser = ArgumentParser(description=desc)
+ parser.add_argument("--input", type=FileType("r"), default="-",
+ help="A single question to solve")
+ parser.add_argument("--output", default=stdout, type=FileType("w"),
+ help="The output file. Defaults to stdout")
+ return parser
+
+def main():
+ args = argparse().parse_args()
+
+ p = Problem(args.input.read())
+ p.solve()
+ args.output.write(str(p) + "\n")
+
+ exit(0)
+
+if __name__ == "__main__":
+ main()
View
@@ -0,0 +1 @@
+Jane has 14 balloons. She buys another 6 balloons. How many balloons does she have now?
View
@@ -0,0 +1 @@
+Mrs. Jones bought some bananas. Her friends ate 5 bananas. She gave the remaining 4 bananas to her friend. How many bananas did she buy in the beginning?
View
@@ -0,0 +1 @@
+Tony has 19 jars. He gives 16 jars to his sister. How many jars does he have now?
View
@@ -0,0 +1 @@
+Lucy has 8 dolls. Ethelle has 4 more dolls than her. How many dolls does Ethelle have?
View
@@ -0,0 +1 @@
+Joey has 13 toy cars. Chandler has 6 toy cars. How many fewer toy cars does Chandler have than Joey?
View
@@ -0,0 +1,18 @@
+#! /usr/bin/env python
+from distutils.core import setup
+from os import environ, mkdir, symlink
+from os.path import expanduser, isdir
+from distutils.sysconfig import get_python_lib
+
+setup(
+ name="zoidberg",
+ description="A word problem solver.",
+ author="Eric Garside",
+ author_email="eric@knewton.com",
+ url="http://github.com/Knewton/Zoidberg",
+ packages = ["zoidberg"],
+ platforms=["any"],
+ data_files=[
+ ("/usr/local/bin", ["bin/zoidberg"])
+ ]
+)
View
No changes.
View
@@ -0,0 +1,61 @@
+#!/usr/bin/env python
+from nltk import word_tokenize, pos_tag, data
+
+class Problem(object):
+ def __init__(self, text):
+ # Problem text
+ self.text = text
+
+ # Digest
+ self.sentences = None
+ self.sentence_tags = None
+ self.all_tags = None
+ self.all_words = None
+ self.longest_word = None
+ self.digest()
+
+ def digest(self):
+ # Digest the problem into sentences
+ if self.sentences is None:
+ tokenizer = data.load("tokenizers/punkt/english.pickle")
+ self.sentences = tokenizer.tokenize(self.text.strip())
+
+ # Digest each sentence into words and part-of-speech tags
+ if self.sentence_tags is None:
+ sentence_tags = []
+ all_tags = []
+ all_words = []
+ for s in self.sentences:
+ all_words.append(s)
+ tags = pos_tag(word_tokenize(s))
+ sentence_tags.append(tags)
+ for t in tags:
+ l = len(t[0])
+ if not self.longest_word or self.longest_word < l:
+ self.longest_word = l
+ all_tags.append(t[1])
+ self.sentence_tags = sentence_tags
+ self.all_tags = list(set(all_tags))
+ self.all_words = list(set(all_words))
+
+ def solve(self):
+ pass
+
+ def __str__(self):
+ o = []
+
+ o.append("# Zoidberg Solution")
+ o.append("## The problem")
+ o.append(self.text)
+
+ o.append("## Parsed problem")
+ for s_tags in self.sentence_tags:
+ words, tags = [], []
+ for tag in s_tags:
+ words.append("{: <{l}}".format(tag[0], l=self.longest_word))
+ tags.append("{: <{l}}".format(tag[1], l=self.longest_word))
+ o.append("\t".join(words))
+ o.append("\t".join(tags))
+ o.append("")
+
+ return "\n".join(o)

0 comments on commit 7360dde

Please sign in to comment.