Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Major <jmikem@bellsouth.net>2009-08-22 02:20:02 (GMT)
committer Mike Major <jmikem@bellsouth.net>2009-08-22 02:20:02 (GMT)
commit9456b125831c9cbc06f340e269c261d9627ac083 (patch)
tree8159c91c201b1e0900d44d50fda5164644096ed3
parentce3a918598a007a9e035f07d5ac163f81a344126 (diff)
Rewritten with MVC; Progressive levels; Tabbed user input.
Levels start at 'rounding to 10' and proceed through the next decades.
-rw-r--r--activity/activity.info2
-rw-r--r--data.py83
-rw-r--r--[-rwxr-xr-x]hoparound.py227
-rw-r--r--view.py115
4 files changed, 248 insertions, 179 deletions
diff --git a/activity/activity.info b/activity/activity.info
index 843f4a5..7abc7f6 100644
--- a/activity/activity.info
+++ b/activity/activity.info
@@ -3,6 +3,6 @@ name = Hop-A-Round
bundle_id = org.laptop.HopaRound
class = hoparound.HopaRoundActivity
icon = hoparound-icon
-activity_version = 6
+activity_version = 7
host_version = 1
show_launcher = yes
diff --git a/data.py b/data.py
new file mode 100644
index 0000000..dd45592
--- /dev/null
+++ b/data.py
@@ -0,0 +1,83 @@
+import random, math
+
+class LevelData():
+ def __init__(self):
+ self.digits = []
+ self.min_level = 1
+ self.max_level = 5
+ self.thresh_up = 6
+ self.thresh_down = 0
+ self.current_level = 1
+ self.level_change = 0
+ self.level_score = 0
+ self.question_max = 6
+ self.question_count = 0
+ self.thresh_slider = 0
+ self.thresh_mult = 2
+ self.thresh_entry = 4
+ random.seed()
+
+ def check_answer(self, response):
+ if response == self.correct_answer:
+ self.level_score += 1
+ else:
+ self.level_score -= 1
+ if self.question_count == self.question_max:
+ if self.level_score >= self.thresh_up and self.current_level < self.max_level:
+ self.level_change = 1
+ elif self.level_score <= self.thresh_down and self.current_level > self.min_level:
+ self.level_change = -1
+ self.question_count = self.level_score = 0
+ return self.correct_answer == response
+
+ def increase_level(self):
+ if self.current_level < self.max_level:
+ self.current_level += 1
+ self.answer_decade = int(10**self.current_level)
+ self.level_change = 0
+
+ def decrease_level(self):
+ if self.current_level > self.min_level:
+ self.current_level -= 1
+ self.answer_decade = int(10**self.current_level)
+ self.level_change = 0
+
+ def gen_random(self):
+ if self.level_change == 1:
+ self.increase_level()
+ elif self.level_change == -1:
+ self.decrease_level()
+ self.question_count += 1
+ # generate a random number. don't use digits 0 or 9; they cause duplicates in the mult choice answer set.
+ self.digits = range(1,9)
+ random.shuffle(self.digits)
+ str_num = ""
+ for x in range(0, self.current_level + 2):
+ str_num += str(random.choice(self.digits))
+ self.random_number = int(str_num)
+ self.answer_decade = int(math.pow(10, self.current_level))
+ self.correct_answer = int(round(self.random_number/(self.answer_decade*1.0), 0) * self.answer_decade)
+ # create the multiple choice possibilities
+ self.mult=[]
+ self.mult.append(int(math.floor(self.random_number/(self.answer_decade*1.0)) * self.answer_decade))
+ self.mult.append(int(math.ceil(self.random_number/(self.answer_decade*1.0)) * self.answer_decade))
+ if self.current_level == self.min_level:
+ self.mult.append(int(math.floor(self.random_number/(self.answer_decade*10.0)) * self.answer_decade * 10.0))
+ self.mult.append(int(math.ceil(self.random_number/(self.answer_decade*10.0)) * self.answer_decade * 10.0))
+ elif self.current_level == self.max_level:
+ self.mult.append(int(math.floor(self.random_number/(self.answer_decade*0.1)) * self.answer_decade * 0.1))
+ self.mult.append(int(math.ceil(self.random_number/(self.answer_decade*0.1)) * self.answer_decade * 0.1))
+ else:
+ factor = random.choice([0.1,10.0])
+ self.mult.append(int(math.floor(self.random_number/(self.answer_decade*factor)) * self.answer_decade * factor))
+ self.mult.append(int(math.ceil(self.random_number/(self.answer_decade*factor)) * self.answer_decade * factor))
+
+ def show_game_data(self):
+ temp = "\nLevel: " + str(self.current_level)
+ #temp += "\nRandom Number: " + str(self.random_number)
+ #temp += "\nDecade: " + str(self.answer_decade)
+ #temp += "\nCorrect Answer: " + str(self.correct_answer)
+ #temp += "\nMult Choices: " + str(self.mult)
+ temp += "\nScore: " + str(self.level_score)
+ temp += "\nCount: " + str(self.question_count)
+ return temp
diff --git a/hoparound.py b/hoparound.py
index 376a063..9d98c5e 100755..100644
--- a/hoparound.py
+++ b/hoparound.py
@@ -1,179 +1,50 @@
-import gtk, math
-import random, locale
+from data import LevelData
+from view import Views
+import gtk, locale
from sugar.activity import activity
-
-class HopaRoundActivity(activity.Activity):
- def __init__(self, handle):
- activity.Activity.__init__(self, handle)
- print "INFO: activity running"
- locale.setlocale(locale.LC_ALL,"")
- # make the toolbox
- toolbox = activity.ActivityToolbox(self)
- self.set_toolbox(toolbox)
- toolbox.show()
- #initialize variables
- print "INFO: initialize variables"
- self.decades = (10,100,1000,10000,100000)
- self.rounded={0:0,1:1,2:2,3:3,4:4,9:0,10:0,11:0,99:0,100:0,101:0,999:0,1000:0,1001:0,9999:0,10000:0,10001:0,99999:0,100000:0,100001:0}
- self.lower_bound = 1
- self.upper_bound = 500000
- self.correct = 0
- self.incorrect = 0
- self.dec_answer = 0
- random.seed()
- self.correct_answer = gtk.gdk.pixbuf_new_from_file("hoppy-right.svg")
- self.incorrect_answer = gtk.gdk.pixbuf_new_from_file("hoppy-wrong.svg")
- self.image_answer = gtk.Image()
- #create view ports
- print "INFO: create view ports"
- self.main_view = gtk.HBox()
- self.panels = gtk.VBox()
- self.panes = gtk.HBox(True)
- self.left_view = gtk.VBox()
- self.mid_view = gtk.VBox()
- self.right_view = gtk.VBox()
- self.instructions = gtk.Label()
- self.instructions.set_justify(gtk.JUSTIFY_LEFT)
- self.instructions.set_markup("\n\nLet's play...")
- self.type_answer_instructions = gtk.Label("Type your answer below")
- self.mult_instructions = gtk.Label("Choose one of the answers below")
- self.answer = gtk.Entry()
- self.answer.set_text("?")
- self.answer.connect("activate", self.check_answer, 0)
- self.play_btn = gtk.Button("Play")
- self.play_btn.connect("clicked", self.play)
- self.check_answer_btn = gtk.Button("Check Answer")
- self.check_answer_btn.connect("clicked", self.check_answer, 0)
- self.mult_1 = gtk.Button()
- self.mult_1.connect("clicked", self.check_answer, 1)
- self.mult_2 = gtk.Button()
- self.mult_2.connect("clicked", self.check_answer, 2)
- self.mult_3 = gtk.Button()
- self.mult_3.connect("clicked", self.check_answer, 3)
- self.mult_4 = gtk.Button()
- self.mult_4.connect("clicked", self.check_answer, 4)
- self.output = gtk.Label()
- self.output.set_justify(gtk.JUSTIFY_LEFT)
- #show the widgets
- print "INFO: show widgets"
- self.main_view.pack_start(self.panels, False, False, 10)
- self.main_view.pack_start(self.right_view, False, False, 10)
- self.panels.pack_start(self.instructions, False, False, 10)
- self.panels.pack_start(self.play_btn, False, False, 10)
- self.panels.pack_start(self.panes, False, False, 10)
- self.panes.pack_start(self.left_view, False, False, 10)
- self.panes.pack_start(self.mid_view, False, False, 10)
- self.left_view.pack_start(self.type_answer_instructions, False, False, 10)
- self.left_view.pack_start(self.answer, False, False, 10)
- self.left_view.pack_start(self.check_answer_btn, False, False, 10)
- self.mid_view.pack_start(self.mult_instructions, False, False, 10)
- self.mid_view.pack_start(self.mult_1, False, False, 10)
- self.mid_view.pack_start(self.mult_2, False, False, 10)
- self.mid_view.pack_start(self.mult_3, False, False, 10)
- self.mid_view.pack_start(self.mult_4, False, False, 10)
- self.right_view.pack_start(self.output, False, False, 10)
- self.right_view.pack_start(self.image_answer, False, False, 10)
- self.set_canvas(self.main_view)
- self.show_all()
- self.play_btn.grab_focus()
-
- def play(self, widget):
- print "INFO: play clicked"
- self.dec_answer = random.choice(self.decades)
- self.gen_random(self)
- self.guesses = 0
- self.answer.set_text("?")
- message = "\nRound the number <b>"
- message += locale.format("%d", self.rounded[0], True)
- message += "</b> to the nearest <b>"
- message += locale.format("%d", self.dec_answer, True)
- message += "</b>:\n"
- self.instructions.set_markup(message)
- self.mult_1.set_label(locale.format("%d", self.rounded[1], True))
- self.mult_2.set_label(locale.format("%d", self.rounded[2], True))
- self.mult_3.set_label(locale.format("%d", self.rounded[3], True))
- self.mult_4.set_label(locale.format("%d", self.rounded[4], True))
- message = "Correct:\t\t" + str(self.correct)
- message += "\nIncorrect:\t" + str(self.incorrect)
- self.image_answer.clear()
- self.output.set_markup(message)
- #self.show_random_numbers(self)
- self.answer.grab_focus()
-
- def check_answer(self, widget, response=None):
- print "INFO: check answer clicked"
- print "INFO: response = '" + str(response) + "'"
- try:
- if response == 0:
- print "INFO: entry = '" + str(self.answer.get_text()) + "'"
- response = int(self.answer.get_text())
- elif response == 1: response = self.rounded[response]
- elif response == 2: response = self.rounded[response]
- elif response == 3: response = self.rounded[response]
- elif response == 4: response = self.rounded[response]
- if response == self.rounded[self.dec_answer]:
- self.correct += 1
- message = "Correct:\t\t" + str(self.correct)
- message += "\nIncorrect:\t" + str(self.incorrect)
- message += "\n\n<b>That's correct!\n\n\n\n</b>"
- self.output.set_markup(message)
- self.image_answer.set_from_pixbuf(self.correct_answer)
- self.instructions.set_markup("\n\nLet's play...")
- self.answer.set_text("?")
- self.play_btn.grab_focus()
- else:
- self.incorrect += 1
- message = "Correct:\t\t" + str(self.correct)
- message += "\nIncorrect:\t" + str(self.incorrect)
- message += "<span foreground=\"red\">\n\n<b>Sorry, the correct answer was\n"
- message += locale.format('%d', self.rounded[self.dec_answer], True)
- message += "\n\nYou answered\n" + str(response)
- message += "</b></span>"
- self.output.set_markup(message)
- self.image_answer.set_from_pixbuf(self.incorrect_answer)
- self.answer.set_text("?")
- self.play_btn.grab_focus()
- except:
- message = "<span foreground=\"red\"><b>Please enter a number only.</b></span>"
- self.output.set_markup(message)
- self.answer.grab_focus()
-
- def gen_random(self, widget):
- print "INFO: generating random number"
- #generate a random number and round it to the different decades
- self.rounded[0] = random.randint(self.lower_bound,self.upper_bound)
- for item in self.decades:
- self.rounded[item-1] = int(math.floor(self.rounded[0]/(item*1.0)) * item)
- self.rounded[item] = int(round(self.rounded[0]/(item*1.0), 0) * item)
- self.rounded[item+1] = int(math.ceil(self.rounded[0]/(item*1.0)) * item)
- #create a list of decades that are not the right answer and choose one
- self.dec_temp_list = [10, 100, 1000, 10000, 100000]
- del self.dec_temp_list[self.dec_temp_list.index(self.dec_answer)]
- self.dec_temp = random.choice(self.dec_temp_list)
- #generate the multiple choice answer set
- self.mult = range(1,5)
- self.mult_temp = random.choice(self.mult)
- self.rounded[self.mult_temp] = self.rounded[self.dec_answer - 1]
- del self.mult[self.mult.index(self.mult_temp)]
- self.mult_temp = random.choice(self.mult)
- self.rounded[self.mult_temp] = self.rounded[self.dec_answer + 1]
- del self.mult[self.mult.index(self.mult_temp)]
- self.mult_temp = random.choice(self.mult)
- self.rounded[self.mult_temp] = self.rounded[self.dec_temp - 1]
- del self.mult[self.mult.index(self.mult_temp)]
- self.mult_temp = random.choice(self.mult)
- self.rounded[self.mult_temp] = self.rounded[self.dec_temp + 1]
-
- def show_random_numbers(self, widget):
- print "INFO: showing random numbers"
- message = "Lower Bound: \t\t\t<b>" + str(self.lower_bound) + "</b>"
- message += "\n\nUpper Bound: \t\t\t<b>" + str(self.upper_bound) + "</b>"
- message += "\n\nNumber Generated: \t<b>" + str(self.rounded[0]) + "</b>"
- message += "\n"
- for item in self.rounded:
- #1message += "\n\nRounded to 10<sup>" + str(int(math.log10(item))) + "</sup>: \t\t<b>" + str(self.rounded[item]) + "</b>"
- #2message += str(item-1) + ": \t" + str(self.rounded[item-1]) + "\n"
- #2message += str(item) + ": \t" + str(self.rounded[item]) + "\n"
- #2message += str(item+1) + ": \t" + str(self.rounded[item+1]) + "\n"
- message += str(item) + ":\t" + str(self.rounded[item]) + "\n"
- self.output.set_markup(message)
+import locale
+
+class HopaRoundActivity(activity.Activity):
+ def __init__(self, handle):
+ activity.Activity.__init__(self, handle)
+ # make the toolbox
+ toolbox = activity.ActivityToolbox(self)
+ self.set_toolbox(toolbox)
+ toolbox.show()
+ self.data = LevelData()
+ self.ui = Views()
+ self.ui.slider_click.connect("clicked", self.submit_answer, self.ui.slider_tool)
+ self.ui.mult_1.connect("clicked", self.submit_answer, self.ui.mult_1)
+ self.ui.mult_2.connect("clicked", self.submit_answer, self.ui.mult_2)
+ self.ui.mult_3.connect("clicked", self.submit_answer, self.ui.mult_3)
+ self.ui.mult_4.connect("clicked", self.submit_answer, self.ui.mult_4)
+ self.ui.entry_click.connect("clicked", self.submit_answer, self.ui.entry_tool)
+ self.ui.entry_tool.connect("activate", self.submit_answer, self.ui.entry_tool)
+ self.setup(self.data, self.ui)
+ #sugar canvas
+ self.set_canvas(self.ui.get_user_interaction())
+ self.show_all()
+
+ def setup(self, data, ui):
+ data.gen_random()
+ ui.set_rounding_phrase(self.data)
+ ui.set_choices(self.data.random_number, self.data.mult)
+ ui.set_tab(self.data)
+
+ def submit_answer(self, widget, answer):
+ try: # for int answer because of entry field
+ if answer.get_name() == "GtkHScale":
+ num = int(answer.get_value())
+ elif answer.get_name() == "GtkButton":
+ num = locale.atoi(answer.get_label())
+ elif answer.get_name() == "GtkEntry":
+ num = locale.atoi(answer.get_text())
+ except:
+ self.ui.answer_nan()
+ else:
+ if self.data.check_answer(num):
+ self.ui.answer_correct(self.data)
+ else:
+ self.ui.answer_incorrect(self.data)
+ self.setup(self.data, self.ui)
+
diff --git a/view.py b/view.py
new file mode 100644
index 0000000..7b8bdbb
--- /dev/null
+++ b/view.py
@@ -0,0 +1,115 @@
+import gtk, random
+import locale
+
+class Views():
+ def __init__(self):
+ locale.setlocale(locale.LC_ALL,"")
+ self.user_interaction = gtk.HBox()
+ self.user_input = gtk.VBox()
+ self.user_interaction.pack_start(self.user_input, False, False, 10)
+ self.rounding_phrase = gtk.Label("rounding phrase")
+ self.user_input.pack_start(self.rounding_phrase, False, False, 10)
+ #create the notebook
+ self.tabber = gtk.Notebook()
+ self.tabber.set_show_tabs(False)
+ self.user_input.pack_start(self.tabber, False, False, 10)
+ #create the slider tab
+ self.slider_tab = gtk.VButtonBox()
+ self.slider_instruction = gtk.Label("Move the slider to choose the correct answer")
+ self.slider_tab.pack_start(self.slider_instruction, False, False, 10)
+ self.slider_adjustment = gtk.Adjustment()
+ self.slider_tool = gtk.HScale(self.slider_adjustment)
+ self.slider_tool.set_digits(0)
+ self.slider_tab.pack_start(self.slider_tool, False, False, 10)
+ self.slider_click = gtk.Button("OK")
+ self.slider_tab.pack_start(self.slider_click, False, False, 10)
+ self.tabber.append_page(self.slider_tab)
+ #create the multiple choice tab
+ self.mult_tab = gtk.VBox()
+ self.mult_instruction = gtk.Label("Choose one of the answers below")
+ self.mult_tab.pack_start(self.mult_instruction, False, False, 10)
+ self.mult_1 = gtk.Button()
+ self.mult_tab.pack_start(self.mult_1, False, False, 10)
+ self.mult_2 = gtk.Button()
+ self.mult_tab.pack_start(self.mult_2, False, False, 10)
+ self.mult_3 = gtk.Button()
+ self.mult_tab.pack_start(self.mult_3, False, False, 10)
+ self.mult_4 = gtk.Button()
+ self.mult_tab.pack_start(self.mult_4, False, False, 10)
+ self.tabber.append_page(self.mult_tab)
+ #create the entry tab
+ self.entry_tab = gtk.VButtonBox()
+ self.entry_instruction = gtk.Label("Type your answer below and click 'OK'")
+ self.entry_tab.pack_start(self.entry_instruction, False, False, 10)
+ self.entry_tool = gtk.Entry()
+ self.entry_tab.pack_start(self.entry_tool, False, False, 10)
+ self.entry_click = gtk.Button("OK")
+ self.entry_tab.pack_start(self.entry_click, False, False, 10)
+ self.tabber.append_page(self.entry_tab)
+ #create the output
+ self.user_output = gtk.VBox()
+ self.user_interaction.pack_start(self.user_output, False, False, 10)
+ self.output = gtk.Label("")
+ self.output.set_alignment(0.1, 0.5)
+ self.user_output.pack_start(self.output, False, False, 10)
+ self.image_output = gtk.Image()
+ self.user_output.pack_start(self.image_output, False, False, 10)
+ self.image_correct_answer = gtk.gdk.pixbuf_new_from_file("hoppy-right.svg")
+ self.image_incorrect_answer = gtk.gdk.pixbuf_new_from_file("hoppy-wrong.svg")
+
+ def get_user_interaction(self):
+ return self.user_interaction
+
+ def set_rounding_phrase(self, data):
+ text = "Round the number <b>"
+ text += self.locl(data.random_number)
+ text += "</b> to the nearest <b>"
+ text += self.locl(data.answer_decade) + "</b>"
+ self.rounding_phrase.set_markup(text)
+
+ def set_choices(self, number, choices):
+ self.slider_adjustment.set_all(number, choices[0], choices[1], 1)
+ # shuffle around the possibilities
+ random.shuffle(choices)
+ self.mult_1.set_label(self.locl(choices[0]))
+ self.mult_2.set_label(self.locl(choices[1]))
+ self.mult_3.set_label(self.locl(choices[2]))
+ self.mult_4.set_label(self.locl(choices[3]))
+ self.entry_tool.set_text("")
+
+ def answer_correct(self, data):
+ text = "<span foreground=\"dark green\"><b>That's Right!!! =8-) </b></span> \n\n"
+ text += self.locl(data.random_number) + " rounded to the nearest "
+ text += self.locl(data.answer_decade) + " is " + self.locl(data.correct_answer)
+ if data.level_change:
+ text += "\n\n<span foreground=\"dark green\"><b>You made it to the next level! =8^P</b></span>"
+ text += "\n" #+ data.show_game_data()
+ self.output.set_markup(text)
+ self.image_output.set_from_pixbuf(self.image_correct_answer)
+
+ def answer_incorrect(self, data):
+ text = "<span foreground=\"red\"><b>Sorry Charlie >:( </b></span> \n\n"
+ text += self.locl(data.random_number) + " rounded to the nearest "
+ text += self.locl(data.answer_decade) + " is " + self.locl(data.correct_answer)
+ if data.level_change:
+ text += "\n\n<span foreground=\"red\"><b>You dropped a level. Concentrate! >8^|</b></span>"
+ text += "\n" #+ data.show_game_data()
+ self.output.set_markup(text)
+ self.image_output.set_from_pixbuf(self.image_incorrect_answer)
+
+ def answer_nan(self):
+ text = "<span foreground=\"blue\"><b>Please enter only numbers.</b></span> \n\n"
+ self.output.set_markup(text)
+
+ def set_tab(self, data):
+ if data.question_count > data.thresh_entry:
+ self.tabber.set_current_page(2)
+ self.entry_tool.grab_focus()
+ elif data.question_count > data.thresh_mult:
+ self.tabber.set_current_page(1)
+ elif data.question_count > data.thresh_slider:
+ self.tabber.set_current_page(0)
+ self.slider_tool.grab_focus()
+
+ def locl(self, characters):
+ return str(locale.format("%d", characters, True))