def formQuizStart(relation, fds, mvds): inputString = "<div class=\"well\">Du hast folgendes eingegeben:</div>" if DBnormalizer.longAttributeNamesUsed(): inputString = inputString = inputString + views.inputToString( relation, fds, mvds) inputString = inputString + "<div class=\"well\">Dass du gleich nicht so viel tippen musst, machen wir daraus mal das hier:</div>" DBnormalizer.resetDictionaries() inputString = inputString + views.inputToString(relation, fds, mvds) relationString = views.setOfAttributesToString(relation) fdsString = views.fdsToString(fds) + views.mvdsToString(mvds) html = """<form class="form" action="quiz.py" method="POST">""" html = html + "<p>Willkommen beim Quiz.</p>" html = html + """<input type="hidden" value=" """ + relationString + """" name="relation"></input> <input type="hidden" value=" """ + fdsString + """" name="fds"></input> <div class="row"> <div class="col-xs-2 pull-right"> <br/> <button id="step" name="step" type="submit" class="btn btn-primary" value="1">Start</button> </div> </div> </form> """ return views.getJumbotron("Hallo.", html) + inputString
def validateDecompositionEnd(relations, fds, mvds, targetnf): if targetnf == "BCNF": i,r = DBnormalizer.getFirstNonBCNFRelation(relations, fds) else: i,r = DBnormalizer.getFirstNon4NFRelation(relations, fds, mvds) if i==-1: return True else: return False
def validateDecompositionSplitNewRelations(fdsInR, mvdsInR, splitrelation, newfirstrelation, newsecondrelation, targetnf): possibleSplitFdsMvds = DBnormalizer.getAllNonBCNFfds(splitrelation, fdsInR) if targetnf == "4NF": possibleSplitFdsMvds.extend(DBnormalizer.getAllNon4NFmvds(splitrelation, fdsInR, mvdsInR)) for fdmvd in possibleSplitFdsMvds: r1,r2 = DBnormalizer.splitRelationAtFdMvd(splitrelation, fdmvd) if r1 == newfirstrelation and r2 == newsecondrelation: return True return False
def printResults(string): x = DBnormalizer.parseInput(string) if len(x) < 3: return x[0] else: relation = x[0] fds = x[1][:] mvds = x[2][:] numberOfAttributes = x[3] result = DBnormalizer.computeEverything(relation, fds, mvds) return views.resultToString(relation, x[1], x[2], result)
def validateDecompositionSplit(fds, mvds, splitrelation, newfirstrelation, newsecondrelation, targetnf): fdsInR = DBnormalizer.fdsInRelation(fds, splitrelation) mvdsInR = DBnormalizer.mvdsInRelation(mvds, splitrelation) normalforms = DBnormalizer.getNormalForms(splitrelation, fdsInR, mvdsInR) if targetnf == "BCNF": i=3 else: i=4 if not normalforms[i]: #splitrelation not in BCNF/4NF, user is correct so far return validateDecompositionSplitNewRelations(fdsInR, mvdsInR, splitrelation, newfirstrelation, newsecondrelation, targetnf) else: #splitrelation already in BCNF/4NF, user is wrong, relation must not be splitted return False
def validateFinalCanonicalCoverFds(fds, fdinputstring): inputfds,inputmvds = DBnormalizer.parseInputFDsMVDs(fdinputstring) correctfds = DBnormalizer.collapseEqualLeftSides(fds[:]) correct = True for fd in correctfds: if fd not in inputfds: correct = False for fd in inputfds: if fd not in correctfds: correct = False if correct: return correctfds else: return []
def validateRightReduction(fds, rightSides): newfds = fds[:] for i, rs in enumerate(rightSides): newfds[i] = (fds[i][0], rs) validRightReduction = True for i, fd in enumerate(fds): if DBnormalizer.closure(fd[0], newfds) != DBnormalizer.closure(fd[0], fds) or not rightSides[i] <= fd[1]: validRightReduction = False if validRightReduction: if newfds != DBnormalizer.rightReduction(newfds): validRightReduction = False if validRightReduction: return newfds else: return []
def validateLeftReduction(fds, leftSides): newfds = fds[:] for i, ls in enumerate(leftSides): newfds[i] = (ls, fds[i][1]) validLeftReduction = True for i, fd in enumerate(fds): if DBnormalizer.closure(fd[0], newfds) != DBnormalizer.closure(fd[0], fds) or DBnormalizer.closure(leftSides[i], newfds) != DBnormalizer.closure(leftSides[i], fds) or not leftSides[i] <= fd[0]: validLeftReduction = False if validLeftReduction: if newfds != DBnormalizer.leftReduction(newfds): validLeftReduction = False if validLeftReduction: return newfds else: return []
def setOfAttributesToString(attributes, key=None): setOfAttributesString = "" delimiter = "" for i, attr in enumerate(sortSet(attributes)): if attr != DBnormalizer.EMPTY_SET: if key is not None and attr in key: underlineAttribute = True else: underlineAttribute = False if DBnormalizer.longAttributeNamesUsed(): attr = DBnormalizer.dictionaryReplToName[attr] if i < len(attributes) - 1: delimiter = ", " else: delimiter = "" elif len(attr) > 1: #fun mode if DBnormalizer.EMPTY_SET in attributes: offset = 2 else: offset = 1 if i < len(attributes) - offset: delimiter = ", " else: delimiter = "" setOfAttributesString = setOfAttributesString + underlineString( attr, underlineAttribute) + delimiter return setOfAttributesString
def validatePrimaryKeys(relations, fds, primarykeys): keysAndFds = DBnormalizer.getKeysAndFDsMVDsOfRelations(relations, fds) valid = True for i, pk in enumerate(primarykeys): if pk not in keysAndFds[i]['keys']: valid=False return valid
def relationToString(relation, i, candidateKeys = None, fds = [], mvds = [], additionalFds = [], primaryKey=None): if candidateKeys is not None: if mvds: show = "FDs/MVDs" else: show = "FDs" if primaryKey is None: primaryKey = DBnormalizer.getFirstKey(candidateKeys) tooltiptext = "<div class='panel panel-primary'><div class='panel-heading'><h5 class='panel-title'>"+show+"</h5></div><div class='panel-body'>" if not fds and not mvds: tooltiptext = tooltiptext + "In dieser Relation gelten keine nicht-trivialen Abhängigkeiten." else: tooltiptext = tooltiptext + fdsToHtmlString(fds, additionalFds)+mvdsToHtmlString(mvds) tooltiptext = tooltiptext + "</div></div><div class='panel panel-primary'><div class='panel-heading'><h3 class='panel-title'>Kandidatenschlüssel</h3></div><div class='panel-body'>"+ keysToString(candidateKeys)+"</div></div>" if "*" in tooltiptext: tooltiptext = tooltiptext + "<h6><small>* Unter anderem diese FD kann mithilfe der Armstrong-Axiome zusätzlich hergeleitet werden</small></h6>" else: #Do not show tooltip, only blank relation primaryKey = None tooltiptext = "" relationString="R<sub>"+str(i)+"</sub>:={" relationString=relationString+setOfAttributesToString(relation, primaryKey) relationString = relationString + "}" relationString = addPopoverText(relationString, relationString, tooltiptext) return relationString
def setOfAttributesToString(attributes, key=None): setOfAttributesString="" delimiter="" for i,attr in enumerate(sortSet(attributes)): if attr != DBnormalizer.EMPTY_SET: if key is not None and attr in key: underlineAttribute=True else: underlineAttribute=False if DBnormalizer.longAttributeNamesUsed(): attr = DBnormalizer.dictionaryReplToName[attr] if i < len(attributes)-1: delimiter=", " else: delimiter="" elif len(attr)>1: #fun mode if DBnormalizer.EMPTY_SET in attributes: offset = 2 else: offset=1 if i < len(attributes)-offset : delimiter=", " else: delimiter="" setOfAttributesString = setOfAttributesString + underlineString(attr, underlineAttribute) + delimiter return setOfAttributesString
def synthesealgorithmToString(algorithmResult, satisfiedNormalForms): if DBnormalizer.longAttributeNamesUsed(): numberOfColumns = 2 else: numberOfColumns = 4 if satisfiedNormalForms[2]: #original schema was already in 3NF. Let the user know this info = infoNFwasAlreadySatisfied("3NF") else: info = "" resultString = getPanelHeading("synthese", False, info) + """<div class="row">""" resultString = resultString + wrapInPanel( "<span class='badge'>1</span> Kanonische Überdeckung", fdsToHtmlString(algorithmResult[0]), numberOfColumns) resultString = resultString + wrapInPanel( "<span class='badge'>2</span> Relationsschemata formen", schemaToString(algorithmResult[1][0], algorithmResult[1][1]), numberOfColumns) resultString = resultString + wrapInPanel( "<span class='badge'>3</span> Schlüssel hinzufügen", schemaToString(algorithmResult[2][0], algorithmResult[2][1]), numberOfColumns) resultString = resultString + wrapInPanel( "<span class='badge'>4</span> Redundante Schemata eliminieren", "<strong>" + schemaToString(algorithmResult[3][0], algorithmResult[3][1]) + "</strong>", numberOfColumns) resultString = resultString + """</div>""" return resultString
def validateAddKeyRelation(originrelation, fds, relations, keyrelationstring): keys = DBnormalizer.getKeys(originrelation, fds) keyrelation = frozenset(keyrelationstring) | frozenset(EMPTY_SET) newrelations = relations[:] if len(DBnormalizer.addRelationWithKey(relations[:], keys)) > len(relations): #key must be added if keyrelation in keys: newrelations.append(keyrelation) return newrelations else: return [] else: #no key must be added if keyrelationstring == "": return newrelations else: return []
def printQuizStart(string): x = DBnormalizer.parseInput(string) if len(x) < 3: return x[0] else: relation = x[0] fds = x[1][:] mvds = x[2][:] return quizForms.formQuizStart(relation, fds, mvds)
def validateRemoveRelations(relations, removeindices): redundantindices=[] newrelations = DBnormalizer.removeRedundantSchemas(relations) newrelationsuser = [] for i, relation in enumerate(relations): if str(i) not in removeindices: newrelationsuser.append(relation) if sorted(newrelations[:]) == sorted(newrelationsuser[:]): return newrelations else: return []
def canonicalCoverToString(algorithmResult): if DBnormalizer.longAttributeNamesUsed(): numberOfColumns = 2 else: numberOfColumns = 4 resultString = getPanelHeading("canonicalCover",False)+"""<div class="row">""" resultString = resultString+wrapInPanel("<span class='badge'>1</span> Linksreduktion", fdsToHtmlString(algorithmResult[0]),numberOfColumns) resultString = resultString+wrapInPanel("<span class='badge'>2</span> Rechtsreduktion", fdsToHtmlString(algorithmResult[1]),numberOfColumns) resultString = resultString+wrapInPanel("<span class='badge'>3</span> α→∅ entfernen", fdsToHtmlString(algorithmResult[2]),numberOfColumns) resultString = resultString+wrapInPanel("<span class='badge'>4</span> FDs zusammenfassen", "<strong>"+fdsToHtmlString(algorithmResult[3])+"</strong>",numberOfColumns) resultString = resultString + """</div>""" return resultString
def formQuizStart(relation, fds, mvds): inputString ="<div class=\"well\">Du hast folgendes eingegeben:</div>" if DBnormalizer.longAttributeNamesUsed(): inputString = inputString = inputString + views.inputToString(relation, fds,mvds) inputString = inputString + "<div class=\"well\">Dass du gleich nicht so viel tippen musst, machen wir daraus mal das hier:</div>" DBnormalizer.resetDictionaries() inputString = inputString + views.inputToString(relation, fds,mvds) relationString = views.setOfAttributesToString(relation) fdsString = views.fdsToString(fds)+views.mvdsToString(mvds) html = """<form class="form" action="quiz.py" method="POST">""" html = html + "<p>Willkommen beim Quiz.</p>" html = html + """<input type="hidden" value=" """+relationString+"""" name="relation"></input> <input type="hidden" value=" """+fdsString+"""" name="fds"></input> <div class="row"> <div class="col-xs-2 pull-right"> <br/> <button id="step" name="step" type="submit" class="btn btn-primary" value="1">Start</button> </div> </div> </form> """ return views.getJumbotron("Hallo.", html ) + inputString
def validateCandidateKeys(relation, fds, inputKeysString): keys = DBnormalizer.getKeys(relation, fds) inputKeysArray = inputKeysString.split() inputKeys = set("") for k in inputKeysArray: inputKeys.add(frozenset(k)|frozenset(EMPTY_SET)) if not inputKeys: inputKeys.add(frozenset(EMPTY_SET)) isCorrect = True for k in keys: if k not in inputKeys: isCorrect = False for k in inputKeys: if k not in keys: isCorrect = False return isCorrect
def synthesealgorithmToString(algorithmResult, satisfiedNormalForms): if DBnormalizer.longAttributeNamesUsed(): numberOfColumns = 2 else: numberOfColumns = 4 if satisfiedNormalForms[2]: #original schema was already in 3NF. Let the user know this info = infoNFwasAlreadySatisfied("3NF") else: info = "" resultString = getPanelHeading("synthese",False,info)+"""<div class="row">""" resultString = resultString+wrapInPanel("<span class='badge'>1</span> Kanonische Überdeckung", fdsToHtmlString(algorithmResult[0]),numberOfColumns) resultString = resultString+wrapInPanel("<span class='badge'>2</span> Relationsschemata formen", schemaToString(algorithmResult[1][0], algorithmResult[1][1]),numberOfColumns) resultString = resultString+wrapInPanel("<span class='badge'>3</span> Schlüssel hinzufügen", schemaToString(algorithmResult[2][0], algorithmResult[2][1]),numberOfColumns) resultString = resultString+wrapInPanel("<span class='badge'>4</span> Redundante Schemata eliminieren", "<strong>"+schemaToString(algorithmResult[3][0], algorithmResult[3][1])+"</strong>",numberOfColumns) resultString = resultString + """</div>""" return resultString
def relationToString(relation, i, candidateKeys=None, fds=[], mvds=[], additionalFds=[], additionalMvds=[], primaryKey=None): if candidateKeys is not None: if mvds: show = "FDs/MVDs" else: show = "FDs" if primaryKey is None: primaryKey = DBnormalizer.getFirstKey(candidateKeys) tooltiptext = "<div class='panel panel-primary'><div class='panel-heading'><h5 class='panel-title'>" + show + "</h5></div><div class='panel-body'>" if not fds and not mvds: tooltiptext = tooltiptext + "In dieser Relation gelten keine nicht-trivialen Abhängigkeiten." else: tooltiptext = tooltiptext + fdsToHtmlString( fds, additionalFds) + mvdsToHtmlString(mvds, additionalMvds) tooltiptext = tooltiptext + "</div></div><div class='panel panel-primary'><div class='panel-heading'><h3 class='panel-title'>Kandidatenschlüssel</h3></div><div class='panel-body'>" + keysToString( candidateKeys) + "</div></div>" if additionalFds: tooltiptext = tooltiptext + "<h6><small>* Unter anderem diese FD kann mithilfe der Armstrong-Axiome zusätzlich hergeleitet werden</small></h6>" if additionalMvds: tooltiptext = tooltiptext + "<h6><small>** Unter anderem diese MVD kann mithilfe der Komplementregel zusätzlich hergeleitet werden</small></h6>" else: #Do not show tooltip, only blank relation primaryKey = None tooltiptext = "" relationString = "R<sub>" + str(i).strip() + "</sub>:={" relationString = relationString + setOfAttributesToString( relation, primaryKey) relationString = relationString + "}" relationString = addPopoverText(relationString, relationString, tooltiptext) return relationString
def canonicalCoverToString(algorithmResult): if DBnormalizer.longAttributeNamesUsed(): numberOfColumns = 2 else: numberOfColumns = 4 resultString = getPanelHeading("canonicalCover", False) + """<div class="row">""" resultString = resultString + wrapInPanel( "<span class='badge'>1</span> Linksreduktion", fdsToHtmlString(algorithmResult[0]), numberOfColumns) resultString = resultString + wrapInPanel( "<span class='badge'>2</span> Rechtsreduktion", fdsToHtmlString(algorithmResult[1]), numberOfColumns) resultString = resultString + wrapInPanel( "<span class='badge'>3</span> α→∅ entfernen", fdsToHtmlString(algorithmResult[2]), numberOfColumns) resultString = resultString + wrapInPanel( "<span class='badge'>4</span> FDs zusammenfassen", "<strong>" + fdsToHtmlString(algorithmResult[3]) + "</strong>", numberOfColumns) resultString = resultString + """</div>""" return resultString
</body> </html> """ try: numberOfAttributes = form['numberOfAttributes'].value except KeyError: numberOfAttributes = 5 try: mode = form['mode'].value try: funMode = int(form['fun'].value) except: funMode = 0 if mode == 'generateFds': relation, fds, mvds = DBnormalizer.generateNewProblem( numberOfAttributes, False, funMode) print html(views.setOfAttributesToString(relation), views.fdsToString(fds) + views.mvdsToString(mvds), numberOfAttributes, funMode) + views.getAlgorithmTutorial() + htmlend elif mode == 'generateMvds': relation, fds, mvds = DBnormalizer.generateNewProblem( numberOfAttributes, True, funMode) print html(views.setOfAttributesToString(relation), views.fdsToString(fds) + views.mvdsToString(mvds), numberOfAttributes, funMode) + views.getAlgorithmTutorial() + htmlend else: #Mode is showResults or Quiz relation = str(form['relation'].value) fds = str(form['fds'].value)
} ); }); </script> </body> </html> """ return html try: relationString = str(form['relation'].value).replace(" ", "").replace( "\n", "").replace("\r", "") relation = set(relationString) | set(EMPTY_SET) fdsString = re.sub("(\r\n)*", "", str(form['fds'].value), 1) fds, mvds = DBnormalizer.parseInputFDsMVDs(fdsString) additionalFds = [] additionalMvds = [] step = str(form['step'].value).replace(" ", "").replace("\n", "").replace("\r", "") candidatekeys = DBnormalizer.getKeys(relation, fds) noRightSideAttributes = relation - DBnormalizer.getRightSideAttributes(fds) alert = "" info = "" inputpanel = views.inputToString(relation, fds, mvds, additionalFds, additionalMvds, "default") quizform = "" try: numberOfTries = int(form['numberOfTries'].value)
}); </script> </body> </html> """ return html try: relationString = str(form['relation'].value).replace(" ", "").replace("\n", "").replace("\r", "") relation = set(relationString)|set(EMPTY_SET) fdsString = re.sub("(\r\n)*", "", str(form['fds'].value), 1) fds,mvds = DBnormalizer.parseInputFDsMVDs(fdsString) additionalFds = [] step = str(form['step'].value).replace(" ", "").replace("\n", "").replace("\r", "") candidatekeys = DBnormalizer.getKeys(relation, fds) alert = "" info = "" inputpanel = views.inputToString(relation, fds, mvds, additionalFds, "default") quizform = "" try: numberOfTries = int(form['numberOfTries'].value) numberOfSteps = int(form['numberOfSteps'].value) except KeyError: numberOfTries = 0 numberOfSteps = 0 numberOfTries = numberOfTries + 1