Skip to content
This repository has been archived by the owner on Nov 22, 2020. It is now read-only.

Commit

Permalink
documented code.
Browse files Browse the repository at this point in the history
  • Loading branch information
rouge8 committed Jun 5, 2010
1 parent f19ee3d commit b0003ac
Show file tree
Hide file tree
Showing 6 changed files with 130 additions and 153 deletions.
Binary file modified 20q.db
Binary file not shown.
10 changes: 0 additions & 10 deletions TODO.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,8 @@ ASK USER IF THEY'D LIKE TO ANSWER A FEW MORE QUESTIONS IF GUESS WAS WRONG?

http://net.tutsplus.com/tutorials/javascript-ajax/submit-a-form-without-page-refresh-using-jquery/

change guess to look at the character with the most right? (that might already be what it does. WHO KNOWS?)

display candidates option on ask pages.

BUILD QUESTION MANAGER

FIX FORM ALIGNMENT (checkboxes and radios)

ADMIN PAGE LOGINS
http://dloewenherz.blogspot.com/2010/01/openid-clickpass-webpy-and-python.html
or do this the crappy way ourselves. or just don't worry for the project.

guess once value is over 100?

LOOK AT UPDATE_LOCAL_KNOWLEDGEBASE
20 changes: 18 additions & 2 deletions admin.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# admin.py
'''
admin.py
Andy Freeland and Dan Levy
5 June 2010
Provides administrative functions, such as retraining characters and deleting
objects and characters. Accessed at the /admin url. Laughably insecure.
'''

import web
import config, model
Expand All @@ -21,36 +29,43 @@

class admin:
def GET(self):
'''Renders the admin page, presenting a menu of administrative functions.'''
return render.admin()

class delete_question:
def GET(self):
'''Lists all of the questions so that selected questions can be deleted.'''
questions = model.get_questions()
return render.delete_question(questions)
def POST(self):
'''Deletes selected questions and returns to the admin page.'''
question_ids = web.input()
for id in question_ids:
model.delete_question(id)
raise web.seeother('/')

class delete_object:
def GET(self):
'''Lists all of the objects so that selected objects can be deleted.'''
objects = model.get_objects()
return render.delete_object(objects)
def POST(self):
'''Deletes selected objects. and returns to the admin page.'''
object_ids = web.input()
for id in object_ids:
model.delete_object(id)
raise web.seeother('/')

class data:
def GET(self):
'''Renders a page listing all of the objects so that they can be retrained.'''
objects = model.get_objects()

return render.data(list(objects))

class retrain:
def GET(self, object_id):
'''Renders a page with all of the questions and values for a specified
object_id so that it can be retrained manually.'''
object = model.get_object_by_id(object_id)
questions = model.get_questions()
data = model.get_data_dictionary()
Expand All @@ -60,6 +75,7 @@ def GET(self, object_id):
raise web.seeother('/') # returns to admin page

def POST(self, object_id):
'''Updates object_id with the newly selected answers to questions.'''
inputs = web.input()
for question_id in inputs:
answer = inputs[question_id]
Expand Down
48 changes: 0 additions & 48 deletions cli.py

This file was deleted.

120 changes: 60 additions & 60 deletions twentyquestions.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,42 +22,32 @@
RETRAIN_SCALE = 2 # scale for weights set through the admin interface
NEW_QUESTION_SCALE = 5 # scale for weights learned through the new question/guess page

def load_initial_questions():
'''Loads questions we always want to ask as well as some random ones so that we can learn more
about the objects.'''

initial_questions = []
initial_questions.append(model.get_question_by_id(1)) # is character real
questions = list(model.get_questions()) # converts from webpy's IterBetter to a list

for i in range(2): # up to 2 initial random questions
q = random.choice(questions)
if not(q in initial_questions):
initial_questions.append(q)

initial_questions.append(model.get_question_by_id(6)) # is the character a man

return initial_questions

def guess(objects_values):
'''Returns the object with the highest value.'''
def load_objects_values():
'''Initializes objects values, a list with an entry for each object, initialized at 0.'''

if objects_values == {}: # nothing in the database :(
return None
else:
chosen = get_nearby_objects(objects_values, how_many=1)[0]
return chosen

def learn_character(asked_questions, name):
'''Adds a new object to the database and then learns that object. Returns
the id of that object.'''
if name.strip() != '':
object = model.get_object_by_name(name)
if object: # character in database
learn(asked_questions, object.id)
return object.id
else:
new_object_id = model.add_object(name) ### adds to database and trains
learn(asked_questions, new_object_id)
return new_object_id

def learn(asked_questions, object_id):
'''Updates the data for the correct object based on information in asked_questions.
Also updates times played for the object and stores the playlog.'''
for question in asked_questions:
current_weight = model.get_value(object_id, question)
if not(current_weight): current_weight = 0

new_weight = current_weight + asked_questions[question]
model.update_data(object_id, question, new_weight)

model.update_times_played(object_id)

model.record_playlog(object_id, asked_questions, True)
objects_values = {}
objects = model.get_objects()
for object in objects:
objects_values[object.id] = 0

return objects_values

def sort_objects_values(objects_values):
'''Returns a list of the objects with the highest values in the local knowledge base.'''
Expand All @@ -66,7 +56,7 @@ def sort_objects_values(objects_values):
sorted_objects_values.reverse()

return sorted_objects_values

def get_nearby_objects(objects_values, how_many=10):
'''Returns how_many objects with the highest values in the local knowledge base.
Default: how_many=10.'''
Expand Down Expand Up @@ -145,7 +135,7 @@ def simple_entropy(objects,question):
question_entropy += unknowns * 5 # arbitrary weight to discourage questions with lots of unknowns

return abs(question_entropy)

def choose_question(initial_questions, objects_values, asked_questions, how_many=10):
'''Returns a question with the lowest entropy.'''

Expand Down Expand Up @@ -210,32 +200,42 @@ def update_local_knowledgebase(objects_values, asked_questions, question_id, ans
objects_values[weight.object_id] += answer*value
asked_questions[question_id] = answer

def load_initial_questions():
'''Loads questions we always want to ask as well as some random ones so that we can learn more
about the objects.'''

initial_questions = []
initial_questions.append(model.get_question_by_id(1)) # is character real
questions = list(model.get_questions()) # converts from webpy's IterBetter to a list

for i in range(2): # up to 2 initial random questions
q = random.choice(questions)
if not(q in initial_questions):
initial_questions.append(q)

initial_questions.append(model.get_question_by_id(6)) # is the character a man
def guess(objects_values):
'''Returns the object with the highest value.'''

return initial_questions
if objects_values == {}: # nothing in the database :(
return None
else:
chosen = get_nearby_objects(objects_values, how_many=1)[0]
return chosen

def learn_character(asked_questions, name):
'''Adds a new object to the database and then learns that object. Returns
the id of that object.'''
if name.strip() != '':
object = model.get_object_by_name(name)
if object: # character in database
learn(asked_questions, object.id)
return object.id
else:
new_object_id = model.add_object(name) ### adds to database and trains
learn(asked_questions, new_object_id)
return new_object_id

def learn(asked_questions, object_id):
'''Updates the data for the correct object based on information in asked_questions.
Also updates times played for the object and stores the playlog.'''
for question in asked_questions:
current_weight = model.get_value(object_id, question)
if not(current_weight): current_weight = 0

new_weight = current_weight + asked_questions[question]
model.update_data(object_id, question, new_weight)

model.update_times_played(object_id)

model.record_playlog(object_id, asked_questions, True)

def load_objects_values():
'''Initializes objects values, a list with an entry for each object, initialized at 0.'''

objects_values = {}
objects = model.get_objects()
for object in objects:
objects_values[object.id] = 0

return objects_values

if __name__ == '__main__':
##### Tests entropy! #####
Expand Down
Loading

0 comments on commit b0003ac

Please sign in to comment.