예제 #1
0
    def __init__(self, ui_filename):
        # Load UI
        self.dialog = loader.load(
            os.path.join(os.path.dirname(__file__), ui_filename), None)
        self.dialog.show()

        # Set title image
        pixmap = QtGui.QPixmap(
            os.path.join(os.path.dirname(__file__), 'title.png'))
        self.dialog.label.setPixmap(pixmap)

        # Button actions
        self.dialog.btn_getrecipes.clicked.connect(self.btn_getrecipe)
        self.dialog.btn_resetquery.clicked.connect(self.btn_resetquery)
        self.dialog.btn_rate.clicked.connect(self.btn_rate)

        # Menu actions
        self.dialog.actionAbout.triggered.connect(self.about)
        self.dialog.actionConstraints.triggered.connect(
            self.load_constraints_file)
        self.dialog.actionLibrary.triggered.connect(self.load_library_file)
        self.dialog.actionExport.triggered.connect(
            self.export_constraints_file)
        self.dialog.actionUser_Manual.triggered.connect(self.open_user_manual)

        # Slider action
        self.dialog.slider_evaluation.valueChanged.connect(self.slider_change)

        # Init CBR
        self.cbr = CBR(os.path.join(DATA_PATH, 'case_library.xml'),
                       verbose=True)
예제 #2
0
    def load_library_file(self):
        library_file, _ = QtWidgets.QFileDialog.getOpenFileName(
            self.dialog, "Open Library", DATA_PATH, 'XML Files (*.xml)')
        print(f'Load CBR library from: {library_file} ...')

        try:
            # Init CBR
            self.cbr = CBR(library_file, verbose=True)
        except Exception as e:
            # Prompt error message
            button = QtWidgets.QMessageBox.critical(
                self.dialog,
                "Library error!",
                f'Library error. Choose a valid case library.\nException:{str(e)}',
                buttons=QtWidgets.QMessageBox.Close,
                defaultButton=QtWidgets.QMessageBox.Close)
예제 #3
0
def get_curs(start_date, end_date):
    start_date = datetime.datetime.strptime(start_date, '%Y-%m-%dT00:00:00')
    end_date = datetime.datetime.strptime(end_date, '%Y-%m-%dT00:00:00')

    days = [start_date + datetime.timedelta(days=x) for x in range((end_date - start_date).days + 1)]

    cbr = CBR()
    for day in days:
        curs = cbr.get_curs_on_date(day.strftime('%Y-%m-%d'))
        for c in curs['curs']:
            if db.session.query(Valuta).get({'id': c['Vcode']}) is None:
                valuta = Valuta(id=int(c['Vcode']), ch_code=c['VchCode'], name=c['Vname'])
                db.session.add(valuta)
                db.session.commit()

            if db.session.query(Curs).filter(Curs.code == c['Vcode']).filter(
                    Curs.date == day.strftime('%Y-%m-%d')).first() is None:
                curs_record = Curs(code=int(c['Vcode']), date=day, nom=c['Vnom'], curs=c['Vcurs'])
                db.session.add(curs_record)
                db.session.commit()
예제 #4
0
import random
import os
import json
import sys

sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
from cbr import CBR

DATA_PATH = '../Data'

# Create cocktails CBR
cocktails_cbr = CBR(os.path.join(DATA_PATH, 'case_library.xml'), verbose=True)

number_of_tests = [100, 500, 1000]

n_constraints = 8

for n_tests in number_of_tests:
    names = [f"cocktail_{i}" for i in range(n_tests)]

    all_tests = {}

    for i in range(n_tests):

        my_dict = {"name": names[i]}

        n_categories, n_glasses, n_alc_types, n_basic_tastes, n_ingredients, n_exc_ingredients, n_exc_alc_types, \
            n_exc_basic_tastes = [random.randint(0, 3) for i in range(n_constraints)]

        my_dict["category"] = random.sample(cocktails_cbr.categories,
                                            n_categories)
예제 #5
0
    positional arguments:
        caselibrary           Filepath of the XML case library

        optional arguments:
        -h, --help            show this help message and exit
        --verbosity VERBOSITY
                                Output verbosity level. Set to 1 to print debug
                                messages.
        -c CONSTRAINTS, --constraints CONSTRAINTS
                                Filepath of the JSON constraints file
    """
    # Input arguments
    args = parse_arguments()
    
    # Initialize CBR
    cbr = CBR(args.caselibrary, verbose=args.verbosity)
    
    # Get user constraints
    constraints = get_constraints(args, cbr)   

    # Get new case
    retrieved_case, adapted_case, original = cbr.get_new_case(constraints)
    
    # Print retrieved case
    print('\n=====================================================================')
    print(f'Retrieved cocktail: {retrieved_case.find("name").text}')
    print('\nIngredients:')
    cbr.print_ingredients(retrieved_case)
    print('\nPreparation:')
    cbr.print_preparation(retrieved_case) 
    
예제 #6
0
from cbr import CBR
import utils

DATA_PATH = os.path.join(os.path.dirname(__file__), '..', 'Data')

# constraints = {'name': 'SEL-cocktail', 'category': ['shot'], 'glass_type': ['old-fashioned glass'],
#                'ingredients': ['cranberry juice', 'malibu rum'], 'alc_type': ['sweet liqueur', 'vodka'],
#                'basic_taste': [], 'exc_ingredients': ['amaretto', 'pineapple juice'], 'exc_alc_type': ['cachaca'],
#                'exc_basic_taste': ['spicy']}

# Load constraints from JSON
constraints = utils.load_constraints(
    os.path.join(DATA_PATH, 'my_constraints.json'))

# Create cocktails CBR
cocktails_cbr = CBR(os.path.join(DATA_PATH, 'case_library.xml'), verbose=True)
print('Cocktails CBR initialized')

print('\nConstraints:')
print(constraints)

# Retrive cocktail wight given constraints
c = cocktails_cbr._retrieval(constraints)
print(f'\n{c.find("name").text} cocktail retrieved')
print('\nOriginal Ingredients:')
cocktails_cbr.print_ingredients(c)
print('\nOriginal Preparation:')
cocktails_cbr.print_preparation(c)

adapted_cocktail, n_changes = cocktails_cbr._adaptation(constraints, c)
print(
예제 #7
0
class CocktailsApp():
    """ Cocktails App
    
    Define and configure various functions used to detect button clicks and
    retrieve text from input boxes.
    """
    def __init__(self, ui_filename):
        # Load UI
        self.dialog = loader.load(
            os.path.join(os.path.dirname(__file__), ui_filename), None)
        self.dialog.show()

        # Set title image
        pixmap = QtGui.QPixmap(
            os.path.join(os.path.dirname(__file__), 'title.png'))
        self.dialog.label.setPixmap(pixmap)

        # Button actions
        self.dialog.btn_getrecipes.clicked.connect(self.btn_getrecipe)
        self.dialog.btn_resetquery.clicked.connect(self.btn_resetquery)
        self.dialog.btn_rate.clicked.connect(self.btn_rate)

        # Menu actions
        self.dialog.actionAbout.triggered.connect(self.about)
        self.dialog.actionConstraints.triggered.connect(
            self.load_constraints_file)
        self.dialog.actionLibrary.triggered.connect(self.load_library_file)
        self.dialog.actionExport.triggered.connect(
            self.export_constraints_file)
        self.dialog.actionUser_Manual.triggered.connect(self.open_user_manual)

        # Slider action
        self.dialog.slider_evaluation.valueChanged.connect(self.slider_change)

        # Init CBR
        self.cbr = CBR(os.path.join(DATA_PATH, 'case_library.xml'),
                       verbose=True)

        # Redirect stdout and stderr
        # sys.stdout = OutLog(self.dialog.logText)
        # sys.stderr = OutLog(self.dialog.logText, color=QtGui.QColor(255,0,0))

    def open_user_manual(self):
        """ Open Ueser Manual PDF
        """
        filename = os.path.join(os.path.dirname(__file__), '..',
                                'Documentation', USER_MANUAL)
        filename = os.path.abspath(filename)
        print(f'Opening {filename}...')
        wb.open_new(r'file://{}'.format(filename))

    def slider_change(self):
        """ When evaluation slider changes, update label.
        """
        self.dialog.label_rating.setText(
            str(self.dialog.slider_evaluation.value()))

    def btn_rate(self):
        """ When button "Rate" is clicked, evalute adapted cocktail
        """
        evaluation = self.dialog.slider_evaluation.value()
        self.cbr.evaluate_new_case(self.retrieved_cocktail,
                                   self.adapted_cocktail, evaluation)
        self.dialog.btn_rate.setEnabled(False)

    def btn_resetquery(self):
        """ When the button "Reset Query" is clicked, clear all the text boxes.
        """
        self.dialog.text_ingredients.clear()
        self.dialog.text_alc_types.clear()
        self.dialog.text_basic_tastes.clear()
        self.dialog.text_glass_types.clear()
        self.dialog.text_exc_ingredients.clear()
        self.dialog.text_exc_alc_types.clear()
        self.dialog.text_exc_basic_tastes.clear()
        self.dialog.text_name.clear()
        self.dialog.or_recipe_text.clear()
        self.dialog.ad_recipe_text.clear()

        cat_checkboxes = self.dialog.categoriesBox.findChildren(
            QtWidgets.QCheckBox)
        for c in cat_checkboxes:
            c.setChecked(False)

        self.dialog.btn_rate.setEnabled(True)

    def btn_getrecipe(self):
        """ When the button "Get Recipe" is clicked, retrieve inputs,
        call CBR and display retrieved and adapted recipes.
        """
        # Get constraints from user input
        constraints = self.get_constraints()

        # Check if constraints contain any error
        constraints_err = self.cbr.check_constraints(constraints)
        if len(constraints_err):
            # Prompt error message
            button = QtWidgets.QMessageBox.critical(
                self.dialog,
                "Constraints error!",
                "\n".join(constraints_err),
                buttons=QtWidgets.QMessageBox.Close,
                defaultButton=QtWidgets.QMessageBox.Close)
        else:
            # Print constraints
            print(f'constraints: {constraints}\n')

            self.test_cbr(constraints)

    def get_constraints(self):
        """ Get constraints from user input

        Returns:
            dict: constraints
        """
        ingredients = self.dialog.text_ingredients.text().lower().split(', ')
        if not ingredients[0]:
            ingredients = []

        alc_types = self.dialog.text_alc_types.text().lower().split(', ')
        if not alc_types[0]:
            alc_types = []

        basic_tastes = self.dialog.text_basic_tastes.text().lower().split(', ')
        if not basic_tastes[0]:
            basic_tastes = []

        glass_types = self.dialog.text_glass_types.text().lower().split(', ')
        if not glass_types[0]:
            glass_types = []

        exc_ingredients = self.dialog.text_exc_ingredients.text().lower(
        ).split(', ')
        if not exc_ingredients[0]:
            exc_ingredients = []

        exc_alc_types = self.dialog.text_exc_alc_types.text().lower().split(
            ', ')
        if not exc_alc_types[0]:
            exc_alc_types = []

        exc_basic_tastes = self.dialog.text_exc_basic_tastes.text().lower(
        ).split(', ')
        if not exc_basic_tastes[0]:
            exc_basic_tastes = []

        name = self.dialog.text_name.text()
        if not name:
            name = 'SEL-Cocktail'

        cat_checkboxes = self.dialog.categoriesBox.findChildren(
            QtWidgets.QCheckBox)
        categories = [
            c.text().lower() for c in cat_checkboxes if c.isChecked()
        ]

        constraints = {
            'name': name,
            'category': categories,
            'glass_type': glass_types,
            'ingredients': ingredients,
            'alc_type': alc_types,
            'basic_taste': basic_tastes,
            'exc_ingredients': exc_ingredients,
            'exc_alc_type': exc_alc_types,
            'exc_basic_taste': exc_basic_tastes
        }

        return constraints

    def test_cbr(self, constraints):
        """ Run CBR and obtain cocktail from constraints

        Args:
            constraints (dict): constraints to fulfill
        """
        # Get new case
        self.retrieved_cocktail, self.adapted_cocktail, original = self.cbr.get_new_case(
            constraints)

        # Get info about retrieved and adapted cocktails
        or_name = self.retrieved_cocktail.find("name").text
        print(f'\nRetrieved cocktail: {or_name}')
        print('\nOriginal Ingredients:')
        or_ingr_str = self.cbr.print_ingredients(self.retrieved_cocktail)
        print('\nOriginal Preparation:')
        or_prep_str = self.cbr.print_preparation(self.retrieved_cocktail)

        ad_name = self.adapted_cocktail.find("name").text
        print(f'\nAdapted cocktail: {ad_name}')
        print('\nAdapted Ingredients:')
        ad_ingr_str = self.cbr.print_ingredients(self.adapted_cocktail)
        print('\nAdapted Preparation:')
        ad_prep_str = self.cbr.print_preparation(self.adapted_cocktail)

        # Output original and adapte recipe
        self.dialog.or_recipe_text.setText(
            f'{or_name}\n\nIngredients:\n{or_ingr_str}\nPreparation:\n{or_prep_str}'
        )
        self.dialog.ad_recipe_text.setText(
            f'{ad_name}\n\nIngredients:\n{ad_ingr_str}\nPreparation:\n{ad_prep_str}'
        )

        # Evaluate if cocktail is derivated (not original)
        if not original:
            # Enable rating button
            self.dialog.btn_rate.setEnabled(True)

    def about(self):
        about_text = """<b>Cocktails Recipes CBR</b>
                            <p>Copyright &copy; 2021. Some rights reserved.
                            <p>This CBR application is part of the final project of SEL PW3 
                            <p>(MAI - UPC) 
                            <p>
                            <p>Python {} - PySide version {} - Qt version {} on {}""".format(
            platform.python_version(), PySide2.__version__, QtCore.__version__,
            platform.system())
        dlg = loader.load(os.path.join(os.path.dirname(__file__), 'about.ui'),
                          None)
        dlg.label.setText(about_text)
        # Set image
        pixmap = QtGui.QPixmap(
            os.path.join(os.path.dirname(__file__), 'beers.png'))
        dlg.label_beers.setPixmap(pixmap)
        dlg.exec_()

    def load_constraints_file(self):
        constraints_file, _ = QtWidgets.QFileDialog.getOpenFileName(
            self.dialog, "Open Constraints", DATA_PATH, 'Json Files (*.json)')
        print(f'Load constraints from: {constraints_file} ...')

        # Load constraints
        constraints = load_constraints(constraints_file)

        # Set constraints
        self.dialog.text_ingredients.setText(', '.join(
            constraints['ingredients']))
        self.dialog.text_alc_types.setText(', '.join(constraints['alc_type']))
        self.dialog.text_basic_tastes.setText(', '.join(
            constraints['basic_taste']))
        self.dialog.text_glass_types.setText(', '.join(
            constraints['glass_type']))
        self.dialog.text_exc_ingredients.setText(', '.join(
            constraints['exc_ingredients']))
        self.dialog.text_exc_alc_types.setText(', '.join(
            constraints['exc_alc_type']))
        self.dialog.text_exc_basic_tastes.setText(', '.join(
            constraints['exc_basic_taste']))
        self.dialog.text_name.setText(constraints['name'])

        # Set categories
        cat_checkboxes = self.dialog.categoriesBox.findChildren(
            QtWidgets.QCheckBox)
        for c in cat_checkboxes:
            if c.text().lower() in constraints['category']:
                c.setChecked(True)
            else:
                c.setChecked(False)

    def load_library_file(self):
        library_file, _ = QtWidgets.QFileDialog.getOpenFileName(
            self.dialog, "Open Library", DATA_PATH, 'XML Files (*.xml)')
        print(f'Load CBR library from: {library_file} ...')

        try:
            # Init CBR
            self.cbr = CBR(library_file, verbose=True)
        except Exception as e:
            # Prompt error message
            button = QtWidgets.QMessageBox.critical(
                self.dialog,
                "Library error!",
                f'Library error. Choose a valid case library.\nException:{str(e)}',
                buttons=QtWidgets.QMessageBox.Close,
                defaultButton=QtWidgets.QMessageBox.Close)

    def export_constraints_file(self):
        constraints_file, _ = QtWidgets.QFileDialog.getSaveFileName(
            self.dialog, "Save File", DATA_PATH, 'Json Files (*.json)')
        print(f'Save constraints to: {constraints_file} ...')
        constraints = self.get_constraints()
        with open(constraints_file, 'w') as f:
            json.dump(constraints, f, indent=1)
예제 #8
0
def perform_tests(args):
    # Convert CSV to xml to make sure that case_library.xml only contains original recipes
    xml_file = os.path.join(DATA_PATH, 'case_library.xml')
    create_xml_library(args.path, xml_file)

    cbr = CBR(xml_file)
    get_new_case_times = []
    evaluated_learn_new_case_times = []
    with open(args.tests) as json_file:
        data = json.load(json_file)
        for key, value in data.items():
            # Get test constraints of each case
            constraints = value
            # Get new case
            start_ra = time.time()
            retrieved_case, adapted_case, original = cbr.get_new_case(
                constraints)
            end_ra = time.time()
            get_new_case_times.append(end_ra - start_ra)

            # Evaluate if cocktail is derived (not original)
            start_el = time.time()
            if not original:
                cbr.evaluate_new_case(retrieved_case, adapted_case, 8.0)
            end_el = time.time()
            evaluated_learn_new_case_times.append(end_el - start_el)

        total_times = np.array(get_new_case_times) + np.array(
            evaluated_learn_new_case_times)

        mean_ra_time = np.mean(np.array(get_new_case_times))
        mean_el_time = np.mean(np.array(evaluated_learn_new_case_times))
        mean_total_time = np.mean(total_times)
        print(
            f"The average time needed for retrieval and adaptation steps is : {mean_ra_time}"
        )
        print(
            f"The average time needed for evaluation and adaptation steps is: {mean_el_time}"
        )
        print(
            f"The average total time for the complete CBR cycle over a new case is : {mean_total_time}"
        )

        experiments = [i for i in range(len(total_times))]
        plt.plot(experiments, total_times, color="red", label="Total Time")
        plt.plot(experiments,
                 np.array(get_new_case_times),
                 color="green",
                 label="Retrieval and Adaptation")
        plt.plot(experiments,
                 np.array(evaluated_learn_new_case_times),
                 color="blue",
                 label="Evaluation and Learning")
        plt.plot([0, len(total_times)], [mean_total_time, mean_total_time],
                 "--",
                 color="red",
                 label="Average Total Time")
        plt.title(
            f"Times needed for each phase for {len(total_times)} experiments")
        plt.xlabel("Queries performed")
        plt.ylabel("Time in seconds")
        plt.legend(loc="upper left")
        plt.savefig(f"{len(total_times)}_results.png")
        plt.show()

    with open(f"./{len(total_times)}_results.txt", 'w') as output:
        print(get_new_case_times, file=output)
        print(evaluated_learn_new_case_times, file=output)