features to flask srv. degrees.py started
This commit is contained in:
parent
565f48f230
commit
9712e3eeb5
Binary file not shown.
|
After Width: | Height: | Size: 338 B |
Binary file not shown.
|
After Width: | Height: | Size: 2.1 KiB |
|
|
@ -0,0 +1,164 @@
|
|||
from lark import Lark, Transformer, v_args
|
||||
|
||||
|
||||
|
||||
|
||||
"""describe college courses, their number of units, any other courses that are prerequisites, as well as various degrees which
|
||||
consist of groups of courses that must be taken. The groups have rules associated with them, such as:
|
||||
- take all (the following courses)
|
||||
- take n (where n=3 or 5 or something)
|
||||
- take at least n units from the following list (so the taken course's unit value must add up to n or greater)
|
||||
- and so on."""
|
||||
|
||||
|
||||
|
||||
|
||||
grammar = """
|
||||
start: program
|
||||
|
||||
program: course_declaration*
|
||||
|
||||
course_declaration: "course" CNAME INT "prerequisites" (CNAME ","?)* "degree" CNAME "{" degree_rule* "}"
|
||||
|
||||
degree_rule: "take" ("all" | "at" INT "from") ("the" "following") "courses" course_list
|
||||
|
||||
course_list: (CNAME ","?)*
|
||||
|
||||
%import common.CNAME
|
||||
%import common.INT
|
||||
%import common.WS
|
||||
%ignore WS
|
||||
"""
|
||||
|
||||
class Course:
|
||||
def __init__(self, name, units, prerequisites, degree):
|
||||
self.name = name
|
||||
self.units = units
|
||||
self.prerequisites = prerequisites
|
||||
self.degree = degree
|
||||
|
||||
class DegreeRule:
|
||||
def __init__(self, verb, n, course_list):
|
||||
self.verb = verb
|
||||
self.n = n
|
||||
self.course_list = course_list
|
||||
|
||||
class Degree:
|
||||
def __init__(self, name, degree_rules):
|
||||
self.name = name
|
||||
self.degree_rules = degree_rules
|
||||
|
||||
class Rule:
|
||||
pass
|
||||
|
||||
class TakeAll(Rule):
|
||||
def __init__(self, courses):
|
||||
self.courses = courses
|
||||
|
||||
class TakeN(Rule):
|
||||
def __init__(self, courses, n):
|
||||
self.courses = courses
|
||||
self.n = n
|
||||
|
||||
class TakeNUnits(Rule):
|
||||
def __init__(self, courses, n):
|
||||
self.courses = courses
|
||||
self.n = n
|
||||
|
||||
@v_args(inline=True)
|
||||
class DSLTransformer(Transformer):
|
||||
def __init__(self):
|
||||
self.courses = {}
|
||||
self.degrees = {}
|
||||
|
||||
def course_declaration(self, name, units, prerequisites, degree):
|
||||
return Course(name, int(units), prerequisites.children, degree)
|
||||
|
||||
def degree(self, name, required_courses):
|
||||
self.degrees[name] = Degree(name, required_courses)
|
||||
|
||||
def take_all(self, courses):
|
||||
return TakeAll(courses)
|
||||
|
||||
def take_n(self, courses, n):
|
||||
return TakeN(courses, n)
|
||||
|
||||
def take_n_units(self, courses, n):
|
||||
return TakeNUnits(courses, n)
|
||||
|
||||
def degree_rule(self, items):
|
||||
verb = items[0]
|
||||
n = None
|
||||
course_list = items[-1]
|
||||
if len(items) == 4:
|
||||
n = int(items[2])
|
||||
return DegreeRule(verb, n, course_list.children)
|
||||
|
||||
def course_list(self, items):
|
||||
return items[:-1]
|
||||
|
||||
def program(self, items):
|
||||
courses = [item for item in items if isinstance(item, Course)]
|
||||
degrees = [item for item in items if isinstance(item, Degree)]
|
||||
return courses, degrees
|
||||
|
||||
|
||||
dsl = DSLTransformer()
|
||||
dsl.course('CS101', 3)
|
||||
dsl.course('CS102', 3, prerequisites=['CS101'])
|
||||
dsl.course('MATH101', 3)
|
||||
dsl.degree('CS', [
|
||||
dsl.take_all(['CS101', 'CS102']),
|
||||
dsl.take_n_units(['CS101', 'CS102', 'MATH101'], 9),
|
||||
dsl.take_n(['CS101', 'CS102', 'MATH101'], 2),
|
||||
])
|
||||
|
||||
print(dsl.courses)
|
||||
print(dsl.degrees)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
parser = Lark(grammar)
|
||||
transformer = DSLTransformer()
|
||||
|
||||
def parse_dsl(dsl):
|
||||
tree = parser.parse(dsl)
|
||||
return transformer.transform(tree)
|
||||
|
||||
dsl = """
|
||||
course CS101 3 prerequisites none degree CS {
|
||||
take all the following courses {
|
||||
CS102, CS103
|
||||
}
|
||||
take at least 6 from {
|
||||
MATH101, MATH102, MATH103
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
courses, degrees = parse_dsl(dsl)
|
||||
print(courses)
|
||||
print(degrees)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def compute_degree_progress(student_courses, degree):
|
||||
total_units_completed = 0
|
||||
total_required_units = 0
|
||||
for course in degree['required_courses']:
|
||||
if course['id'] in student_courses:
|
||||
total_units_completed += course['units']
|
||||
if 'additional_rules' in course:
|
||||
for rule in course['additional_rules']:
|
||||
if rule['type'] == 'at_least_n_units_from_list':
|
||||
units_from_list = sum([c['units'] for c in degree['courses'] if c['id'] in student_courses and c['id'] in rule['course_list']])
|
||||
if units_from_list < rule['n']:
|
||||
break
|
||||
total_required_units += course['units']
|
||||
progress_percent = total_units_completed / total_required_units * 100 if total_required_units > 0 else 0
|
||||
return progress_percent
|
||||
|
||||
|
|
@ -16,6 +16,15 @@ from canvas_secrets import flask_secretkey
|
|||
|
||||
from content import my_site
|
||||
|
||||
|
||||
|
||||
|
||||
### SET THIS ENV VAR TO GET RELOADING
|
||||
# (win)
|
||||
# set FLASK_ENV=development
|
||||
# (linux)
|
||||
# export FLASK_ENV=development
|
||||
|
||||
import socket
|
||||
this_host = socket.gethostname()
|
||||
|
||||
|
|
@ -155,6 +164,15 @@ def flask_thread(q):
|
|||
return image_crop(filename,x,y,w,h,newname)
|
||||
|
||||
|
||||
@app.route('/md', methods=['GET', 'POST'])
|
||||
def convert_markdown():
|
||||
if request.method == 'POST':
|
||||
markdown_input = request.form.get('markdown_input', '')
|
||||
html_output = markdown.markdown(markdown_input)
|
||||
return render_template('basic.html', title='md -> html', html_output=html_output)
|
||||
return render_template('convert.html')
|
||||
|
||||
|
||||
|
||||
#
|
||||
# SAVING STUFF
|
||||
|
|
@ -166,9 +184,12 @@ def flask_thread(q):
|
|||
path = request.form['path']
|
||||
txt = request.form['content']
|
||||
|
||||
try:
|
||||
o3 = codecs.open(server.writing_path + path, 'r', 'utf-8')
|
||||
orig_text = o3.read()
|
||||
o3.close()
|
||||
except Exception as e:
|
||||
orig_text = ''
|
||||
|
||||
bu_filename = server.writing_path + 'older_copies/' + path + '_' + now + '.md'
|
||||
o2 = codecs.open( bu_filename, 'w', 'utf-8' )
|
||||
|
|
@ -321,7 +342,7 @@ def flask_thread(q):
|
|||
|
||||
|
||||
|
||||
socketio.run(app, host= '0.0.0.0')
|
||||
socketio.run(app, host= '0.0.0.0') # , debug=True
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
14
server.py
14
server.py
|
|
@ -1,5 +1,6 @@
|
|||
import json, codecs, re, markdown, os, pypandoc, striprtf, sqlite3, random, urllib
|
||||
import subprocess, html, time
|
||||
from markdownify import markdownify as md
|
||||
from striprtf.striprtf import rtf_to_text
|
||||
from flask import render_template, Response
|
||||
from flask import send_from_directory
|
||||
|
|
@ -145,8 +146,9 @@ def screenoff():
|
|||
|
||||
br = "<br />"
|
||||
nl = "\n"
|
||||
style = """<style> body { line-height: 2.3em; margin: 4em; }
|
||||
</style><link rel="stylesheet" href="/data/gui/public/simplemde.min.css">
|
||||
style = """<link rel="stylesheet" href="/data/gui/public/simplemde.min.css">
|
||||
<style> body { line-height: 2.3em; margin: 4em; } #editor { line-height: 1em!important; }
|
||||
</style>
|
||||
<script src="/data/gui/public/simplemde.min.js"></script>"""
|
||||
|
||||
|
||||
|
|
@ -188,6 +190,7 @@ def homepage():
|
|||
a('Pi frame on','/displaypi/on') + br + br + \
|
||||
a('Pi frame off','/displaypi/off') + br + br + \
|
||||
a('Knowledge Base','/x/writing/index') + br + \
|
||||
a('Markdown -> HTML converter','/md') + br + \
|
||||
a('Gav web mirror','/mirror') + br + \
|
||||
a('Graph of users','/x/user/1') + "<br />" + \
|
||||
a('Courses in a dept','/x/dept/csis') + "<br />" + \
|
||||
|
|
@ -262,7 +265,12 @@ def writing(fname):
|
|||
#output = pypandoc.convert_file('C:/Users/peter/Nextcloud/Documents/writing/' + fname, 'html',
|
||||
output = pypandoc.convert_file(writing_path + fname, 'html',
|
||||
extra_args=['--extract-media=%s' % hash ]) # file:///c:/Users/peter/Nextcloud/Documents/writing
|
||||
return style + output
|
||||
output2 = pypandoc.convert_file(writing_path + fname, 'markdown',
|
||||
extra_args=['--extract-media=%s' % hash+'_md' ]) # file:///c:/Users/peter/Nextcloud/Documents/writing
|
||||
new_fname = fname[:-5] + '.md'
|
||||
#as_md = md(output)
|
||||
return style + output + in_form(editor(output2),new_fname)
|
||||
|
||||
return style + markdown.markdown( "".join( [ orgline(x) for x in inp.readlines() ] ) )
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>{{ title }}</title>
|
||||
<style>
|
||||
textarea { width: 75%; height: 45rem;}
|
||||
.title {color:grey;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Converted HTML Output</h1>
|
||||
<div>{{ html_output|safe }}</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Markdown to HTML Converter</title>
|
||||
<style>
|
||||
textarea { width: 75%; height: 45rem;}
|
||||
.title {color:rgb(65, 65, 65);}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1 class="title">Markdown to HTML Converter</h1>
|
||||
<form method="POST" action="/md">
|
||||
<textarea name="markdown_input" rows="10" cols="50"></textarea><br>
|
||||
<input type="submit" value="Convert">
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Reference in New Issue