features to flask srv. degrees.py started

This commit is contained in:
Coding with Peter 2023-05-17 08:53:54 -07:00
parent 565f48f230
commit 9712e3eeb5
7 changed files with 232 additions and 8 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 338 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

164
degrees.py Normal file
View File

@ -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

View File

@ -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']
o3 = codecs.open(server.writing_path + path, 'r', 'utf-8')
orig_text = o3.read()
o3.close()
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

View File

@ -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() ] ) )

14
templates/basic.html Normal file
View File

@ -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>

17
templates/convert.html Normal file
View File

@ -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>