common_func.py 5.32 KB
#-*- coding:utf-8 -*-

#Copyright (c) 2012, Bartłomiej Nitoń
#All rights reserved.

#Redistribution and use in source and binary forms, with or without modification, are permitted provided 
#that the following conditions are met:

#    Redistributions of source code must retain the above copyright notice, this list of conditions and 
#    the following disclaimer.
#    Redistributions in binary form must reproduce the above copyright notice, this list of conditions 
#    and the following disclaimer in the documentation and/or other materials provided with the distribution.

# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED 
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 
# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
# POSSIBILITY OF SUCH DAMAGE.

'''
Common functions used in Slowal application.
'''

from collections import Counter

from dictionary.models import Position, sortPositions, sortArguments, sortFrameChars

def args_to_pos_lists(arguments):
    positions_objs = []
    for arg in arguments:
        pos_text_rep = '{%s}' % (arg.text_rep)
        pos_objs = Position.objects.filter(text_rep=pos_text_rep) 
        if pos_objs.count() > 0:
            pos_obj = pos_objs.all()[0]
        else:
            pos_obj = Position(text_rep=pos_text_rep)
            pos_obj.save()
            pos_obj.arguments.add(arg)
        positions_objs.append(pos_obj)
    sorted_positions = []  
    sorted_pos_dict = sortPositions(positions_objs)
    for pos_dict in sorted_pos_dict:
        sorted_positions.append(pos_dict['position'])
    sort_pos_str_tab = []
    for sort_pos in sorted_positions:
        sort_pos_str_tab.append(sort_pos.text_rep)  
    return (sort_pos_str_tab, positions_objs)   

def position_data_to_text_rep(categories, arguments):
    sorted_arguments = sortArguments(arguments.all())
    sorted_categories = categories.order_by('priority')
    args_text_reps = [arg.text_rep for arg in sorted_arguments]
    cats_text_reps = [cat.category for cat in sorted_categories]
    position_text_rep = u'%s{%s}' % (','.join(cats_text_reps), ';'.join(args_text_reps))
    return position_text_rep

def frame_data_to_text_rep(characteristics, positions):
    sorted_chars = sortFrameChars(characteristics.all())
    sorted_positions = sortPositions(positions.all())
    chars_text_reps = [char.value.value for char in sorted_chars]
    positions_text_reps = [pos['position'].text_rep for pos in sorted_positions]
    frame_text_rep = u'%s:%s' % (':'.join(chars_text_reps), '+'.join(positions_text_reps)) 
    return frame_text_rep
    

#######################

def subframe_exists(frames, subframe):
    exists = False
    for frame in frames:
        if is_subframe(frame, subframe):
            exists = True
            break
    return exists        

def is_subframe(frame, subframe, ignore_characteristics=True):
    match = False
    wrong_frame = False
    for subframe_pos in subframe.positions.all(): 
        unmatched_poss = list(frame.positions.all())
        smallest_poss = None
        for frame_pos in unmatched_poss:
            frame_args = set(frame_pos.arguments.all())
            subframe_args = set(subframe_pos.arguments.all())
            if len(subframe_args - frame_args) == 0:
                if (not smallest_poss or 
                    smallest_poss.arguments.count() > frame_pos.arguments.count()): 
                    smallest_poss = frame_pos
        if not smallest_poss:
            wrong_frame = True
        else:
            unmatched_poss.remove(smallest_poss)
    if not wrong_frame:
        match = True
    return match

def frame_structure_exists(frames, searched_frame):
    exists = False
    for frame in frames:
        if have_same_structure(frame, searched_frame):
            exists = True
            break
    return exists 

# sprawdza czy dwa schematy posiadaj taka sama strukture, nie uwzglednia charakterystyk schematu
def have_same_structure(frame1, frame2):
    same_structure = True
    if (frame1.positions.count() == frame2.positions.count()):
        for pos1 in frame1.positions.all():
            pos_match = False
            for pos2 in frame2.positions.all():
                if have_same_positions_structure(pos1, pos2):
                    pos_match = True
                    break
            if not pos_match:
                same_structure = False
                break
    else:
        same_structure = False
    return same_structure              
            
def have_same_positions_structure(pos1, pos2):
    same_structure = False
    pos1_args = Counter(pos1.arguments.all())
    pos2_args = Counter(pos2.arguments.all())
    pos1_cats = Counter(pos1.categories.all())
    pos2_cats = Counter(pos2.categories.all())
    if(pos1_args == pos2_args and pos1_cats==pos2_cats):
        same_structure = True
    return same_structure