import os
import sys
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from generator import *

def leadmm():
    w = Workflow(name="leadmm", description="""LEAD Mesoscale Meterology workflow (Figure 1 in Ramakrishnan and Gannon)""")

    infile = File(name="input.txt", size=147*MB)

    tppo1 = File(name="tpp.txt", size=0.2*MB)
    tpp = Job(id="tpp", namespace="leadmm", name="TerrainPreProcessor", runtime=4*SECONDS, outputs=[tppo1])
    w.addJob(tpp)

    wrfstatico1 = File(name="wrfstatic.txt", size=19*MB)
    wrfstatic = Job(id="wrfstatic", namespace="leadmm", name="WrfStatic", runtime=338*SECONDS, outputs=[wrfstatico1])
    w.addJob(wrfstatic)

    lbio1 = File("lbi.txt", size=488*MB)
    lbi = Job(id="lbi", namespace="leadmm", name="LateralBoundaryInterpolator", runtime=146*SECONDS, inputs=[infile, tppo1], outputs=[lbio1])
    w.addJob(lbi)

    tdio1 = File("tdi.txt", size=243*MB)
    tdi = Job(id="tdi", namespace="leadmm", name="3DInterpolator", runtime=88*SECONDS, inputs=[infile, tppo1], outputs=[tdio1])
    w.addJob(tdi)

    wrf_dat = File("wrf.dat", size=206*MB)
    arps2wrf = Job(id="arps2wrf", namespace="leadmm", name="ARPS2WRF", runtime=78*SECONDS, inputs=[wrfstatico1, lbio1, tdio1], outputs=[wrf_dat])
    w.addJob(arps2wrf)

    wrf_out = File("wrf.dat.out", size=2422*MB)
    wrf = Job(id="wrf", namespace="leadmm", name="WRF", runtime=4570*SECONDS, cores=16, inputs=[wrf_dat], outputs=[wrf_out])
    w.addJob(wrf)

    return w

def main(*args):
    class LEADMM(Main):
        def genworkflow(self, options):
            return leadmm()

    LEADMM().main(*args)

if __name__ == '__main__':
    main(*sys.argv[1:])


# Character Creation Presentation (1.0.8)
# Created by Windyplains.  Inspired by Dunde's character creation presentation in Custom Commander.

from header_common import *
from header_presentations import *
from header_mission_templates import *
from ID_meshes import *
from header_operations import *
from header_triggers import *
from module_constants import *
from header_items import *   # Added for Show all Items presentation.
from module_items import *   # Added for Show all Items presentation.
import string

####################################################################################################################
#  Each presentation record contains the following fields:
#  1) Presentation id: used for referencing presentations in other files. The prefix prsnt_ is automatically added before each presentation id.
#  2) Presentation flags. See header_presentations.py for a list of available flags
#  3) Presentation background mesh: See module_meshes.py for a list of available background meshes
#  4) Triggers: Simple triggers that are associated with the presentation
####################################################################################################################

# script_gpu_create_checkbox     - pos_x, pos_y, label, storage_slot, value_slot
# script_gpu_create_mesh         - mesh_id, pos_x, pos_y, size_x, size_y
# script_gpu_create_portrait     - troop_id, pos_x, pos_y, size, storage_id
# script_gpu_create_button       - title, pos_x, pos_y, storage_id
# script_gpu_create_game_button  - title, pos_x, pos_y, storage_id
# script_gpu_create_text_label   - title, pos_x, pos_y, storage_id, design
# script_gpu_resize_object       - storage_id, percent size
# script_gpu_draw_line           - x length, y length, pos_x, pos_y, color
# script_gpu_container_heading   - pos_x, pos_y, size_x, size_y, storage_id
# script_gpu_create_slider       - min, max, pos_x, pos_y, storage_id, value_id

presentations = [
###########################################################################################################################
#####                                        CHARACTER CREATION PRESENTATION                                          #####
###########################################################################################################################

("ccp_character_creation", 0, mesh_load_window, [
    (ti_on_presentation_load,
      [
        (presentation_set_duration, 999999),
        (set_fixed_point_multiplier, 1000),

		(call_script, "script_gpu_create_mesh", "mesh_character_creator", 0, 0, 1000, 1325),
		(overlay_set_alpha, reg1, 0x00),

		(assign, "$gpu_storage", "trp_tpe_presobj"),

		# Bottom Buttons
		(call_script, "script_gpu_create_game_button", "str_ccp_label_done", 890, 15, ccp_obj_button_done),
		(call_script, "script_gpu_create_game_button", "str_ccp_label_back", 715, 15, ccp_obj_button_back),
		(call_script, "script_gpu_create_game_button", "str_ccp_label_default", 105, 15, ccp_obj_button_default),
		(call_script, "script_gpu_create_game_button", "str_ccp_label_random", 280, 15, ccp_obj_button_random),

		(assign, ":menu_size", 75), # This is % of original size.  So 75 -> 750.

		(assign, ":pos_x_menus", 122),
		(call_script, "script_gpu_create_text_label", "str_ccp_label_gender",    ":pos_x_menus", 650, ccp_obj_label_gender, gpu_center_with_outline),
		(overlay_set_color, reg1, gpu_white),
		(call_script, "script_gpu_create_text_label", "str_ccp_label_father",    ":pos_x_menus", 590, ccp_obj_label_father, gpu_center_with_outline),
		(overlay_set_color, reg1, gpu_white),
		(call_script, "script_gpu_create_text_label", "str_ccp_label_earlylife", ":pos_x_menus", 530, ccp_obj_label_earlylife, gpu_center_with_outline),
		(overlay_set_color, reg1, gpu_white),
		(call_script, "script_gpu_create_text_label", "str_ccp_label_later",     ":pos_x_menus", 470, ccp_obj_label_later, gpu_center_with_outline),
		(overlay_set_color, reg1, gpu_white),
		(call_script, "script_gpu_create_text_label", "str_ccp_label_reason",    ":pos_x_menus", 410, ccp_obj_label_reason, gpu_center_with_outline),
		(overlay_set_color, reg1, gpu_white),
		(call_script, "script_gpu_resize_object", ccp_obj_label_gender, ":menu_size"),
		(call_script, "script_gpu_resize_object", ccp_obj_label_father, ":menu_size"),
		(call_script, "script_gpu_resize_object", ccp_obj_label_earlylife, ":menu_size"),
		(call_script, "script_gpu_resize_object", ccp_obj_label_later, ":menu_size"),
		(call_script, "script_gpu_resize_object", ccp_obj_label_reason, ":menu_size"),

		(position_set_x, pos1, 150),
		# gender
        (position_set_y, pos1, 610),
        (create_combo_button_overlay, reg1),
        (overlay_set_position, reg1, pos1),
        (overlay_add_item, reg1, "@male"),
		(overlay_add_item, reg1, "@female"),
        (overlay_set_val, reg1, "$character_gender"),
		(troop_set_slot, ccp_objects, ccp_obj_menu_gender, reg1),
        (call_script, "script_gpu_resize_object", ccp_obj_menu_gender, ":menu_size"),

		# father
        (position_set_y, pos1, 550),
        (create_combo_button_overlay, reg1),
        (overlay_set_position, reg1, pos1),
        (overlay_add_item, reg1, "@a priest"),
        (overlay_add_item, reg1, "@a thief"),
        (overlay_add_item, reg1, "@a steppe nomad"),
        (overlay_add_item, reg1, "@a hunter"),
        (overlay_add_item, reg1, "@a veteran warrior"),
        (overlay_add_item, reg1, "@a travelling merchant"),
        (overlay_add_item, reg1, "@an impoverished noble"),
		(overlay_set_val, reg1, "$background_type"),
		(troop_set_slot, ccp_objects, ccp_obj_menu_father, reg1),
		(call_script, "script_gpu_resize_object", ccp_obj_menu_father, ":menu_size"),

		# early life
        (position_set_y, pos1, 490),
        (create_combo_button_overlay, reg1),
        (overlay_set_position, reg1, pos1),
        (overlay_add_item, reg1, "@an acolyte"),
        (overlay_add_item, reg1, "@a noble in training"),
        (overlay_add_item, reg1, "@a courtier"),
        (overlay_add_item, reg1, "@a mummer"),
        (overlay_add_item, reg1, "@a shop assistant"),
        (overlay_add_item, reg1, "@a steppe child"),
        (overlay_add_item, reg1, "@a street urchin"),
        (overlay_add_item, reg1, "@a craftsman's apprentice"),
        (overlay_add_item, reg1, "@a page at a nobleman's court"),
		(overlay_set_val, reg1, "$background_answer_2"),
		(troop_set_slot, ccp_objects, ccp_obj_menu_earlylife, reg1),
		(call_script, "script_gpu_resize_object", ccp_obj_menu_earlylife, ":menu_size"),

		# later
        (position_set_y, pos1, 430),
        (create_combo_button_overlay, reg1),
        (overlay_set_position, reg1, pos1),
        (try_begin),
          (eq,"$character_gender",tf_male),
          (overlay_add_item, reg1, "@a squire"),
        (else_try),
          (eq,"$character_gender",tf_female),
          (overlay_add_item, reg1, "@a lady-in-waiting"),
        (try_end),
		(overlay_add_item, reg1, "@a university student"),
		(overlay_add_item, reg1, "@a troubadour"),
		(overlay_add_item, reg1, "@a preacher"),
		(overlay_add_item, reg1, "@a goods peddler"),
        (overlay_add_item, reg1, "@a smith"),
        (overlay_add_item, reg1, "@a game poacher"),
        (overlay_add_item, reg1, "@a mercenary"),
		(overlay_add_item, reg1, "@a bravo"),
		(overlay_add_item, reg1, "@a thief"),
		(overlay_add_item, reg1, "@a gladiator"),
		(overlay_add_item, reg1, "@a bandit"),
		(overlay_add_item, reg1, "@a slave-trader"),
		(overlay_set_val, reg1, "$background_answer_3"),
		(troop_set_slot, ccp_objects, ccp_obj_menu_later, reg1),
		(call_script, "script_gpu_resize_object", ccp_obj_menu_later, ":menu_size"),

		# reason
        (position_set_y, pos1, 370),
        (create_combo_button_overlay, reg1),
        (overlay_set_position, reg1, pos1),
        (overlay_add_item, reg1, "@lust for money and power"),
        (overlay_add_item, reg1, "@being forced out of your home"),
        (overlay_add_item, reg1, "@religious fervor"),
        (overlay_add_item, reg1, "@wanderlust"),
        (overlay_add_item, reg1, "@the loss of a loved one"),
        (overlay_add_item, reg1, "@personal revenge"),
		(overlay_add_item, reg1, "@sense of duty"),
		(overlay_set_val, reg1, "$background_answer_4"),
		(troop_set_slot, ccp_objects, ccp_obj_menu_reason, reg1),
		(call_script, "script_gpu_resize_object", ccp_obj_menu_reason, ":menu_size"),

		## story
        (call_script, "script_ccp_get_character_background_text"),
        (create_text_overlay, reg1, "@{s1}", tf_double_space|tf_scrollable),
        (position_set_x, pos1, 255),
        (position_set_y, pos1, 90),
        (overlay_set_position, reg1, pos1),
        (position_set_x, pos1, 470),
        (position_set_y, pos1, 585),
        (overlay_set_area_size, reg1, pos1),

		##########################################################
		###                 FLORIS GAME OPTIONS                ###
		##########################################################

		# MTT Choice begin
		# (assign, ":pos_x_labels", 870),
		# (call_script, "script_gpu_create_text_label", "str_ccp_label_mtt", ":pos_x_labels", 650, ccp_obj_label_mtt, gpu_center_with_outline),
		# (overlay_set_color, reg1, gpu_white),
		# (call_script, "script_gpu_resize_object", ccp_obj_label_mtt, ":menu_size"),

		# (store_add, ":pos_x_menus", ":pos_x_labels", 28),
		# (position_set_x, pos1, ":pos_x_menus"),
		# (position_set_y, pos1, 610),
        # (create_combo_button_overlay, reg1),
        # (overlay_set_position, reg1, pos1),
        # (overlay_add_item, reg1, "@Native Troops"),
		# (overlay_add_item, reg1, "@Reworked Troops"),
        # (overlay_add_item, reg1, "@Expanded Troops"),
        # (troop_get_slot, ":value", ccp_objects, ccp_val_menu_trooptrees),
        # (overlay_set_val, reg1, ":value"),
		# (troop_set_slot, ccp_objects, ccp_obj_menu_trooptrees, reg1),
		# (call_script, "script_gpu_resize_object", ccp_obj_menu_trooptrees, ":menu_size"),
		# MTT Choice end

		# Starting Area Choice begin
		(assign, ":pos_x_labels", 870),
		(call_script, "script_gpu_create_text_label", "str_ccp_label_region", ":pos_x_labels", 650, ccp_obj_label_region, gpu_center_with_outline),
		(overlay_set_color, reg1, gpu_white),
		(call_script, "script_gpu_resize_object", ccp_obj_label_region, ":menu_size"),

		(store_add, ":pos_x_menus", ":pos_x_labels", 28),
		(position_set_x, pos1, ":pos_x_menus"),
		(position_set_y, pos1, 610),
        (create_combo_button_overlay, reg1),
        (overlay_set_position, reg1, pos1),
		(try_for_range, ":faction_no", kingdoms_begin, kingdoms_end),
			(neq, ":faction_no", kingdoms_begin),
			(str_store_faction_name, s1, ":faction_no"),
			(overlay_add_item, reg1, s1),
		(try_end),
        (troop_get_slot, ":value", ccp_objects, ccp_val_menu_initial_region),
        (overlay_set_val, reg1, ":value"),
		(troop_set_slot, ccp_objects, ccp_obj_menu_initial_region, reg1),
		(call_script, "script_gpu_resize_object", ccp_obj_menu_initial_region, ":menu_size"),
		# Starting Area Choice end

		# MOD DIFFICULTY MENU begin
		(assign, ":pos_x_labels", 870),
		(call_script, "script_gpu_create_text_label", "str_ccp_label_mod_difficulty", ":pos_x_labels", 590, ccp_label_mod_difficulty, gpu_center_with_outline),
		(overlay_set_color, reg1, gpu_white),
		(call_script, "script_gpu_resize_object", ccp_label_mod_difficulty, ":menu_size"),

		(store_add, ":pos_x_menus", ":pos_x_labels", 28),
		(position_set_x, pos1, ":pos_x_menus"),
		(position_set_y, pos1, 550),
        (create_combo_button_overlay, reg1),
        (overlay_set_position, reg1, pos1),
        (overlay_add_item, reg1, "@Easy"),
		(overlay_add_item, reg1, "@Normal"),
        (overlay_add_item, reg1, "@Hard"),
        (overlay_add_item, reg1, "@Very Hard"),
		(troop_get_slot, ":value", ccp_objects, ccp_val_menu_mod_difficulty),
        (overlay_set_val, reg1, ":value"),
		(troop_set_slot, ccp_objects, ccp_obj_menu_mod_difficulty, reg1),
		(call_script, "script_gpu_resize_object", ccp_obj_menu_mod_difficulty, ":menu_size"),
		# MOD DIFFICULTY MENU end

		# QUEST REACTION MENU begin
		(assign, ":pos_x_labels", 870),
		(call_script, "script_gpu_create_text_label", "str_ccp_label_quest_reaction", ":pos_x_labels", 530, ccp_obj_label_mtt, gpu_center_with_outline),
		(overlay_set_color, reg1, gpu_white),
		(call_script, "script_gpu_resize_object", ccp_obj_label_mtt, ":menu_size"),

		(store_add, ":pos_x_menus", ":pos_x_labels", 28),
		(position_set_x, pos1, ":pos_x_menus"),
		(position_set_y, pos1, 490),
        (create_combo_button_overlay, reg1),
        (overlay_set_position, reg1, pos1),
        (overlay_add_item, reg1, "@High"),
		(overlay_add_item, reg1, "@Medium"),
        (overlay_add_item, reg1, "@Low"),
		(troop_get_slot, ":value", ccp_objects, ccp_val_menu_questreaction),
        (overlay_set_val, reg1, ":value"),
		(troop_set_slot, ccp_objects, ccp_obj_menu_questreaction, reg1),
		(call_script, "script_gpu_resize_object", ccp_obj_menu_questreaction, ":menu_size"),
		# QUEST REACTION MENU end

		# Gather companions at nearest tavern
		# (try_begin),
			# (eq, "$g_gether_npcs", 1),
			# (troop_set_slot, ccp_objects, ccp_val_checkbox_gather_npcs, "$g_gether_npcs"),
		# (try_end),
		(call_script, "script_gpu_create_checkbox_white", 755, 450, "str_ccp_label_gather_npcs", ccp_obj_checkbox_gather_npcs, ccp_val_checkbox_gather_npcs), # was 755, 460 with Fog of War
		(overlay_set_val, reg1, "$g_gether_npcs"),

		# Fog of War
		# (try_begin),
			# (eq, "$g_fog", 1),
			# (troop_set_slot, ccp_objects, ccp_val_checkbox_fogofwar, "$g_fog"),
		# (try_end),
		# (call_script, "script_gpu_create_checkbox_white", 755, 420, "str_ccp_label_fog_of_war", ccp_obj_checkbox_fogofwar, ccp_val_checkbox_fogofwar),

		# Initialize the equipment list
		(call_script, "script_ccp_initialize_faction_items"),

		##########################################################
		###                 GENERATE STAT INFO                 ###
		##########################################################
		(assign, ":pos_y_stats", 290),
		(store_sub, ":pos_y_stat_values", ":pos_y_stats", 25),
		(assign, ":pos_x_stat_1", 55),  # Strength
		(assign, ":pos_x_stat_2", 100),  # Agility
		(assign, ":pos_x_stat_3", 145), # Intelligence
		(assign, ":pos_x_stat_4", 190), # Charisma
		(str_clear, s31),

		### STRENGTH ###
		# Label
		(call_script, "script_gpu_create_text_label", "str_ccp_str", ":pos_x_stat_1", ":pos_y_stats", ccp_obj_label_strength, gpu_center_with_outline),
		(overlay_set_color, reg1, gpu_white),
		(call_script, "script_gpu_resize_object", ccp_obj_label_strength, ":menu_size"),
		# Value
		(call_script, "script_gpu_create_text_label", "str_ccp_empty", ":pos_x_stat_1", ":pos_y_stat_values", ccp_obj_stat_strength, gpu_center_with_outline),
		(overlay_set_color, reg1, gpu_white),
		(call_script, "script_gpu_resize_object", ccp_obj_stat_strength, ":menu_size"),

		### AGILITY ###
		# Label
		(call_script, "script_gpu_create_text_label", "str_ccp_agi", ":pos_x_stat_2", ":pos_y_stats", ccp_obj_label_agility, gpu_center_with_outline),
		(overlay_set_color, reg1, gpu_white),
		(call_script, "script_gpu_resize_object", ccp_obj_label_agility, ":menu_size"),
		# Value
		(call_script, "script_gpu_create_text_label", "str_ccp_empty", ":pos_x_stat_2", ":pos_y_stat_values", ccp_obj_stat_agility, gpu_center_with_outline),
		(overlay_set_color, reg1, gpu_white),
		(call_script, "script_gpu_resize_object", ccp_obj_stat_agility, ":menu_size"),

		### INTELLIGENCE ###
		# Label
		(call_script, "script_gpu_create_text_label", "str_ccp_int", ":pos_x_stat_3", ":pos_y_stats", ccp_obj_label_intelligence, gpu_center_with_outline),
		(overlay_set_color, reg1, gpu_white),
		(call_script, "script_gpu_resize_object", ccp_obj_label_intelligence, ":menu_size"),
		# Value
		(call_script, "script_gpu_create_text_label", "str_ccp_empty", ":pos_x_stat_3", ":pos_y_stat_values", ccp_obj_stat_intelligence, gpu_center_with_outline),
		(overlay_set_color, reg1, gpu_white),
		(call_script, "script_gpu_resize_object", ccp_obj_stat_intelligence, ":menu_size"),

		### CHARISMA ###
		# Label
		(call_script, "script_gpu_create_text_label", "str_ccp_cha", ":pos_x_stat_4", ":pos_y_stats", ccp_obj_label_charisma, gpu_center_with_outline),
		(overlay_set_color, reg1, gpu_white),
		(call_script, "script_gpu_resize_object", ccp_obj_label_charisma, ":menu_size"),
		# Value
		(call_script, "script_gpu_create_text_label", "str_ccp_empty", ":pos_x_stat_4", ":pos_y_stat_values", ccp_obj_stat_charisma, gpu_center_with_outline),
		(overlay_set_color, reg1, gpu_white),
		(call_script, "script_gpu_resize_object", ccp_obj_stat_charisma, ":menu_size"),

		(assign, ":pos_x_misc_icon", 65),
		(assign, ":pos_x_misc_labels", 25),
		# (call_script, "script_ccp_generate_skill_set", summarize_skill_count),
		# (store_mul, ":pos_y_misc", reg1, 25),
		(assign, ":pos_y_misc", 300), # was 230, but that was causing it to run out of scroll room if too many options were selected.
		(assign, ":y_step_1", 20), # For text lines.
		(assign, ":y_step_2", 5), # For images

		# script_gpu_container_heading   - pos_x, pos_y, size_x, size_y, storage_id
		(call_script, "script_gpu_container_heading", 0, 60, 220, 195, ccp_obj_stat_container),
		############### ATTRIBUTES CONTAINER BEGIN ###############

			### GOLD ###
			# Value
			(call_script, "script_gpu_create_text_label", "str_ccp_zero", ":pos_x_misc_labels", ":pos_y_misc", ccp_obj_stat_gold, gpu_center_with_outline),
			(overlay_set_color, reg1, gpu_white),
			(call_script, "script_gpu_resize_object", ccp_obj_stat_gold, ":menu_size"),
			# Image
			(val_sub, ":pos_y_misc", ":y_step_2"),
			(store_sub, ":pos_y_temp", ":pos_y_misc", 5),
			(store_sub, ":pos_x_temp", ":pos_x_misc_icon", 22),
			(call_script, "script_gpu_create_mesh", "mesh_golden_coins", ":pos_x_temp", ":pos_y_temp", 250, 250),

			### RENOWN ###
			(val_sub, ":pos_y_misc", ":y_step_1"),
			# Value
			(call_script, "script_gpu_create_text_label", "str_ccp_zero", ":pos_x_misc_labels", ":pos_y_misc", ccp_obj_stat_renown, gpu_center_with_outline),
			(overlay_set_color, reg1, gpu_white),
			(call_script, "script_gpu_resize_object", ccp_obj_stat_renown, ":menu_size"),
			# Image
			(val_sub, ":pos_y_misc", ":y_step_2"),
			# (store_add, ":pos_y_temp", ":pos_y_misc", 2), # Line used when image was a shield.
			(store_sub, ":pos_y_temp", ":pos_y_misc", -5), # line used for new crown image.
			(store_sub, ":pos_x_temp", ":pos_x_misc_icon", -3), # 12 as a shield.
			(str_store_string, s31, "@Renown"),
			(call_script, "script_gpu_create_text_label", "str_ccp_empty", ":pos_x_temp", ":pos_y_temp", 0, gpu_center_with_outline),
			(overlay_set_color, reg1, gpu_white),
			(call_script, "script_gpu_resize_object", 0, ":menu_size"),
			#(call_script, "script_gpu_create_mesh", "mesh_status_renown", ":pos_x_temp", ":pos_y_temp", 150, 150),

			### WEAPON PROF - ONE HAND ###
			(val_sub, ":pos_y_misc", ":y_step_1"),
			# Value
			(call_script, "script_gpu_create_text_label", "str_ccp_zero", ":pos_x_misc_labels", ":pos_y_misc", ccp_obj_stat_weapon_onehand, gpu_center_with_outline),
			(overlay_set_color, reg1, gpu_white),
			(call_script, "script_gpu_resize_object", ccp_obj_stat_weapon_onehand, ":menu_size"),
			# Image
			(val_sub, ":pos_y_misc", ":y_step_2"),
			(store_sub, ":pos_x_temp", ":pos_x_misc_icon", 5),
			(call_script, "script_gpu_create_mesh", "mesh_weapon_onehand", ":pos_x_temp", ":pos_y_misc", 150, 150),

			### WEAPON PROF - TWO HAND ###
			(val_sub, ":pos_y_misc", ":y_step_1"),
			# Value
			(call_script, "script_gpu_create_text_label", "str_ccp_zero", ":pos_x_misc_labels", ":pos_y_misc", ccp_obj_stat_weapon_twohand, gpu_center_with_outline),
			(overlay_set_color, reg1, gpu_white),
			(call_script, "script_gpu_resize_object", ccp_obj_stat_weapon_twohand, ":menu_size"),
			# Image
			(val_sub, ":pos_y_misc", ":y_step_2"),
			(call_script, "script_gpu_create_mesh", "mesh_weapon_twohand", ":pos_x_misc_icon", ":pos_y_misc", 150, 150),

			### WEAPON PROF - POLEARM ###
			(val_sub, ":pos_y_misc", ":y_step_1"),
			# Value
			(call_script, "script_gpu_create_text_label", "str_ccp_zero", ":pos_x_misc_labels", ":pos_y_misc", ccp_obj_stat_weapon_polearm, gpu_center_with_outline),
			(overlay_set_color, reg1, gpu_white),
			(call_script, "script_gpu_resize_object", ccp_obj_stat_weapon_polearm, ":menu_size"),
			# Image
			(val_sub, ":pos_y_misc", ":y_step_2"),
			(store_sub, ":pos_x_temp", ":pos_x_misc_icon", 2),
			(call_script, "script_gpu_create_mesh", "mesh_weapon_polearm", ":pos_x_temp", ":pos_y_misc", 200, 200),

			### WEAPON PROF - ARCHERY ###
			(val_sub, ":pos_y_misc", ":y_step_1"),
			# Value
			(call_script, "script_gpu_create_text_label", "str_ccp_zero", ":pos_x_misc_labels", ":pos_y_misc", ccp_obj_stat_weapon_archery, gpu_center_with_outline),
			(overlay_set_color, reg1, gpu_white),
			(call_script, "script_gpu_resize_object", ccp_obj_stat_weapon_archery, ":menu_size"),
			# Image
			(val_sub, ":pos_y_misc", ":y_step_2"),
			(store_sub, ":pos_x_temp", ":pos_x_misc_icon", 10),
			(call_script, "script_gpu_create_mesh", "mesh_weapon_bow", ":pos_x_temp", ":pos_y_misc", 250, 250),

			### WEAPON PROF - CROSSBOW ###
			(val_sub, ":pos_y_misc", ":y_step_1"),
			# Value
			(call_script, "script_gpu_create_text_label", "str_ccp_zero", ":pos_x_misc_labels", ":pos_y_misc", ccp_obj_stat_weapon_crossbow, gpu_center_with_outline),
			(overlay_set_color, reg1, gpu_white),
			(call_script, "script_gpu_resize_object", ccp_obj_stat_weapon_crossbow, ":menu_size"),
			# Image
			(val_sub, ":pos_y_misc", ":y_step_2"),
			(store_sub, ":pos_x_temp", ":pos_x_misc_icon", 3),
			(call_script, "script_gpu_create_mesh", "mesh_weapon_crossbow", ":pos_x_temp", ":pos_y_misc", 250, 250),

			### WEAPON PROF - THROWING ###
			(val_sub, ":pos_y_misc", ":y_step_1"),
			# Value
			(call_script, "script_gpu_create_text_label", "str_ccp_zero", ":pos_x_misc_labels", ":pos_y_misc", ccp_obj_stat_weapon_throwing, gpu_center_with_outline),
			(overlay_set_color, reg1, gpu_white),
			(call_script, "script_gpu_resize_object", ccp_obj_stat_weapon_throwing, ":menu_size"),
			# Image
			(val_sub, ":pos_y_misc", ":y_step_2"),
			(store_sub, ":pos_x_temp", ":pos_x_misc_icon", 3),
			(call_script, "script_gpu_create_mesh", "mesh_weapon_thorwing", ":pos_x_temp", ":pos_y_misc", 150, 150),

			# This needs to come after all of the text fields are created since it fills them.
			(call_script, "script_ccp_generate_skill_set", limit_to_stats),

		############### ATTRIBUTES CONTAINER END ###############
		(set_container_overlay, -1),

      ]),

    (ti_on_presentation_event_state_change,
      [
        (store_trigger_param_1, ":object"),
        (store_trigger_param_2, ":value"),

		(try_begin), ####### DONE BUTTON #######
			(troop_slot_eq, ccp_objects, ccp_obj_button_done, ":object"),
			(call_script, "script_ccp_end_presentation_begin_game"),
			# Decide on whether to use a banner or not
			(try_begin),
			## CCP 1.1+ ## - Workaround for the Warband 1.151 broken banner presentation.
				# (eq, "$background_type", cb_noble),
				# (jump_to_menu, "mnu_auto_return"),
				# (start_presentation, "prsnt_banner_selection"),
			# (else_try),
			## CCP 1.1- ##
				(presentation_set_duration, 0),
				(jump_to_menu, "mnu_auto_return"),
			(try_end),

			#(jump_to_menu, "mnu_start_phase_2_5"),

		(else_try), ####### BACK BUTTON #######
			(troop_slot_eq, ccp_objects, ccp_obj_button_back, ":object"),
			(presentation_set_duration, 0),
			(jump_to_menu, "mnu_start_game_0"),

		(else_try), ####### DEFAULT BUTTON #######]
			(troop_slot_eq, ccp_objects, ccp_obj_button_default, ":object"),
			(call_script, "script_ccp_default_settings"),
			(start_presentation, "prsnt_ccp_character_creation"),

		(else_try), ####### RANDOMIZE BUTTON #######
			(troop_slot_eq, ccp_objects, ccp_obj_button_random, ":object"),
			(store_random_in_range, "$character_gender", 0, 2),    # Gender
			(store_random_in_range, "$background_type", 0, 6),     # Father background
			(store_random_in_range, "$background_answer_2", 0, 5), # Early life
			(store_random_in_range, "$background_answer_3", 0, 6), # Later life
			(store_random_in_range, "$background_answer_4", 0, 5), # Reason
            (store_random_in_range, reg21, 0, 5), # Starting Region
			(troop_set_slot, ccp_objects, ccp_val_menu_initial_region, reg21),
            (start_presentation, "prsnt_ccp_character_creation"),

		(else_try), ####### GENDER MENU #######
			(troop_slot_eq, ccp_objects, ccp_obj_menu_gender, ":object"),
			(assign, "$character_gender", ":value"),
			(start_presentation, "prsnt_ccp_character_creation"),
			(ge, DEBUG_CCP_general, 2),
			(assign, reg1, ":value"),
			(display_message, "@Gender option changed to option {reg1}."),

		(else_try), ####### FATHER BACKGROUND MENU #######
			(troop_slot_eq, ccp_objects, ccp_obj_menu_father, ":object"),
			(assign, "$background_type", ":value"),
			(start_presentation, "prsnt_ccp_character_creation"),
			(ge, DEBUG_CCP_general, 2),
			(assign, reg1, ":value"),
			(display_message, "@Father background option changed to option {reg1}."),

		(else_try), ####### EARLY LIFE BACKGROUND MENU #######
			(troop_slot_eq, ccp_objects, ccp_obj_menu_earlylife, ":object"),
			(assign, "$background_answer_2", ":value"),
			(start_presentation, "prsnt_ccp_character_creation"),
			(ge, DEBUG_CCP_general, 2),
			(assign, reg1, ":value"),
			(display_message, "@Early life option changed to option {reg1}."),

		(else_try), ####### LATER LIFE BACKGROUND MENU #######
			(troop_slot_eq, ccp_objects, ccp_obj_menu_later, ":object"),
			(assign, "$background_answer_3", ":value"),
			(start_presentation, "prsnt_ccp_character_creation"),
			(ge, DEBUG_CCP_general, 2),
			(assign, reg1, ":value"),
			(display_message, "@Later life option changed to option {reg1}."),

		(else_try), ####### REASON BACKGROUND MENU #######
			(troop_slot_eq, ccp_objects, ccp_obj_menu_reason, ":object"),
			(assign, "$background_answer_4", ":value"),
			(start_presentation, "prsnt_ccp_character_creation"),
			(ge, DEBUG_CCP_general, 2),
			(assign, reg1, ":value"),
			(display_message, "@Reason option changed to option {reg1}."),

		# (else_try), ####### TROOP TREE SELECTION MENU #######
			# (troop_slot_eq, ccp_objects, ccp_obj_menu_trooptrees, ":object"),
			# (troop_set_slot, ccp_objects, ccp_val_menu_trooptrees, ":value"),
			# (try_begin),
				# (eq, ":value", 0),
				# (assign, "$troop_trees", troop_trees_0),
			# (else_try),
				# (eq, ":value", 1),
				# (assign, "$troop_trees", troop_trees_1),
			# (else_try),
				# (eq, ":value", 2),
				# (assign, "$troop_trees", troop_trees_2),
			# (else_try),
				# (display_message, "@ERROR: No valid troop tree selection found."),
			# (try_end),
			# (start_presentation, "prsnt_ccp_character_creation"),
			# (ge, DEBUG_CCP_general, 1),
			# (assign, reg1, ":value"),
			# (display_message, "@Troop tree changed to option {reg1?Expanded or Reworked:Native} Trees [ {reg1} ]."),

		(else_try), ####### MOD DIFFICULTY SELECTION MENU #######
			(troop_slot_eq, ccp_objects, ccp_obj_menu_mod_difficulty, ":object"),
			(troop_set_slot, ccp_objects, ccp_val_menu_mod_difficulty, ":value"),
			(try_begin),
				(eq, ":value", 0),
				(assign, "$mod_difficulty", GAME_MODE_EASY),
			(else_try),
				(eq, ":value", 1),
				(assign, "$mod_difficulty", GAME_MODE_NORMAL),
			(else_try),
				(eq, ":value", 2),
				(assign, "$mod_difficulty", GAME_MODE_HARD),
			(else_try),
				(eq, ":value", 3),
				(assign, "$mod_difficulty", GAME_MODE_VERY_HARD),
			(else_try),
				(display_message, "@ERROR: No mod difficulty selection found so defaulting to normal.", gpu_red),
				(assign, "$mod_difficulty", GAME_MODE_NORMAL),
			(try_end),
			(call_script, "script_initialize_faction_troop_types"),
			(call_script, "script_reset_garrisons"),

		(else_try), ####### QUEST REACTION SELECTION MENU #######
			(troop_slot_eq, ccp_objects, ccp_obj_menu_questreaction, ":object"),
			(troop_set_slot, ccp_objects, ccp_val_menu_questreaction, ":value"),
			(try_begin),
				(eq, ":value", 0),
				(assign, "$quest_reactions", QUEST_REACTIONS_HIGH),
			(else_try),
				(eq, ":value", 1),
				(assign, "$quest_reactions", QUEST_REACTIONS_MEDIUM),
			(else_try),
				(eq, ":value", 2),
				(assign, "$quest_reactions", QUEST_REACTIONS_LOW),
			(else_try),
				(display_message, "@ERROR: No quest reaction selection found."),
			(try_end),
			#(start_presentation, "prsnt_ccp_character_creation"),
			(ge, DEBUG_CCP_general, 1),
			(assign, reg1, ":value"),
			(assign, reg2, "$quest_reactions"),
			(display_message, "@Quest reaction changed to option {reg1} -> reaction {reg2}.", gpu_red),

		# (else_try), ####### FOG OF WAR CHECKBOX #######
			# (troop_slot_eq, ccp_objects, ccp_obj_checkbox_fogofwar, ":object"),
			# (assign, "$g_fog", ":value"),
			# (call_script, "script_initialize_fog"),
			# (troop_set_slot, ccp_objects, ccp_val_checkbox_fogofwar, ":value"),
			# (ge, DEBUG_CCP_general, 1),
			# (assign, reg1, ":value"),
			# (display_message, "@Option: Fog of War has been {reg1?ENABLED:turned off} [ {reg1} ]."),

		(else_try), ####### GATHER NPCS CHECKBOX #######
			(troop_slot_eq, ccp_objects, ccp_obj_checkbox_gather_npcs, ":object"),
			(assign, "$g_gether_npcs", ":value"),
			(troop_set_slot, ccp_objects, ccp_val_checkbox_gather_npcs, ":value"),
			(ge, DEBUG_CCP_general, 1),
			(assign, reg1, ":value"),
			(display_message, "@Option: Gathering companions has been {reg1?ENABLED:turned off} [ {reg1} ].", gpu_debug),

		(else_try), ####### STARTING REGION MENU #######
			(troop_slot_eq, ccp_objects, ccp_obj_menu_initial_region, ":object"),
			(troop_set_slot, ccp_objects, ccp_val_menu_initial_region, ":value"),
			(start_presentation, "prsnt_ccp_character_creation"),
			(ge, DEBUG_CCP_general, 1),
			(assign, reg1, ":value"),
			(store_add, ":faction_picked", kingdoms_begin, ":value"),
			(val_add, ":faction_picked", 1),
			(str_store_faction_name, s2, ":faction_picked"),
			(display_message, "@Option: Starting region has been set to {s2} [{reg1}]."),

		(try_end),
      ]),

    ]),

 ]

def modmerge_presentations(orig_presentations, check_duplicates = False):
    if( not check_duplicates ):
        orig_presentations.extend(presentations) # Use this only if there are no replacements (i.e. no duplicated item names)
    else:
    # Use the following loop to replace existing entries with same id
        for i in range (0,len(presentations)-1):
          find_index = find_object(orig_presentations, presentations[i][0]); # find_object is from header_common.py
          if( find_index == -1 ):
            orig_presentations.append(presentations[i])
          else:
            orig_presentations[find_index] = presentations[i]

# Used by modmerger framework version >= 200 to merge stuff
def modmerge(var_set):
    try:
        var_name_1 = "presentations"
        orig_presentations = var_set[var_name_1]
        modmerge_presentations(orig_presentations)
    except KeyError:
        errstring = "Variable set does not contain expected variable: \"%s\"." % var_name_1
        raise ValueError(errstring)

Source - Character Creation/ccp_presentations.py


import os, sys
import numpy as np

abs_path = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.join(abs_path, ".."))
from simplenet import ffnet

TOLERANCE_ABSOLUTE = 5E-2

def test_ffnet_error(device_id):
    np.random.seed(98052)
    last_avg_error, avg_error = ffnet()
    expected_last_avg_error = 0.24
    expected_avg_error = 0.04

    assert np.allclose(avg_error, expected_avg_error, atol=TOLERANCE_ABSOLUTE)
    assert np.allclose(last_avg_error, expected_last_avg_error, atol=TOLERANCE_ABSOLUTE)


import numpy as np
import theano
import theano.tensor as T

def sgd(params, cost_var, learning_rate=1.0):

    grads = [T.grad(cost_var, param_var) for param_var in params]

    return [
        (param_var, param_var - learning_rate * grad_var)
        for param_var, grad_var in zip(params, grads)
    ]

def adadelta(params, cost_var, rho=0.95, epsilon=1e-6):

    """
        Zeiler, M. D. 2012.
        ADADELTA: An adaptive learning rate method.
        arXiv:1212.5701.
    """

    grads = [T.grad(cost_var, param_var) for param_var in params]

    updates = []
    for param_var, grad_var in zip(params, grads):

        accu_var = theano.shared(
            np.zeros(
                param_var.get_value(borrow=True).shape,
                dtype=theano.config.floatX
            ),
            borrow=True
        )

        delta_var = theano.shared(
            np.zeros(
                param_var.get_value(borrow=True).shape,
                dtype=theano.config.floatX
            ),
            borrow=True
        )

        accu_update_var = (
            rho * accu_var + (1 - rho) * grad_var ** 2
        )
        param_update_var = (
            T.sqrt((delta_var + epsilon) / (accu_update_var + epsilon)) * grad_var
        )
        delta_update_var = (
            rho * delta_var + (1 - rho) * param_update_var ** 2
        )

        updates.extend(
            [
                (accu_var, accu_update_var),
                (delta_var, delta_update_var),
                (param_var, param_var - param_update_var)
            ]
        )

    return updates


import importlib
import test_arcade
from logging import getLogger

logger = getLogger(__file__)

persist_state = None

def run_game():
    global persist_state
    game = test_arcade.MyGame(persist_state)
    game.setup()
    test_arcade.arcade.run()
    persist_state = game.state
    return game.terminated

while True:
    importlib.reload(test_arcade)
    terminate = run_game()
    if terminate:
        logger.warning("Terminating game...")
        break


import os
import glob
import requests
import json
import cv2
import numpy as np
import re
import sys
import torch
from PIL import Image
from pprint import pprint
import base64
from io import BytesIO
import torchvision.transforms.functional as F
from torchvision.io import read_video, read_image, ImageReadMode
from torchvision.models.optical_flow import Raft_Large_Weights
from torchvision.models.optical_flow import raft_large
from torchvision.io import read_video, read_image, ImageReadMode
from torchvision.utils import flow_to_image
import cv2
from torchvision.io import write_jpeg
import pickle

import argparse

def get_args():
    parser = argparse.ArgumentParser()

    parser.add_argument('--prompt', dest='prompt', default="")
    parser.add_argument('--negative-prompt', dest='negative_prompt', default="")

    parser.add_argument('--init-image', dest='init_image', default="./init.png")
    parser.add_argument('--input-dir', dest='input_dir', default="./Input_Images")
    parser.add_argument('--output-dir', dest='output_dir', default="./output")

    parser.add_argument('--width', default=720, type=int)
    parser.add_argument('--height', default=1280, type=int)

    return parser.parse_args()

args = get_args()

device = "cuda" if torch.cuda.is_available() else "cpu"

model = raft_large(weights=Raft_Large_Weights.DEFAULT, progress=False).to(device)
model = model.eval()

# Replace with the actual path to your image file and folder

os.makedirs(args.output_dir, exist_ok=True)

def get_image_paths(folder):
    image_extensions = ("*.jpg", "*.jpeg", "*.png", "*.bmp")
    files = []
    for ext in image_extensions:
        files.extend(glob.glob(os.path.join(folder, ext)))
    return sorted(files)

y_paths = get_image_paths(args.input_dir)

def get_controlnet_models():
    url = "http://localhost:7860/controlnet/model_list"

    temporalnet_model = None
    temporalnet_re = re.compile("^temporalnetversion2 \[.{8}\]")

    ip2p_model = None
    ip2p_re = re.compile("^control_.*ip2p.* \[.{8}\]")

    tile_model = None
    tile_re = re.compile("^control_.*tile.* \[.{8}\]")

    depth_model = None
    depth_re = re.compile("^control_.*depth.* \[.{8}\]")

    lineart_model = None
    lineart_re = re.compile("^control_.*lineart.* \[.{8}\]")

    softedge_model = None
    softedge_re = re.compile("^control_.*softedge.* \[.{8}\]")

    response = requests.get(url)
    if response.status_code == 200:
        models = json.loads(response.content)
    else:
        raise Exception("Unable to list models from the SD Web API! "
                        "Is it running and is the controlnet extension installed?")

    for model in models['model_list']:
        if temporalnet_model is None and temporalnet_re.match(model):
            temporalnet_model = model
        elif ip2p_model is None and ip2p_re.match(model):
            ip2p_model = model
        elif tile_model is None and tile_re.match(model):
            tile_model = model
        elif depth_model is None and depth_re.match(model):
            depth_model = model
        elif lineart_model is None and lineart_re.match(model):
            lineart_model = model
        elif softedge_model is None and softedge_re.match(model):
            softedge_model = model

    assert temporalnet_model is not None, "Unable to find the temporalnet2 model!  Ensure it's copied into the stable-diffusion-webui/extensions/models directory!"
    assert ip2p_model is not None, "Unable to find the ip2p_model model!  Ensure it's copied into the stable-diffusion-webui/extensions/models directory!"
    assert depth_model is not None, "Unable to find the depth model!  Ensure it's copied into the stable-diffusion-webui/extensions/models directory!"
    assert tile_model is not None, "Unable to find the tile model!  Ensure it's copied into the stable-diffusion-webui/extensions/models directory!"
    assert lineart_model is not None, "Unable to find the lineart model!  Ensure it's copied into the stable-diffusion-webui/extensions/models directory!"
    assert softedge_model is not None, "Unable to find the lineart model!  Ensure it's copied into the stable-diffusion-webui/extensions/models directory!"
    return temporalnet_model, ip2p_model, depth_model, tile_model, lineart_model, softedge_model

TEMPORALNET_MODEL, IP2P_MODEL, DEPTH_MODEL, TILE_MODEL, LINEART_MODEL, SOFTEDGE_MODEL  = get_controlnet_models()

def send_request(last_image_path, optical_flow_path,current_image_path):
    url = "http://localhost:7860/sdapi/v1/txt2img"

    with open(last_image_path, "rb") as b:
       last_image_encoded = base64.b64encode(b.read()).decode("utf-8")

    # Load and process the last image
    last_image = cv2.imread(last_image_path)
    last_image = cv2.cvtColor(last_image, cv2.COLOR_BGR2RGB)

    # Load and process the optical flow image
    flow_image = cv2.imread(optical_flow_path)
    flow_image = cv2.cvtColor(flow_image, cv2.COLOR_BGR2RGB)

    # Load and process the current image
    with open(current_image_path, "rb") as b:
       current_image = base64.b64encode(b.read()).decode("utf-8")

    # Concatenating the three images to make a 6-channel image
    six_channel_image = np.dstack((last_image, flow_image))

    # Serializing the 6-channel image
    serialized_image = pickle.dumps(six_channel_image)

    # Encoding the serialized image
    encoded_image = base64.b64encode(serialized_image).decode('utf-8')

    data = {
        "init_images": [current_image],
        "inpainting_fill": 0,
        "inpaint_full_res": True,
        "inpaint_full_res_padding": 1,
        "inpainting_mask_invert": 1,
        "resize_mode": 0,
        "prompt": args.prompt,
        "negative_prompt": args.negative_prompt,
        "alwayson_scripts": {
            "ControlNet":{
                "args": [
                    {
                        "input_image": current_image,
                        "module": "lineart_realistic",
                        "model": LINEART_MODEL,
                        "weight": 0.35,
                        "guidance": 1,
                        "pixel_perfect": True,
                        "resize_mode": 0,
                        "control_mode": 0,
                   },
                    {
                        "input_image": encoded_image,
                        "model": TEMPORALNET_MODEL,
                        "module": "none",
                        "weight": 1.0,
                        "guidance_end": 0.4,
                        "guidance_start": 0,
                        # "processor_res": 512,
                        "pixel_perfect": True,
                        "threshold_a": 64,
                        "threshold_b": 64,
                        "resize_mode": 0,
                        "control_mode": 2,
                    },
                    {
                        "input_image": current_image,
                        "model": IP2P_MODEL,
                        "module": "none",
                        "weight": 1.0,
                        "guidance": 1,
                        "guidance_end": 0.6,
                        "guidance_start": 0,
                        "pixel_perfect": True,
                        "resize_mode": 0,
                        "control_mode": 0,
                    },
                    #{
                    #    "input_image": current_image,
                    #    "model": TILE_MODEL,
                    #    "module": "tile_colorfix",
                    #    "weight": 0.4,
                    #    "guidance": 1,
                    #   "pixel_perfect": True,
                    #    "resize_mode": 0,
                    #    "control_mode": 0,
                   # },

                ]
            }
        },
        "seed": 1849402459,
        "subseed": -1,
        "subseed_strength": -1,
        "sampler_index": "Euler a",
        "batch_size": 1,
        "n_iter": 1,
        "steps": 22,
        "cfg_scale": 4,
        "width": args.width,
        "height": args.height,
        "restore_faces": True,
        "include_init_images": True,
        "override_settings": {},
        "override_settings_restore_afterwards": True
    }
    response = requests.post(url, json=data)
    if response.status_code == 200:
        return response.content
    else:
        try:
            error_data = response.json()
            print("Error:")
            print(str(error_data))

        except json.JSONDecodeError:
            print(f"Error: Unable to parse JSON error data.")
        return None

def infer(frameA, frameB):

    input_frame_1 = read_image(str(frameA), ImageReadMode.RGB)

    input_frame_2 = read_image(str(frameB), ImageReadMode.RGB)

    #img1_batch = torch.stack([frames[0]])
    #img2_batch = torch.stack([frames[1]])

    img1_batch = torch.stack([input_frame_1])
    img2_batch = torch.stack([input_frame_2])

    weights = Raft_Large_Weights.DEFAULT
    transforms = weights.transforms()

    def preprocess(img1_batch, img2_batch):
        img1_batch = F.resize(img1_batch, size=[512, 512])
        img2_batch = F.resize(img2_batch, size=[512, 512])
        return transforms(img1_batch, img2_batch)

    img1_batch, img2_batch = preprocess(img1_batch, img2_batch)

    list_of_flows = model(img1_batch.to(device), img2_batch.to(device))

    predicted_flow = list_of_flows[-1][0]
    opitcal_flow_path = os.path.join(args.output_dir, f"flow_{i}.png")

    flow_img = flow_to_image(predicted_flow).to("cpu")
    flow_img = F.resize(flow_img, size=[args.height, args.width])

    write_jpeg(flow_img, opitcal_flow_path)

    return opitcal_flow_path

output_images = []
output_paths = []

# Initialize with the first image path

result = args.init_image
output_image_path = os.path.join(args.output_dir, f"output_image_0.png")

#with open(output_image_path, "wb") as f:
   # f.write(result)

last_image_path = args.init_image
for i in range(1, len(y_paths)):
    # Use the last image path and optical flow map to generate the next input
    optical_flow = infer(y_paths[i - 1], y_paths[i])

    # Modify your send_request to use the last_image_path
    result = send_request(last_image_path, optical_flow, y_paths[i])
    data = json.loads(result)

    for j, encoded_image in enumerate(data["images"]):
        if j == 0:
            output_image_path = os.path.join(args.output_dir, f"output_image_{i}.png")
            last_image_path = output_image_path
        else:
            output_image_path = os.path.join(args.output_dir, f"controlnet_image_{j}_{i}.png")

        with open(output_image_path, "wb") as f:
           f.write(base64.b64decode(encoded_image))
    print(f"Written data for frame {i}:")


from common import *

def reverse(num):
    return int(str(num)[::-1])

T = readInt()
for t in range(T):
    N = readInt()
    count,n = 1,1
    while n != N:
        rev = reverse(n)
        if N-rev < 0:
            n += 1
        elif N-rev < N-n-1:
            n = rev
        else:
            n += 1
        count += 1
    writeLine("Case #{}: {}".format(t+1, count))


import tkinter
from tkinter import BOTH, END, StringVar, messagebox
from PIL import ImageTk, Image

root = tkinter.Tk()
root.title('Hello GUI World')
root.iconbitmap('wave.ico')
root.geometry('400x400')
root.resizable(False, False)

# define fonts and colors
root_color = '#224870'
input_color = '#2a4494'
output_color = '#4ea5d9'
root.config(bg=root_color)

# define functions
def submit_name():
    if name.get() == '':
        tkinter.messagebox.showwarning("Warning", "input can not be empty before submiting")
        return

    if case_style.get() == 'normal':
        name_label = tkinter.Label(output_frame, text="Hello " + name.get() + "! Keep learning tkinter")
    elif case_style.get() == 'upper':
        name_label = tkinter.Label(output_frame, text=("Hello " + name.get() + "! Keep learning tkinter").upper())
    name_label.config(bg=output_color)
    name_label.pack()
    name.delete(0, END)

# define layout
input_frame = tkinter.LabelFrame(root, bg=input_color)
output_frame = tkinter.LabelFrame(root, bg=output_color)
input_frame.pack(pady=10)
output_frame.pack(padx=10, pady=(0, 10), fill=BOTH, expand=True)

# define input and button
name = tkinter.Entry(input_frame, text='Enter your name', width=20)
submit_button = tkinter.Button(input_frame, text='Submit', command=submit_name)
name.grid(row=0, column=0, padx=10, pady=10)
submit_button.grid(row=0, column=1, padx=10, pady=10, ipadx=20)

# define radio buttons
case_style = StringVar()
case_style.set('normal')
normal_button = tkinter.Radiobutton(input_frame, text='Normal Case', variable=case_style, value='normal')
normal_button.config(bg=input_color)
upper_button = tkinter.Radiobutton(input_frame, text='Upper Case', variable=case_style, value='upper')
upper_button.config(bg=input_color)
normal_button.grid(row=1, column=0, padx=2, pady=2)
upper_button.grid(row=1, column=1, padx=2, pady=2)

# add an image
smile_img = ImageTk.PhotoImage(Image.open('smile.png'))
smile_label = tkinter.Label(output_frame, image=smile_img)
smile_label.config(bg=output_color)
smile_label.pack()

root.mainloop()


"""
ICDexplorer
URL settings.

(c) 2011 Jan Poeschko
jan@poeschko.com
"""

from django.conf.urls.defaults import *
from django.conf import settings

# Uncomment the next two lines to enable the admin:
# from django.contrib import admin
# admin.autodiscover()

urlpatterns = patterns('',
    # Example:
    # (r'^icdexplorer/', include('icdexplorer.foo.urls')),

    # Uncomment the admin/doc line below and add 'django.contrib.admindocs'
    # to INSTALLED_APPS to enable admin documentation:
    # (r'^admin/doc/', include('django.contrib.admindocs.urls')),

    # Uncomment the next line to enable the admin:
    # (r'^admin/', include(admin.site.urls)),
)

urlpatterns = patterns('icd.views',
    (r'dashboard/$', 'dashboard'),
    (r'^$', 'network'),
    (r'^search/$', 'search'),
    (r'^about/$', 'about'),
    (r'^categories/$', 'categories'),
    (r'^authors/$', 'authors'),
    (r'^properties/$', 'properties'),
    (r'^categories/(?P<name>.+)/$', 'category'),
    (r'^authors/(?P<name>.*)/$', 'author'),
    (r'^properties/(?P<name>.*)/$', 'property'),
    (r'^categorylisting/(?P<attribute>.*?)/$', 'categorylisting'),
    (r'^categorylisting/(?P<attribute>.*?)/(?P<page_index>\d+)$', 'categorylisting'),
    (r'^authorlisting/(?P<attribute>.*?)/(?P<page_index>\d+)/$', 'authorlisting'),
    (r'^authorlisting/(?P<attribute>.*?)/$', 'authorlisting'),
    (r'^ajax/graph/$', 'ajax_graph'),
)

urlpatterns += patterns('',
    (r'^accounts/login/$', 'django.contrib.auth.views.login'),#, {'template_name': 'myapp/login.html'}),
    (r'^accounts/logout/$', 'django.contrib.auth.views.logout_then_login'),
)

#if not settings.IS_SERVER:
urlpatterns += patterns('django.views.static',
    (r'^media/(?P<path>.*)$', 'serve', {'document_root': settings.MEDIA_ROOT[:-1], 'show_indexes': True}),
    (r'^favicon\.ico$', 'serve', {'document_root': settings.MEDIA_ROOT + '../static', 'path': 'favicon.ico'}),
)


def get_fibonacci(position):
    before_num = 0
    after_num = 1
    fibonacci_num = 0
    if position == 0:
        print(before_num)
    elif position == 1:
        print(after_num)
    else:
        for _ in range(position-1):
            fibonacci_num = before_num + after_num
            before_num = after_num
            after_num = fibonacci_num
        print(fibonacci_num)

n = int(input())
get_fibonacci(n)


#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
(c) 2019 under a MIT License (https://mit-license.org)

Authors:
- Lukas Brunner || lukas.brunner@env.ethz.ch

Abstract:

"""
import os
import logging
import numpy as np

from core import utils

logger = logging.getLogger(__name__)

types = {
    # --- other parameters ---
    'variants_use': (int, str),
    'variants_select': str,
    'variants_independence': bool,
    'variants_combine': bool,
    'idx_lats': (int, type(None)),
    'idx_lons': (int, type(None)),
    'inside_ratio': (float, str, type(None)),
    'overwrite': bool,
    'percentiles': float,
    'performance_metric': str,
    'plot_path': (str, type(None)),
    'plot': bool,
    'subset': (str, type(None)),
    'save_path': str,
    'sigma_i': (int, float, type(None)),
    'sigma_q': (int, float, type(None)),

    # --- data ---
    'model_path': str,
    'model_id': str,
    'model_scenario': str,
    'obs_path': str,
    'obs_id': str,
    'obs_uncertainty': (str, type(None)),

    # --- target ---
    'target_diagnostic': (str, type(None)),
    'target_agg': str,
    'target_season': str,
    'target_mask': (bool, str),
    'target_region': str,
    'target_startyear': int,
    'target_endyear': int,
    'target_startyear_ref': (int, type(None)),
    'target_endyear_ref': (int, type(None)),

    # --- performance ---
    'performance_diagnostics': (str, type(None)),
    'performance_aggs': (str, type(None)),
    'performance_seasons': (str, type(None)),
    'performance_masks': (bool, str, type(None)),
    'performance_regions': (str, type(None)),
    'performance_startyears': (int, type(None)),
    'performance_endyears': (int, type(None)),
    'performance_normalizers': (str, int, float, type(None)),
    'performance_weights': (int, float, type(None)),

    # --- independence ---
    'independence_diagnostics': str,
    'independence_aggs': str,
    'independence_seasons': str,
    'independence_masks': (bool, str),
    'independence_regions': str,
    'independence_startyears': int,
    'independence_endyears': int,
    'independence_normalizers': (str, int, float),
    'independence_weights': (int, float, type(None)),
}

values = {
    # --- other parameters ---
    'idx_lats': None,
    'idx_lons': None,
    'inside_ratio': None,  # TODO
    'overwrite': [True, False],
    'percentiles': None,
    'performance_metric': ['RMSE'],
    'plot_path': None,  # TODO: writable
    'plot': [True, False],
    'subset': None,
    'save_path': None,  # TODO: writable
    'sigma_i': None,
    'sigma_q': None,

    # --- data ---
    'model_path': None,  # TODO: exists
    'model_id': ['CMIP3', 'CMIP5', 'CMIP6', 'LE'],
    'model_scenario': None,  # TODO:
    'variants_use': ['all', *list(range(1, 100))],
    'variants_select': ['sorted', 'natsorted', 'random'],
    'variants_independence': [True, False],
    'variants_combine': [True, False],
    'obs_path': None,  # TODO: None or exists
    'obs_id': None,
    'obs_uncertainty': [None, 'range', 'mean', 'median', 'center'],

    # --- target ---
    'target_diagnostic': None,
    'target_agg': ['CLIM'],
    'target_season': ['ANN', 'JJA', 'SON', 'DJF', 'MAM'],
    'target_mask': [False, 'sea', 'land'],
    'target_region': None,   # TODO: check SREX or in folder
    'target_startyear': range(1850, 2101),
    'target_endyear': range(1850, 2101),
    'target_startyear_ref': range(1850, 2101),
    'target_endyear_ref': range(1850, 2101),

    # --- performance ---
    'performance_diagnostics': None,
    'performance_aggs': ['ANOM-GLOBAL', 'ANOM-LOCAL', 'CLIM', 'STD', 'TREND'],
    'performance_seasons': ['ANN', 'JJA', 'SON', 'DJF', 'MAM'],
    'performance_masks': [False, 'sea', 'land'],
    'performance_regions': None,  # TODO: check SREX or in folder
    'performance_startyears': range(1850, 2020),
    'performance_endyears': range(1850, 2020),
    'performance_normalizers': None,
    'performance_weights': None,

    # --- independence ---
    'independence_diagnostics': None,
    'independence_aggs': ['ANOM-GLOBAL', 'ANOM-LOCAL', 'CLIM', 'STD', 'TREND'],
    'independence_seasons': ['ANN', 'JJA', 'SON', 'DJF', 'MAM'],
    'independence_masks': [False, 'sea', 'land'],
    'independence_regions': None,  # TODO: check SREX or in folder
    'independence_startyears': range(1850, 2020),
    'independence_endyears': range(1850, 2020),
    'independence_normalizers': None,
    'independence_weights': None,
}

def check_types(cfg, types):
    for param in types.keys():
        if isinstance(cfg[param], list):
            for value in cfg[param]:
                if not isinstance(value, types[param]):
                    errmsg = ' '.join([
                        f'Wrong type in input field {param}! Each element',
                        f'should be {" or ".join(types[param])} at least one',
                        f'is {type(value)}!'])
                    logger.error(errmsg)
                    raise IOError(errmsg)
        else:
            if not isinstance(cfg[param], types[param]):
                errmsg = ' '.join([
                    f'Wrong type in input field {param}! Should be',
                    f'{", ".join(types[param])} is {type(value)}!'])
                logger.error(errmsg)
                raise IOError(errmsg)

def check_values(cfg, values):
    for param in values.keys():
        if values[param] is None:
            continue
        if isinstance(cfg[param], list):
            for value in cfg[param]:
                if value not in values[param]:
                    errmsg = ' '.join([
                        f'Wrong input value in field {param}! Each element',
                        f'should be in {", ".join(values[param])} at least one',
                        f'is not: {value}'])
                    logger.error(errmsg)
                    raise IOError(errmsg)
        else:
            if cfg[param] not in values[param]:
                errmsg = ' '.join([
                    f'Wrong input value in field {param}! Should be in',
                    f'{", ".join(values[param])} but is: {value}'])
                logger.error(errmsg)
                raise IOError(errmsg)

def set_default_values(cfg):
    try:
        cfg.subset
    except AttributeError:
        cfg.subset = None

    try:
        cfg.idx_lats
    except AttributeError:
        cfg.idx_lats = None

    try:
        cfg.idx_lons
    except AttributeError:
        cfg.idx_lons = None

    try:
        cfg.performance_metric
    except AttributeError:
        cfg.performance_metric = 'RMSE'

    independence_parameters = [
        'independence_diagnostics',
        'independence_aggs',
        'independence_seasons',
        'independence_masks',
        'independence_regions',
        'independence_startyears',
        'independence_endyears',
        'independence_normalizers',
        'independence_weights',
    ]
    # if non of them exists (old way) default to the same as performance
    if not np.all([hasattr(cfg, param) for param in independence_parameters]):
        for param in independence_parameters:
            cfg[param] = cfg[param.replace('independence_', 'performance_')]

def process_other_parameters(cfg):
    other_parameters = {
        'variants_use',
        'variants_select',
        'variants_independence',
        'idx_lats',
        'idx_lons',
        'inside_ratio',
        'overwrite',
        'percentiles',
        'performance_metric',
        'plot_path',
        'plot',
        'subset',
        'save_path',
    }

    for param in other_parameters:
        if param == 'variants_independence':
            if cfg['variants_independence'] and cfg['variants_use'] == 1:
                raise ValueError('Can not use variants_independence without variants')
        elif param == 'percentiles':
            if not np.all((value > 0) & (value < 1) for value in cfg[param]):
                raise ValueError
            if not len(cfg[param]) == 2:
                raise ValueError
        elif param == 'inside_ratio':
            if cfg[param] is None:
                cfg[param] = cfg['percentiles'][1] - cfg['percentiles'][0]
            elif cfg[param] == 'force':
                pass
            elif cfg[param] < 0 or cfg[param] > 1:
                raise ValueError

        elif param == 'performance_metric':
            if not cfg[param] in ['RMSE']:
                raise ValueError

        elif param == 'plot_path':
            if cfg['plot']:
                if cfg['plot_path'] is None:
                    raise ValueError
                if not os.access(cfg.plot_path, os.W_OK | os.X_OK):
                    raise ValueError('plot_path is not writable')

        elif param == 'save_path':
            if not os.access(cfg.plot_path, os.W_OK | os.X_OK):
                raise ValueError('save_path is not writable')

def process_model_parameters(cfg):
    model_parameters = {
        'model_path': str,
        'model_id': str,
        'model_scenario': str,
    }

    for param in model_parameters:
        if not isinstance(cfg[param], list):
            cfg[param] = [cfg[param]]
        if not np.all([isinstance(value, model_parameters[param])
                       for value in cfg[param]]):
            raise ValueError

    size = len(cfg.model_path)
    for param in model_parameters:
        if not len(cfg[param]) == size:
            raise ValueError

def process_obs_parameters(cfg):
    obs_parameters = {
        'obs_path': str,
        'obs_id': str,
        'obs_uncertainty': (str, type(None)),
    }

    if cfg.obs_path is None:
        for param in obs_parameters.keys():
            cfg[param] = None
        return  # all parameters contain a single None

    param = 'obs_path'
    if cfg[param] is None:
        cfg['obs_id'] = None
    else:
        if not isinstance(cfg[param], list):
            cfg[param] = [cfg[param]]
            if not np.all([isinstance(value, obs_parameters[param])
                           for value in cfg[param]]):
                raise ValueError
        size = len(cfg[param])

    param = 'obs_id'
    if cfg[param] is None:
        cfg['obs_path'] = None
    else:
        if not isinstance(cfg[param], list):
            cfg[param] = [cfg[param]]
        if not np.all([isinstance(value, obs_parameters[param])
                       for value in cfg[param]]):
            raise ValueError
        if not len(cfg[param]) == size:
            raise ValueError

    param = 'obs_uncertainty'
    if not isinstance(cfg[param], obs_parameters[param]):
        raise ValueError
    if cfg[param] is None and not (len(cfg['obs_path']) == 1 or cfg['obs_path'] is None):
        raise ValueError

def process_target_parameters(cfg):
    target_parameters = {
        'target_diagnostic': str,
        'target_agg': str,
        'target_season': str,
        'target_mask': (bool, str),
        'target_region': str,
        'target_startyear': int,
        'target_endyear': int,
        'target_startyear_ref': (int, type(None)),
        'target_endyear_ref': (int, type(None)),
    }
    if cfg.target_diagnostic is None:
        # for param in target_parameters.keys():
        #     if cfg[param] is not None:
        #         raise ValueError
        return  # all parameters contain a single None

    for param in target_parameters.keys():
        if not isinstance(cfg[param], target_parameters[param]):
            raise ValueError

def process_multi_vars(cfg):
    for param in ['performance_diagnostics', 'independence_diagnostics']:
        if cfg[param] is not None:
            for idx, diagn in enumerate(cfg[param]):
                if '-' in diagn:
                    varns = diagn.split('-')
                    assert len(varns) == 2
                    cfg[param][idx] = {diagn: varns}

def process_performance_parameters(cfg):
    performance_parameters = {
        'performance_diagnostics': str,
        'performance_aggs': str,
        'performance_seasons': str,
        'performance_masks': (bool, str),
        'performance_regions': str,
        'performance_startyears': int,
        'performance_endyears': int,
        'performance_normalizers': (str, int, float),
        'performance_weights': (int, float, type(None)),
    }

    expand_parameters = [
        'performance_seasons',
        'performance_masks',
        'performance_regions',
        'performance_startyears',
        'performance_endyears',
        'performance_normalizers',
        'performance_weights',
    ]

    if cfg.performance_diagnostics is None:  # no performance weighting
        for param in performance_parameters.keys():
            if cfg[param] is not None:
                raise ValueError
        return  # all parameters contain a single None

    if not isinstance(cfg.performance_diagnostics, list):  # only one diagnostic
        for param in performance_parameters.keys():
            if isinstance(cfg[param], list):  # then all need to be not a list
                raise ValueError
            else:
                cfg[param] = [cfg[param]]

    size = len(cfg.performance_diagnostics)
    for param in expand_parameters:
        if not isinstance(cfg[param], list) and cfg[param] is not None:
            # allow only one value for some parameters and expand to list here
            cfg[param] = [cfg[param]] * size

    for param in performance_parameters.keys():
        if cfg[param] is None:
            continue
        if not isinstance(cfg[param], list):
            raise ValueError
        if len(cfg[param]) != size:
            errmsg = ' '.join([
                'All performance_* parameters need to have same length',
                f'{param} has {len(cfg[param])} but should have {size}'])
            logger.error(errmsg)
            raise ValueError(errmsg)
        if not np.all([isinstance(value, performance_parameters[param])
                       for value in cfg[param]]):
            raise ValueError

def process_independence_parameters(cfg):
    independence_parameters = {
        'independence_diagnostics': str,
        'independence_aggs': str,
        'independence_seasons': str,
        'independence_masks': (bool, str),
        'independence_regions': str,
        'independence_startyears': int,
        'independence_endyears': int,
        'independence_normalizers': (str, int, float),
        'independence_weights': (int, float, type(None)),
    }

    expand_parameters = [
        'independence_seasons',
        'independence_masks',
        'independence_regions',
        'independence_startyears',
        'independence_endyears',
        'independence_normalizers',
        'independence_weights',
    ]

    if cfg.independence_diagnostics is None:  # no independence weighting
        for param in independence_parameters.keys():
            if cfg[param] is not None:
                raise ValueError
        return  # all parameters contain a single None

    if not isinstance(cfg.independence_diagnostics, list):  # only one diagnostic
        for param in independence_parameters.keys():
            if isinstance(cfg[param], list):
                raise ValueError
            else:
                cfg[param] = [cfg[param]]

    size = len(cfg.independence_diagnostics)
    for param in expand_parameters:
        if not isinstance(cfg[param], list) and cfg[param] is not None:
            # allow only one value for some parameters and expand to list here
            cfg[param] = [cfg[param]] * size

    for param in independence_parameters.keys():
        if cfg[param] is None:
            continue
        if not isinstance(cfg[param], list):
            raise ValueError
        if len(cfg[param]) != size:
            raise ValueError
        if not np.all([isinstance(value, independence_parameters[param])
                       for value in cfg[param]]):
            raise ValueError

def process_sigmas(cfg):
    if cfg.target_diagnostic is None:
        if cfg.sigma_i is None or cfg.sigma_q is None:
            errmsg = 'If target_diagnostic is None, both sigmas need to be set!'
            raise ValueError(errmsg)

    # TODO: is it allowed to have one sigma None and the other set?
    # TODO: I think I can remove the sigma = -99 case with the new separation between
    # dependence and performance

def check_perfect_model_test(cfg):
    """
    For the perfect model test the performance and independence parameters
    need to be identical. So setting them separately is only allowed if the
    sigma values are use-given so that the perfect model test can be omitted.
    """
    parameters = [
        '{}_diagnostics',
        '{}_aggs',
        '{}_seasons',
        '{}_masks',
        '{}_regions',
        '{}_startyears',
        '{}_endyears',
        '{}_normalizers',
        '{}_weights',
    ]
    same = True
    for param in parameters:
        if ((cfg[param.format('performance')] is None and cfg[param.format('independence')] is not None) or
            (cfg[param.format('performance')] is not None and cfg[param.format('independence')] is None)):
            same = False
        elif cfg[param.format('performance')] is None and cfg[param.format('independence')] is None:
            pass
        elif not tuple(cfg[param.format('performance')]) == tuple(cfg[param.format('independence')]):
            same = False

    if not same and (cfg.sigma_i is None or cfg.sigma_q is None):
        errmsg = 'If performance_* and independence_* parameters are not identical sigmas have to be set!'
        raise ValueError(errmsg)

    if not same and cfg.obs_id is None:
        errmsg = 'If performance_* and independence_* parameters are not identical obs_id has to be set!'
        raise ValueError(errmsg)

def read_config(config, config_file):
    """Read a configuration from a configuration file.

    Parameters
    ----------
    config : string
        A string identifying a configuration in config_file. This string will
        also be used to name the final output file.
    config_file : string
        A valid configuration file name (ending with ".ini")

    Returns
    -------
    cfg : configuration object
        A configuration object with must contain all mandatory configurations.
    """
    cfg = utils.read_config(config, config_file)
    set_default_values(cfg)
    process_other_parameters(cfg)
    process_model_parameters(cfg)
    process_obs_parameters(cfg)
    process_target_parameters(cfg)
    process_performance_parameters(cfg)
    process_independence_parameters(cfg)
    process_multi_vars(cfg)
    process_sigmas(cfg)
    check_perfect_model_test(cfg)
    utils.log_parser(cfg)
    return cfg


import json
import math
import numpy as np

import networkx as nx
import matplotlib.pyplot as plt

def draw_networkx(graph: nx.Graph, iterations=15, seed=42, node_size=10, with_labels=False, arrows=False, width=0.15):
    """Draw networkx graph with spring layout.

    Args:
        graph (nx.Graph): the graph to draw.
        iterations (int, optional): max number of iterations to spring. Defaults to 15.
        seed (int, optional): random seed. Defaults to 42.
        node_size (int, optional): node size of draw. Defaults to 10.
        with_labels (bool, optional): whether draw labels. Defaults to False.
        arrows (bool, optional): whether draw arrows. Defaults to False.
        width (float, optional): edge width of draw. Defaults to 0.15.
    """

    pos = nx.spring_layout(graph, iterations=iterations, seed=seed)
    fig, ax = plt.subplots(figsize=(15, 9))
    ax.axis('off')
    nx.draw_networkx(graph, pos=pos, ax=ax, arrows=arrows,
                     node_size=node_size, with_labels=with_labels, width=width)

def draw_evaluation(record_path: str, type: str = 'elapsed', datasets=['MathOverflow', 'StackOverflow', 'WikiTalk', 'AskUbuntu'], algor=['SBG', 'CE-SBG', 'O_SBG'], mark=['ro-', 'bs-', 'gd-'], hatch =['.', 'x', '|'], save_path=None, figsize=(10, 8), suptitle=None, ncols=2):
    with open(record_path, 'r') as f:
        record = json.load(f)

    vary = record['vary']
    vary_list = record[vary]

    ncols = 1 if len(datasets) == 1 else ncols
    nrows = math.ceil(len(datasets) / ncols)
    fig, axs = plt.subplots(nrows, ncols, figsize=figsize)
    if suptitle:
        fig.suptitle(suptitle)
    for i, dataset in enumerate(datasets):
        if len(datasets) == 1:
            ax = axs
        elif len(datasets) == 2:
            ax = axs[i]
        else:
            ax = axs[int(i/ncols), i%ncols]
        if type == 'elapsed':
            draw_efficiency_evaluation(ax, vary_list, record, dataset, algor, mark)
            ylabel = 'Time (s)'
        elif type == 'spread':
            draw_quality_evaluation(ax, vary_list, record, dataset, algor, hatch)
            ylabel = 'Influenced number'
        elif type == 'prob_edge':
            draw_prob_edge(ax, vary_list, record, dataset, algor, hatch)
            ylabel = 'Number of Probing edges'

        # ax.set_title(dataset, y=1.04, fontsize='x-large')
        ax.set_title(dataset, y=1.08, fontsize='x-large')
        ax.set_ylabel(ylabel, fontsize='large')
        ax.set_xlabel(vary, fontsize='large')
        ax.legend(bbox_to_anchor=(0, 0.98, 1, 0.10), loc='lower left', ncol=3, mode='expand', edgecolor='1.0')
        ax.tick_params(direction='in', bottom=True, top=True, left=True, right=True, pad=8, labelsize='large')

    fig.tight_layout()
    if save_path:
        plt.savefig(save_path)
    plt.show()

def draw_efficiency_evaluation(ax, vary_list, record_data, dataset, algor=['SBG', 'CE-SBG', 'O_SBG'], mark=['r+-', 'bs-', 'gd-']):
    for alg, m in zip(algor, mark):
        value = np.array(record_data[f'{dataset}_{alg}_elapsed'])

        value = np.where(value > 3600 * 24, 3600 * 24, value)
        valid_value = np.ma.masked_where(value >= 3600 * 24, value)
        invalid_value = np.ma.masked_where(value < 3600 * 24, value)

        ax.plot(vary_list, valid_value, m, label=alg, markersize=9, clip_on=False)
        # plot invalid value with *
        ax.plot(vary_list, invalid_value, f'{m[0]}*-', markersize=9, clip_on=False)

    ax.set_yscale('log', base=10, subs=[10])
    ax.set_yticks([10 ** i for i in range(-1, 6)])
    ax.set_ylim((0.1, 10 ** 5))
    ax.set_xticks(vary_list)
    ax.set_xlim((vary_list[0], vary_list[-1]))

def draw_quality_evaluation(ax, vary_list, record_data, dataset, algor=['SBG', 'CE-SBG', 'O_SBG'], hatch =['.', 'x', '|'], color=['#069AF3', '#F97306', '#15B01A']):
    x = np.arange(len(vary_list))
    width = 0.2
    for alg, h, c, label, offset in zip(algor, hatch, color, ['SBG', 'CE-SBG', 'O-SBG'], [-width, 0, width]):
        value = np.array(record_data[f'{dataset}_{alg}_spread'])
        value = np.where(value < 0, 1, value)

        ax.bar(x + offset, value, width, hatch=h, label=label)

    ax.set_yticks(np.arange(0, 30 * 11, 30))
    ax.set_ylim((0, 300))
    ax.set_xticks(x, vary_list)

def draw_prob_edge(ax, vary_list, record_data, dataset, algor=['SBG', 'CE-SBG', 'O_SBG'], hatch =['.', 'x', '|'], color=['#069AF3', '#F97306', '#15B01A']):
    x = np.arange(len(vary_list))
    width = 0.2
    for alg, h, c, label, offset in zip(algor, hatch, color, ['SBG', 'CE-SBG', 'O-SBG'], [-width, 0, width]):
        value = np.array(record_data[f'{dataset}_{alg}_edges'])
        ax.bar(x + offset, value, width, hatch=h, label=label)

    ax.set_yscale('log', base=10, subs=[10])
    ax.set_yticks([10 ** i for i in range(0, 7)])
    ax.set_ylim((1, 10 ** 6))
    ax.set_xticks(x, vary_list)


'''10.2 Write a program to read through the mbox-short.txt and figure out the
distribution by hour of the day for each of the messages. You can pull the hour
out from the 'From ' line by finding the time and then splitting the string a
second time using a colon.

From stephen.marquard@uct.ac.za Sat Jan  5 09:14:16 2008

Once you have accumulated the counts for each hour, print out the counts,
sorted by hour as shown below.'''

fname = 'mbox-short.txt'
try :
    file = open(fname , 'r')
except :
    print("File cannot be found!! :", fname)
    quit()

words = list()
all_hrs = dict()
for line in file :
    new_line = line.rstrip()

    if not new_line.startswith('From ') :
        continue

    words = new_line.split()

    hours = words[5]
    hrs = hours.split(':')
    hh = hrs[0]

    #Creating the dictionary to get all hours and their count
    all_hrs[hh] = all_hrs.get(hh , 0) + 1

get_hours = list()
for (h,c) in all_hrs.items() :
    newtup = (h,c)
    get_hours.append(newtup)

get_hours = sorted(get_hours)

for h,c in get_hours :
    print(h,c)
print('********************************************************************')
print(sorted([(h,c) for (h,c) in all_hrs.items()]))


#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os, sys
import numpy as np
import scipy.ndimage as ndimage
from scipy.ndimage import morphology
from scipy.ndimage import measurements
import pandas as pd
from copy import copy

sys.path.insert(0, '/home/fajtai/py/')

def labelData(data,struct = None):
    """
    :param data: input matrix
    :type data: np.ndarray
    :return: (labeledData, numOfLabels)

    """
    if isinstance(struct,type(None)):
        struct = morphology.generate_binary_structure(data.ndim,1)

    labeledData, numOfLabels = measurements.label(data,structure=struct)
    return labeledData, numOfLabels

def get_label_with_overlap(labeled_data, mask, only_max_hit = False, hit_percentage_filter = 0):
    """
    This function is stands for filtering labeled data with a binary mask. Only labels overlapped with the given binary mask will be kept.\n
    :param labeled_data: labeled image data
    :param mask: the binary mask, which is filled with 1 in the target region
    :param only_max_hit: if this switch true, the function returns only one label, with the highest mask hit count
    :param hit_percentage_filter: leaves out the labels with hit count less than X percentage (default 50)
    :return: binary mask of the filtered labeled data
    """
    overlap = ((mask*labeled_data)>0).astype("int")
    hits = pd.DataFrame(columns = ["label_value","hit_count"])
    indices=np.argwhere(overlap>0)
    for i in indices:
        label_val = labeled_data[tuple(i)]
        if not any(hits["label_value"]==label_val):
            hits= hits.append({"label_value":label_val, "hit_count":1},ignore_index=True)
        else:
            c = hits.loc[hits["label_value"]==label_val,"hit_count"]
            hits.loc[hits["label_value"] == label_val, "hit_count"] = c+1

    if only_max_hit:
        hits = hits[hits["hit_count"]==np.max(hits["hit_count"])]

    overlap_filtered_labels = np.zeros_like(labeled_data)

    # print(hits)
    for _,row in hits.iterrows():
        label_indices = labeled_data==row["label_value"]
        if hit_percentage_filter>0:
            if np.sum(label_indices)*hit_percentage_filter/100<= row["hit_count"]:
                overlap_filtered_labels[label_indices]=1
        else:
            overlap_filtered_labels[label_indices]=1

    return overlap_filtered_labels

def get_label_stats(sample,binary_masks,is_labeled=False,ignore_zero = True):
    if not isinstance(binary_masks, np.ndarray) or not isinstance(sample,np.ndarray):
        raise TypeError

    if binary_masks.shape != sample.shape:
        raise IndexError("Sample and mas must have the same size!")

    if not is_labeled:
        labeled_data, num_of_labels = labelData(binary_masks)
        if ignore_zero:
            labels = np.arange(1, num_of_labels+1, dtype="int")
        else:
            labels = np.arange(0, num_of_labels+1, dtype="int")
    else:
        labeled_data = binary_masks
        labels = np.unique(labeled_data)
        if ignore_zero:
            labels = labels[labels!=0]

    df_list = []

    for L in labels:
        ind = labeled_data==L

        df_list.append({"label":L,
                        "count":np.sum(ind),
                        "mean":np.mean(sample[ind]),
                        "min":np.min(sample[ind]),
                        "max":np.max(sample[ind]),
                        "sd":np.std(sample[ind])})
    df = pd.DataFrame(df_list)

    return labeled_data, df

def labeling_data_with_counts(data,remove_background = True):
    labeledData, _ = ndm.label(data)
    unique,counts = np.unique(labeledData,return_counts=True)
    counts = zip(unique,counts)
    counts = sorted(counts, key=lambda x: x[1], reverse=True)

    if remove_background:
        del(counts[0])

    return labeledData, counts

def labelData_highpass(data,threshold):

    filtered_data = np.zeros_like(data)

    filtered_data[data>threshold]=1

    outData = labelData(filtered_data)
    return outData

def shift_label_indices(orig_label_map, delta):
    if not isinstance(orig_label_map,np.ndarray):
        return orig_label_map

    if delta==0:
        return orig_label_map

    shifted = orig_label_map+delta
    shifted[orig_label_map==0]=0

    return shifted

def merge_label_maps(fix_label_map,shifting_label_map, method = 0, return_start_indices = False):
    """

    :param fix_label_map: fix label map
    :param shifting_label_map: label map, which's indices will be shifted
    :param method: 0 - overlapping label indices will be relabeled\n
    1 - fix label map values overrides shifting label map values\n
    2 - shifting label map values overrides fix label map values
    :param return_start_indices:
    :return: merged label map
    """
    if not isinstance(fix_label_map,np.ndarray):
        return

    if not isinstance(shifting_label_map,np.ndarray):
        return

    if fix_label_map.shape != shifting_label_map.shape:
        return

    F = copy(fix_label_map)
    S = copy(shifting_label_map)

    overlap = np.logical_and(fix_label_map > 0, S > 0).astype("int")

    delta = np.max(fix_label_map)
    overlap_delta = 0

    shifted = shift_label_indices(S,delta)
    merged = None

    if method == 0:
        labeled_overlap,_ = labelData(overlap)
        overlap_delta = np.max(shifted)

        shifted[overlap==1]=0
        F[overlap==1]=0

        shifted_labeled_overlap = shift_label_indices(labeled_overlap,overlap_delta)

        merged = F + shifted + shifted_labeled_overlap

    if method == 1:
        shifted[overlap==1]=0
        merged = F + shifted

    if method == 2:
        F[overlap==1]=0
        merged = F + shifted

    if return_start_indices:
        return merged, [delta+1,overlap_delta+1]

    else:
        return merged

def main():
    # A = np.array([1,0,3,0,2,2])
    # B = np.array([2,0,1,1,1,0])
    #
    # print(merge_label_maps(A,B,method=0))
    # print(merge_label_maps(A,B,method=1))
    # print(merge_label_maps(A,B,method=2))
    pass

if __name__ == '__main__':
    main()


#!/usr/bin/python3
"""Alta3 Research | RZFeeser@alta3.com
   Challenge Solution 01 - JSON to CSV"""

import pandas

def main():

    # create a dataframe from json
    df = pandas.read_json("5movies.json")

    # writeout dataframe to xls
    df.to_excel("5movies-translated-from-jason.xls")

if __name__ == "__main__":
    main()


# maximal marginal relevance (MMR)
import math

# read the BM25 file from Q1
# return the [Query_id document_id]
def readTheFile_Query_document_Q1(filename):
    qurey_document = []
    # read the idcg data
    with open(filename) as infile:
        for line in infile:
            qurey_document.append(line.split(" ")[0] + " " + line.split(" ")[2]+ " " + line.split(" ")[3]+ " " + line.split(" ")[4])
        return qurey_document

# read the query
# return the {query_id {1:2}, query_id {1:2}}
def readTheFile_query_term_vector(filename):
    query_id = dict()
    with open(filename) as infile:
        for line in infile:
            term_id_freqency = dict()
            line = line.strip(" \n")
            line = line.split(" ")
            for i in range(1, len(line)):
                term_id_freqency[int(line[i].split(":")[0])] = int(line[i].split(":")[1])
                query_id[int(line[0])] = term_id_freqency

    return query_id

# Almost the same as "readTheFile_query_term_vector"
# return the same format data but the key is document_id
def readTheFile_document_term_vector(filename):
    document_id = dict()
    with open(filename) as infile:
        for line in infile:
            term_id_freqency = dict()
            line = line.strip(" \n")
            line = line.split(" ")
            for i in range(1, len(line)):
                term_id_freqency[int(line[i].split(":")[0])] = int(line[i].split(":")[1])
                document_id[(line[0])] = term_id_freqency

    return document_id

# Calculate the Pd,dj value, it will be used when calculated the Portfolio score
def Pddj(d, dj):  # {} {}

    # d   {1:1,2:100,4:500}
    # dj  {1:1,2:100,4:500}

    #Fulfill the Set, the set contains all of the term_id that appear in both d and dj, like a union
    complete_set = set()
    for term_id in d:
        complete_set.add(term_id)
    for term_id in dj:
        complete_set.add(term_id)

    length_complete_set = len(complete_set)

    #Calculate the Mean of d and dj
    mean_d = 0.0
    mean_dj = 0.0
    for term_id in d:
        mean_d += d[term_id]
    mean_d /= length_complete_set

    for term_id in dj:
        mean_dj += dj[term_id]
    mean_dj /= length_complete_set

    # calculated the Numerator part
    # calculated the denominator part
    Numerator = 0.0
    denominator_left = 0.0
    denominator_right = 0.0
    for term_id in complete_set:
        Numerator += (d.get(term_id, 0) - mean_d ) * (dj.get(term_id, 0) - mean_dj )
        denominator_left += (d.get(term_id, 0) - mean_d ) ** 2
        denominator_right += (dj.get(term_id, 0) - mean_dj ) ** 2

    return Numerator / math.sqrt(denominator_left * denominator_right)

def portfolio(mmr_query_id, Q1_sequence, document_term_vector):  # [] {}
    # Q1_sequence [201 clueweb12-1700tw-11-11014, 201 clueweb12-1700tw-11-11014]
    # document_term_vector { clueweb12-1700tw-11-11014: {1:1,2:2,3:3}}
    b2 = 4.0
    b1 = -4.0
    # query_term_vector  -> q
    D = dict()  # doc_id * 100 are all in D dict
    D_ranking = dict()  # the relvant ranking are also put in D_ranking dict
    Dq = []  # whenever the D remove the element, then add it into the Dq

    for record in Q1_sequence:
        D[record.split(" ")[1]] = float(record.split(" ")[3])
        D_ranking[record.split(" ")[1]] = int(record.split(" ")[2])

    # The first ranking element is the BM25 1st one, so we simply manually print the result
    chosen_document_id = Q1_sequence[0].split(" ")[1]

    print("%d  q0  %s   %3d  %.7f" % (mmr_query_id, chosen_document_id, 1, D[chosen_document_id] - b1 * (1 / (D_ranking[chosen_document_id] + 1))))
    del D[chosen_document_id]
    chosen_score = -999.0
    chosen_document_id = ''

    # iterations for calculated the rest of score
    for i in range(1, 100):
        for document_id in D:

            # the sum_value is the part of the score function
            sum_value = 0
            for j in range(1, len(Dq) + 1):
                sum_value += (1 / pow(2, j)) * Pddj(document_term_vector[document_id], document_term_vector[Dq[j - 1]])
            # that's the score function of Portfolio ranking
            score = D[document_id] - b1 * (1 / (D_ranking[document_id] + 1) ) - 2 * b1 * sum_value

            # Only memorize the largest score and it's document id
            if score > chosen_score:
                chosen_score = score
                chosen_document_id = document_id

        # Add it into Dq dict and remove it from D dcit
        Dq.append(chosen_document_id)
        del D[chosen_document_id]
        print("%d  q0  %s   %3d  %.7f" % (mmr_query_id, chosen_document_id, i + 1, chosen_score))
        # reset the score for every iteraion
        chosen_score = -999.0

######################################## # main function Started here ################################################

if __name__ == '__main__':

    # return ['201 clueweb12-0905wb-50-14578 0 16.702539979527295'.....]
    Query_document_Q1 = readTheFile_Query_document_Q1("../data/Q4/Q1answer.txt")
    # return the {document_id {1:2}, document_id {1:2}}
    document_term_vector = readTheFile_document_term_vector("../data/Q4/document_term_vectors.dat")

    count = 0
    # used the Q1_sequence to store every 100 data and calculate their portfolio score
    Q1_sequence = []
    for query_document_record_in_Q1 in Query_document_Q1:
        Q1_sequence.append(query_document_record_in_Q1)
        count += 1
        if count % 100 == 0:
            # The index should be 201,202,....
            index = int(query_document_record_in_Q1.split(" ")[0])
            portfolio(int(200 + count/100), Q1_sequence, document_term_vector)
            #reset the Q1_sequence
            Q1_sequence = []


# Creates a csv file containing the coordinates of each molecule and its corresponding energy.

import pandas as pd
import numpy as np

path = '/home/s2113337/MAC-MIGS/IBM/'
energies = pd.read_csv(path+'energies.txt')

# get coordinates of all atoms i
#option: make 3 columns with tuples i.e. x col contains all x coordinates etc ??

def get_coordinates(n, energies, cols, all_cols):
    # for row n in energies file ...
    coord_path = path + energies['filename'][n]
    # read coordinates
    coords = pd.read_csv(coord_path, skiprows = 1, delim_whitespace = True)
    # make temporary df with coordinates for each atom
    coord_df = pd.DataFrame(data = coords.values, columns = cols)
    # if there are <17 atoms in compound then pack left over columns with nan
    buffer = np.empty((1,4*(21 - len(coord_df.index)))).reshape(1,-1)
    buffer[:] = np.nan
    data = np.concatenate((coord_df.values.reshape((1,-1)), buffer), axis = 1)
    # make df containing all coordinates
    df = pd.DataFrame(data, columns = all_cols)
    df.drop(columns='filename',inplace=True)
    return df, all_cols

cols = ['element','x coordinates', 'y coordinates', 'z coordinates']
# make enough columns to store all coordinates
all_cols = [x+'_'+str(i) for i in range(30) for x in cols]

# get coordinates for all
data = [get_coordinates(i, energies, cols, all_cols)[0] for i in range(len(energies.index))]
coord_df = pd.concat(data).reset_index()

coord_df = coord_df.drop(columns = ['index'])

energies_new = pd.concat([energies, coord_df], axis=1)
energies_new.to_csv(path+'energies_coordinates.csv')


#01
# 题目要求各类字母数量都一样！
# 注意变量名...不要搞错了！
N = int(input())
s = []
dics = []
for i in range(0,N):
    s.append(input().replace(" ",""))
for item in s:
    dic = {}
    for i in range(0,len(item)):
        if item[i] not in dic:
            dic[item[i]] = 1
        else:
            dic[item[i]] += 1
    dics.append(dic)
count = 1
tar = dics[0]
for i in range(1,len(dics)):
    cmp = dics[i]
    for k in tar.keys():
        if k not in cmp.keys():
            count += 1
            break
        else:
            if cmp[k] != tar[k]:
                count += 1
                break
print(count,end="")


""" Displayes
"""
from zope.component import getAdapter
from eea.reports.relations.interfaces import IGroupRelations
from Products.Five import BrowserView

class ReportContainerView(BrowserView):
    """ Default report view
    """
    def __init__(self, context, request):
        self.context = context
        self.request = request

    def is_replaced_by(self):
        """ Is this report replaced by?
        """
        relations = getAdapter(self.context, IGroupRelations)
        return relations.forward()

    def does_replace(self):
        """ Does this report replace other reports?
        """
        relations = getAdapter(self.context, IGroupRelations)
        return relations.backward()

    @property
    def serial_title(self):
        """ Compute serial title for display
        """
        field = self.context.getField('serial_title')
        if field.is_empty(self.context):
            return ''

        value = field.getAccessor(self.context)()

        alt = value[3] if len(value) > 3 else ''
        if alt:
            return alt

        vocab = field.Vocabulary(self.context)
        rtype = vocab.getValue(value[0]) if len(value) > 0  else ''
        number = value[1] if len(value) > 1 else 0
        year = value[2] if len(value) > 2 else -1

        text = rtype

        if text is None:
            text = value[0]

        if number:
            text += " No %s" % number

        if year != -1:
            text += "/%s" % year

        return text

    @property
    def publishers(self):
        """ Compute publishers to be displayed
        """
        field = self.context.getField('publishers')
        value = field.getAccessor(self.context)()
        vocab = field.Vocabulary(self.context)

        for publisher in value:
            yield vocab.getValue(publisher, publisher)

    @property
    def report(self):
        """ Report file
        """
        field = self.context.getField('file')
        return field.getAccessor(self.context)()

    @property
    def filename(self):
        """ Report filename
        """
        size = self.report.get_size()
        if not size:
            return ''

        field = self.context.getField('file')
        filename = field.getFilename(self.context)
        return filename if filename else self.context.pretty_title_or_id()

    @property
    def size(self):
        """ Report file size
        """
        return self.report.getObjSize(self.report)

    @property
    def items(self):
        """ Files children
        """
        return self.context.getFolderContents({
            'portal_type': ['Document', 'File', 'Link', 'Folder']
        })

    @property
    def has_children(self):
        """ Report has children?
        """
        return self.size or self.items

class ReportContainerDownload(BrowserView):
    """ Report download
    """
    def __init__(self, context, request):
        self.context = context
        self.request = request

    def __call__(self):
        """ Download
        """
        field = self.context.getField('file')
        return field.download(self.context, self.request, self.request.response)


#!/usr/bin/python3
"""it's a square module that defines a square"""

class Square:
    """it's a class that defines a square
    """
    def __init__(self, size=0, position=(0, 0)):
        """initialize size

        Args:
            size (int): square size.
            position (tuple): square position.
        """
        self.__size = size
        self.__position = position

    @property
    def size(self):
        """it's a property to retrieve the square size
        """
        return (self.__size)

    @size.setter
    def size(self, value):
        """to set the size value

        Args:
            value (int): size value
        """
        if type(value) != int:
            raise TypeError("size must be an integer")
        elif value < 0:
            raise ValueError("size must be >= 0")
        self.__size = value

    @property
    def position(self):
        """it's a property to retrieve the square position
        """
        return (self.__position)

    @position.setter
    def position(self, value):
        """to set the positions value

        Args:
            value (tuple): position value
        """
        if (not isinstance(value, tuple) or
                len(value) != 2 or
                not all(isinstance(num, int) for num in value) or
                not all(num >= 0 for num in value)):
            raise TypeError("position must be a tuple of 2 positive integers")

    def area(self):
        """return the square area
        """
        return (self.__size ** 2)

    def my_print(self):
        """a method that prints in stdout the square with the character #
        """
        if self.__size == 0:
            print()
        else:
            for i in range(self.__position[1]):
                print()
            for i in range(0, self.__size):
                for j in range(self.position[0]):
                    print(" ", end="")
                for k in range(self.size):
                    print("#", end="")
                print()


def isHappy(num,b:list=[]):
    digsq=0
    for i in range(len(str(num))):
        digsq += int( str(num)[i] )  ** (2)

    if digsq==1:
        b=num=digsq=None
        b=[]
        del b
        del num
        del digsq

        return True
    elif digsq in b:
        b=num=digsq=None
        b=[]
        del b
        del num
        del digsq

        return False
    else:
        b.append(digsq)
        ret=isHappy(digsq,b)
        b=num=digsq=None
        b=[]
        del b
        del num
        del digsq

        return ret
    del b
# x=[i for i in range(100) if isHappy(i)]
# 1 7 10 13 19 23 28 31 32 44 49 68 70 79 82 86 91 94 97 100
x=[]
dec=False
for j in range(100):
    dec=isHappy(j,b=[])
    if dec:
        x.append(j)

print(x)

'''

'''