예제 #1
0
    def _find(self, column, threshold):
        # 记录所有可能出现的feature,以供后边统计字典中该feature出现的次数
        # find all the feature , prepare for calculating the count that the feature appears
        column_list = self.raw_data[:, column]
        pre_dict = {}
        end_dict = {}
        start = time.clock()
        for i in range(self.row_number):
            for j in range(i + 1, self.row_number):
                pre_pattern = PatternHelper.find_pre_common_str(
                    column_list[i], column_list[j])
                end_pattern = PatternHelper.find_end_common_str(
                    column_list[i], column_list[j])
                if pre_pattern != '':
                    DictHelper.increase_dic_key(pre_dict, pre_pattern)
                    self.cell_pre_patterns[i][column].append(pre_pattern)
                    self.cell_pre_patterns[j][column].append(pre_pattern)
                if end_pattern != '':
                    DictHelper.increase_dic_key(end_dict, end_pattern)
                    self.cell_end_patterns[i][column].append(end_pattern)
                    self.cell_end_patterns[j][column].append(end_pattern)
        print("find1 : {0}".format(time.clock() - start))

        pre_list = [
            key for key, value in pre_dict.items() if value > threshold
        ]
        end_list = [
            key for key, value in end_dict.items() if value > threshold
        ]
        return pre_list, end_list
예제 #2
0
 def update_probability_dict(dict_file, new_dict_file_list):
     probability_dict = StoreHelper.load_data(dict_file, {})
     for dict_file in new_dict_file_list:
         new_dict = StoreHelper.load_data(dict_file, {})
         print("Get %s with records: %i" % (dict_file, len(new_dict)))
         DictHelper.update_dict(probability_dict, new_dict)
     StoreHelper.store_data(probability_dict, dict_file)
예제 #3
0
 def split_dict():
     phase_dict = StoreHelper.load_data("phase_dict.dat", {})
     phase_dict_single = {}
     phase_dict_double = {}
     for key, value in phase_dict.items():
         if '_' in key:
             phase_dict_double[key] = value
         else:
             phase_dict_single[key] = value
     StoreHelper.save_file(DictHelper.get_sorted_list(phase_dict_single), 'phase_dict_single.txt')
     StoreHelper.save_file(DictHelper.get_sorted_list(phase_dict_double), 'phase_dict_double.txt')
예제 #4
0
 def score_column_candidate(self, column, recover_list, small_pattern_list):
     score_dict = {}
     for candidate in recover_list[column]:
         candidate_small_pattern = self.train.get_small_pattern(
             candidate, column)
         for j in range(self.column_number_test):
             if len(recover_list[j]) == 1 and self.train.vote_for_column(
                     column, candidate_small_pattern, j,
                     small_pattern_list[j]):  # can be a judge
                 DictHelper.increase_dic_key(score_dict, candidate)
     return score_dict
예제 #5
0
 def merge_dict():
     profile_dict_list = StoreHelper.load_data(
         '../resource/convert_profile.dat', [])
     merged_list = []
     for profile_dict in profile_dict_list:
         merged_dict = {}
         for feature in profile_dict:
             for key in profile_dict[feature]:
                 DictHelper.increase_dic_key(merged_dict, key)
         merged_list.append(merged_dict)
     StoreHelper.store_data(merged_list, '../resource/merged_profile.dat')
     StoreHelper.save_file(merged_list, '../resource/merged_profile.txt')
예제 #6
0
 def generate_probability_dict(file_content_list):
     # statistics single word and continue two words
     single_word_dict = {}
     two_word_dict = {}
     for file_content in file_content_list:
         for line in file_content.splitlines():
             word_list = SegmentHelper.segment_text(line)
             if len(word_list) == 1:
                 DictHelper.increase_dic_key(single_word_dict, word_list[0])
             else:
                 for i in range(len(word_list) - 1):
                     DictHelper.increase_dic_key(single_word_dict,
                                                 word_list[i])
                     DictHelper.increase_dic_key(
                         two_word_dict,
                         "%s %s" % (word_list[i], word_list[i + 1]))
                 DictHelper.increase_dic_key(single_word_dict,
                                             word_list[-1])
     # compute two word probability
     prob_a_b_dict = {}
     for words, count in two_word_dict.items():
         word_a, word_b = words.split(' ')
         pro_a_b = two_word_dict[words] * 1.0 / single_word_dict[word_b]
         pro_b_a = two_word_dict[words] * 1.0 / single_word_dict[word_a]
         prob_a_b_dict[words] = max(pro_a_b, pro_b_a)
     return prob_a_b_dict
예제 #7
0
 def _add_and_remove(self, words_dict):
     for words, count in words_dict.items():
         if words in self.phrase_dict:
             if self.phrase_dict[words] < count:
                 DictHelper.increase_dic_key(
                     self.phrase_dict, words,
                     count - self.phrase_dict[words])
                 self._count_down_single_word(
                     words, count - self.phrase_dict[words])
             elif self.phrase_dict[words] > count:
                 print(
                     "Warning: phrase match times little than origin split: %s"
                     % words)
         else:
             DictHelper.increase_dic_key(self.phrase_dict, words, count)
             self._count_down_single_word(words, count)
예제 #8
0
    def sorted_data_by_row(csv_columns, data_list, sort_data_row, escape_first):
        # step 1, parameters check
        if sort_data_row >= len(data_list):
            print ("Sort row large than the data row!")
            return

        # step 2, construct data structure
        new_csv_column = csv_columns[: escape_first]
        new_data_list = [row[: escape_first] for row in data_list]
        data_dict = {}
        # For each column
        for column in range(escape_first, len(csv_columns)):
            # Get the column data for each rwo
            data_column = [data_list[row][column] for row in range(len(data_list))]
            key_for_sort = float(data_list[sort_data_row][column])
            while key_for_sort in data_dict:
                key_for_sort += random.randint(0, 100) * 0.000000001
            data_dict[key_for_sort] = (csv_columns[column], data_column)

        # step 3, sorted by key
        sorted_list = DictHelper.get_sorted_list(data_dict, sorted_by_key=True)
        print (sorted_list)
        for key_for_sort, csv_data in sorted_list:
            new_csv_column.append(csv_data[0])
            for row in range(len(new_data_list)):
                new_data_list[row].append(csv_data[1][row])
        return new_csv_column, new_data_list
예제 #9
0
 def get_combine_company_dict(store_data_file):
     company_dict = {}
     for tab in range(2):
         header, raw_data = ExcelHelper.read_excel('../resource/us_list_company2.xlsx', tab)
         row, column = raw_data.shape
         for i in range(row):
             company_name = SegmentHelper.normalize(str(raw_data[i][0]).strip())
             if len(company_name) > 0:
                 DictHelper.increase_dic_key(company_dict, raw_data[i][0])
     df = pd.read_csv('../resource/us_list_company_1.csv')
     name_serial = df['Name']
     for i in range(df.shape[0]):
         company_name = SegmentHelper.normalize(name_serial[i])
         if len(company_name) > 0:
             DictHelper.increase_dic_key(company_dict, name_serial[i])
     StoreHelper.store_data(company_dict, store_data_file)
예제 #10
0
 def get_dict_pattern(context, _dict, convert=True):
     match_result = {}
     for key in _dict.keys():
         key_split = key.split(' ')
         if len(key_split) >= 3 and key_split[1] == '...':
             match_times = len(
                 re.findall(
                     re.escape(key_split[0]) + r'( \w+){0,5} ' +
                     re.escape(' '.join(key_split[2:])), context))
         else:
             key = key.strip()
             match_times = len(
                 re.findall(r'\b' + re.escape(key) + r'\b', context))
         if match_times > 0:
             if convert is True and type(_dict[key]) is not int:
                 DictHelper.increase_dic_key(match_result, _dict[key],
                                             match_times)
             else:
                 DictHelper.increase_dic_key(match_result, key, match_times)
     return match_result
예제 #11
0
 def print_label(label, index_list, cluster_number=None):
     if cluster_number is None:
         label_dict = DictHelper.dict_from_count_list(label)
         print("\t".join([str(i) for i in label]))
         print(label_dict)
         print("max cluster number: %i" % max(label_dict))
         print("min cluster number: %i" % min(label_dict))
         position_tag = {}
         for i in range(len(label)):
             DictHelper.append_dic_key(position_tag, label[i],
                                       int(index_list[i]))
         for key, value in position_tag.items():
             print("%s: %s" % (key, value))
         StoreHelper.store_data(position_tag, 'position_tag.dat')
         StoreHelper.save_file(position_tag, 'position_tag.txt')
     else:
         length = len(label)
         clusters = [[str(j) for j in range(length) if label[j] == i]
                     for i in range(cluster_number)]
         for i in range(len(clusters)):
             print("Cluster %i has %i position, position: %s" %
                   (i, len(clusters[i]), str(clusters[i])))
예제 #12
0
 def _get_working_year_words(self, year_convert_file=None):
     year_list = TextHelper.get_years_pattern(self.raw_position)
     if len(year_list) == 0:
         default_year_requirement = "[0]"
         self.new_words_list.append(default_year_requirement)
         year_list = [default_year_requirement]
     elif year_convert_file is not None:
         year_convert_dict = StoreHelper.load_data(year_convert_file, {})
         year_list = [
             year_convert_dict[item] for item in year_list
             if item in year_convert_dict
         ]
     return DictHelper.dict_from_count_list(year_list)
예제 #13
0
 def convert(self, skill_dict, discipline_dict, education_dict,
             responsibility_dict, year_convert_file):
     year_phase_dict = self._get_working_year_words(year_convert_file)
     skill_phase_dict = self._get_skill_words(skill_dict)
     discipline_phase_dict = self._get_discipline_words(discipline_dict)
     education_phase_dict = self._get_education_words(education_dict)
     responsibility_phase_dict = self._get_responsibility_words(
         responsibility_dict)
     self._add_and_remove(year_phase_dict)
     self._add_and_remove(skill_phase_dict)
     self._add_and_remove(discipline_phase_dict)
     self._add_and_remove(education_phase_dict)
     self._add_and_remove(responsibility_phase_dict)
     for word in self.new_words_list:
         DictHelper.increase_dic_key(self.phrase_dict, word)
     result_dict = {
         "education": education_phase_dict.keys(),
         "major": discipline_phase_dict.keys(),
         "skills": skill_phase_dict.keys(),
         "working-year": year_phase_dict.keys(),
         "responsibility": responsibility_phase_dict.keys()
     }
     return result_dict
예제 #14
0
 def convert_university(profile, convert_dict, debug=False):
     university_list = profile['university']
     if len(university_list) == 0:
         return None
     university_list = [
         SegmentHelper.normalize(university)
         for university in university_list
     ]
     for university in university_list:
         convert_name = DictHelper.find_in_key(convert_dict, university)
         if convert_name is not None:
             if debug:
                 print("%s ==> %s" % (university, convert_name))
             return convert_dict[convert_name]
     return university_list[0]
    def init(self):
        Logger.instance().log_debug("PostPhotoScene.init");
        self._config_filename = scene_manager.SceneManager.instance().get_postphoto_scene_filename();

        #Validate the configuration.
        config_info = config_validation.validate("PostPhotoScene",
                                                 self._config_filename,
                                                 PostPhotoScene._REQUIRED_KEYS);
        self._config_contents = DictHelper(config_info);

        #Init the UI.
        self._init_static_sprites();
        self._init_photo_sprite();
        self._init_frame_sprite();
        self._init_buttons();
예제 #16
0
    def init(self):
        Logger.instance().log_debug("CameraScene.init");
        self._config_filename = scene_manager.SceneManager.instance().get_camera_scene_filename();

        #Validate the configuration.
        config_dict = config_validation.validate("CameraScene",
                                                 self._config_filename,
                                                 CameraScene._REQUIRED_KEYS);
        self._config_contents = DictHelper(config_dict);


        #Init the UI.
        self._init_static_sprites();
        self._init_camera_sprite();
        self._init_frame_sprite();
        self._init_buttons();
        self._init_countdown_sprite();
예제 #17
0
    def _get_full_relation(self, column1, column2, row):
        # for pre pattern
        cell1_patterns = self.cell_pre_patterns[row][column1]
        cell2_patterns = self.cell_pre_patterns[row][column2]
        for pattern1 in cell1_patterns:
            for pattern2 in cell2_patterns:
                DictHelper.increase_dic_key(
                    self.pre_pattern_relation[column1][column2],
                    pattern1 + "|" + pattern2)
                DictHelper.increase_dic_key(
                    self.pre_pattern_relation[column2][column1],
                    pattern2 + "|" + pattern1)

        # for end pattern
        cell1_patterns = self.cell_end_patterns[row][column1]
        cell2_patterns = self.cell_end_patterns[row][column2]
        for pattern1 in cell1_patterns:
            for pattern2 in cell2_patterns:
                DictHelper.increase_dic_key(
                    self.end_pattern_relation[column1][column2],
                    pattern1 + "|" + pattern2)
                DictHelper.increase_dic_key(
                    self.end_pattern_relation[column2][column1],
                    pattern2 + "|" + pattern1)
예제 #18
0
 def __init__(self, raw_position, word_list=[]):
     self.raw_position = raw_position.lower()
     self.word_list = word_list
     self.phrase_dict = DictHelper.dict_from_count_list(self.word_list)
     self.new_words_list = []
예제 #19
0
 def _count_down_single_word(self, words, decrease_value=1):
     word_list = [word for word in words.split(' ') if len(word) > 0]
     for word in word_list:
         DictHelper.decrease_dic_key(self.phrase_dict, word, decrease_value)
예제 #20
0
 def convert_2(self, probability_dict):
     year_phase_list = self._get_working_year_words()
     phrase_list = self._remove_conjunction_segment(probability_dict)
     phrase_list.extend(year_phase_list)
     return DictHelper.dict_from_count_list(phrase_list)
예제 #21
0
 def _collect_words_dict(self):
     result_dict = {}
     for _dict in self.blob_dict_list:
         for key in _dict.keys():
             DictHelper.increase_dic_key(result_dict, key)
     return result_dict
예제 #22
0
            url_list.extend(
                CrawlHelper.extract_job_id_list(
                    CrawlHelper.get_web_source(web_url)))
        return url_list

    @staticmethod
    def get_all_job_post(url_file, post_file):
        post_info_list = []
        for url in StoreHelper.load_data(url_file, {}):
            web_content = CrawlHelper.get_web_source(url)
            post_info_list.append((url, web_content))
        StoreHelper.store_data(post_info_list, post_file)


if __name__ == '__main__':
    raw_dict = DictHelper.load_dict_from_excel(
        "../resource/linkedin_geography.xlsx")
    us_geography = DictHelper.generate_geography_dic(raw_dict, 'na.us', 1)
    print(us_geography)
    continue_failed = 0
    escape = 2
    for key, value in us_geography.items():
        if escape > 0:
            escape -= 1
            continue
        status = CrawlHelper.crawl_post_information(
            "../data/%s.ids.dat" % key.encode('utf-8'),
            "../data/post/%s.dat" % key.encode('utf-8'))
        if status is False:
            continue_failed += 1
            if continue_failed >= 2:
                print("Program exit! Maybe robot identified!")
예제 #23
0
 def get_frequency_dict(content):
     words_list = []
     for line in content.splitlines():
         words_list.extend(
             SegmentHelper.lemmatization(SegmentHelper.segment_text(line)))
     return DictHelper.dict_from_count_list(words_list)
예제 #24
0
class CameraScene(BaseScene):
    ############################################################################
    ## Constants                                                              ##
    ############################################################################
    #Required Keys.
    _KEY_CAMERA_PLACEHOLDER_SPRITE = "camera_placeholder";
    _KEY_CAMERA_FRAME_SPRITE       = "camera_frame";
    _KEY_TAKEPHOTO_BUTTON          = "take_photo";
    _KEY_STATIC_SPRITES            = "static_sprites";
    _KEY_COUNTDOWN_SPRITES         = "countdown";

    _REQUIRED_KEYS = [
        _KEY_CAMERA_PLACEHOLDER_SPRITE,
        _KEY_CAMERA_FRAME_SPRITE,
        _KEY_TAKEPHOTO_BUTTON,
        _KEY_STATIC_SPRITES,
        _KEY_COUNTDOWN_SPRITES,
    ];

    #How much time each countdown step will take (in ms).
    _COUNTDOWN_CLOCK_TIME = 10;

    #Layers.
    _LAYER_INDEX_STATIC_SPRITE    = 1;
    _LAYER_INDEX_CAMERA_SPRITE    = 2;
    _LAYER_INDEX_FRAME_SPRITE     = 3;
    _LAYER_INDEX_PHOTO_BUTTON     = 4;
    _LAYER_INDEX_COUNTDOWN_SPRITE = 5;


    ############################################################################
    ## CTOR                                                                   ##
    ############################################################################
    def __init__(self):
        BaseScene.__init__(self);

        ## iVars ##
        #Filenames and Content.
        self._config_filename = None;
        self._config_contents = None;

        #UI Elements.
        self._countdown_sprite  = None;
        self._camera_sprite     = None;
        self._frame_sprite      = None;
        self._take_photo_button = None;

        #Countdown clock.
        self._countdown_clock = BasicClock(CameraScene._COUNTDOWN_CLOCK_TIME,
                                           self._on_countdown_timer_tick);

        self._camera_sprite_size = None;


    ############################################################################
    ## Overriden Methods                                                      ##
    ############################################################################
    def start(self):
        Logger.instance().log_debug("CameraScene.start");

    def end(self):
        Logger.instance().log_debug("CameraScene.end");


    ############################################################################
    ## Init                                                                   ##
    ############################################################################
    def init(self):
        Logger.instance().log_debug("CameraScene.init");
        self._config_filename = scene_manager.SceneManager.instance().get_camera_scene_filename();

        #Validate the configuration.
        config_dict = config_validation.validate("CameraScene",
                                                 self._config_filename,
                                                 CameraScene._REQUIRED_KEYS);
        self._config_contents = DictHelper(config_dict);


        #Init the UI.
        self._init_static_sprites();
        self._init_camera_sprite();
        self._init_frame_sprite();
        self._init_buttons();
        self._init_countdown_sprite();


    def _init_static_sprites(self):
        sprite_list = self._config_contents.value_or_die(CameraScene._KEY_STATIC_SPRITES);
        for info in sprite_list:
            #Create the sprite.
            sprite = Sprite();

            #Set the sprite properties.
            sprite.load_image  (info["image"   ]);
            sprite.set_position(info["position"]);

            self._background_sprite = sprite;
            #Add to scene.
            self.add(sprite, layer = CameraScene._LAYER_INDEX_STATIC_SPRITE);

    def _init_camera_sprite(self):
        #Initialize the sprite.
        self._camera_sprite = Sprite();

        #Get the info.
        info = self._config_contents.value_or_die(CameraScene._KEY_CAMERA_PLACEHOLDER_SPRITE);

        #Set the sprite properties.
        self._camera_sprite.load_image  (info["image"   ]);
        self._camera_sprite.set_position(info["position"]);

        #Add to scene.
        self.add(self._camera_sprite,
                 layer = CameraScene._LAYER_INDEX_CAMERA_SPRITE);

        self._camera_sprite_size = self._camera_sprite.get_size();

    def _init_frame_sprite(self):
        #Get the info.
        info = self._config_contents.value_or_die(CameraScene._KEY_CAMERA_FRAME_SPRITE);

        #Don't need the frame...
        if(info == False):
            return;

        #Init the sprite.
        self._frame_sprite = Sprite();

        #Set the sprite properties.
        self._frame_sprite.load_image(info["image"]);
        self._frame_sprite.set_position(info["position"]);

        #Frame isn't same size of camera image, so scale it.
        if(self._frame_sprite.get_size() != self._camera_sprite_size):
            frame_image  = self._frame_sprite.image;
            scaled_image = pygame.transform.scale(frame_image,
                                                  self._camera_sprite_size);

            self._frame_sprite.update_image(scaled_image);


        #Add to scene.
        self.add(self._frame_sprite,
                 layer = CameraScene._LAYER_INDEX_FRAME_SPRITE);

    def _init_buttons(self):
        #Initialize the button.
        self._take_photo_button = Button();

        #Get the info.
        info = self._config_contents.value_or_die(CameraScene._KEY_TAKEPHOTO_BUTTON);

        #Set the button properties.
        self._take_photo_button.load_images(info["normal_image"],
                                            info["pressed_image"]);

        self._take_photo_button.set_position(info["position"]);

        self._take_photo_button.set_click_callback(self._on_take_photo_button_pressed);

        #Add to scene.
        self.add(self._take_photo_button,
                 layer = CameraScene._LAYER_INDEX_PHOTO_BUTTON);

    def _init_countdown_sprite(self):
        #Initialize the Sprite.
        self._countdown_sprite = Sprite();

        #Get the info.
        info = self._config_contents.value_or_die(CameraScene._KEY_COUNTDOWN_SPRITES);

        #Set the sprite properties.
        self._countdown_sprite.set_position(info["position"]);
        self._countdown_sprite.load_image(info["sprites"][0]);

        #Countdown is hidden by default.


    ############################################################################
    ## Update / Draw / Handle Events Methods                                  ##
    ############################################################################
    def update(self, dt):
        self._countdown_clock.update(dt);
        img = Camera.instance().get_frame(scale_to = self._camera_sprite_size);
        self._camera_sprite.update_image(img);

    def handle_events(self, event):
        self._take_photo_button.handle_events(event);


    ############################################################################
    ## Button Callbacks                                                       ##
    ############################################################################
    def _on_take_photo_button_pressed(self):
        #Set the UI Elements visibility.
        self.remove(self._take_photo_button);
        self.add(self._countdown_sprite,
                 layer = CameraScene._LAYER_INDEX_COUNTDOWN_SPRITE);

        #Start the countdown...
        self._countdown_clock.start();


    ############################################################################
    ## Timer Callbacks                                                        ##
    ############################################################################
    def _on_countdown_timer_tick(self):
        #Get the info.
        info = self._config_contents.value_or_die(CameraScene._KEY_COUNTDOWN_SPRITES);

        sprites_list = info["sprites"];
        index        = self._countdown_clock.get_ticks_count();

        #Check if have more countdown images to show...
        if(index < len(sprites_list)):
            self._countdown_sprite.load_image(sprites_list[index]);
        else:
            #Reset the image to the first frame and inform that
            #the countdown is done.
            self._countdown_sprite.load_image(sprites_list[0]);
            self._countdown_timer_finished();


    ############################################################################
    ## Other Methods                                                          ##
    ############################################################################
    def _countdown_timer_finished(self):
        #Set the UI Elements visibility.
        self.remove(self._countdown_sprite);
        self.add(self._take_photo_button,
                 layer = CameraScene._LAYER_INDEX_PHOTO_BUTTON);

        #Stop the countdown...
        self._countdown_clock.stop();

        #Call the Camera to grab a photo.
        Camera.instance().take_photo();

        #Go to another scene.
        scene_mgr = scene_manager.SceneManager;
        scene_mgr.instance().scene_is_complete(scene_mgr.SCENE_NAME_POSTPHOTO);
class PostPhotoScene(BaseScene):
    ############################################################################
    ## Constants                                                              ##
    ############################################################################
    #Required Keys.
    _KEY_PHOTO_PLACEHOLDER_SPRITE = "photo_placeholder";
    _KEY_PHOTO_FRAME_SPRITE       = "photo_frame";
    _KEY_STATIC_SPRITES           = "static_sprites";

    _KEY_ACCEPT_BUTTON = "accept_button";
    _KEY_REJECT_BUTTON = "reject_button";

    _REQUIRED_KEYS = [
        _KEY_PHOTO_PLACEHOLDER_SPRITE,
        _KEY_PHOTO_FRAME_SPRITE,
        _KEY_STATIC_SPRITES,

        _KEY_ACCEPT_BUTTON,
        _KEY_REJECT_BUTTON,
    ];

    #Layers.
    _LAYER_INDEX_STATIC_SPRITE = 1;
    _LAYER_INDEX_CAMERA_SPRITE = 2;
    _LAYER_INDEX_FRAME_SPRITE  = 3;
    _LAYER_INDEX_BUTTONS       = 4;


    ############################################################################
    ## CTOR                                                                   ##
    ############################################################################
    def __init__(self):
        BaseScene.__init__(self);

        ## iVars ##
        #Filenames and Content.
        self._config_filename = None;
        self._config_contents = None;

        #UI Elements.
        self._accept_button = None;
        self._reject_button = None;

        self._photo_sprite  = None;
        self._frame_sprite  = None;


    ############################################################################
    ## Overriden Methods                                                      ##
    ############################################################################
    def start(self):
        Logger.instance().log_debug("PostPhotoScene.start");

        #Update the placeholder image to the last photo taken by camera.
        placeholder_size = self._photo_sprite.get_size();
        last_photo = Camera.instance().get_last_photo(scale_to = placeholder_size);
        self._photo_sprite.update_image(last_photo);

    def end(self):
        Logger.instance().log_debug("PostPhotoScene.end");


    ############################################################################
    ## Init                                                                   ##
    ############################################################################
    def init(self):
        Logger.instance().log_debug("PostPhotoScene.init");
        self._config_filename = scene_manager.SceneManager.instance().get_postphoto_scene_filename();

        #Validate the configuration.
        config_info = config_validation.validate("PostPhotoScene",
                                                 self._config_filename,
                                                 PostPhotoScene._REQUIRED_KEYS);
        self._config_contents = DictHelper(config_info);

        #Init the UI.
        self._init_static_sprites();
        self._init_photo_sprite();
        self._init_frame_sprite();
        self._init_buttons();


    def _init_static_sprites(self):
        sprite_list = self._config_contents.value_or_die(PostPhotoScene._KEY_STATIC_SPRITES);
        for info in sprite_list:
            #Create the sprite.
            sprite = Sprite();

            #Set the sprite properties.
            sprite.load_image  (info["image"   ]);
            sprite.set_position(info["position"]);

            #Add to scene.
            self.add(sprite, layer = PostPhotoScene._LAYER_INDEX_STATIC_SPRITE);

    def _init_photo_sprite(self):
        #Get the info.
        info = self._config_contents.value_or_die(PostPhotoScene._KEY_PHOTO_PLACEHOLDER_SPRITE);

        #Create the sprite.
        self._photo_sprite = Sprite();

        #Set the sprite properties.
        self._photo_sprite.load_image  (info["image"  ]);
        self._photo_sprite.set_position(info["position"]);

        #Add to scene.
        self.add(self._photo_sprite,
                 layer = PostPhotoScene._LAYER_INDEX_CAMERA_SPRITE);

    def _init_frame_sprite(self):
        #Get the info.
        info = self._config_contents.value_or_die(PostPhotoScene._KEY_PHOTO_FRAME_SPRITE);

        #Don't need the frame...
        if(info == False):
            return;

        #Init the sprite.
        self._frame_sprite = Sprite();

        #Set the sprite properties.
        self._frame_sprite.load_image  (info["image"   ]);
        self._frame_sprite.set_position(info["position"]);

        #Frame isn't same size of camera image, so scale it.
        photo_sprite_size = self._photo_sprite.get_size();
        if(self._frame_sprite.get_size() != photo_sprite_size):
            frame_image  = self._frame_sprite.image;
            scaled_image = pygame.transform.scale(frame_image,
                                                  photo_sprite_size);

            self._frame_sprite.update_image(scaled_image);

        #Add to scene.
        self.add(self._frame_sprite,
                 layer = PostPhotoScene._LAYER_INDEX_FRAME_SPRITE);

    def _init_buttons(self):
        ## Initialize the Accept and Reject Buttons. ##
        #Get the infos.
        accept_info = self._config_contents.value_or_die(PostPhotoScene._KEY_ACCEPT_BUTTON);
        reject_info = self._config_contents.value_or_die(PostPhotoScene._KEY_REJECT_BUTTON);

        #Initialize the buttons.
        self._accept_button = self._create_button_helper(accept_info,
                                                         self._on_accept_button_pressed);

        self._reject_button = self._create_button_helper(reject_info,
                                                         self._on_reject_button_pressed);


    def _create_button_helper(self, info, callback):
        button = Button();

        #Images.
        button.load_images(info["normal_image"],
                           info["pressed_image"]);
        #Position.
        button.set_position(info["position"]);
        #Callback.
        button.set_click_callback(callback);

        #Add to scene.
        self.add(button, layer = PostPhotoScene._LAYER_INDEX_BUTTONS);

        return button;

    ############################################################################
    ## Update / Draw / Handle Events                                          ##
    ############################################################################
    def handle_events(self, event):
        #Those buttons are *always* present.
        self._accept_button.handle_events(event);
        self._reject_button.handle_events(event);


    ############################################################################
    ## Button Callbacks                                                       ##
    ############################################################################
    def _on_accept_button_pressed(self):
        self._save_photo_on_disk();

        #Change to other scene.
        self._change_scene(scene_manager.SceneManager.SCENE_NAME_DONE);

    def _on_reject_button_pressed(self):
        self._change_scene(scene_manager.SceneManager.SCENE_NAME_CAMERA);


    ############################################################################
    ## Helper Methods                                                         ##
    ############################################################################
    def _change_scene(self, scene_name):
        scene_manager.SceneManager.instance().scene_is_complete(target_scene_name=scene_name);

    def _save_photo_on_disk(self):
        #Save the photo on disk...
        filesystem.save_photo(Camera.instance().get_last_photo(),
                              use_another_thread = True);