Adding projects from cs50
|
|
@ -0,0 +1,26 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="PYTHON_MODULE" version="4">
|
||||||
|
<component name="Flask">
|
||||||
|
<option name="enabled" value="true" />
|
||||||
|
</component>
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
<orderEntry type="library" name="jquery" level="application" />
|
||||||
|
</component>
|
||||||
|
<component name="PyDocumentationSettings">
|
||||||
|
<option name="renderExternalDocumentation" value="true" />
|
||||||
|
</component>
|
||||||
|
<component name="TemplatesService">
|
||||||
|
<option name="TEMPLATE_CONFIGURATION" value="Jinja2" />
|
||||||
|
<option name="TEMPLATE_FOLDERS">
|
||||||
|
<list>
|
||||||
|
<option value="$MODULE_DIR$/templates" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
<component name="TestRunnerService">
|
||||||
|
<option name="PROJECT_TEST_RUNNER" value="Unittests" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="JavaScriptSettings">
|
||||||
|
<option name="languageLevel" value="ES6" />
|
||||||
|
</component>
|
||||||
|
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.7" project-jdk-type="Python SDK" />
|
||||||
|
</project>
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/final.iml" filepath="$PROJECT_DIR$/.idea/final.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
|
|
@ -0,0 +1,212 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ChangeListManager">
|
||||||
|
<list default="true" id="de1f1682-056b-43d2-9afd-d9f8b554aeeb" name="Default Changelist" comment="" />
|
||||||
|
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
|
||||||
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
|
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||||
|
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||||
|
</component>
|
||||||
|
<component name="FileEditorManager">
|
||||||
|
<leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
|
||||||
|
<file pinned="false" current-in-tab="true">
|
||||||
|
<entry file="file://$PROJECT_DIR$/templates/layout.html">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="204">
|
||||||
|
<caret line="12" selection-start-line="12" selection-end-line="12" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</file>
|
||||||
|
<file pinned="false" current-in-tab="false">
|
||||||
|
<entry file="file://$PROJECT_DIR$/templates/riemann.html">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="-170">
|
||||||
|
<caret line="2" column="17" selection-start-line="2" selection-start-column="17" selection-end-line="2" selection-end-column="17" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</file>
|
||||||
|
<file pinned="false" current-in-tab="false">
|
||||||
|
<entry file="file://$PROJECT_DIR$/templates/rightSummed.html">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="374">
|
||||||
|
<caret line="22" column="37" selection-start-line="22" selection-start-column="37" selection-end-line="22" selection-end-column="37" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</file>
|
||||||
|
<file pinned="false" current-in-tab="false">
|
||||||
|
<entry file="file://$PROJECT_DIR$/templates/index.html">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="238">
|
||||||
|
<caret line="14" column="14" selection-start-line="14" selection-start-column="14" selection-end-line="14" selection-end-column="14" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</file>
|
||||||
|
</leaf>
|
||||||
|
</component>
|
||||||
|
<component name="IdeDocumentHistory">
|
||||||
|
<option name="CHANGED_PATHS">
|
||||||
|
<list>
|
||||||
|
<option value="$PROJECT_DIR$/templates/layout.html" />
|
||||||
|
<option value="$PROJECT_DIR$/templates/index.html" />
|
||||||
|
<option value="$PROJECT_DIR$/templates/basic.html" />
|
||||||
|
<option value="$PROJECT_DIR$/application.py" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
<component name="ProjectFrameBounds" extendedState="6">
|
||||||
|
<option name="x" value="371" />
|
||||||
|
<option name="y" value="-15" />
|
||||||
|
<option name="width" value="979" />
|
||||||
|
<option name="height" value="934" />
|
||||||
|
</component>
|
||||||
|
<component name="ProjectView">
|
||||||
|
<navigator proportions="" version="1">
|
||||||
|
<foldersAlwaysOnTop value="true" />
|
||||||
|
</navigator>
|
||||||
|
<panes>
|
||||||
|
<pane id="ProjectPane">
|
||||||
|
<subPane>
|
||||||
|
<expand>
|
||||||
|
<path>
|
||||||
|
<item name="final" type="b2602c69:ProjectViewProjectNode" />
|
||||||
|
<item name="final" type="462c0819:PsiDirectoryNode" />
|
||||||
|
</path>
|
||||||
|
<path>
|
||||||
|
<item name="final" type="b2602c69:ProjectViewProjectNode" />
|
||||||
|
<item name="final" type="462c0819:PsiDirectoryNode" />
|
||||||
|
<item name="templates" type="462c0819:PsiDirectoryNode" />
|
||||||
|
</path>
|
||||||
|
</expand>
|
||||||
|
<select />
|
||||||
|
</subPane>
|
||||||
|
</pane>
|
||||||
|
<pane id="Scope" />
|
||||||
|
</panes>
|
||||||
|
</component>
|
||||||
|
<component name="PropertiesComponent">
|
||||||
|
<property name="WebServerToolWindowFactoryState" value="false" />
|
||||||
|
<property name="last_opened_file_path" value="$PROJECT_DIR$" />
|
||||||
|
<property name="node.js.detected.package.eslint" value="true" />
|
||||||
|
<property name="node.js.path.for.package.eslint" value="project" />
|
||||||
|
<property name="node.js.selected.package.eslint" value="(autodetect)" />
|
||||||
|
<property name="nodejs_interpreter_path.stuck_in_default_project" value="undefined stuck path" />
|
||||||
|
<property name="nodejs_npm_path_reset_for_default_project" value="true" />
|
||||||
|
</component>
|
||||||
|
<component name="RunDashboard">
|
||||||
|
<option name="ruleStates">
|
||||||
|
<list>
|
||||||
|
<RuleState>
|
||||||
|
<option name="name" value="ConfigurationTypeDashboardGroupingRule" />
|
||||||
|
</RuleState>
|
||||||
|
<RuleState>
|
||||||
|
<option name="name" value="StatusDashboardGroupingRule" />
|
||||||
|
</RuleState>
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
<component name="RunManager">
|
||||||
|
<configuration name="final" type="Python.FlaskServer">
|
||||||
|
<module name="final" />
|
||||||
|
<option name="target" value="$PROJECT_DIR$/application.py" />
|
||||||
|
<option name="targetType" value="PATH" />
|
||||||
|
<option name="INTERPRETER_OPTIONS" value="" />
|
||||||
|
<option name="PARENT_ENVS" value="true" />
|
||||||
|
<option name="SDK_HOME" value="" />
|
||||||
|
<option name="WORKING_DIRECTORY" value="" />
|
||||||
|
<option name="IS_MODULE_SDK" value="false" />
|
||||||
|
<option name="ADD_CONTENT_ROOTS" value="true" />
|
||||||
|
<option name="ADD_SOURCE_ROOTS" value="true" />
|
||||||
|
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
|
||||||
|
<option name="launchJavascriptDebuger" value="false" />
|
||||||
|
<method v="2" />
|
||||||
|
</configuration>
|
||||||
|
</component>
|
||||||
|
<component name="SvnConfiguration">
|
||||||
|
<configuration />
|
||||||
|
</component>
|
||||||
|
<component name="TaskManager">
|
||||||
|
<task active="true" id="Default" summary="Default task">
|
||||||
|
<changelist id="de1f1682-056b-43d2-9afd-d9f8b554aeeb" name="Default Changelist" comment="" />
|
||||||
|
<created>1556603970433</created>
|
||||||
|
<option name="number" value="Default" />
|
||||||
|
<option name="presentableId" value="Default" />
|
||||||
|
<updated>1556603970433</updated>
|
||||||
|
<workItem from="1556603972060" duration="2623000" />
|
||||||
|
<workItem from="1556645242916" duration="3303000" />
|
||||||
|
<workItem from="1561683875314" duration="263000" />
|
||||||
|
</task>
|
||||||
|
<servers />
|
||||||
|
</component>
|
||||||
|
<component name="TimeTrackingManager">
|
||||||
|
<option name="totallyTimeSpent" value="6189000" />
|
||||||
|
</component>
|
||||||
|
<component name="ToolWindowManager">
|
||||||
|
<frame x="-7" y="-7" width="1550" height="838" extended-state="6" />
|
||||||
|
<editor active="true" />
|
||||||
|
<layout>
|
||||||
|
<window_info active="true" content_ui="combo" id="Project" order="0" visible="true" weight="0.14879356" />
|
||||||
|
<window_info id="Structure" order="1" side_tool="true" weight="0.25" />
|
||||||
|
<window_info id="Favorites" order="2" side_tool="true" />
|
||||||
|
<window_info anchor="bottom" id="Message" order="0" />
|
||||||
|
<window_info anchor="bottom" id="Find" order="1" />
|
||||||
|
<window_info anchor="bottom" id="Run" order="2" />
|
||||||
|
<window_info anchor="bottom" id="Debug" order="3" weight="0.4" />
|
||||||
|
<window_info anchor="bottom" id="Cvs" order="4" weight="0.25" />
|
||||||
|
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
|
||||||
|
<window_info anchor="bottom" id="TODO" order="6" />
|
||||||
|
<window_info anchor="bottom" id="Docker" order="7" show_stripe_button="false" />
|
||||||
|
<window_info anchor="bottom" id="Version Control" order="8" />
|
||||||
|
<window_info anchor="bottom" id="Database Changes" order="9" />
|
||||||
|
<window_info anchor="bottom" id="Event Log" order="10" side_tool="true" />
|
||||||
|
<window_info anchor="bottom" id="Terminal" order="11" visible="true" weight="0.4016973" />
|
||||||
|
<window_info anchor="bottom" id="Python Console" order="12" />
|
||||||
|
<window_info anchor="right" id="Commander" internal_type="SLIDING" order="0" type="SLIDING" weight="0.4" />
|
||||||
|
<window_info anchor="right" id="Ant Build" order="1" weight="0.25" />
|
||||||
|
<window_info anchor="right" content_ui="combo" id="Hierarchy" order="2" weight="0.25" />
|
||||||
|
<window_info anchor="right" id="SciView" order="3" />
|
||||||
|
<window_info anchor="right" id="Database" order="4" />
|
||||||
|
</layout>
|
||||||
|
</component>
|
||||||
|
<component name="TypeScriptGeneratedFilesManager">
|
||||||
|
<option name="version" value="1" />
|
||||||
|
</component>
|
||||||
|
<component name="editorHistoryManager">
|
||||||
|
<entry file="file://$PROJECT_DIR$/mathquill/mathquill-0.10.1/Makefile" />
|
||||||
|
<entry file="file://$PROJECT_DIR$/mathquill-0.10.1/Makefile" />
|
||||||
|
<entry file="file://$PROJECT_DIR$/templates/basic.html" />
|
||||||
|
<entry file="file://$PROJECT_DIR$/application.py" />
|
||||||
|
<entry file="file://$PROJECT_DIR$/templates/index.html">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="238">
|
||||||
|
<caret line="14" column="14" selection-start-line="14" selection-start-column="14" selection-end-line="14" selection-end-column="14" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/templates/riemann.html">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="-170">
|
||||||
|
<caret line="2" column="17" selection-start-line="2" selection-start-column="17" selection-end-line="2" selection-end-column="17" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/templates/rightSummed.html">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="374">
|
||||||
|
<caret line="22" column="37" selection-start-line="22" selection-start-column="37" selection-end-line="22" selection-end-column="37" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/templates/layout.html">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="204">
|
||||||
|
<caret line="12" selection-start-line="12" selection-end-line="12" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
"# final"
|
||||||
|
|
@ -0,0 +1,340 @@
|
||||||
|
import os
|
||||||
|
|
||||||
|
from math import *
|
||||||
|
from cs50 import SQL
|
||||||
|
from flask import Flask, flash, jsonify, redirect, render_template, request, session
|
||||||
|
from flask_session import Session
|
||||||
|
from tempfile import mkdtemp
|
||||||
|
from werkzeug.exceptions import default_exceptions, HTTPException, InternalServerError
|
||||||
|
from werkzeug.security import check_password_hash, generate_password_hash
|
||||||
|
import numpy as np
|
||||||
|
import sympy as sp
|
||||||
|
from sympy import *
|
||||||
|
from latex2sympy import *
|
||||||
|
from sympy.parsing.latex import parse_latex
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
from helpers import apology, login_required, lookup, usd
|
||||||
|
|
||||||
|
# Configure application
|
||||||
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
# Ensure templates are auto-reloaded
|
||||||
|
app.config["TEMPLATES_AUTO_RELOAD"] = True
|
||||||
|
|
||||||
|
# Ensure responses aren't cached
|
||||||
|
@app.after_request
|
||||||
|
def after_request(response):
|
||||||
|
response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
|
||||||
|
response.headers["Expires"] = 0
|
||||||
|
response.headers["Pragma"] = "no-cache"
|
||||||
|
return response
|
||||||
|
|
||||||
|
# Custom filter
|
||||||
|
app.jinja_env.filters["usd"] = usd
|
||||||
|
|
||||||
|
# Configure session to use filesystem (instead of signed cookies)
|
||||||
|
app.config["SESSION_FILE_DIR"] = mkdtemp()
|
||||||
|
app.config["SESSION_PERMANENT"] = False
|
||||||
|
app.config["SESSION_TYPE"] = "filesystem"
|
||||||
|
Session(app)
|
||||||
|
|
||||||
|
# Configure CS50 Library to use SQLite database
|
||||||
|
db = SQL("sqlite:///finance.db")
|
||||||
|
|
||||||
|
@app.route("/")
|
||||||
|
def index():
|
||||||
|
"""Intro to website"""
|
||||||
|
return render_template("index.html")
|
||||||
|
|
||||||
|
@app.route("/differentiation", methods=["GET", "POST"])
|
||||||
|
@login_required
|
||||||
|
def differentiation():
|
||||||
|
if request.method == "POST":
|
||||||
|
# Check if inputs were given
|
||||||
|
if not request.form.get("function"):
|
||||||
|
return apology("must provide a function", 400)
|
||||||
|
f = request.form.get("function")
|
||||||
|
x = symbols('x')
|
||||||
|
f = sympify(f)
|
||||||
|
|
||||||
|
# Differentiate and return latex expressions
|
||||||
|
fprime = latex(f.diff(x))
|
||||||
|
value = latex(f)
|
||||||
|
return render_template("differentiated.html", value=value, fprime=fprime)
|
||||||
|
else:
|
||||||
|
return render_template("differentiation.html")
|
||||||
|
|
||||||
|
@app.route("/integration", methods=["GET", "POST"])
|
||||||
|
@login_required
|
||||||
|
def integration():
|
||||||
|
if request.method == "POST":
|
||||||
|
# Check if inputs were given
|
||||||
|
if not request.form.get("function"):
|
||||||
|
return apology("must provide a function", 400)
|
||||||
|
|
||||||
|
# Integrate and return latex expressions
|
||||||
|
f = request.form.get("function")
|
||||||
|
x = symbols('x')
|
||||||
|
f = sympify(f)
|
||||||
|
fintegral = latex(f.integrate(x))
|
||||||
|
value = latex(f)
|
||||||
|
return render_template("integrated.html", value=value, fintegral=fintegral)
|
||||||
|
else:
|
||||||
|
return render_template("integration.html")
|
||||||
|
|
||||||
|
@app.route("/riemann", methods = ["GET", "POST"])
|
||||||
|
@login_required
|
||||||
|
def riemann():
|
||||||
|
if request.method == "POST":
|
||||||
|
# Check if inputs were given
|
||||||
|
if not request.form.get("function"):
|
||||||
|
return apology("must provide a function", 400)
|
||||||
|
if not request.form.get("lowerbound"):
|
||||||
|
return apology("must provide a lower bound", 400)
|
||||||
|
if not request.form.get("upperbound"):
|
||||||
|
return apology("must provide an upper bound", 400)
|
||||||
|
if not request.form.get("subintervals"):
|
||||||
|
return apology("must provide a number of subintervals", 400)
|
||||||
|
if not request.form.get("sumtype"):
|
||||||
|
return apology("must choose left or right", 400)
|
||||||
|
|
||||||
|
# Get inputs, check for validity and sympify
|
||||||
|
f = request.form.get("function")
|
||||||
|
sumtype = request.form.get("sumtype")
|
||||||
|
lb = int(request.form.get("lowerbound"))
|
||||||
|
ub = int(request.form.get("upperbound"))
|
||||||
|
si = int(request.form.get("subintervals"))
|
||||||
|
x = symbols('x')
|
||||||
|
f = sympify(f)
|
||||||
|
dx = (ub - lb) / si
|
||||||
|
value = latex(f)
|
||||||
|
|
||||||
|
# Run through Riemann Sum algorithm, creatings lists for display
|
||||||
|
# of inputs, outputs, and areas (their products)
|
||||||
|
inputs = list()
|
||||||
|
if sumtype == "1":
|
||||||
|
for i in range(0, si):
|
||||||
|
inputs.append(dx * (i))
|
||||||
|
if sumtype == "2":
|
||||||
|
for i in range(0, si):
|
||||||
|
inputs.append(dx * (i + 1))
|
||||||
|
outputs = list()
|
||||||
|
for input in inputs:
|
||||||
|
temp = f.subs(x, input)
|
||||||
|
outputs.append(temp)
|
||||||
|
rectangles = list()
|
||||||
|
for output in outputs:
|
||||||
|
temp = output * dx
|
||||||
|
rectangles.append(temp)
|
||||||
|
result = sum(rectangles)
|
||||||
|
|
||||||
|
# Choose template based on left or right sum
|
||||||
|
if sumtype == "1":
|
||||||
|
return render_template("summed.html", value=value, sumtype=sumtype, lb=lb, ub=ub, si=si, dx=dx,
|
||||||
|
inputs=inputs, outputs=outputs, rectangles=rectangles, result=result)
|
||||||
|
else:
|
||||||
|
return render_template("rightSummed.html", value=value, sumtype=sumtype, lb=lb, ub=ub, si=si, dx=dx,
|
||||||
|
inputs=inputs, outputs=outputs, rectangles=rectangles, result=result)
|
||||||
|
else:
|
||||||
|
return render_template("riemann.html")
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/maxmin", methods=["GET", "POST"])
|
||||||
|
def maxmin():
|
||||||
|
if request.method == "POST":
|
||||||
|
# Check if inputs were given
|
||||||
|
if not request.form.get("function"):
|
||||||
|
return apology("must provide a function", 400)
|
||||||
|
if not request.form.get("lowerbound"):
|
||||||
|
return apology("must provide a lower bound", 400)
|
||||||
|
if not request.form.get("upperbound"):
|
||||||
|
return apology("must provide an upper bound", 400)
|
||||||
|
|
||||||
|
# Get input from form
|
||||||
|
f = request.form.get("function")
|
||||||
|
lb = sympify(request.form.get("lowerbound"))
|
||||||
|
ub = sympify(request.form.get("upperbound"))
|
||||||
|
|
||||||
|
# Prep input for numpy / sympy
|
||||||
|
x = symbols('x')
|
||||||
|
f = sympify(f)
|
||||||
|
|
||||||
|
# Get Derivative, solve for real solutions, update candidates list
|
||||||
|
fprime = f.diff(x)
|
||||||
|
solutions = list()
|
||||||
|
solutions.append(f.subs(x,0))
|
||||||
|
candidates = list()
|
||||||
|
for solution in solutions:
|
||||||
|
candidates.append(solution)
|
||||||
|
candidates.append(lb)
|
||||||
|
candidates.append(ub)
|
||||||
|
|
||||||
|
# Fill values list with solutions
|
||||||
|
values = list()
|
||||||
|
for candidate in candidates:
|
||||||
|
temp = f.subs(x, candidate)
|
||||||
|
values.append(temp)
|
||||||
|
|
||||||
|
# Find max/min of values
|
||||||
|
maximum = max(values)
|
||||||
|
newvar = min(values)
|
||||||
|
|
||||||
|
# Turn all into latex
|
||||||
|
value = latex(f)
|
||||||
|
fprime = latex(fprime)
|
||||||
|
for i, solution in enumerate(solutions):
|
||||||
|
solutions[i] = latex(solution)
|
||||||
|
return render_template("optimized.html", value=value, fprime=fprime, solutions=solutions, lb=lb, ub=ub,
|
||||||
|
candidates=candidates, newvar=newvar, values=values, maximum=maximum)
|
||||||
|
else:
|
||||||
|
return render_template("maxmin.html")
|
||||||
|
|
||||||
|
@app.route("/aprox", methods=["GET", "POST"])
|
||||||
|
def aprox():
|
||||||
|
if request.method == "POST":
|
||||||
|
# Check if inputs were given
|
||||||
|
if not request.form.get("function"):
|
||||||
|
return apology("must provide a function", 400)
|
||||||
|
if not request.form.get("easy"):
|
||||||
|
return apology("must provide an easy value", 400)
|
||||||
|
if not request.form.get("hard"):
|
||||||
|
return apology("must provide a difficult value", 400)
|
||||||
|
|
||||||
|
# Get inputs, sympify them, and check to see if valid
|
||||||
|
f = request.form.get("function")
|
||||||
|
a = request.form.get("easy")
|
||||||
|
h = request.form.get("hard")
|
||||||
|
x = symbols('x')
|
||||||
|
f = sympify(f)
|
||||||
|
a = sympify(a)
|
||||||
|
h = sympify(h)
|
||||||
|
if not a.is_number:
|
||||||
|
return apology("easy value must be a number", 400)
|
||||||
|
if not h.is_number:
|
||||||
|
return apology("difficult value must be a number", 400)
|
||||||
|
|
||||||
|
# Run through Linearization algorithm
|
||||||
|
fprime = f.diff(x)
|
||||||
|
fa = f.subs(x, a)
|
||||||
|
fprimea = fprime.subs(x, a)
|
||||||
|
lh = fa + fprimea*(float(h)-float(a))
|
||||||
|
|
||||||
|
# Convert to latex for MathJax reading
|
||||||
|
value = latex(f)
|
||||||
|
fprime = latex(fprime)
|
||||||
|
fa = latex(fa)
|
||||||
|
lh = latex(lh)
|
||||||
|
|
||||||
|
return render_template("aproxd.html", value=value, fprime=fprime, a=a, h=h, fa=fa, fprimea=fprimea, lh=lh)
|
||||||
|
else:
|
||||||
|
return render_template("aprox.html")
|
||||||
|
|
||||||
|
@app.route("/check", methods=["GET"])
|
||||||
|
def check():
|
||||||
|
"""Return true if username available, else false, in JSON format"""
|
||||||
|
username = request.args.get("username")
|
||||||
|
usernames = db.execute("SELECT username FROM users WHERE username = :username", username=username)
|
||||||
|
if username and not usernames:
|
||||||
|
return jsonify(True)
|
||||||
|
else:
|
||||||
|
return jsonify(False)
|
||||||
|
|
||||||
|
@app.route("/login", methods=["GET", "POST"])
|
||||||
|
def login():
|
||||||
|
"""Log user in"""
|
||||||
|
|
||||||
|
# Forget any user_id
|
||||||
|
session.clear()
|
||||||
|
|
||||||
|
# User reached route via POST (as by submitting a form via POST)
|
||||||
|
if request.method == "POST":
|
||||||
|
|
||||||
|
# Ensure username was submitted
|
||||||
|
if not request.form.get("username"):
|
||||||
|
return apology("must provide username", 403)
|
||||||
|
|
||||||
|
# Ensure password was submitted
|
||||||
|
elif not request.form.get("password"):
|
||||||
|
return apology("must provide password", 403)
|
||||||
|
|
||||||
|
# Query database for username
|
||||||
|
rows = db.execute("SELECT * FROM users WHERE username = :username",
|
||||||
|
username=request.form.get("username"))
|
||||||
|
|
||||||
|
# Ensure username exists and password is correct
|
||||||
|
if len(rows) != 1 or not check_password_hash(rows[0]["hash"], request.form.get("password")):
|
||||||
|
return apology("invalid username and/or password", 403)
|
||||||
|
|
||||||
|
# Remember which user has logged in
|
||||||
|
session["user_id"] = rows[0]["id"]
|
||||||
|
|
||||||
|
# Redirect user to home page
|
||||||
|
return redirect("/")
|
||||||
|
|
||||||
|
# User reached route via GET (as by clicking a link or via redirect)
|
||||||
|
else:
|
||||||
|
return render_template("login.html")
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/logout")
|
||||||
|
def logout():
|
||||||
|
"""Log user out"""
|
||||||
|
|
||||||
|
# Forget any user_id
|
||||||
|
session.clear()
|
||||||
|
|
||||||
|
# Redirect user to login form
|
||||||
|
return redirect("/")
|
||||||
|
|
||||||
|
@app.route("/register", methods=["GET", "POST"])
|
||||||
|
def register():
|
||||||
|
"""Register user"""
|
||||||
|
# Forget any user_id
|
||||||
|
session.clear()
|
||||||
|
|
||||||
|
# User reached route via POST (as by submitting a form via POST)
|
||||||
|
if request.method == "POST":
|
||||||
|
|
||||||
|
# Ensure username was submitted
|
||||||
|
if not request.form.get("username"):
|
||||||
|
return apology("must provide username", 400)
|
||||||
|
|
||||||
|
# Ensure password was submitted
|
||||||
|
elif not request.form.get("password"):
|
||||||
|
return apology("must provide password", 400)
|
||||||
|
|
||||||
|
# Ensure passwords match
|
||||||
|
elif not request.form.get("password") == request.form.get("confirmation"):
|
||||||
|
return apology("passwords must match", 400)
|
||||||
|
|
||||||
|
# Create hash for password
|
||||||
|
hash = generate_password_hash(request.form.get("password"))
|
||||||
|
|
||||||
|
# Insert username into database
|
||||||
|
result = db.execute("Insert INTO users (username, hash) VALUES(:username, :hash)", username = request.form.get("username"), hash = hash)
|
||||||
|
|
||||||
|
# Check if username is already taken
|
||||||
|
if not result:
|
||||||
|
return apology("Username has been taken", 400)
|
||||||
|
|
||||||
|
# Remember which user has logged in
|
||||||
|
session["user_id"] = result
|
||||||
|
|
||||||
|
# Redirect user to home page
|
||||||
|
return redirect("/")
|
||||||
|
|
||||||
|
# User reached route via GET (as by clicking a link or via redirect)
|
||||||
|
else:
|
||||||
|
return render_template("register.html")
|
||||||
|
|
||||||
|
def errorhandler(e):
|
||||||
|
"""Handle error"""
|
||||||
|
if not isinstance(e, HTTPException):
|
||||||
|
e = InternalServerError()
|
||||||
|
return apology(e.name, e.code)
|
||||||
|
|
||||||
|
# Listen for errors
|
||||||
|
for code in default_exceptions:
|
||||||
|
app.errorhandler(code)(errorhandler)
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
import requests
|
||||||
|
import urllib.parse
|
||||||
|
|
||||||
|
from flask import redirect, render_template, request, session
|
||||||
|
from functools import wraps
|
||||||
|
|
||||||
|
|
||||||
|
def apology(message, code=400):
|
||||||
|
"""Render message as an apology to user."""
|
||||||
|
def escape(s):
|
||||||
|
"""
|
||||||
|
Escape special characters.
|
||||||
|
|
||||||
|
https://github.com/jacebrowning/memegen#special-characters
|
||||||
|
"""
|
||||||
|
for old, new in [("-", "--"), (" ", "-"), ("_", "__"), ("?", "~q"),
|
||||||
|
("%", "~p"), ("#", "~h"), ("/", "~s"), ("\"", "''")]:
|
||||||
|
s = s.replace(old, new)
|
||||||
|
return s
|
||||||
|
return render_template("apology.html", top=code, bottom=escape(message)), code
|
||||||
|
|
||||||
|
|
||||||
|
def login_required(f):
|
||||||
|
"""
|
||||||
|
Decorate routes to require login.
|
||||||
|
|
||||||
|
http://flask.pocoo.org/docs/1.0/patterns/viewdecorators/
|
||||||
|
"""
|
||||||
|
@wraps(f)
|
||||||
|
def decorated_function(*args, **kwargs):
|
||||||
|
if session.get("user_id") is None:
|
||||||
|
return redirect("/login")
|
||||||
|
return f(*args, **kwargs)
|
||||||
|
return decorated_function
|
||||||
|
|
||||||
|
|
||||||
|
def lookup(symbol):
|
||||||
|
"""Look up quote for symbol."""
|
||||||
|
|
||||||
|
# Contact API
|
||||||
|
try:
|
||||||
|
response = requests.get(f"https://api.iextrading.com/1.0/stock/{urllib.parse.quote_plus(symbol)}/quote")
|
||||||
|
response.raise_for_status()
|
||||||
|
except requests.RequestException:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Parse response
|
||||||
|
try:
|
||||||
|
quote = response.json()
|
||||||
|
return {
|
||||||
|
"name": quote["companyName"],
|
||||||
|
"price": float(quote["latestPrice"]),
|
||||||
|
"symbol": quote["symbol"]
|
||||||
|
}
|
||||||
|
except (KeyError, TypeError, ValueError):
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def usd(value):
|
||||||
|
"""Format value as USD."""
|
||||||
|
return f"${value:,.2f}"
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
cs50
|
||||||
|
Flask
|
||||||
|
Flask-Session
|
||||||
|
requests
|
||||||
|
After Width: | Height: | Size: 5.4 KiB |
|
After Width: | Height: | Size: 2.1 MiB |
|
|
@ -0,0 +1,425 @@
|
||||||
|
/*
|
||||||
|
* MathQuill v0.10.1 http://mathquill.com
|
||||||
|
* by Han, Jeanine, and Mary maintainers@mathquill.com
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the
|
||||||
|
* Mozilla Public License, v. 2.0. If a copy of the MPL
|
||||||
|
* was not distributed with this file, You can obtain
|
||||||
|
* one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
@font-face {
|
||||||
|
font-family: Symbola;
|
||||||
|
src: url(font/Symbola-basic.eot);
|
||||||
|
src: local("Symbola Regular"), local("Symbola"), url(font/Symbola-basic.woff2) format("woff2"), url(font/Symbola-basic.woff) format("woff"), url(font/Symbola-basic.ttf) format("truetype");
|
||||||
|
}
|
||||||
|
.mq-editable-field {
|
||||||
|
display: -moz-inline-box;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.mq-editable-field .mq-cursor {
|
||||||
|
border-left: 1px solid black;
|
||||||
|
margin-left: -1px;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
padding: 0;
|
||||||
|
display: -moz-inline-box;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.mq-editable-field .mq-cursor.mq-blink {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
.mq-editable-field,
|
||||||
|
.mq-math-mode .mq-editable-field {
|
||||||
|
border: 1px solid gray;
|
||||||
|
}
|
||||||
|
.mq-editable-field.mq-focused,
|
||||||
|
.mq-math-mode .mq-editable-field.mq-focused {
|
||||||
|
-webkit-box-shadow: #8bd 0 0 1px 2px, inset #6ae 0 0 2px 0;
|
||||||
|
-moz-box-shadow: #8bd 0 0 1px 2px, inset #6ae 0 0 2px 0;
|
||||||
|
box-shadow: #8bd 0 0 1px 2px, inset #6ae 0 0 2px 0;
|
||||||
|
border-color: #709AC0;
|
||||||
|
border-radius: 1px;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-editable-field {
|
||||||
|
margin: 1px;
|
||||||
|
}
|
||||||
|
.mq-editable-field .mq-latex-command-input {
|
||||||
|
color: inherit;
|
||||||
|
font-family: "Courier New", monospace;
|
||||||
|
border: 1px solid gray;
|
||||||
|
padding-right: 1px;
|
||||||
|
margin-right: 1px;
|
||||||
|
margin-left: 2px;
|
||||||
|
}
|
||||||
|
.mq-editable-field .mq-latex-command-input.mq-empty {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
.mq-editable-field .mq-latex-command-input.mq-hasCursor {
|
||||||
|
border-color: ActiveBorder;
|
||||||
|
}
|
||||||
|
.mq-editable-field.mq-empty:after,
|
||||||
|
.mq-editable-field.mq-text-mode:after,
|
||||||
|
.mq-math-mode .mq-empty:after {
|
||||||
|
visibility: hidden;
|
||||||
|
content: 'c';
|
||||||
|
}
|
||||||
|
.mq-editable-field .mq-cursor:only-child:after,
|
||||||
|
.mq-editable-field .mq-textarea + .mq-cursor:last-child:after {
|
||||||
|
visibility: hidden;
|
||||||
|
content: 'c';
|
||||||
|
}
|
||||||
|
.mq-editable-field .mq-text-mode .mq-cursor:only-child:after {
|
||||||
|
content: '';
|
||||||
|
}
|
||||||
|
.mq-editable-field.mq-text-mode {
|
||||||
|
overflow-x: auto;
|
||||||
|
overflow-y: hidden;
|
||||||
|
}
|
||||||
|
.mq-root-block,
|
||||||
|
.mq-math-mode .mq-root-block {
|
||||||
|
display: -moz-inline-box;
|
||||||
|
display: inline-block;
|
||||||
|
width: 100%;
|
||||||
|
padding: 2px;
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
-moz-box-sizing: border-box;
|
||||||
|
box-sizing: border-box;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
.mq-math-mode {
|
||||||
|
font-variant: normal;
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
font-size: 115%;
|
||||||
|
line-height: 1;
|
||||||
|
display: -moz-inline-box;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-non-leaf,
|
||||||
|
.mq-math-mode .mq-scaled {
|
||||||
|
display: -moz-inline-box;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.mq-math-mode var,
|
||||||
|
.mq-math-mode .mq-text-mode,
|
||||||
|
.mq-math-mode .mq-nonSymbola {
|
||||||
|
font-family: "Times New Roman", Symbola, serif;
|
||||||
|
line-height: .9;
|
||||||
|
}
|
||||||
|
.mq-math-mode * {
|
||||||
|
font-size: inherit;
|
||||||
|
line-height: inherit;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
border-color: black;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-empty {
|
||||||
|
background: #ccc;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-empty.mq-root-block {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
.mq-math-mode.mq-empty {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-text-mode {
|
||||||
|
font-size: 87%;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-font {
|
||||||
|
font: 1em "Times New Roman", Symbola, serif;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-font * {
|
||||||
|
font-family: inherit;
|
||||||
|
font-style: inherit;
|
||||||
|
}
|
||||||
|
.mq-math-mode b,
|
||||||
|
.mq-math-mode b.mq-font {
|
||||||
|
font-weight: bolder;
|
||||||
|
}
|
||||||
|
.mq-math-mode var,
|
||||||
|
.mq-math-mode i,
|
||||||
|
.mq-math-mode i.mq-font {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
.mq-math-mode var.mq-f {
|
||||||
|
margin-right: 0.2em;
|
||||||
|
margin-left: 0.1em;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-roman var.mq-f {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.mq-math-mode big {
|
||||||
|
font-size: 125%;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-roman {
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-sans-serif {
|
||||||
|
font-family: sans-serif, Symbola, serif;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-monospace {
|
||||||
|
font-family: monospace, Symbola, serif;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-overline {
|
||||||
|
border-top: 1px solid black;
|
||||||
|
margin-top: 1px;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-underline {
|
||||||
|
border-bottom: 1px solid black;
|
||||||
|
margin-bottom: 1px;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-binary-operator {
|
||||||
|
padding: 0 0.2em;
|
||||||
|
display: -moz-inline-box;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-supsub {
|
||||||
|
font-size: 90%;
|
||||||
|
vertical-align: -0.5em;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-supsub.mq-limit {
|
||||||
|
font-size: 80%;
|
||||||
|
vertical-align: -0.4em;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-supsub.mq-sup-only {
|
||||||
|
vertical-align: .5em;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-supsub.mq-sup-only .mq-sup {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: text-bottom;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-supsub .mq-sup {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-supsub .mq-sub {
|
||||||
|
display: block;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-supsub.mq-limit .mq-sub {
|
||||||
|
margin-left: -0.25em;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-supsub .mq-binary-operator {
|
||||||
|
padding: 0 .1em;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-supsub .mq-fraction {
|
||||||
|
font-size: 70%;
|
||||||
|
}
|
||||||
|
.mq-math-mode sup.mq-nthroot {
|
||||||
|
font-size: 80%;
|
||||||
|
vertical-align: 0.8em;
|
||||||
|
margin-right: -0.6em;
|
||||||
|
margin-left: .2em;
|
||||||
|
min-width: .5em;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-paren {
|
||||||
|
padding: 0 .1em;
|
||||||
|
vertical-align: top;
|
||||||
|
-webkit-transform-origin: center .06em;
|
||||||
|
-moz-transform-origin: center .06em;
|
||||||
|
-ms-transform-origin: center .06em;
|
||||||
|
-o-transform-origin: center .06em;
|
||||||
|
transform-origin: center .06em;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-paren.mq-ghost {
|
||||||
|
color: silver;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-paren + span {
|
||||||
|
margin-top: .1em;
|
||||||
|
margin-bottom: .1em;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-array {
|
||||||
|
vertical-align: middle;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-array > span {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-operator-name {
|
||||||
|
font-family: Symbola, "Times New Roman", serif;
|
||||||
|
line-height: .9;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
.mq-math-mode var.mq-operator-name.mq-first {
|
||||||
|
padding-left: .2em;
|
||||||
|
}
|
||||||
|
.mq-math-mode var.mq-operator-name.mq-last {
|
||||||
|
padding-right: .2em;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-fraction {
|
||||||
|
font-size: 90%;
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: -0.4em;
|
||||||
|
padding: 0 .2em;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-fraction,
|
||||||
|
.mq-math-mode .mq-large-operator,
|
||||||
|
.mq-math-mode x:-moz-any-link {
|
||||||
|
display: -moz-groupbox;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-fraction,
|
||||||
|
.mq-math-mode .mq-large-operator,
|
||||||
|
.mq-math-mode x:-moz-any-link,
|
||||||
|
.mq-math-mode x:default {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-numerator,
|
||||||
|
.mq-math-mode .mq-denominator {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-numerator {
|
||||||
|
padding: 0 0.1em;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-denominator {
|
||||||
|
border-top: 1px solid;
|
||||||
|
float: right;
|
||||||
|
width: 100%;
|
||||||
|
padding: 0.1em;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-sqrt-prefix {
|
||||||
|
padding-top: 0;
|
||||||
|
position: relative;
|
||||||
|
top: 0.1em;
|
||||||
|
vertical-align: top;
|
||||||
|
-webkit-transform-origin: top;
|
||||||
|
-moz-transform-origin: top;
|
||||||
|
-ms-transform-origin: top;
|
||||||
|
-o-transform-origin: top;
|
||||||
|
transform-origin: top;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-sqrt-stem {
|
||||||
|
border-top: 1px solid;
|
||||||
|
margin-top: 1px;
|
||||||
|
padding-left: .15em;
|
||||||
|
padding-right: .2em;
|
||||||
|
margin-right: .1em;
|
||||||
|
padding-top: 1px;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-vector-prefix {
|
||||||
|
display: block;
|
||||||
|
text-align: center;
|
||||||
|
line-height: .25em;
|
||||||
|
margin-bottom: -0.1em;
|
||||||
|
font-size: 0.75em;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-vector-stem {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-large-operator {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-large-operator .mq-from,
|
||||||
|
.mq-math-mode .mq-large-operator big,
|
||||||
|
.mq-math-mode .mq-large-operator .mq-to {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-large-operator .mq-from,
|
||||||
|
.mq-math-mode .mq-large-operator .mq-to {
|
||||||
|
font-size: 80%;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-large-operator .mq-from {
|
||||||
|
float: right;
|
||||||
|
/* take out of normal flow to manipulate baseline */
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.mq-math-mode,
|
||||||
|
.mq-math-mode .mq-editable-field {
|
||||||
|
cursor: text;
|
||||||
|
font-family: Symbola, "Times New Roman", serif;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-overarrow {
|
||||||
|
border-top: 1px solid black;
|
||||||
|
margin-top: 1px;
|
||||||
|
padding-top: 0.2em;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-overarrow:before {
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
top: -0.34em;
|
||||||
|
font-size: 0.5em;
|
||||||
|
line-height: 0em;
|
||||||
|
content: '\27A4';
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-overarrow.mq-arrow-left:before {
|
||||||
|
-moz-transform: scaleX(-1);
|
||||||
|
-o-transform: scaleX(-1);
|
||||||
|
-webkit-transform: scaleX(-1);
|
||||||
|
transform: scaleX(-1);
|
||||||
|
filter: FlipH;
|
||||||
|
-ms-filter: "FlipH";
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-selection,
|
||||||
|
.mq-editable-field .mq-selection,
|
||||||
|
.mq-math-mode .mq-selection .mq-non-leaf,
|
||||||
|
.mq-editable-field .mq-selection .mq-non-leaf,
|
||||||
|
.mq-math-mode .mq-selection .mq-scaled,
|
||||||
|
.mq-editable-field .mq-selection .mq-scaled {
|
||||||
|
background: #B4D5FE !important;
|
||||||
|
background: Highlight !important;
|
||||||
|
color: HighlightText;
|
||||||
|
border-color: HighlightText;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-selection .mq-matrixed,
|
||||||
|
.mq-editable-field .mq-selection .mq-matrixed {
|
||||||
|
background: #39F !important;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-selection .mq-matrixed-container,
|
||||||
|
.mq-editable-field .mq-selection .mq-matrixed-container {
|
||||||
|
filter: progid:DXImageTransform.Microsoft.Chroma(color='#3399FF') !important;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-selection.mq-blur,
|
||||||
|
.mq-editable-field .mq-selection.mq-blur,
|
||||||
|
.mq-math-mode .mq-selection.mq-blur .mq-non-leaf,
|
||||||
|
.mq-editable-field .mq-selection.mq-blur .mq-non-leaf,
|
||||||
|
.mq-math-mode .mq-selection.mq-blur .mq-scaled,
|
||||||
|
.mq-editable-field .mq-selection.mq-blur .mq-scaled,
|
||||||
|
.mq-math-mode .mq-selection.mq-blur .mq-matrixed,
|
||||||
|
.mq-editable-field .mq-selection.mq-blur .mq-matrixed {
|
||||||
|
background: #D4D4D4 !important;
|
||||||
|
color: black;
|
||||||
|
border-color: black;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-selection.mq-blur .mq-matrixed-container,
|
||||||
|
.mq-editable-field .mq-selection.mq-blur .mq-matrixed-container {
|
||||||
|
filter: progid:DXImageTransform.Microsoft.Chroma(color='#D4D4D4') !important;
|
||||||
|
}
|
||||||
|
.mq-editable-field .mq-textarea,
|
||||||
|
.mq-math-mode .mq-textarea {
|
||||||
|
position: relative;
|
||||||
|
-webkit-user-select: text;
|
||||||
|
-moz-user-select: text;
|
||||||
|
user-select: text;
|
||||||
|
}
|
||||||
|
.mq-editable-field .mq-textarea *,
|
||||||
|
.mq-math-mode .mq-textarea *,
|
||||||
|
.mq-editable-field .mq-selectable,
|
||||||
|
.mq-math-mode .mq-selectable {
|
||||||
|
-webkit-user-select: text;
|
||||||
|
-moz-user-select: text;
|
||||||
|
user-select: text;
|
||||||
|
position: absolute;
|
||||||
|
clip: rect(1em 1em 1em 1em);
|
||||||
|
-webkit-transform: scale(0);
|
||||||
|
-moz-transform: scale(0);
|
||||||
|
-ms-transform: scale(0);
|
||||||
|
-o-transform: scale(0);
|
||||||
|
transform: scale(0);
|
||||||
|
resize: none;
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-matrixed {
|
||||||
|
background: white;
|
||||||
|
display: -moz-inline-box;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-matrixed-container {
|
||||||
|
filter: progid:DXImageTransform.Microsoft.Chroma(color='white');
|
||||||
|
margin-top: -0.1em;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,425 @@
|
||||||
|
/*
|
||||||
|
* MathQuill v0.10.1 http://mathquill.com
|
||||||
|
* by Han, Jeanine, and Mary maintainers@mathquill.com
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the
|
||||||
|
* Mozilla Public License, v. 2.0. If a copy of the MPL
|
||||||
|
* was not distributed with this file, You can obtain
|
||||||
|
* one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
@font-face {
|
||||||
|
font-family: Symbola;
|
||||||
|
src: url(font/Symbola.eot);
|
||||||
|
src: local("Symbola Regular"), local("Symbola"), url(font/Symbola.woff2) format("woff2"), url(font/Symbola.woff) format("woff"), url(font/Symbola.ttf) format("truetype"), url(font/Symbola.otf) format("opentype"), url(font/Symbola.svg#Symbola) format("svg");
|
||||||
|
}
|
||||||
|
.mq-editable-field {
|
||||||
|
display: -moz-inline-box;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.mq-editable-field .mq-cursor {
|
||||||
|
border-left: 1px solid black;
|
||||||
|
margin-left: -1px;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
padding: 0;
|
||||||
|
display: -moz-inline-box;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.mq-editable-field .mq-cursor.mq-blink {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
.mq-editable-field,
|
||||||
|
.mq-math-mode .mq-editable-field {
|
||||||
|
border: 1px solid gray;
|
||||||
|
}
|
||||||
|
.mq-editable-field.mq-focused,
|
||||||
|
.mq-math-mode .mq-editable-field.mq-focused {
|
||||||
|
-webkit-box-shadow: #8bd 0 0 1px 2px, inset #6ae 0 0 2px 0;
|
||||||
|
-moz-box-shadow: #8bd 0 0 1px 2px, inset #6ae 0 0 2px 0;
|
||||||
|
box-shadow: #8bd 0 0 1px 2px, inset #6ae 0 0 2px 0;
|
||||||
|
border-color: #709AC0;
|
||||||
|
border-radius: 1px;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-editable-field {
|
||||||
|
margin: 1px;
|
||||||
|
}
|
||||||
|
.mq-editable-field .mq-latex-command-input {
|
||||||
|
color: inherit;
|
||||||
|
font-family: "Courier New", monospace;
|
||||||
|
border: 1px solid gray;
|
||||||
|
padding-right: 1px;
|
||||||
|
margin-right: 1px;
|
||||||
|
margin-left: 2px;
|
||||||
|
}
|
||||||
|
.mq-editable-field .mq-latex-command-input.mq-empty {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
.mq-editable-field .mq-latex-command-input.mq-hasCursor {
|
||||||
|
border-color: ActiveBorder;
|
||||||
|
}
|
||||||
|
.mq-editable-field.mq-empty:after,
|
||||||
|
.mq-editable-field.mq-text-mode:after,
|
||||||
|
.mq-math-mode .mq-empty:after {
|
||||||
|
visibility: hidden;
|
||||||
|
content: 'c';
|
||||||
|
}
|
||||||
|
.mq-editable-field .mq-cursor:only-child:after,
|
||||||
|
.mq-editable-field .mq-textarea + .mq-cursor:last-child:after {
|
||||||
|
visibility: hidden;
|
||||||
|
content: 'c';
|
||||||
|
}
|
||||||
|
.mq-editable-field .mq-text-mode .mq-cursor:only-child:after {
|
||||||
|
content: '';
|
||||||
|
}
|
||||||
|
.mq-editable-field.mq-text-mode {
|
||||||
|
overflow-x: auto;
|
||||||
|
overflow-y: hidden;
|
||||||
|
}
|
||||||
|
.mq-root-block,
|
||||||
|
.mq-math-mode .mq-root-block {
|
||||||
|
display: -moz-inline-box;
|
||||||
|
display: inline-block;
|
||||||
|
width: 100%;
|
||||||
|
padding: 2px;
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
-moz-box-sizing: border-box;
|
||||||
|
box-sizing: border-box;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
.mq-math-mode {
|
||||||
|
font-variant: normal;
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
font-size: 115%;
|
||||||
|
line-height: 1;
|
||||||
|
display: -moz-inline-box;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-non-leaf,
|
||||||
|
.mq-math-mode .mq-scaled {
|
||||||
|
display: -moz-inline-box;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.mq-math-mode var,
|
||||||
|
.mq-math-mode .mq-text-mode,
|
||||||
|
.mq-math-mode .mq-nonSymbola {
|
||||||
|
font-family: "Times New Roman", Symbola, serif;
|
||||||
|
line-height: .9;
|
||||||
|
}
|
||||||
|
.mq-math-mode * {
|
||||||
|
font-size: inherit;
|
||||||
|
line-height: inherit;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
border-color: black;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-empty {
|
||||||
|
background: #ccc;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-empty.mq-root-block {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
.mq-math-mode.mq-empty {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-text-mode {
|
||||||
|
font-size: 87%;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-font {
|
||||||
|
font: 1em "Times New Roman", Symbola, serif;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-font * {
|
||||||
|
font-family: inherit;
|
||||||
|
font-style: inherit;
|
||||||
|
}
|
||||||
|
.mq-math-mode b,
|
||||||
|
.mq-math-mode b.mq-font {
|
||||||
|
font-weight: bolder;
|
||||||
|
}
|
||||||
|
.mq-math-mode var,
|
||||||
|
.mq-math-mode i,
|
||||||
|
.mq-math-mode i.mq-font {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
.mq-math-mode var.mq-f {
|
||||||
|
margin-right: 0.2em;
|
||||||
|
margin-left: 0.1em;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-roman var.mq-f {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.mq-math-mode big {
|
||||||
|
font-size: 125%;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-roman {
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-sans-serif {
|
||||||
|
font-family: sans-serif, Symbola, serif;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-monospace {
|
||||||
|
font-family: monospace, Symbola, serif;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-overline {
|
||||||
|
border-top: 1px solid black;
|
||||||
|
margin-top: 1px;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-underline {
|
||||||
|
border-bottom: 1px solid black;
|
||||||
|
margin-bottom: 1px;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-binary-operator {
|
||||||
|
padding: 0 0.2em;
|
||||||
|
display: -moz-inline-box;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-supsub {
|
||||||
|
font-size: 90%;
|
||||||
|
vertical-align: -0.5em;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-supsub.mq-limit {
|
||||||
|
font-size: 80%;
|
||||||
|
vertical-align: -0.4em;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-supsub.mq-sup-only {
|
||||||
|
vertical-align: .5em;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-supsub.mq-sup-only .mq-sup {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: text-bottom;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-supsub .mq-sup {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-supsub .mq-sub {
|
||||||
|
display: block;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-supsub.mq-limit .mq-sub {
|
||||||
|
margin-left: -0.25em;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-supsub .mq-binary-operator {
|
||||||
|
padding: 0 .1em;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-supsub .mq-fraction {
|
||||||
|
font-size: 70%;
|
||||||
|
}
|
||||||
|
.mq-math-mode sup.mq-nthroot {
|
||||||
|
font-size: 80%;
|
||||||
|
vertical-align: 0.8em;
|
||||||
|
margin-right: -0.6em;
|
||||||
|
margin-left: .2em;
|
||||||
|
min-width: .5em;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-paren {
|
||||||
|
padding: 0 .1em;
|
||||||
|
vertical-align: top;
|
||||||
|
-webkit-transform-origin: center .06em;
|
||||||
|
-moz-transform-origin: center .06em;
|
||||||
|
-ms-transform-origin: center .06em;
|
||||||
|
-o-transform-origin: center .06em;
|
||||||
|
transform-origin: center .06em;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-paren.mq-ghost {
|
||||||
|
color: silver;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-paren + span {
|
||||||
|
margin-top: .1em;
|
||||||
|
margin-bottom: .1em;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-array {
|
||||||
|
vertical-align: middle;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-array > span {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-operator-name {
|
||||||
|
font-family: Symbola, "Times New Roman", serif;
|
||||||
|
line-height: .9;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
.mq-math-mode var.mq-operator-name.mq-first {
|
||||||
|
padding-left: .2em;
|
||||||
|
}
|
||||||
|
.mq-math-mode var.mq-operator-name.mq-last {
|
||||||
|
padding-right: .2em;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-fraction {
|
||||||
|
font-size: 90%;
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: -0.4em;
|
||||||
|
padding: 0 .2em;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-fraction,
|
||||||
|
.mq-math-mode .mq-large-operator,
|
||||||
|
.mq-math-mode x:-moz-any-link {
|
||||||
|
display: -moz-groupbox;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-fraction,
|
||||||
|
.mq-math-mode .mq-large-operator,
|
||||||
|
.mq-math-mode x:-moz-any-link,
|
||||||
|
.mq-math-mode x:default {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-numerator,
|
||||||
|
.mq-math-mode .mq-denominator {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-numerator {
|
||||||
|
padding: 0 0.1em;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-denominator {
|
||||||
|
border-top: 1px solid;
|
||||||
|
float: right;
|
||||||
|
width: 100%;
|
||||||
|
padding: 0.1em;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-sqrt-prefix {
|
||||||
|
padding-top: 0;
|
||||||
|
position: relative;
|
||||||
|
top: 0.1em;
|
||||||
|
vertical-align: top;
|
||||||
|
-webkit-transform-origin: top;
|
||||||
|
-moz-transform-origin: top;
|
||||||
|
-ms-transform-origin: top;
|
||||||
|
-o-transform-origin: top;
|
||||||
|
transform-origin: top;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-sqrt-stem {
|
||||||
|
border-top: 1px solid;
|
||||||
|
margin-top: 1px;
|
||||||
|
padding-left: .15em;
|
||||||
|
padding-right: .2em;
|
||||||
|
margin-right: .1em;
|
||||||
|
padding-top: 1px;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-vector-prefix {
|
||||||
|
display: block;
|
||||||
|
text-align: center;
|
||||||
|
line-height: .25em;
|
||||||
|
margin-bottom: -0.1em;
|
||||||
|
font-size: 0.75em;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-vector-stem {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-large-operator {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-large-operator .mq-from,
|
||||||
|
.mq-math-mode .mq-large-operator big,
|
||||||
|
.mq-math-mode .mq-large-operator .mq-to {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-large-operator .mq-from,
|
||||||
|
.mq-math-mode .mq-large-operator .mq-to {
|
||||||
|
font-size: 80%;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-large-operator .mq-from {
|
||||||
|
float: right;
|
||||||
|
/* take out of normal flow to manipulate baseline */
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.mq-math-mode,
|
||||||
|
.mq-math-mode .mq-editable-field {
|
||||||
|
cursor: text;
|
||||||
|
font-family: Symbola, "Times New Roman", serif;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-overarrow {
|
||||||
|
border-top: 1px solid black;
|
||||||
|
margin-top: 1px;
|
||||||
|
padding-top: 0.2em;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-overarrow:before {
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
top: -0.34em;
|
||||||
|
font-size: 0.5em;
|
||||||
|
line-height: 0em;
|
||||||
|
content: '\27A4';
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-overarrow.mq-arrow-left:before {
|
||||||
|
-moz-transform: scaleX(-1);
|
||||||
|
-o-transform: scaleX(-1);
|
||||||
|
-webkit-transform: scaleX(-1);
|
||||||
|
transform: scaleX(-1);
|
||||||
|
filter: FlipH;
|
||||||
|
-ms-filter: "FlipH";
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-selection,
|
||||||
|
.mq-editable-field .mq-selection,
|
||||||
|
.mq-math-mode .mq-selection .mq-non-leaf,
|
||||||
|
.mq-editable-field .mq-selection .mq-non-leaf,
|
||||||
|
.mq-math-mode .mq-selection .mq-scaled,
|
||||||
|
.mq-editable-field .mq-selection .mq-scaled {
|
||||||
|
background: #B4D5FE !important;
|
||||||
|
background: Highlight !important;
|
||||||
|
color: HighlightText;
|
||||||
|
border-color: HighlightText;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-selection .mq-matrixed,
|
||||||
|
.mq-editable-field .mq-selection .mq-matrixed {
|
||||||
|
background: #39F !important;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-selection .mq-matrixed-container,
|
||||||
|
.mq-editable-field .mq-selection .mq-matrixed-container {
|
||||||
|
filter: progid:DXImageTransform.Microsoft.Chroma(color='#3399FF') !important;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-selection.mq-blur,
|
||||||
|
.mq-editable-field .mq-selection.mq-blur,
|
||||||
|
.mq-math-mode .mq-selection.mq-blur .mq-non-leaf,
|
||||||
|
.mq-editable-field .mq-selection.mq-blur .mq-non-leaf,
|
||||||
|
.mq-math-mode .mq-selection.mq-blur .mq-scaled,
|
||||||
|
.mq-editable-field .mq-selection.mq-blur .mq-scaled,
|
||||||
|
.mq-math-mode .mq-selection.mq-blur .mq-matrixed,
|
||||||
|
.mq-editable-field .mq-selection.mq-blur .mq-matrixed {
|
||||||
|
background: #D4D4D4 !important;
|
||||||
|
color: black;
|
||||||
|
border-color: black;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-selection.mq-blur .mq-matrixed-container,
|
||||||
|
.mq-editable-field .mq-selection.mq-blur .mq-matrixed-container {
|
||||||
|
filter: progid:DXImageTransform.Microsoft.Chroma(color='#D4D4D4') !important;
|
||||||
|
}
|
||||||
|
.mq-editable-field .mq-textarea,
|
||||||
|
.mq-math-mode .mq-textarea {
|
||||||
|
position: relative;
|
||||||
|
-webkit-user-select: text;
|
||||||
|
-moz-user-select: text;
|
||||||
|
user-select: text;
|
||||||
|
}
|
||||||
|
.mq-editable-field .mq-textarea *,
|
||||||
|
.mq-math-mode .mq-textarea *,
|
||||||
|
.mq-editable-field .mq-selectable,
|
||||||
|
.mq-math-mode .mq-selectable {
|
||||||
|
-webkit-user-select: text;
|
||||||
|
-moz-user-select: text;
|
||||||
|
user-select: text;
|
||||||
|
position: absolute;
|
||||||
|
clip: rect(1em 1em 1em 1em);
|
||||||
|
-webkit-transform: scale(0);
|
||||||
|
-moz-transform: scale(0);
|
||||||
|
-ms-transform: scale(0);
|
||||||
|
-o-transform: scale(0);
|
||||||
|
transform: scale(0);
|
||||||
|
resize: none;
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-matrixed {
|
||||||
|
background: white;
|
||||||
|
display: -moz-inline-box;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.mq-math-mode .mq-matrixed-container {
|
||||||
|
filter: progid:DXImageTransform.Microsoft.Chroma(color='white');
|
||||||
|
margin-top: -0.1em;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
nav .navbar-brand
|
||||||
|
{
|
||||||
|
/* size for brand */
|
||||||
|
font-size: xx-large;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* colors for brand */
|
||||||
|
nav .navbar-brand .blue
|
||||||
|
{
|
||||||
|
color: #537fbe;
|
||||||
|
}
|
||||||
|
nav .navbar-brand .red
|
||||||
|
{
|
||||||
|
color: #ea433b;
|
||||||
|
}
|
||||||
|
nav .navbar-brand .yellow
|
||||||
|
{
|
||||||
|
color: #f5b82e;
|
||||||
|
}
|
||||||
|
nav .navbar-brand .green
|
||||||
|
{
|
||||||
|
color: #2e944b;
|
||||||
|
}
|
||||||
|
|
||||||
|
main .form-control
|
||||||
|
{
|
||||||
|
/* center form controls */
|
||||||
|
display: inline-block;
|
||||||
|
|
||||||
|
/* override Bootstrap's 100% width for form controls */
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
main
|
||||||
|
{
|
||||||
|
/* scroll horizontally as needed */
|
||||||
|
overflow-x: auto;
|
||||||
|
|
||||||
|
/* center contents */
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
main img
|
||||||
|
{
|
||||||
|
/* constrain images on small screens */
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
{% extends "layout.html" %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
Differentiation
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
<p>Function you would like to Derive: </p>
|
||||||
|
<p>Type math here: <span id="math-field"></span></p>
|
||||||
|
<form action="/differentiation" method="post">
|
||||||
|
<div class = "form-group">
|
||||||
|
<input autocomplete="off" autofocus class="form-control" name="function" placeholder="Function" type="hidden" id="function" />
|
||||||
|
</div>
|
||||||
|
<p id="jp">Your Input Will Appear Here</p>
|
||||||
|
<button class="btn btn-primary" type="submit" id="btn">Derive</button>
|
||||||
|
</form>
|
||||||
|
<script>
|
||||||
|
let value = $("#function").val();
|
||||||
|
$(document).ready(function(){
|
||||||
|
$('#function').on('input', function() {
|
||||||
|
let testvalue = $('#function').val();
|
||||||
|
$('#jp').html("$f(x) = "+testvalue+"$");
|
||||||
|
MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var mathFieldSpan = document.getElementById('math-field');
|
||||||
|
var latexSpan = document.getElementById('latex');
|
||||||
|
|
||||||
|
var MQ = MathQuill.getInterface(2); // for backcompat
|
||||||
|
var mathField = MQ.MathField(mathFieldSpan, {
|
||||||
|
spaceBehavesLikeTab: true, // configurable
|
||||||
|
handlers: {
|
||||||
|
edit: function() { // useful event handlers
|
||||||
|
latexSpan.textContent = mathField.latex(); // simple API
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var formInput = document.getElementById("function")
|
||||||
|
$(document).ready(function(){
|
||||||
|
$('#btn').click(function (evt) {
|
||||||
|
document.getElementById("function").value = mathField.latex();
|
||||||
|
})
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
{% extends "layout.html" %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
Apology
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
<img alt="{{ top }}" class="border" src="http://memegen.link/custom/{{ top | urlencode }}/{{ bottom | urlencode }}.jpg?alt=https://i.imgur.com/CsCgN7Ll.png" title="{{ top }}">
|
||||||
|
{% endblock %}
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
{% extends "layout.html" %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
Approximation
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
<span>Function you would like to Approximate:</span>
|
||||||
|
<form action="/aprox" method="post">
|
||||||
|
<div class = "form-group">
|
||||||
|
<input autocomplete="off" autofocus class="form-control" name="function" placeholder="Function" type="text" id="function">
|
||||||
|
</div>
|
||||||
|
<p id="jp">Your Input Will Appear Here</p>
|
||||||
|
<p>To create the Linearization of f at a, L(x) = f(a) + f'(a)(x-a), we need an easy to calculate value, a,
|
||||||
|
and a difficult to find value for x</p>
|
||||||
|
<div class = "form-group">
|
||||||
|
<input autocomplete="off" autofocus class="form-control" name="easy" placeholder="Easy Value a" type="text" id="easy">
|
||||||
|
<input autocomplete="off" autofocus class="form-control" name="hard" placeholder="Difficult Value for x" type="text" id="hard">
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-primary" type="submit">Approximate</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
let value = $("#function").val();
|
||||||
|
$(document).ready(function(){
|
||||||
|
$('#function').on('input', function() {
|
||||||
|
let testvalue = $('#function').val();
|
||||||
|
$('#jp').html("$f(x) = "+testvalue+"$");
|
||||||
|
MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
{% extends "layout.html" %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
Differentiated
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
<div>
|
||||||
|
<p>Your function is $f(x) = {{ value }}$</p>
|
||||||
|
<p>Your Linear Approximation of $f(x)$ at $x = {{ h }}$ is ${{ lh }}$</p>
|
||||||
|
</div>
|
||||||
|
<table class="table" action="optimized">
|
||||||
|
<tbody>
|
||||||
|
<tr class="bg-dark text-white">
|
||||||
|
<td>Step 1</td>
|
||||||
|
<td>Setup L(x)</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="table-secondary">
|
||||||
|
<td></td>
|
||||||
|
<td>$L(x) = f({{ a }}) + f'({{ a }})(x-{{ a }})$</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="bg-dark text-white">
|
||||||
|
<td>Step 2</td>
|
||||||
|
<td>Take the Derivative</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="table-secondary">
|
||||||
|
<td></td>
|
||||||
|
<td>$f'(x) = {{ fprime }}$</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="bg-dark text-white">
|
||||||
|
<td>Step 3</td>
|
||||||
|
<td>Plug in values</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="table-secondary">
|
||||||
|
<td></td>
|
||||||
|
<td>$f({{ a }}) = {{ fa }}$</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="table-secondary">
|
||||||
|
<td></td>
|
||||||
|
<td>$f'({{ a }}) = {{ fprimea }}$</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="table-secondary">
|
||||||
|
<td></td>
|
||||||
|
<td>$L(x) = {{ fa }} + [{{ fprimea }}(x - {{ a }})]$</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="bg-dark text-white">
|
||||||
|
<td>Step 4</td>
|
||||||
|
<td>Use our $L(x)$ to approximate $f({{ h }})$</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="table-secondary">
|
||||||
|
<td></td>
|
||||||
|
<td>$L({{ h }}) = {{ fa }} + [{{ fprimea }}({{ h }} - {{ a }})]$</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="table-secondary">
|
||||||
|
<td></td>
|
||||||
|
<td> $= {{ lh }}$</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{% endblock %}
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
{% extends "layout.html" %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
Differentiated
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
<div>
|
||||||
|
<p>For $f(x) = {{ value }}$</p>
|
||||||
|
<p>$f'(x) = {{ fprime }}$</p>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
{% extends "layout.html" %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
Differentiation
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
<p>Function you would like to Derive: </p>
|
||||||
|
<form action="/differentiation" method="post">
|
||||||
|
<div class = "form-group">
|
||||||
|
<input autocomplete="off" autofocus class="form-control" name="function" placeholder="Function" type="text" id="function">
|
||||||
|
</div>
|
||||||
|
<p id="jp">Your Input Will Appear Here</p>
|
||||||
|
<button class="btn btn-primary" type="submit">Differentiate</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
let value = $("#function").val();
|
||||||
|
$(document).ready(function(){
|
||||||
|
$('#function').on('input', function() {
|
||||||
|
let testvalue = $('#function').val();
|
||||||
|
$('#jp').html("$f(x) = "+testvalue+"$");
|
||||||
|
MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
{% extends "layout.html" %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
Index
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
<p>This is a website dedicated to making the lives of calculus students easier, if ever so slightly.</p>
|
||||||
|
<P>All function inputs will be taken assuming 'x' as your variable. All other letters will be treated as constants</P>
|
||||||
|
<p>That noted, you may enter terms for well known constants and they will likely be accounted for</p>
|
||||||
|
<p>As an example you could enter the function $sin(\pi x)$ with the notation sin(pi*x)</p>
|
||||||
|
<p>As a once struggling calculus student, I highly recommend this site be used either to check your work or as a tool
|
||||||
|
to understand the steps behind those problems which you failed in solving alone</p>
|
||||||
|
<p>Good luck!</p>
|
||||||
|
{% endblock %}
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
{% extends "layout.html" %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
Integrated
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
<div>
|
||||||
|
<p>Your Equation is: ${{ value }}$</p>
|
||||||
|
<p>Your integral is: ${{ fintegral }}$</p>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
{% extends "layout.html" %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
Integration
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
<p>Function you would like to Integrate: </p>
|
||||||
|
<form action="/integration" method="post">
|
||||||
|
<div class = "form-group">
|
||||||
|
<input autocomplete="off" autofocus class="form-control" name="function" placeholder="Function" type="text" id="function">
|
||||||
|
</div>
|
||||||
|
<p id="jp">Your Input Will Appear Here</p>
|
||||||
|
<button class="btn btn-primary" type="submit">Integrate</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
let value = $("#function").val();
|
||||||
|
$(document).ready(function(){
|
||||||
|
$('#function').on('input', function() {
|
||||||
|
let testvalue = $('#function').val();
|
||||||
|
$('#jp').html("$f(x) = "+testvalue+"$");
|
||||||
|
MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
@ -0,0 +1,84 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
|
||||||
|
<!-- Required meta tags -->
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
|
|
||||||
|
<!-- documentation at http://getbootstrap.com/docs/4.1/, alternative themes at https://bootswatch.com/ -->
|
||||||
|
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<!-- https://favicon.io/emoji-favicons/money-mouth-face/ -->
|
||||||
|
<link href="/static/favicon.ico" rel="icon">
|
||||||
|
|
||||||
|
<link href="/static/styles.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"></script>
|
||||||
|
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>
|
||||||
|
|
||||||
|
<!-- MathJax Integration and configuration -->
|
||||||
|
<script src='https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-MML-AM_CHTML' async></script>
|
||||||
|
<script type="text/x-mathjax-config">
|
||||||
|
MathJax.Hub.Config({tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- MathQuill Link -->
|
||||||
|
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/mathquill/0.10.1/mathquill.min.css">`
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathquill/0.10.1/mathquill.min.js" type="text/javascript"></script>
|
||||||
|
<script>var MQ = MathQuill.getInterface(2);</script>
|
||||||
|
|
||||||
|
<title>C$50 Math: {% block title %}{% endblock %}</title>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<nav class="navbar navbar-expand-md navbar-light bg-light border">
|
||||||
|
<a class="navbar-brand" href="/"><span class="blue">C</span><span class="red">$</span><span class="yellow">5</span><span class="green">0</span> <span class="red">Math</span></a>
|
||||||
|
<button aria-controls="navbar" aria-expanded="false" aria-label="Toggle navigation" class="navbar-toggler" data-target="#navbar" data-toggle="collapse" type="button">
|
||||||
|
<span class="navbar-toggler-icon"></span>
|
||||||
|
</button>
|
||||||
|
<div class="collapse navbar-collapse" id="navbar">
|
||||||
|
{% if session.user_id %}
|
||||||
|
<ul class="navbar-nav mr-auto mt-2">
|
||||||
|
<li class="nav-item"><a class="nav-link" href="/differentiation">Differentiation</a></li>
|
||||||
|
<li class="nav-item"><a class="nav-link" href="/integration">Integration</a></li>
|
||||||
|
<li class="nav-item"><a class="nav-link" href="/maxmin">Max/Min</a></li>
|
||||||
|
<li class="nav-item"><a class="nav-link" href="/aprox">Linearization</a></li>
|
||||||
|
<li class="nav-item"><a class="nav-link" href="/riemann">Riemann</a></li>
|
||||||
|
</ul>
|
||||||
|
<ul class="navbar-nav ml-auto mt-2">
|
||||||
|
<li class="nav-item"><a class="nav-link" href="/logout">Log Out</a></li>
|
||||||
|
</ul>
|
||||||
|
{% else %}
|
||||||
|
<ul class="navbar-nav ml-auto mt-2">
|
||||||
|
<li class="nav-item"><a class="nav-link" href="/register">Register</a></li>
|
||||||
|
<li class="nav-item"><a class="nav-link" href="/login">Log In</a></li>
|
||||||
|
</ul>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
{% if get_flashed_messages() %}
|
||||||
|
<header>
|
||||||
|
<div class="alert alert-primary border text-center" role="alert">
|
||||||
|
{{ get_flashed_messages() | join(" ") }}
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<main class="container p-5">
|
||||||
|
{% block main %}{% endblock %}
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<footer class="small text-center text-muted">
|
||||||
|
Huge thanks to the staff at Harvard's <a href="https://cs50.harvard.edu/college/">CS50</a>.
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
{% extends "layout.html" %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
Log In
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
<form action="/login" method="post">
|
||||||
|
<div class="form-group">
|
||||||
|
<input autocomplete="off" autofocus class="form-control" name="username" placeholder="Username" type="text">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<input class="form-control" name="password" placeholder="Password" type="password">
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-primary" type="submit">Log In</button>
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
{% extends "layout.html" %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
Max/Min
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
<span>Function you would like to Max/Min:</span>
|
||||||
|
<form action="/maxmin" method="post">
|
||||||
|
<div class = "form-group">
|
||||||
|
<input autocomplete="off" autofocus class="form-control" name="function" placeholder="Function" type="text" id="function">
|
||||||
|
</div>
|
||||||
|
<p id="jp">Your Input Will Appear Here</p>
|
||||||
|
<div class = "form-group">
|
||||||
|
<input autocomplete="off" autofocus class="form-control" name="lowerbound" placeholder="Lowerbound" type="text" id="lowerbound">
|
||||||
|
<input autocomplete="off" autofocus class="form-control" name="upperbound" placeholder="Upperbound" type="text" id="upperbound">
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-primary" type="submit">Optimize</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
let value = $("#function").val();
|
||||||
|
$(document).ready(function(){
|
||||||
|
$('#function').on('input', function() {
|
||||||
|
let testvalue = $('#function').val();
|
||||||
|
$('#jp').html("$f(x) = "+testvalue+"$");
|
||||||
|
MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
||||||
|
|
@ -0,0 +1,64 @@
|
||||||
|
{% extends "layout.html" %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
Optimized
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
<div>
|
||||||
|
<p>Your function is $f(x) = {{ value }}$</p>
|
||||||
|
<p>Your maximum value is ${{ maximum }}$ and your minimum value is ${{ newvar }}$</p>
|
||||||
|
</div>
|
||||||
|
<table class="table table-hover" action="optimized">
|
||||||
|
<tbody>
|
||||||
|
<tr class="bg-dark text-white">
|
||||||
|
<td>Step 1</td>
|
||||||
|
<td>Take the Derivative</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="table-secondary">
|
||||||
|
<td></td>
|
||||||
|
<td>$f'(x) = {{ fprime }}$</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="bg-dark text-white">
|
||||||
|
<td>Step 2</td>
|
||||||
|
<td>Set $f'(x) = 0$</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="table-secondary">
|
||||||
|
<td></td>
|
||||||
|
<td>$0 = {{ fprime }}$</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="bg-dark text-white">
|
||||||
|
<td>Step 3</td>
|
||||||
|
<td>Solve for $x$:</td>
|
||||||
|
</tr>
|
||||||
|
{% for solution in solutions %}
|
||||||
|
<tr class="table-secondary">
|
||||||
|
<td></td>
|
||||||
|
<td>$x = {{ solution }}$</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
<tr class="bg-dark text-white">
|
||||||
|
<td>Step 4</td>
|
||||||
|
<td>Plug solutions and endpoints into $f(x)$:</td>
|
||||||
|
</tr>
|
||||||
|
{% for candidate in candidates %}
|
||||||
|
<tr class="table-secondary">
|
||||||
|
<td></td>
|
||||||
|
<td>$f({{ candidate }}) = {{values[loop.index - 1]}}$</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
<tr class="bg-dark text-white">
|
||||||
|
<td>Step 5</td>
|
||||||
|
<td>Grab the highest and lowest values</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="table-secondary">
|
||||||
|
<td></td>
|
||||||
|
<td>Your maximum value is ${{ maximum }}$</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="table-secondary">
|
||||||
|
<td></td>
|
||||||
|
<td>Your minimum value is ${{ newvar }}$</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{% endblock %}
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
{% extends "layout.html" %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
Register
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
<form action="/register" method="post" id="form">
|
||||||
|
<div class="form-group">
|
||||||
|
<input autocomplete="off" autofocus class="form-control" name="username" placeholder="Username" id="username" type="text">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<input class="form-control" name="password" placeholder="Password" type="password">
|
||||||
|
</div>
|
||||||
|
<span id="availability"></span>
|
||||||
|
<div class="form-group">
|
||||||
|
<input class="form-control" name="confirmation" placeholder="confirm" type="password">
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-primary" type="submit" id="btn">Register</button>
|
||||||
|
</form>
|
||||||
|
<script type="text/javascript">
|
||||||
|
var username = document.getElementById("username");
|
||||||
|
$(document).ready(function(){
|
||||||
|
$('#btn').click(function (evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
$.get("/check", {username:username.value}, function(data){
|
||||||
|
if (data == false){
|
||||||
|
alert("Username is Taken")
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$('#form').submit();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
{% extends "layout.html" %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
Riemann
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
<span>Function you would like to integrate:</span>
|
||||||
|
<form action="/riemann" method="post">
|
||||||
|
<div class = "form-group">
|
||||||
|
<input autocomplete="off" autofocus class="form-control" name="function" placeholder="Function" type="text" id="function">
|
||||||
|
</div>
|
||||||
|
<p id="jp">Your Input Will Appear Here</p>
|
||||||
|
<span>Range of values (a,b):</span>
|
||||||
|
<div class = "form-group">
|
||||||
|
<input autocomplete="off" autofocus class="form-control" name="lowerbound" placeholder="Lowerbound a" type="text" id="lowerbound">
|
||||||
|
<input autocomplete="off" autofocus class="form-control" name="upperbound" placeholder="Upperbound b" type="text" id="upperbound">
|
||||||
|
</div>
|
||||||
|
<span>Amount of subintervals (how many rectangles?):</span>
|
||||||
|
<div class="form-group">
|
||||||
|
<input autocomplete="off" autofocus class="form-control" name="subintervals" placeholder="Subintervals" type="text" id="subintervals">
|
||||||
|
</div>
|
||||||
|
<div class="radio">
|
||||||
|
<label><input type="radio" name="sumtype" checked value="1">Left Riemann Sum</label>
|
||||||
|
</div>
|
||||||
|
<div class="radio">
|
||||||
|
<label><input type="radio" name="sumtype" value="2">Right Riemann Sum</label>
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-primary" type="submit">Summation</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
let value = $("#function").val();
|
||||||
|
$(document).ready(function(){
|
||||||
|
$('#function').on('input', function() {
|
||||||
|
let testvalue = $('#function').val();
|
||||||
|
$('#jp').html("$f(x) = "+testvalue+"$");
|
||||||
|
MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
{% extends "layout.html" %}
|
||||||
|
|
||||||
|
{% block title%}
|
||||||
|
Summed
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
<span>Approximating the integral of $f(x) = {{ value }}$ from ${{ lb }}$ to ${{ ub }}$ using ${{ si }}$ subintervals</span>
|
||||||
|
<table class="table table-hover" action="optimized">
|
||||||
|
<tbody>
|
||||||
|
<tr class="bg-dark text-white">
|
||||||
|
<td>Step 1</td>
|
||||||
|
<td>Calculate $\Delta x$</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="table-secondary">
|
||||||
|
<td></td>
|
||||||
|
<td>$\Delta x = {{ dx }}$</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="bg-dark text-white">
|
||||||
|
<td>Step 2</td>
|
||||||
|
<td>Check values for $x_i$ (start at lowerbound a and add $\Delta x$ repeatedly)</td>
|
||||||
|
</tr>
|
||||||
|
{% for input in inputs %}
|
||||||
|
<tr class="table-secondary">
|
||||||
|
<td></td>
|
||||||
|
<td>$f(x_{{ loop.index }}) = f({{ input }}) = {{ outputs[loop.index - 1] }}$</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
<tr class="bg-dark text-white">
|
||||||
|
<td>Step 3</td>
|
||||||
|
<td>Multiply $f(x_i)$ and $\Delta x$ for each subinterval</td>
|
||||||
|
</tr>
|
||||||
|
{% for rectangle in rectangles %}
|
||||||
|
<tr class="table-secondary">
|
||||||
|
<td></td>
|
||||||
|
<td>$f(x_{{ loop.index}}) \Delta x = f({{ inputs[loop.index - 1]}})*{{ dx }} = {{ rectangle }}$</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
<tr class="bg-dark text-white">
|
||||||
|
<td>Step 4</td>
|
||||||
|
<td>Add up all products (rectangles) to get final approximation:</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="table-secondary">
|
||||||
|
<td></td>
|
||||||
|
<td>The integral of $f(x) = {{ value }}$ from ${{ lb }}$ to ${{ ub }}$ is approximately equal to ${{ result }}$</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{% endblock %}
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
{% extends "layout.html" %}
|
||||||
|
|
||||||
|
{% block title%}
|
||||||
|
Summed
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
<span>Approximating the integral of $f(x) = {{ value }}$ from ${{ lb }}$ to ${{ ub }}$ using ${{ si }}$ subintervals</span>
|
||||||
|
<table class="table table-hover" action="optimized">
|
||||||
|
<tbody>
|
||||||
|
<tr class="bg-dark text-white">
|
||||||
|
<td>Step 1</td>
|
||||||
|
<td>Calculate $\Delta x$</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="table-secondary">
|
||||||
|
<td></td>
|
||||||
|
<td>$\Delta x = {{ dx }}$</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="bg-dark text-white">
|
||||||
|
<td>Step 2</td>
|
||||||
|
<td>Check values for $x_i$ (start at lowerbound a and add $\Delta x$ repeatedly)</td>
|
||||||
|
</tr>
|
||||||
|
{% for input in inputs %}
|
||||||
|
<tr class="table-secondary">
|
||||||
|
<td></td>
|
||||||
|
<td>$f(x_{{ loop.index - 1 }}) = f({{ input }}) = {{ outputs[loop.index - 1] }}$</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
<tr class="bg-dark text-white">
|
||||||
|
<td>Step 3</td>
|
||||||
|
<td>Multiply $f(x_i)$ and $\Delta x$ for each subinterval</td>
|
||||||
|
</tr>
|
||||||
|
{% for rectangle in rectangles %}
|
||||||
|
<tr class="table-secondary">
|
||||||
|
<td></td>
|
||||||
|
<td>$f(x_{{ loop.index - 1 }}) \Delta x = f({{ inputs[loop.index - 1]}})*{{ dx }} = {{ rectangle }}$</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
<tr class="bg-dark text-white">
|
||||||
|
<td>Step 4</td>
|
||||||
|
<td>Add up all products (rectangles) to get final approximation:</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="table-secondary">
|
||||||
|
<td></td>
|
||||||
|
<td>The integral of $f(x) = {{ value }}$ from ${{ lb }}$ to ${{ ub }}$ is approximately equal to ${{ result }}$</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{% endblock %}
|
||||||
|
|
@ -0,0 +1,319 @@
|
||||||
|
import os
|
||||||
|
|
||||||
|
from cs50 import SQL
|
||||||
|
from flask import Flask, flash, jsonify, redirect, render_template, request, session
|
||||||
|
from flask_session import Session
|
||||||
|
from tempfile import mkdtemp
|
||||||
|
from werkzeug.exceptions import default_exceptions, HTTPException, InternalServerError
|
||||||
|
from werkzeug.security import check_password_hash, generate_password_hash
|
||||||
|
|
||||||
|
from helpers import apology, login_required, lookup, usd
|
||||||
|
|
||||||
|
# Configure application
|
||||||
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
# Ensure templates are auto-reloaded
|
||||||
|
app.config["TEMPLATES_AUTO_RELOAD"] = True
|
||||||
|
|
||||||
|
# Ensure responses aren't cached
|
||||||
|
@app.after_request
|
||||||
|
def after_request(response):
|
||||||
|
response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
|
||||||
|
response.headers["Expires"] = 0
|
||||||
|
response.headers["Pragma"] = "no-cache"
|
||||||
|
return response
|
||||||
|
|
||||||
|
# Custom filter
|
||||||
|
app.jinja_env.filters["usd"] = usd
|
||||||
|
|
||||||
|
# Configure session to use filesystem (instead of signed cookies)
|
||||||
|
app.config["SESSION_FILE_DIR"] = mkdtemp()
|
||||||
|
app.config["SESSION_PERMANENT"] = False
|
||||||
|
app.config["SESSION_TYPE"] = "filesystem"
|
||||||
|
Session(app)
|
||||||
|
|
||||||
|
# Configure CS50 Library to use SQLite database
|
||||||
|
db = SQL("sqlite:///finance.db")
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/")
|
||||||
|
@login_required
|
||||||
|
def index():
|
||||||
|
"""Show portfolio of stocks"""
|
||||||
|
rows = db.execute("SELECT * FROM users WHERE id = :id",
|
||||||
|
id=session["user_id"])
|
||||||
|
cash = int(rows[0]["cash"])
|
||||||
|
stocks = db.execute("SELECT symbol, SUM(shares) as sum_shares FROM transactions WHERE id = :user_id GROUP BY symbol HAVING sum_shares > 0", user_id = session["user_id"])
|
||||||
|
prices = list()
|
||||||
|
values = list()
|
||||||
|
for counter, stock in enumerate(stocks):
|
||||||
|
quote = lookup(stocks[counter]["symbol"])
|
||||||
|
prices.append(quote["price"])
|
||||||
|
value = int(quote["price"] * stocks[counter]["sum_shares"])
|
||||||
|
values.append(value)
|
||||||
|
total_value = sum(values)
|
||||||
|
return render_template("index.html", stocks = stocks, prices = prices, values = values, total_value = total_value, cash = cash)
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/buy", methods=["GET", "POST"])
|
||||||
|
@login_required
|
||||||
|
def buy():
|
||||||
|
"""Buy shares of stock"""
|
||||||
|
if request.method == "POST":
|
||||||
|
|
||||||
|
# Ensure quote and shares was submitted
|
||||||
|
if not request.form.get("symbol"):
|
||||||
|
return apology("must provide stock symbol", 400)
|
||||||
|
if not request.form.get("shares"):
|
||||||
|
return apology("must provide amount of shares", 400)
|
||||||
|
|
||||||
|
# Ensure shares is a positive integer
|
||||||
|
shares = request.form.get("shares")
|
||||||
|
if not shares.isdigit():
|
||||||
|
return apology("must enter a positive integer", 400)
|
||||||
|
|
||||||
|
shares = int(request.form.get("shares"))
|
||||||
|
# Get quote
|
||||||
|
quote = lookup(request.form.get("symbol"))
|
||||||
|
|
||||||
|
if quote == None:
|
||||||
|
return apology("please enter a valid quote", 400)
|
||||||
|
|
||||||
|
# Ensure cost is not too high
|
||||||
|
share_price = quote["price"]
|
||||||
|
cost = share_price * shares
|
||||||
|
rows = db.execute("SELECT * FROM users WHERE id = :id",
|
||||||
|
id=session["user_id"])
|
||||||
|
cash = rows[0]["cash"]
|
||||||
|
|
||||||
|
if cost > cash:
|
||||||
|
return apology("not enough cash")
|
||||||
|
|
||||||
|
symbol = quote["symbol"]
|
||||||
|
# If successful update database cash amount
|
||||||
|
db.execute("UPDATE users SET cash = cash - :cost WHERE id = :id", cost = cost, id = session["user_id"])
|
||||||
|
# Add transaction to history
|
||||||
|
db.execute("Insert INTO transactions (id, symbol, shares, price) VALUES(:id, :symbol, :shares, :cost)",
|
||||||
|
id = session["user_id"], symbol = quote["symbol"], shares = shares, cost = cost)
|
||||||
|
return redirect("/")
|
||||||
|
|
||||||
|
if quote == None:
|
||||||
|
return apology("please enter a valid quote", 200)
|
||||||
|
else:
|
||||||
|
return render_template("buy.html")
|
||||||
|
|
||||||
|
@app.route("/trending", methods=["GET", "POST"])
|
||||||
|
@login_required
|
||||||
|
def trending():
|
||||||
|
stocks = db.execute("SELECT COUNT(id) as count_id, symbol, SUM(shares) as sum_shares FROM transactions GROUP BY symbol ORDER BY count_id DESC")
|
||||||
|
prices = list()
|
||||||
|
for counter, stock in enumerate(stocks):
|
||||||
|
quote = lookup(stocks[counter]["symbol"])
|
||||||
|
prices.append(quote["price"])
|
||||||
|
return render_template("trending.html", stocks = stocks, prices = prices)
|
||||||
|
|
||||||
|
@app.route("/check", methods=["GET"])
|
||||||
|
def check():
|
||||||
|
"""Return true if username available, else false, in JSON format"""
|
||||||
|
username = request.args.get("username")
|
||||||
|
usernames = db.execute("SELECT username FROM users WHERE username = :username", username=username)
|
||||||
|
if username and not usernames:
|
||||||
|
return jsonify(True)
|
||||||
|
else:
|
||||||
|
return jsonify(False)
|
||||||
|
|
||||||
|
@app.route("/history")
|
||||||
|
@login_required
|
||||||
|
def history():
|
||||||
|
"""Show history of transactions"""
|
||||||
|
stocks = db.execute("SELECT symbol, price, date, shares FROM transactions WHERE id=:user_id", user_id=session["user_id"])
|
||||||
|
values = list()
|
||||||
|
boo = list()
|
||||||
|
shares = list()
|
||||||
|
for counter, stock in enumerate(stocks):
|
||||||
|
price = stocks[counter]["price"]
|
||||||
|
shares_count = stocks[counter]["shares"]
|
||||||
|
if shares_count < 0:
|
||||||
|
boo.append("Sold")
|
||||||
|
price = price * (-1)
|
||||||
|
shares_count = shares_count * (-1)
|
||||||
|
shares.append(shares_count)
|
||||||
|
values.append(price)
|
||||||
|
else:
|
||||||
|
boo.append("Bought")
|
||||||
|
values.append(price)
|
||||||
|
shares.append(shares_count)
|
||||||
|
|
||||||
|
return render_template("history.html", stocks = stocks, boo = boo, values = values, shares = shares)
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/login", methods=["GET", "POST"])
|
||||||
|
def login():
|
||||||
|
"""Log user in"""
|
||||||
|
|
||||||
|
# Forget any user_id
|
||||||
|
session.clear()
|
||||||
|
|
||||||
|
# User reached route via POST (as by submitting a form via POST)
|
||||||
|
if request.method == "POST":
|
||||||
|
|
||||||
|
# Ensure username was submitted
|
||||||
|
if not request.form.get("username"):
|
||||||
|
return apology("must provide username", 403)
|
||||||
|
|
||||||
|
# Ensure password was submitted
|
||||||
|
elif not request.form.get("password"):
|
||||||
|
return apology("must provide password", 403)
|
||||||
|
|
||||||
|
# Query database for username
|
||||||
|
rows = db.execute("SELECT * FROM users WHERE username = :username",
|
||||||
|
username=request.form.get("username"))
|
||||||
|
|
||||||
|
# Ensure username exists and password is correct
|
||||||
|
if len(rows) != 1 or not check_password_hash(rows[0]["hash"], request.form.get("password")):
|
||||||
|
return apology("invalid username and/or password", 403)
|
||||||
|
|
||||||
|
# Remember which user has logged in
|
||||||
|
session["user_id"] = rows[0]["id"]
|
||||||
|
|
||||||
|
# Redirect user to home page
|
||||||
|
return redirect("/")
|
||||||
|
|
||||||
|
# User reached route via GET (as by clicking a link or via redirect)
|
||||||
|
else:
|
||||||
|
return render_template("login.html")
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/logout")
|
||||||
|
def logout():
|
||||||
|
"""Log user out"""
|
||||||
|
|
||||||
|
# Forget any user_id
|
||||||
|
session.clear()
|
||||||
|
|
||||||
|
# Redirect user to login form
|
||||||
|
return redirect("/")
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/quote", methods=["GET", "POST"])
|
||||||
|
@login_required
|
||||||
|
def quote():
|
||||||
|
"""Get stock quote."""
|
||||||
|
|
||||||
|
if request.method == "POST":
|
||||||
|
|
||||||
|
# Ensure quote was submitted
|
||||||
|
if not request.form.get("symbol"):
|
||||||
|
return apology("must provide stock symbol", 400)
|
||||||
|
|
||||||
|
quote = lookup(request.form.get("symbol"))
|
||||||
|
|
||||||
|
if quote == None:
|
||||||
|
return apology("please enter a valid quote", 400)
|
||||||
|
|
||||||
|
return render_template("quoted.html", quote = quote)
|
||||||
|
else:
|
||||||
|
return render_template("quote.html")
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/register", methods=["GET", "POST"])
|
||||||
|
def register():
|
||||||
|
"""Register user"""
|
||||||
|
# Forget any user_id
|
||||||
|
session.clear()
|
||||||
|
|
||||||
|
# User reached route via POST (as by submitting a form via POST)
|
||||||
|
if request.method == "POST":
|
||||||
|
|
||||||
|
# Ensure username was submitted
|
||||||
|
if not request.form.get("username"):
|
||||||
|
return apology("must provide username", 400)
|
||||||
|
|
||||||
|
# Ensure password was submitted
|
||||||
|
elif not request.form.get("password"):
|
||||||
|
return apology("must provide password", 400)
|
||||||
|
|
||||||
|
# Ensure passwords match
|
||||||
|
elif not request.form.get("password") == request.form.get("confirmation"):
|
||||||
|
return apology("passwords must match", 400)
|
||||||
|
|
||||||
|
# Create hash for password
|
||||||
|
hash = generate_password_hash(request.form.get("password"))
|
||||||
|
|
||||||
|
# Insert username into database
|
||||||
|
result = db.execute("Insert INTO users (username, hash) VALUES(:username, :hash)", username = request.form.get("username"), hash = hash)
|
||||||
|
|
||||||
|
# Check if username is already taken
|
||||||
|
if not result:
|
||||||
|
return apology("Username has been taken", 400)
|
||||||
|
|
||||||
|
# Remember which user has logged in
|
||||||
|
session["user_id"] = result
|
||||||
|
|
||||||
|
# Redirect user to home page
|
||||||
|
return redirect("/")
|
||||||
|
|
||||||
|
# User reached route via GET (as by clicking a link or via redirect)
|
||||||
|
else:
|
||||||
|
return render_template("register.html")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/sell", methods=["GET", "POST"])
|
||||||
|
@login_required
|
||||||
|
def sell():
|
||||||
|
"""Sell shares of stock"""
|
||||||
|
stocks = db.execute("SELECT symbol, SUM(shares) as sum_shares FROM transactions WHERE id = :user_id GROUP BY symbol HAVING sum_shares > 0", user_id = session["user_id"])
|
||||||
|
if request.method == "POST":
|
||||||
|
# Ensure symbol and shares are submitted
|
||||||
|
symbol = request.form.get("symbol")
|
||||||
|
if not symbol:
|
||||||
|
return apology("must choose a symbol", 400)
|
||||||
|
shares = request.form.get("shares")
|
||||||
|
if not shares:
|
||||||
|
return apology("must enter shares amount", 400)
|
||||||
|
|
||||||
|
|
||||||
|
# Ensure shares is a positive integer
|
||||||
|
shares = int(request.form.get("shares"))
|
||||||
|
if not type(shares) == int:
|
||||||
|
return apology("must enter an integer", 400)
|
||||||
|
if shares < 1 :
|
||||||
|
return apology("must enter a positive integer", 400)
|
||||||
|
|
||||||
|
# Ensure proper amount of shares
|
||||||
|
sum_shares = stocks[0]["sum_shares"]
|
||||||
|
if shares > sum_shares:
|
||||||
|
return apology("invalid shares amount", 400)
|
||||||
|
|
||||||
|
# Get quote
|
||||||
|
quote = lookup(request.form.get("symbol"))
|
||||||
|
|
||||||
|
# Log loss of shares and increase in cash
|
||||||
|
share_price = quote["price"]
|
||||||
|
cost = share_price * shares * (-1)
|
||||||
|
shares = shares * (-1)
|
||||||
|
|
||||||
|
symbol = quote["symbol"]
|
||||||
|
# If successful update database cash amount
|
||||||
|
db.execute("UPDATE users SET cash = cash - :cost WHERE id = :id", cost = cost, id = session["user_id"])
|
||||||
|
# Add transaction to history
|
||||||
|
db.execute("Insert INTO transactions (id, symbol, shares, price) VALUES(:id, :symbol, :shares, :cost)",
|
||||||
|
id = session["user_id"], symbol = quote["symbol"], shares = shares, cost = cost)
|
||||||
|
|
||||||
|
# Redirect user to home page
|
||||||
|
return redirect("/")
|
||||||
|
else:
|
||||||
|
return render_template("sell.html", stocks=stocks)
|
||||||
|
|
||||||
|
|
||||||
|
def errorhandler(e):
|
||||||
|
"""Handle error"""
|
||||||
|
if not isinstance(e, HTTPException):
|
||||||
|
e = InternalServerError()
|
||||||
|
return apology(e.name, e.code)
|
||||||
|
|
||||||
|
|
||||||
|
# Listen for errors
|
||||||
|
for code in default_exceptions:
|
||||||
|
app.errorhandler(code)(errorhandler)
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
import requests
|
||||||
|
import urllib.parse
|
||||||
|
|
||||||
|
from flask import redirect, render_template, request, session
|
||||||
|
from functools import wraps
|
||||||
|
|
||||||
|
|
||||||
|
def apology(message, code=400):
|
||||||
|
"""Render message as an apology to user."""
|
||||||
|
def escape(s):
|
||||||
|
"""
|
||||||
|
Escape special characters.
|
||||||
|
|
||||||
|
https://github.com/jacebrowning/memegen#special-characters
|
||||||
|
"""
|
||||||
|
for old, new in [("-", "--"), (" ", "-"), ("_", "__"), ("?", "~q"),
|
||||||
|
("%", "~p"), ("#", "~h"), ("/", "~s"), ("\"", "''")]:
|
||||||
|
s = s.replace(old, new)
|
||||||
|
return s
|
||||||
|
return render_template("apology.html", top=code, bottom=escape(message)), code
|
||||||
|
|
||||||
|
|
||||||
|
def login_required(f):
|
||||||
|
"""
|
||||||
|
Decorate routes to require login.
|
||||||
|
|
||||||
|
http://flask.pocoo.org/docs/1.0/patterns/viewdecorators/
|
||||||
|
"""
|
||||||
|
@wraps(f)
|
||||||
|
def decorated_function(*args, **kwargs):
|
||||||
|
if session.get("user_id") is None:
|
||||||
|
return redirect("/login")
|
||||||
|
return f(*args, **kwargs)
|
||||||
|
return decorated_function
|
||||||
|
|
||||||
|
|
||||||
|
def lookup(symbol):
|
||||||
|
"""Look up quote for symbol."""
|
||||||
|
|
||||||
|
# Contact API
|
||||||
|
try:
|
||||||
|
response = requests.get(f"https://api.iextrading.com/1.0/stock/{urllib.parse.quote_plus(symbol)}/quote")
|
||||||
|
response.raise_for_status()
|
||||||
|
except requests.RequestException:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Parse response
|
||||||
|
try:
|
||||||
|
quote = response.json()
|
||||||
|
return {
|
||||||
|
"name": quote["companyName"],
|
||||||
|
"price": float(quote["latestPrice"]),
|
||||||
|
"symbol": quote["symbol"]
|
||||||
|
}
|
||||||
|
except (KeyError, TypeError, ValueError):
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def usd(value):
|
||||||
|
"""Format value as USD."""
|
||||||
|
return f"${value:,.2f}"
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
cs50
|
||||||
|
Flask
|
||||||
|
Flask-Session
|
||||||
|
requests
|
||||||
|
After Width: | Height: | Size: 5.4 KiB |
|
|
@ -0,0 +1,47 @@
|
||||||
|
nav .navbar-brand
|
||||||
|
{
|
||||||
|
/* size for brand */
|
||||||
|
font-size: xx-large;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* colors for brand */
|
||||||
|
nav .navbar-brand .blue
|
||||||
|
{
|
||||||
|
color: #537fbe;
|
||||||
|
}
|
||||||
|
nav .navbar-brand .red
|
||||||
|
{
|
||||||
|
color: #ea433b;
|
||||||
|
}
|
||||||
|
nav .navbar-brand .yellow
|
||||||
|
{
|
||||||
|
color: #f5b82e;
|
||||||
|
}
|
||||||
|
nav .navbar-brand .green
|
||||||
|
{
|
||||||
|
color: #2e944b;
|
||||||
|
}
|
||||||
|
|
||||||
|
main .form-control
|
||||||
|
{
|
||||||
|
/* center form controls */
|
||||||
|
display: inline-block;
|
||||||
|
|
||||||
|
/* override Bootstrap's 100% width for form controls */
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
main
|
||||||
|
{
|
||||||
|
/* scroll horizontally as needed */
|
||||||
|
overflow-x: auto;
|
||||||
|
|
||||||
|
/* center contents */
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
main img
|
||||||
|
{
|
||||||
|
/* constrain images on small screens */
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
{% extends "layout.html" %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
Apology
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
<img alt="{{ top }}" class="border" src="http://memegen.link/custom/{{ top | urlencode }}/{{ bottom | urlencode }}.jpg?alt=https://i.imgur.com/CsCgN7Ll.png" title="{{ top }}">
|
||||||
|
{% endblock %}
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
{% extends "layout.html" %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
Buy
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
<form action="/buy" method="post">
|
||||||
|
<div class = "form-group">
|
||||||
|
<input autocomplete="off" autofocus class="form-control" name="symbol" placeholder="Stock Symbol" type="text">
|
||||||
|
</div>
|
||||||
|
<div class = "form-group">
|
||||||
|
<input autocomplete="off" autofocus class="form-control" name="shares" placeholder="Shares" type="text">
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-primary" type="submit">Buy</button>
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
{% extends "layout.html" %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
History
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
<table class="table" action="/history">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col">Bought/Sold</th>
|
||||||
|
<th scope="col">Symbol</th>
|
||||||
|
<th scope="col">Price</th>
|
||||||
|
<th scope="col">Shares</th>
|
||||||
|
<th scope="col">DateTime</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for stock in stocks %}
|
||||||
|
<tr>
|
||||||
|
<td>{{boo[loop.index - 1]}}</td>
|
||||||
|
<td>{{stock.symbol}}</td>
|
||||||
|
<td>{{values[loop.index - 1] | usd }}</td>
|
||||||
|
<td>{{shares[loop.index - 1]}}</td>
|
||||||
|
<td>{{stock.date}}</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{% endblock %}
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
{% extends "layout.html" %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
Index
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
<table class="table" action="/index">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col">Stock</th>
|
||||||
|
<th scope="col">Shares</th>
|
||||||
|
<th scope="col">Price</th>
|
||||||
|
<th scope="col">Value</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for stock in stocks %}
|
||||||
|
<tr>
|
||||||
|
<td>{{stock.symbol}}</td>
|
||||||
|
<td>{{stock.sum_shares}}</td>
|
||||||
|
<td>{{prices[loop.index - 1] | usd }}</td>
|
||||||
|
<td>{{values[loop.index - 1] | usd }}</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
<tfoot>
|
||||||
|
<tr>
|
||||||
|
<td>Current Cash:</td>
|
||||||
|
<td>{{cash | usd }}</td>
|
||||||
|
<td>Total Value:</td>
|
||||||
|
<td>{{total_value | usd }}</td>
|
||||||
|
</tr>
|
||||||
|
</tfoot>
|
||||||
|
</table>
|
||||||
|
{% endblock %}
|
||||||
|
|
@ -0,0 +1,73 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
|
||||||
|
<!-- Required meta tags -->
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
|
|
||||||
|
<!-- documentation at http://getbootstrap.com/docs/4.1/, alternative themes at https://bootswatch.com/ -->
|
||||||
|
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<!-- https://favicon.io/emoji-favicons/money-mouth-face/ -->
|
||||||
|
<link href="/static/favicon.ico" rel="icon">
|
||||||
|
|
||||||
|
<link href="/static/styles.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"></script>
|
||||||
|
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>
|
||||||
|
|
||||||
|
<title>C$50 Finance: {% block title %}{% endblock %}</title>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<nav class="navbar navbar-expand-md navbar-light bg-light border">
|
||||||
|
<a class="navbar-brand" href="/"><span class="blue">C</span><span class="red">$</span><span class="yellow">5</span><span class="green">0</span> <span class="red">Finance</span></a>
|
||||||
|
<button aria-controls="navbar" aria-expanded="false" aria-label="Toggle navigation" class="navbar-toggler" data-target="#navbar" data-toggle="collapse" type="button">
|
||||||
|
<span class="navbar-toggler-icon"></span>
|
||||||
|
</button>
|
||||||
|
<div class="collapse navbar-collapse" id="navbar">
|
||||||
|
{% if session.user_id %}
|
||||||
|
<ul class="navbar-nav mr-auto mt-2">
|
||||||
|
<li class="nav-item"><a class="nav-link" href="/quote">Quote</a></li>
|
||||||
|
<li class="nav-item"><a class="nav-link" href="/buy">Buy</a></li>
|
||||||
|
<li class="nav-item"><a class="nav-link" href="/sell">Sell</a></li>
|
||||||
|
<li class="nav-item"><a class="nav-link" href="/history">History</a></li>
|
||||||
|
<li class="nav-item"><a class="nav-link" href="/trending">Trending</a></li>
|
||||||
|
</ul>
|
||||||
|
<ul class="navbar-nav ml-auto mt-2">
|
||||||
|
<li class="nav-item"><a class="nav-link" href="/logout">Log Out</a></li>
|
||||||
|
</ul>
|
||||||
|
{% else %}
|
||||||
|
<ul class="navbar-nav ml-auto mt-2">
|
||||||
|
<li class="nav-item"><a class="nav-link" href="/register">Register</a></li>
|
||||||
|
<li class="nav-item"><a class="nav-link" href="/login">Log In</a></li>
|
||||||
|
</ul>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
{% if get_flashed_messages() %}
|
||||||
|
<header>
|
||||||
|
<div class="alert alert-primary border text-center" role="alert">
|
||||||
|
{{ get_flashed_messages() | join(" ") }}
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<main class="container p-5">
|
||||||
|
{% block main %}{% endblock %}
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<footer class="small text-center text-muted">
|
||||||
|
Data provided for free by <a href="https://iextrading.com/developer">IEX</a>. View <a href="https://iextrading.com/api-exhibit-a/">IEX’s Terms of Use</a>.
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
{% extends "layout.html" %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
Log In
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
<form action="/login" method="post">
|
||||||
|
<div class="form-group">
|
||||||
|
<input autocomplete="off" autofocus class="form-control" name="username" placeholder="Username" type="text">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<input class="form-control" name="password" placeholder="Password" type="password">
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-primary" type="submit">Log In</button>
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
{% extends "layout.html" %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
Quote
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
<form action="/quote" method="post">
|
||||||
|
<div class = "form-group">
|
||||||
|
<input autocomplete="off" autofocus class="form-control" name="symbol" placeholder="Stock Symbol" type="text">
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-primary" type="submit">Get Quote</button>
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
{% extends "layout.html" %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
Quoted
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
<div>
|
||||||
|
{{ quote["symbol"] }}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p>The Price for {{ quote["name"] }} is {{ quote["price"] | usd }} per share</p>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
{% extends "layout.html" %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
Register
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
<form action="/register" method="post" id="form">
|
||||||
|
<div class="form-group">
|
||||||
|
<input autocomplete="off" autofocus class="form-control" name="username" placeholder="Username" id="username" type="text">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<input class="form-control" name="password" placeholder="Password" type="password">
|
||||||
|
</div>
|
||||||
|
<span id="availability"></span>
|
||||||
|
<div class="form-group">
|
||||||
|
<input class="form-control" name="confirmation" placeholder="confirm" type="password">
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-primary" type="submit" id="btn">Register</button>
|
||||||
|
</form>
|
||||||
|
<script type="text/javascript">
|
||||||
|
var username = document.getElementById("username");
|
||||||
|
$(document).ready(function(){
|
||||||
|
$('#btn').click(function (evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
$.get("/check", {username:username.value}, function(data){
|
||||||
|
if (data == false){
|
||||||
|
alert("Username is Taken")
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$('#form').submit();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
{% extends "layout.html" %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
Sell
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
<form action="/sell" method="post">
|
||||||
|
Stock to Sell:
|
||||||
|
<div class="form-group">
|
||||||
|
<select class="form-control" name="symbol">
|
||||||
|
{% for stock in stocks %}
|
||||||
|
<option value="{{stock.symbol}}">{{stock.symbol}}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
<div class = "form-group">
|
||||||
|
<input autocomplete="off" autofocus class="form-control" name="shares" placeholder="Shares" type="text">
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-primary" type="submit">Sell</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
{% extends "layout.html" %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
Trending
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
<table class="table" action="/index">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col">rank</th>
|
||||||
|
<th scope="col">symbol</th>
|
||||||
|
<th scope="col">price</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for stock in stocks %}
|
||||||
|
<tr>
|
||||||
|
<td>{{loop.index}}</td>
|
||||||
|
<td>{{stock.symbol}}</td>
|
||||||
|
<td>{{prices[loop.index - 1] | usd }}</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
{% endblock %}
|
||||||
|
|
@ -0,0 +1,153 @@
|
||||||
|
#include <cs50.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <math.h>
|
||||||
|
int check_length(long int n);
|
||||||
|
int check_digit(long int num, int length, int n);
|
||||||
|
bool luhn_alg(long int num, int length);
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
// setup variables
|
||||||
|
long int num = 0;
|
||||||
|
int length = 0;
|
||||||
|
string type = "";
|
||||||
|
bool check = false;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
// get the number and setup variable to check if valid
|
||||||
|
num = get_long("number:");
|
||||||
|
length = check_length(num);
|
||||||
|
int digit1 = check_digit(num, length, 1);
|
||||||
|
int digit2 = check_digit(num, length, 2);
|
||||||
|
bool luhn = luhn_alg(num, length);
|
||||||
|
if (luhn == false)
|
||||||
|
{
|
||||||
|
printf("INVALID\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//checking all possible lengths, looking at beginning digits to determine card type if valid
|
||||||
|
if (length == 13)
|
||||||
|
{
|
||||||
|
if (digit1 == 4)
|
||||||
|
{
|
||||||
|
type = "VISA";
|
||||||
|
check = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("INVALID\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (length == 15)
|
||||||
|
{
|
||||||
|
if (digit1 == 3 && (digit2 == 4 || digit2 == 7))
|
||||||
|
{
|
||||||
|
type = "AMEX";
|
||||||
|
check = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("INVALID\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (length == 16)
|
||||||
|
{
|
||||||
|
if (digit1 == 5 && digit2 > 0 && digit2 < 6)
|
||||||
|
{
|
||||||
|
type = "MASTERCARD";
|
||||||
|
check = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
else if (digit1 == 4)
|
||||||
|
{
|
||||||
|
type = "VISA";
|
||||||
|
check = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("INVALID\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("INVALID\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
while (check == false);
|
||||||
|
printf("%s\n", type);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//function to check the length of card number given
|
||||||
|
int check_length(long int num)
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
num = num / 10;
|
||||||
|
count = count + 1;
|
||||||
|
}
|
||||||
|
while (num > 0);
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//function to check the nth digit of the card number given
|
||||||
|
int check_digit(long int num, int length, int n)
|
||||||
|
{
|
||||||
|
|
||||||
|
long int digit = num / pow(10, length - n);
|
||||||
|
digit = digit % 10;
|
||||||
|
digit = (int)digit;
|
||||||
|
return digit;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// function to check Luhn's algorithm
|
||||||
|
bool luhn_alg(long int num, int length)
|
||||||
|
{
|
||||||
|
int sum = 0;
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
// get the digit, multiply by 2, add up digits, add to sum for every other digit starting at 2nd to last
|
||||||
|
int temp = check_digit(num, length, length - (count + 1));
|
||||||
|
temp = temp * 2;
|
||||||
|
int templength = check_length(temp);
|
||||||
|
int tempdigit1 = check_digit(temp, templength, 1);
|
||||||
|
int tempdigit2 = check_digit(temp, templength, 2);
|
||||||
|
sum = sum + tempdigit1;
|
||||||
|
sum = sum + tempdigit2;
|
||||||
|
count = count + 2;
|
||||||
|
}
|
||||||
|
while (count < length);
|
||||||
|
count = 0; //reset count
|
||||||
|
do
|
||||||
|
{
|
||||||
|
int temp = check_digit(num, length, length - count);
|
||||||
|
sum = sum + temp;
|
||||||
|
count = count + 2;
|
||||||
|
}
|
||||||
|
while (count < length);
|
||||||
|
|
||||||
|
if (sum % 10 == 0)
|
||||||
|
{
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
#include <cs50.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int get_int_range(string prompt); // making a prototype for our get int function
|
||||||
|
void print_lots(string character,int n); // prototype for printing repeated characters in a line
|
||||||
|
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
int height = get_int_range("Height between 1 and 8:");
|
||||||
|
|
||||||
|
for (int k=0; k<height; k++)
|
||||||
|
{
|
||||||
|
// print characters in proper order
|
||||||
|
print_lots(" ",height - k - 1);
|
||||||
|
print_lots("#",k+1);
|
||||||
|
printf(" ");
|
||||||
|
print_lots("#",k+1);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_int_range(string prompt) // define function to get an int in a range
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
n = get_int("%s", prompt);
|
||||||
|
}
|
||||||
|
while (n < 1 || n>8);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_lots(string character,int n) // define a function to print the same character a bunch
|
||||||
|
{
|
||||||
|
for(int i=0; i<n;i++)
|
||||||
|
{
|
||||||
|
printf("%s", character);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
#include <cs50.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
int main(int argc, string argv[])
|
||||||
|
{
|
||||||
|
//Validate the key
|
||||||
|
if (argc != 2)
|
||||||
|
{
|
||||||
|
printf("Usage: ./caesar key\n");
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
string key = argv[1];
|
||||||
|
int intkey = atoi(argv[1]);
|
||||||
|
|
||||||
|
if (argc == 2)
|
||||||
|
{
|
||||||
|
// Iterate over length of key, checking for non-digits
|
||||||
|
for (int i = 0, n = strlen(key); i < n; i++)
|
||||||
|
{
|
||||||
|
if (isdigit(key[i]) == false)
|
||||||
|
{
|
||||||
|
printf("Usage: ./caesar key\n");
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Setup cipher
|
||||||
|
string plaintext = get_string("plaintext: ");
|
||||||
|
printf("ciphertext: ");
|
||||||
|
// iterate over input of plaintext, seperating into uppor or lower cases, then implementing cypher
|
||||||
|
for (int i = 0, n = strlen(plaintext); i < n; i++)
|
||||||
|
{
|
||||||
|
char c = plaintext[i];
|
||||||
|
char temp = 'a';
|
||||||
|
if (isalpha(c))
|
||||||
|
{
|
||||||
|
if (isupper(c))
|
||||||
|
{
|
||||||
|
temp = (((plaintext[i] - 'A') + intkey) % 26) + 'A';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
temp = (((plaintext[i] - 'a') + intkey) % 26) + 'a';
|
||||||
|
}
|
||||||
|
printf("%c", temp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("%c", c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
#include <cs50.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
int shift(char c);
|
||||||
|
|
||||||
|
int main(int argc, string argv[])
|
||||||
|
{
|
||||||
|
//Validate the key
|
||||||
|
string key = argv[1];
|
||||||
|
if (argc != 2)
|
||||||
|
{
|
||||||
|
printf("Usage: ./vigenere keyword\n");
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Iterate over length of key, checking for non-digits
|
||||||
|
for (int i = 0, n = strlen(key); i < n; i++)
|
||||||
|
{
|
||||||
|
if (isalpha(key[i]) == false)
|
||||||
|
{
|
||||||
|
printf("Usage: ./vigenere keyword\n");
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Setup cipher
|
||||||
|
int length = strlen(key);
|
||||||
|
int k = 0;
|
||||||
|
string plaintext = get_string("plaintext: ");
|
||||||
|
printf("ciphertext: ");
|
||||||
|
// iterate over input of plaintext, seperating into uppor or lower cases, then implementing cypher
|
||||||
|
for (int i = 0, n = strlen(plaintext); i < n;i++)
|
||||||
|
{
|
||||||
|
char c = plaintext[i];
|
||||||
|
char temp = 'a';
|
||||||
|
int intkey = shift(argv[1][(k % length)]);
|
||||||
|
if (isalpha(c))
|
||||||
|
{
|
||||||
|
if (isupper(c))
|
||||||
|
{
|
||||||
|
temp = (((plaintext[i] - 'A') + intkey) % 26) + 'A';
|
||||||
|
k++;
|
||||||
|
}
|
||||||
|
else if (islower(c))
|
||||||
|
{
|
||||||
|
temp = (((plaintext[i] - 'a') + intkey) % 26) + 'a';
|
||||||
|
k++;
|
||||||
|
}
|
||||||
|
printf("%c", temp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("%c", c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Tells us how much to shift based on individual characters
|
||||||
|
int shift(char c)
|
||||||
|
{
|
||||||
|
if isupper(c)
|
||||||
|
{
|
||||||
|
int temp = c - 65;
|
||||||
|
return(temp);
|
||||||
|
}
|
||||||
|
else if islower(c)
|
||||||
|
{
|
||||||
|
int temp = c - 97;
|
||||||
|
return(temp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,107 @@
|
||||||
|
// Copies a BMP file
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "bmp.h"
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
// ensure proper usage
|
||||||
|
if (argc != 3)
|
||||||
|
{
|
||||||
|
printf("Usage: copy infile outfile\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// remember filenames
|
||||||
|
char *infile = argv[1];
|
||||||
|
char *outfile = argv[2];
|
||||||
|
|
||||||
|
// open input file
|
||||||
|
FILE *inptr = fopen(infile, "r");
|
||||||
|
if (inptr == NULL)
|
||||||
|
{
|
||||||
|
printf("Could not open %s.\n", infile);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// open output file
|
||||||
|
FILE *outptr = fopen(outfile, "w");
|
||||||
|
if (outptr == NULL)
|
||||||
|
{
|
||||||
|
fclose(inptr);
|
||||||
|
printf("Could not create %s.\n", outfile);
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// read infile's BITMAPFILEHEADER
|
||||||
|
BITMAPFILEHEADER bf;
|
||||||
|
fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);
|
||||||
|
|
||||||
|
// read infile's BITMAPINFOHEADER
|
||||||
|
BITMAPINFOHEADER bi;
|
||||||
|
fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);
|
||||||
|
|
||||||
|
// ensure infile is (likely) a 24-bit uncompressed BMP 4.0
|
||||||
|
if (bf.bfType != 0x4d42 || bf.bfOffBits != 54 || bi.biSize != 40 ||
|
||||||
|
bi.biBitCount != 24 || bi.biCompression != 0)
|
||||||
|
{
|
||||||
|
fclose(outptr);
|
||||||
|
fclose(inptr);
|
||||||
|
printf("Unsupported file format.\n");
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// write outfile's BITMAPFILEHEADER
|
||||||
|
fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);
|
||||||
|
|
||||||
|
// write outfile's BITMAPINFOHEADER
|
||||||
|
fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, outptr);
|
||||||
|
|
||||||
|
// determine padding for scanlines
|
||||||
|
int padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
|
||||||
|
|
||||||
|
// iterate over infile's scanlines
|
||||||
|
for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
|
||||||
|
{
|
||||||
|
// iterate over pixels in scanline
|
||||||
|
for (int j = 0; j < bi.biWidth; j++)
|
||||||
|
{
|
||||||
|
// temporary storage
|
||||||
|
RGBTRIPLE triple;
|
||||||
|
|
||||||
|
// read RGB triple from infile
|
||||||
|
fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
|
||||||
|
|
||||||
|
if (triple.rgbtRed > 240)
|
||||||
|
{
|
||||||
|
triple.rgbtRed = 00;
|
||||||
|
triple.rgbtBlue = 00;
|
||||||
|
triple.rgbtGreen = 00;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// write RGB triple to outfile
|
||||||
|
fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// skip over padding, if any
|
||||||
|
fseek(inptr, padding, SEEK_CUR);
|
||||||
|
|
||||||
|
// then add it back (to demonstrate how)
|
||||||
|
for (int k = 0; k < padding; k++)
|
||||||
|
{
|
||||||
|
fputc(0x00, outptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// close infile
|
||||||
|
fclose(inptr);
|
||||||
|
|
||||||
|
// close outfile
|
||||||
|
fclose(outptr);
|
||||||
|
|
||||||
|
// success
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,64 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <cs50.h>
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
// check if valid argument counter
|
||||||
|
if (argc != 2)
|
||||||
|
{
|
||||||
|
printf("Usage: ./recover file.jpg\n");
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// initialize input as variable
|
||||||
|
FILE *inptr = fopen(argv[1], "r");
|
||||||
|
|
||||||
|
// open up the file and check if valid file
|
||||||
|
if ( inptr == NULL )
|
||||||
|
{
|
||||||
|
printf("Could not open file\n");
|
||||||
|
return(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
//global variables
|
||||||
|
unsigned char buffer[512];
|
||||||
|
FILE *img = NULL;
|
||||||
|
int counter = 0;
|
||||||
|
char filename[8];
|
||||||
|
|
||||||
|
//Setup loop
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
int read = fread(&buffer, 512, 1, inptr);
|
||||||
|
// break if at EOF
|
||||||
|
if (read != 1)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// check if at start of file
|
||||||
|
if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
|
||||||
|
{
|
||||||
|
// If not at first run, close last file
|
||||||
|
if (img != NULL)
|
||||||
|
{
|
||||||
|
fclose(img);
|
||||||
|
}
|
||||||
|
// open up new file since we are at start
|
||||||
|
sprintf(filename, "%03i.jpg", counter);
|
||||||
|
img = fopen(filename, "w");
|
||||||
|
counter ++;
|
||||||
|
}
|
||||||
|
// only write to the file if we are not in the first run!!!!
|
||||||
|
if (img != NULL)
|
||||||
|
{
|
||||||
|
fwrite(&buffer, 512, 1, img);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
fclose(img);
|
||||||
|
fclose(inptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
// BMP-related data types based on Microsoft's own
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// aliases for C/C++ primitive data types
|
||||||
|
// https://msdn.microsoft.com/en-us/library/cc230309.aspx
|
||||||
|
typedef uint8_t BYTE;
|
||||||
|
typedef uint32_t DWORD;
|
||||||
|
typedef int32_t LONG;
|
||||||
|
typedef uint16_t WORD;
|
||||||
|
|
||||||
|
// information about the type, size, and layout of a file
|
||||||
|
// https://msdn.microsoft.com/en-us/library/dd183374(v=vs.85).aspx
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
WORD bfType;
|
||||||
|
DWORD bfSize;
|
||||||
|
WORD bfReserved1;
|
||||||
|
WORD bfReserved2;
|
||||||
|
DWORD bfOffBits;
|
||||||
|
} __attribute__((__packed__))
|
||||||
|
BITMAPFILEHEADER;
|
||||||
|
|
||||||
|
// information about the dimensions and color format
|
||||||
|
// https://msdn.microsoft.com/en-us/library/dd183376(v=vs.85).aspx
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
DWORD biSize;
|
||||||
|
LONG biWidth;
|
||||||
|
LONG biHeight;
|
||||||
|
WORD biPlanes;
|
||||||
|
WORD biBitCount;
|
||||||
|
DWORD biCompression;
|
||||||
|
DWORD biSizeImage;
|
||||||
|
LONG biXPelsPerMeter;
|
||||||
|
LONG biYPelsPerMeter;
|
||||||
|
DWORD biClrUsed;
|
||||||
|
DWORD biClrImportant;
|
||||||
|
} __attribute__((__packed__))
|
||||||
|
BITMAPINFOHEADER;
|
||||||
|
|
||||||
|
// relative intensities of red, green, and blue
|
||||||
|
// https://msdn.microsoft.com/en-us/library/dd162939(v=vs.85).aspx
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
BYTE rgbtBlue;
|
||||||
|
BYTE rgbtGreen;
|
||||||
|
BYTE rgbtRed;
|
||||||
|
} __attribute__((__packed__))
|
||||||
|
RGBTRIPLE;
|
||||||
|
|
@ -0,0 +1,99 @@
|
||||||
|
// Copies a BMP file
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "bmp.h"
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
// ensure proper usage
|
||||||
|
if (argc != 3)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Usage: copy infile outfile\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// remember filenames
|
||||||
|
char *infile = argv[1];
|
||||||
|
char *outfile = argv[2];
|
||||||
|
|
||||||
|
// open input file
|
||||||
|
FILE *inptr = fopen(infile, "r");
|
||||||
|
if (inptr == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Could not open %s.\n", infile);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// open output file
|
||||||
|
FILE *outptr = fopen(outfile, "w");
|
||||||
|
if (outptr == NULL)
|
||||||
|
{
|
||||||
|
fclose(inptr);
|
||||||
|
fprintf(stderr, "Could not create %s.\n", outfile);
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// read infile's BITMAPFILEHEADER
|
||||||
|
BITMAPFILEHEADER bf;
|
||||||
|
fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);
|
||||||
|
|
||||||
|
// read infile's BITMAPINFOHEADER
|
||||||
|
BITMAPINFOHEADER bi;
|
||||||
|
fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);
|
||||||
|
|
||||||
|
// ensure infile is (likely) a 24-bit uncompressed BMP 4.0
|
||||||
|
if (bf.bfType != 0x4d42 || bf.bfOffBits != 54 || bi.biSize != 40 ||
|
||||||
|
bi.biBitCount != 24 || bi.biCompression != 0)
|
||||||
|
{
|
||||||
|
fclose(outptr);
|
||||||
|
fclose(inptr);
|
||||||
|
fprintf(stderr, "Unsupported file format.\n");
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// write outfile's BITMAPFILEHEADER
|
||||||
|
fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);
|
||||||
|
|
||||||
|
// write outfile's BITMAPINFOHEADER
|
||||||
|
fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, outptr);
|
||||||
|
|
||||||
|
// determine padding for scanlines
|
||||||
|
int padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
|
||||||
|
|
||||||
|
// iterate over infile's scanlines
|
||||||
|
for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
|
||||||
|
{
|
||||||
|
// iterate over pixels in scanline
|
||||||
|
for (int j = 0; j < bi.biWidth; j++)
|
||||||
|
{
|
||||||
|
// temporary storage
|
||||||
|
RGBTRIPLE triple;
|
||||||
|
|
||||||
|
// read RGB triple from infile
|
||||||
|
fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
|
||||||
|
|
||||||
|
// write RGB triple to outfile
|
||||||
|
fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// skip over padding, if any
|
||||||
|
fseek(inptr, padding, SEEK_CUR);
|
||||||
|
|
||||||
|
// then add it back (to demonstrate how)
|
||||||
|
for (int k = 0; k < padding; k++)
|
||||||
|
{
|
||||||
|
fputc(0x00, outptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// close infile
|
||||||
|
fclose(inptr);
|
||||||
|
|
||||||
|
// close outfile
|
||||||
|
fclose(outptr);
|
||||||
|
|
||||||
|
// success
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 486 B |
|
After Width: | Height: | Size: 174 B |
|
|
@ -0,0 +1,135 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include "bmp.h"
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
// ensure proper usage
|
||||||
|
if (argc != 4)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Usage: ./resize n infile outfile\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// remember resize factor n
|
||||||
|
int n = atoi(argv[1]);
|
||||||
|
|
||||||
|
// remember filenames
|
||||||
|
char *infile = argv[2];
|
||||||
|
char *outfile = argv[3];
|
||||||
|
|
||||||
|
// open input file
|
||||||
|
FILE *inptr = fopen(infile, "r");
|
||||||
|
if (inptr == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Could not open %s.\n", infile);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// open output file
|
||||||
|
FILE *outptr = fopen(outfile, "w");
|
||||||
|
if (outptr == NULL)
|
||||||
|
{
|
||||||
|
fclose(inptr);
|
||||||
|
fprintf(stderr, "Could not create %s.\n", outfile);
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// read infile's BITMAPFILEHEADER
|
||||||
|
BITMAPFILEHEADER bf;
|
||||||
|
fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);
|
||||||
|
|
||||||
|
// read infile's BITMAPINFOHEADER
|
||||||
|
BITMAPINFOHEADER bi;
|
||||||
|
fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);
|
||||||
|
|
||||||
|
// ensure infile is (likely) a 24-bit uncompressed BMP 4.0
|
||||||
|
if (bf.bfType != 0x4d42 || bf.bfOffBits != 54 || bi.biSize != 40 ||
|
||||||
|
bi.biBitCount != 24 || bi.biCompression != 0)
|
||||||
|
{
|
||||||
|
fclose(outptr);
|
||||||
|
fclose(inptr);
|
||||||
|
fprintf(stderr, "Unsupported file format.\n");
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// store all old header info which we will change
|
||||||
|
int oldWidth = bi.biWidth;
|
||||||
|
int oldPadding = (4 - (oldWidth * sizeof(RGBTRIPLE)) % 4) % 4;
|
||||||
|
int oldHeight = bi.biHeight;
|
||||||
|
int oldSizeImage = bi.biSizeImage;
|
||||||
|
int oldSize = bf.bfSize;
|
||||||
|
|
||||||
|
// calculate and store new header info
|
||||||
|
int newWidth = bi.biWidth * n;
|
||||||
|
int newPadding = (4 - (newWidth * sizeof(RGBTRIPLE)) % 4) % 4;
|
||||||
|
int newHeight = bi.biHeight * n;
|
||||||
|
int newSizeImage = ((((newWidth * bi.biBitCount) + 31) & ~31) / 8) * abs(newHeight);
|
||||||
|
int newSize = 54 + newWidth * abs(newHeight) * 3 + abs(newHeight) * newPadding;
|
||||||
|
|
||||||
|
// update header info
|
||||||
|
bi.biWidth = newWidth;
|
||||||
|
bi.biHeight = newHeight;
|
||||||
|
bi.biSizeImage = newSizeImage;
|
||||||
|
bf.bfSize = newSize;
|
||||||
|
|
||||||
|
|
||||||
|
// write outfile's BITMAPFILEHEADER
|
||||||
|
fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);
|
||||||
|
|
||||||
|
// write outfile's BITMAPINFOHEADER
|
||||||
|
fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, outptr);
|
||||||
|
|
||||||
|
|
||||||
|
// Go through reading each scanline
|
||||||
|
for (int i = 0; i < abs(oldHeight); i++)
|
||||||
|
{
|
||||||
|
// process of reading and writing the line n times
|
||||||
|
for (int j = 0; j < n; j++)
|
||||||
|
{
|
||||||
|
// go through each pixel to copy and write n times
|
||||||
|
for (int k = 0; k < oldWidth; k++)
|
||||||
|
{
|
||||||
|
// temporary triple
|
||||||
|
RGBTRIPLE triple;
|
||||||
|
|
||||||
|
fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
|
||||||
|
|
||||||
|
// Write the triple N times
|
||||||
|
for (int l = 0; l < n; l++)
|
||||||
|
{
|
||||||
|
fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add newPadding
|
||||||
|
for (int k = 0; k < newPadding; k++)
|
||||||
|
{
|
||||||
|
fputc(0x00, outptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check whether we are on last one, and if not reset the file pointer
|
||||||
|
if (j < n - 1)
|
||||||
|
{
|
||||||
|
fseek(inptr, -oldWidth * sizeof(RGBTRIPLE), SEEK_CUR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// skip reading the old padding once we are done reading/writing and ready to
|
||||||
|
// move to the next line
|
||||||
|
fseek(inptr, oldPadding, SEEK_CUR);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// close infile
|
||||||
|
fclose(inptr);
|
||||||
|
|
||||||
|
// close outfile
|
||||||
|
fclose(outptr);
|
||||||
|
|
||||||
|
// success
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 90 B |
|
After Width: | Height: | Size: 246 B |
|
|
@ -0,0 +1,4 @@
|
||||||
|
speller:
|
||||||
|
clang -fsanitize=signed-integer-overflow -fsanitize=undefined -ggdb3 -O0 -Qunused-arguments -std=c11 -Wall -Werror -Wextra -Wno-sign-compare -Wno-unused-parameter -Wno-unused-variable -Wshadow -c -o speller.o speller.c
|
||||||
|
clang -fsanitize=signed-integer-overflow -fsanitize=undefined -ggdb3 -O0 -Qunused-arguments -std=c11 -Wall -Werror -Wextra -Wno-sign-compare -Wno-unused-parameter -Wno-unused-variable -Wshadow -c -o dictionary.o dictionary.c
|
||||||
|
clang -fsanitize=signed-integer-overflow -fsanitize=undefined -ggdb3 -O0 -Qunused-arguments -std=c11 -Wall -Werror -Wextra -Wno-sign-compare -Wno-unused-parameter -Wno-unused-variable -Wshadow -o speller speller.o dictionary.o
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
cat
|
||||||
|
caterpillar
|
||||||
|
|
@ -0,0 +1,193 @@
|
||||||
|
// Implements a dictionary's functionality
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h> // for isupper/islower
|
||||||
|
|
||||||
|
#include "dictionary.h"
|
||||||
|
|
||||||
|
// global variable to hold word count
|
||||||
|
int words = 0;
|
||||||
|
// Represents number of children for each node in a trie
|
||||||
|
#define N 27
|
||||||
|
|
||||||
|
// Represents a node in a trie
|
||||||
|
typedef struct node
|
||||||
|
{
|
||||||
|
bool is_word;
|
||||||
|
struct node *children[N];
|
||||||
|
}
|
||||||
|
node;
|
||||||
|
|
||||||
|
// Represents a trie
|
||||||
|
node *root;
|
||||||
|
|
||||||
|
// Loads dictionary into memory, returning true if successful else false
|
||||||
|
bool load(const char *dictionary)
|
||||||
|
{
|
||||||
|
// Initialize trie
|
||||||
|
root = malloc(sizeof(node));
|
||||||
|
if (root == NULL)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
root->is_word = false;
|
||||||
|
for (int i = 0; i < N; i++)
|
||||||
|
{
|
||||||
|
root->children[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open dictionary
|
||||||
|
FILE *file = fopen(dictionary, "r");
|
||||||
|
if (file == NULL)
|
||||||
|
{
|
||||||
|
unload();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Buffer for a word
|
||||||
|
char word[LENGTH + 1];
|
||||||
|
|
||||||
|
// Insert words into trie
|
||||||
|
while (fscanf(file, "%s", word) != EOF)
|
||||||
|
{
|
||||||
|
// write word into buffer
|
||||||
|
fwrite(word, LENGTH, 1, file);
|
||||||
|
|
||||||
|
// initialize a pointer to traverse the trie and have it point to root
|
||||||
|
node *trav = root;
|
||||||
|
|
||||||
|
// iterate through each letter in the string
|
||||||
|
for (int i = 0, len = strlen(word); i < len; i++)
|
||||||
|
{
|
||||||
|
// convert letter to number 1-27
|
||||||
|
int childnum = word[i];
|
||||||
|
if (childnum == 39)
|
||||||
|
{
|
||||||
|
childnum = 26;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
childnum = word[i] - 97;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if the c value points to null
|
||||||
|
if (trav->children[childnum] == NULL)
|
||||||
|
{
|
||||||
|
// make a new node and initialize values
|
||||||
|
node *fresh;
|
||||||
|
fresh = malloc(sizeof(node));
|
||||||
|
if (fresh == NULL)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
fresh->is_word = false;
|
||||||
|
for (int k = 0; k < N; k++)
|
||||||
|
{
|
||||||
|
fresh->children[k] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// have last node point to this
|
||||||
|
trav->children[childnum] = fresh;
|
||||||
|
|
||||||
|
// point trav to this new node
|
||||||
|
trav = fresh;
|
||||||
|
}
|
||||||
|
|
||||||
|
// for if there exists a node already
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// have trav point to the non null node
|
||||||
|
trav = trav->children[childnum];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// mark as end of a letter and increase word count
|
||||||
|
trav->is_word = true;
|
||||||
|
words ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close dictionary
|
||||||
|
fclose(file);
|
||||||
|
|
||||||
|
// Indicate success
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns number of words in dictionary if loaded else 0 if not yet loaded
|
||||||
|
unsigned int size(void)
|
||||||
|
{
|
||||||
|
return words;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns true if word is in dictionary else false
|
||||||
|
bool check(const char *word)
|
||||||
|
{
|
||||||
|
// create pointer trav starting at root to traverse the trie (root is itself a pointer so just set equal)
|
||||||
|
node *trav = root;
|
||||||
|
|
||||||
|
// iterate through each letter in the word
|
||||||
|
for (int i=0, n = strlen(word); i < n; i++)
|
||||||
|
{
|
||||||
|
// convert letter to index number
|
||||||
|
int childnum;
|
||||||
|
if (isupper(word[i]))
|
||||||
|
{
|
||||||
|
childnum = word[i] - 65;
|
||||||
|
}
|
||||||
|
else if (islower(word[i]))
|
||||||
|
{
|
||||||
|
childnum = word[i] - 97;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
childnum = 26;
|
||||||
|
}
|
||||||
|
|
||||||
|
// point trav at the corrosponding node
|
||||||
|
trav = trav->children[childnum];
|
||||||
|
|
||||||
|
// Deal with the case where we ran out of nodes to follow
|
||||||
|
if (!trav)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// when we have done all the letters, see if we are at a word
|
||||||
|
if (trav->is_word)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// recursive function which iterates through each letter in a node, if not null letter then do it again on corrosponding node, and at
|
||||||
|
// end of iteration frees the node
|
||||||
|
|
||||||
|
void clear(node *ptr)
|
||||||
|
{
|
||||||
|
for (int i = 0; i<27; i++)
|
||||||
|
{
|
||||||
|
if (ptr->children[i] != NULL)
|
||||||
|
{
|
||||||
|
clear(ptr->children[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unloads dictionary from memory, returning true if successful else false
|
||||||
|
bool unload(void)
|
||||||
|
{
|
||||||
|
clear(root);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
// Declares a dictionary's functionality
|
||||||
|
|
||||||
|
#ifndef DICTIONARY_H
|
||||||
|
#define DICTIONARY_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
// Maximum length for a word
|
||||||
|
// (e.g., pneumonoultramicroscopicsilicovolcanoconiosis)
|
||||||
|
#define LENGTH 45
|
||||||
|
|
||||||
|
// Prototypes
|
||||||
|
bool load(const char *dictionary);
|
||||||
|
unsigned int size(void);
|
||||||
|
bool check(const char *word);
|
||||||
|
bool unload();
|
||||||
|
|
||||||
|
#endif // DICTIONARY_H
|
||||||
|
|
@ -0,0 +1,302 @@
|
||||||
|
|
||||||
|
MISSPELLED WORDS
|
||||||
|
|
||||||
|
Gutenberg's
|
||||||
|
Alice's
|
||||||
|
eBook
|
||||||
|
eBook
|
||||||
|
org
|
||||||
|
Alice's
|
||||||
|
EBook
|
||||||
|
EBOOK
|
||||||
|
ALICE'S
|
||||||
|
ALICE'S
|
||||||
|
MARMALADE'
|
||||||
|
Antipathies
|
||||||
|
Dinah'll
|
||||||
|
Alice's
|
||||||
|
ME'
|
||||||
|
not'
|
||||||
|
ME'
|
||||||
|
ALICE'S
|
||||||
|
ESQ
|
||||||
|
HEARTHRUG
|
||||||
|
ALICE'S
|
||||||
|
skurried
|
||||||
|
O
|
||||||
|
O
|
||||||
|
O
|
||||||
|
Ou
|
||||||
|
chatte
|
||||||
|
better'
|
||||||
|
Morcar
|
||||||
|
Morcar
|
||||||
|
Stigand
|
||||||
|
Atheling
|
||||||
|
William's
|
||||||
|
Normans
|
||||||
|
thimble'
|
||||||
|
C
|
||||||
|
D
|
||||||
|
Mouse's
|
||||||
|
Dinah's
|
||||||
|
naturedly
|
||||||
|
W
|
||||||
|
RABBIT'
|
||||||
|
Dinah'll
|
||||||
|
pleasanter
|
||||||
|
Alice's
|
||||||
|
won't'
|
||||||
|
yer
|
||||||
|
yer
|
||||||
|
arrum
|
||||||
|
yer
|
||||||
|
yer
|
||||||
|
Bill's
|
||||||
|
Bill's
|
||||||
|
Bill's
|
||||||
|
Bill's
|
||||||
|
barrowful
|
||||||
|
barrowful
|
||||||
|
V
|
||||||
|
sir'
|
||||||
|
yawned
|
||||||
|
Footman's
|
||||||
|
nose'
|
||||||
|
Hatter's
|
||||||
|
Alice's
|
||||||
|
Lacie
|
||||||
|
Sh
|
||||||
|
sh
|
||||||
|
were'
|
||||||
|
M
|
||||||
|
M
|
||||||
|
M
|
||||||
|
everything's
|
||||||
|
beheaded
|
||||||
|
King's
|
||||||
|
processions
|
||||||
|
rosetree
|
||||||
|
beheaded
|
||||||
|
croqueted
|
||||||
|
croqueting
|
||||||
|
executioner's
|
||||||
|
King's
|
||||||
|
beheaded
|
||||||
|
Alice's
|
||||||
|
Everything's
|
||||||
|
Alice's
|
||||||
|
Alice's
|
||||||
|
game's
|
||||||
|
Tis
|
||||||
|
tis
|
||||||
|
tis
|
||||||
|
Alice's
|
||||||
|
m
|
||||||
|
Alice's
|
||||||
|
ordered'
|
||||||
|
Hjckrrh
|
||||||
|
mayn't
|
||||||
|
uglifying
|
||||||
|
Seaography
|
||||||
|
X
|
||||||
|
never'
|
||||||
|
dinn
|
||||||
|
Dinn
|
||||||
|
yawned
|
||||||
|
TIS
|
||||||
|
Tis
|
||||||
|
Hm
|
||||||
|
ootiful
|
||||||
|
oop
|
||||||
|
ootiful
|
||||||
|
oop
|
||||||
|
oop
|
||||||
|
e
|
||||||
|
e
|
||||||
|
ootiful
|
||||||
|
oop
|
||||||
|
ootiful
|
||||||
|
oop
|
||||||
|
oop
|
||||||
|
e
|
||||||
|
e
|
||||||
|
beauti
|
||||||
|
FUL
|
||||||
|
oop
|
||||||
|
e
|
||||||
|
e
|
||||||
|
men'
|
||||||
|
slates'll
|
||||||
|
T
|
||||||
|
Alice's
|
||||||
|
jurymen
|
||||||
|
jurymen
|
||||||
|
jurymen
|
||||||
|
jurymen
|
||||||
|
teacups
|
||||||
|
teacups
|
||||||
|
Gutenberg's
|
||||||
|
Alice's
|
||||||
|
EBOOK
|
||||||
|
ALICE'S
|
||||||
|
txt
|
||||||
|
http
|
||||||
|
org
|
||||||
|
tm
|
||||||
|
tm
|
||||||
|
eBooks
|
||||||
|
eBook
|
||||||
|
eBook
|
||||||
|
eBooks
|
||||||
|
tm
|
||||||
|
tm
|
||||||
|
http
|
||||||
|
org
|
||||||
|
tm
|
||||||
|
tm
|
||||||
|
tm
|
||||||
|
tm
|
||||||
|
E
|
||||||
|
B
|
||||||
|
tm
|
||||||
|
C
|
||||||
|
tm
|
||||||
|
tm
|
||||||
|
E
|
||||||
|
C
|
||||||
|
PGLAF
|
||||||
|
tm
|
||||||
|
tm
|
||||||
|
tm
|
||||||
|
tm
|
||||||
|
tm
|
||||||
|
D
|
||||||
|
tm
|
||||||
|
E
|
||||||
|
E
|
||||||
|
tm
|
||||||
|
tm
|
||||||
|
eBook
|
||||||
|
eBook
|
||||||
|
org
|
||||||
|
E
|
||||||
|
tm
|
||||||
|
E
|
||||||
|
E
|
||||||
|
tm
|
||||||
|
E
|
||||||
|
E
|
||||||
|
E
|
||||||
|
tm
|
||||||
|
E
|
||||||
|
E
|
||||||
|
tm
|
||||||
|
E
|
||||||
|
tm
|
||||||
|
tm
|
||||||
|
E
|
||||||
|
E
|
||||||
|
tm
|
||||||
|
E
|
||||||
|
nonproprietary
|
||||||
|
tm
|
||||||
|
tm
|
||||||
|
org
|
||||||
|
tm
|
||||||
|
E
|
||||||
|
E
|
||||||
|
tm
|
||||||
|
E
|
||||||
|
E
|
||||||
|
E
|
||||||
|
tm
|
||||||
|
tm
|
||||||
|
tm
|
||||||
|
e
|
||||||
|
s
|
||||||
|
tm
|
||||||
|
tm
|
||||||
|
F
|
||||||
|
tm
|
||||||
|
E
|
||||||
|
tm
|
||||||
|
tm
|
||||||
|
F
|
||||||
|
F
|
||||||
|
tm
|
||||||
|
tm
|
||||||
|
F
|
||||||
|
F
|
||||||
|
tm
|
||||||
|
tm
|
||||||
|
F
|
||||||
|
F
|
||||||
|
F
|
||||||
|
IS'
|
||||||
|
MERCHANTIBILITY
|
||||||
|
F
|
||||||
|
unenforceability
|
||||||
|
F
|
||||||
|
tm
|
||||||
|
tm
|
||||||
|
tm
|
||||||
|
b
|
||||||
|
tm
|
||||||
|
c
|
||||||
|
tm
|
||||||
|
tm
|
||||||
|
tm's
|
||||||
|
tm
|
||||||
|
tm
|
||||||
|
http
|
||||||
|
pglaf
|
||||||
|
org
|
||||||
|
c
|
||||||
|
c
|
||||||
|
http
|
||||||
|
pglaf
|
||||||
|
org
|
||||||
|
U
|
||||||
|
S
|
||||||
|
Melan
|
||||||
|
S
|
||||||
|
pglaf
|
||||||
|
org
|
||||||
|
http
|
||||||
|
pglaf
|
||||||
|
org
|
||||||
|
B
|
||||||
|
Newby
|
||||||
|
gbnewby
|
||||||
|
pglaf
|
||||||
|
org
|
||||||
|
tm
|
||||||
|
http
|
||||||
|
pglaf
|
||||||
|
org
|
||||||
|
U
|
||||||
|
S
|
||||||
|
http
|
||||||
|
pglaf
|
||||||
|
org
|
||||||
|
tm
|
||||||
|
S
|
||||||
|
tm
|
||||||
|
tm
|
||||||
|
eBooks
|
||||||
|
tm
|
||||||
|
eBooks
|
||||||
|
U
|
||||||
|
S
|
||||||
|
eBooks
|
||||||
|
PG
|
||||||
|
http
|
||||||
|
org
|
||||||
|
tm
|
||||||
|
eBooks
|
||||||
|
eBooks
|
||||||
|
|
||||||
|
WORDS MISSPELLED: 295
|
||||||
|
WORDS IN DICTIONARY: 143091
|
||||||
|
WORDS IN TEXT: 29758
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
|
||||||
|
MISSPELLED WORDS
|
||||||
|
|
||||||
|
|
||||||
|
WORDS MISSPELLED: 0
|
||||||
|
WORDS IN DICTIONARY: 143091
|
||||||
|
WORDS IN TEXT: 6
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
|
||||||
|
MISSPELLED WORDS
|
||||||
|
|
||||||
|
USConstitution
|
||||||
|
http
|
||||||
|
usconstitution
|
||||||
|
const
|
||||||
|
html
|
||||||
|
tempore
|
||||||
|
Impeachments
|
||||||
|
Nays
|
||||||
|
Nays
|
||||||
|
repassed
|
||||||
|
Piracies
|
||||||
|
Felonies
|
||||||
|
attainted
|
||||||
|
Langdon
|
||||||
|
Gilman
|
||||||
|
Brearley
|
||||||
|
Mifflin
|
||||||
|
Clymer
|
||||||
|
Fitzsimons
|
||||||
|
Jared
|
||||||
|
Gouvernour
|
||||||
|
McHenry
|
||||||
|
Jenifer
|
||||||
|
Blount
|
||||||
|
Spaight
|
||||||
|
Cotesworth
|
||||||
|
tempore
|
||||||
|
tempore
|
||||||
|
tempore
|
||||||
|
tempore
|
||||||
|
|
||||||
|
WORDS MISSPELLED: 30
|
||||||
|
WORDS IN DICTIONARY: 143091
|
||||||
|
WORDS IN TEXT: 7573
|
||||||
|
|
@ -0,0 +1,942 @@
|
||||||
|
|
||||||
|
MISSPELLED WORDS
|
||||||
|
|
||||||
|
Etext
|
||||||
|
txt
|
||||||
|
Etext
|
||||||
|
etexts
|
||||||
|
txt
|
||||||
|
txt
|
||||||
|
etext
|
||||||
|
hr
|
||||||
|
Etext
|
||||||
|
x
|
||||||
|
IBC
|
||||||
|
IBC
|
||||||
|
IBC
|
||||||
|
SASLE's
|
||||||
|
RiceMail
|
||||||
|
ATTMAIL
|
||||||
|
MCImail
|
||||||
|
vmd
|
||||||
|
cso
|
||||||
|
uiuc
|
||||||
|
edu
|
||||||
|
uiucvmd
|
||||||
|
uiucvmd
|
||||||
|
vmd
|
||||||
|
cso
|
||||||
|
uiuc
|
||||||
|
edu
|
||||||
|
Attmail
|
||||||
|
vmd
|
||||||
|
cso
|
||||||
|
uiuc
|
||||||
|
edu
|
||||||
|
MCImail
|
||||||
|
MCI
|
||||||
|
MBX
|
||||||
|
vmd
|
||||||
|
cso
|
||||||
|
uiuc
|
||||||
|
edu
|
||||||
|
mrcnext
|
||||||
|
cso
|
||||||
|
uiuc
|
||||||
|
edu
|
||||||
|
cd
|
||||||
|
etext
|
||||||
|
cd
|
||||||
|
cd
|
||||||
|
etext
|
||||||
|
cd
|
||||||
|
etext
|
||||||
|
dir
|
||||||
|
mget
|
||||||
|
AAINDEX
|
||||||
|
MGET
|
||||||
|
ETEXTS
|
||||||
|
etext
|
||||||
|
etext
|
||||||
|
ETEXT
|
||||||
|
tm
|
||||||
|
etext
|
||||||
|
etext
|
||||||
|
etext
|
||||||
|
hysical
|
||||||
|
TM
|
||||||
|
ETEXTS
|
||||||
|
tm
|
||||||
|
etext
|
||||||
|
tm
|
||||||
|
etexts
|
||||||
|
S
|
||||||
|
etext
|
||||||
|
etexts
|
||||||
|
etexts
|
||||||
|
etext
|
||||||
|
etext
|
||||||
|
etext
|
||||||
|
tm
|
||||||
|
etext
|
||||||
|
dis
|
||||||
|
NEGLI
|
||||||
|
GENCE
|
||||||
|
etext
|
||||||
|
etext
|
||||||
|
inaccu
|
||||||
|
ETEXT
|
||||||
|
ETEXT
|
||||||
|
ETEXT
|
||||||
|
etext
|
||||||
|
pense
|
||||||
|
etext
|
||||||
|
ation
|
||||||
|
etext
|
||||||
|
distribu
|
||||||
|
tion
|
||||||
|
etext
|
||||||
|
tm
|
||||||
|
etext
|
||||||
|
ically
|
||||||
|
quires
|
||||||
|
etext
|
||||||
|
etext
|
||||||
|
etext
|
||||||
|
etext
|
||||||
|
etext
|
||||||
|
etext
|
||||||
|
etext
|
||||||
|
etext
|
||||||
|
OCR
|
||||||
|
etexts
|
||||||
|
B
|
||||||
|
ETEXTS
|
||||||
|
Ver
|
||||||
|
unperplexed
|
||||||
|
confederacies
|
||||||
|
proselytes
|
||||||
|
Heresies
|
||||||
|
invectives
|
||||||
|
confederacies
|
||||||
|
votaries
|
||||||
|
PUBLIUS
|
||||||
|
confederacies
|
||||||
|
uncontradicted
|
||||||
|
confederacies
|
||||||
|
sovereignties
|
||||||
|
widespreading
|
||||||
|
sovereignties
|
||||||
|
wellbalanced
|
||||||
|
pursuaded
|
||||||
|
pursuade
|
||||||
|
confederacies
|
||||||
|
confederacies
|
||||||
|
PUBLIUS
|
||||||
|
wellinformed
|
||||||
|
confederacies
|
||||||
|
confederacies
|
||||||
|
violences
|
||||||
|
borderers
|
||||||
|
PUBLIUS
|
||||||
|
confederacies
|
||||||
|
uneasinesses
|
||||||
|
confederacies
|
||||||
|
embarrassments
|
||||||
|
confederacies
|
||||||
|
confederacies
|
||||||
|
PUBLIUS
|
||||||
|
animosities
|
||||||
|
affection''
|
||||||
|
confederacies
|
||||||
|
confederacies
|
||||||
|
confederacies
|
||||||
|
confederacies
|
||||||
|
confederacies
|
||||||
|
borderers
|
||||||
|
confederacies
|
||||||
|
confederacies
|
||||||
|
confederacies
|
||||||
|
sovereignties
|
||||||
|
PUBLIUS
|
||||||
|
confederacies
|
||||||
|
sovereignties
|
||||||
|
rivalships
|
||||||
|
SAMNIANS
|
||||||
|
MEGARENSIANS
|
||||||
|
V
|
||||||
|
V
|
||||||
|
descanted
|
||||||
|
rivalships
|
||||||
|
wellregulated
|
||||||
|
antipathies
|
||||||
|
PUBLIUS
|
||||||
|
Plutarch's
|
||||||
|
P
|
||||||
|
Cambray
|
||||||
|
Principes
|
||||||
|
des
|
||||||
|
Negociations''
|
||||||
|
l'Abbe
|
||||||
|
Mably
|
||||||
|
ungranted
|
||||||
|
cessions
|
||||||
|
preponderated
|
||||||
|
unpropitious
|
||||||
|
SOVEREIGNTIES
|
||||||
|
confederacies
|
||||||
|
procrastinations
|
||||||
|
resentments
|
||||||
|
incumbrances
|
||||||
|
delinquencies
|
||||||
|
Delinquencies
|
||||||
|
confederacies
|
||||||
|
PUBLIUS
|
||||||
|
retaken
|
||||||
|
confederacies
|
||||||
|
expedients
|
||||||
|
confederacies
|
||||||
|
confederacies
|
||||||
|
oppressions
|
||||||
|
encroachments
|
||||||
|
menacings
|
||||||
|
usurpations
|
||||||
|
T
|
||||||
|
disproportioned
|
||||||
|
confederacies
|
||||||
|
distempered
|
||||||
|
PUBLIUS
|
||||||
|
sophisms
|
||||||
|
corruptions
|
||||||
|
PUBLIUS
|
||||||
|
Lawa
|
||||||
|
wellconstructed
|
||||||
|
mischiefs
|
||||||
|
animosities
|
||||||
|
mischiefs
|
||||||
|
suffrages
|
||||||
|
suffrages
|
||||||
|
PUBLIUS
|
||||||
|
rivalships
|
||||||
|
intermeddlings
|
||||||
|
concentred
|
||||||
|
confederated
|
||||||
|
fluctations
|
||||||
|
unsalable
|
||||||
|
PUBLIUS
|
||||||
|
philosophiques
|
||||||
|
Americains
|
||||||
|
rivalship
|
||||||
|
inperceptible
|
||||||
|
confederacies
|
||||||
|
confederacies
|
||||||
|
embarrassments
|
||||||
|
PUBLIUS
|
||||||
|
confederacies
|
||||||
|
sovereignties
|
||||||
|
confederacies
|
||||||
|
confederacies
|
||||||
|
confederacies
|
||||||
|
confederacies
|
||||||
|
PUBLIUS
|
||||||
|
concentred
|
||||||
|
fellowcitizens
|
||||||
|
PUBLIUS
|
||||||
|
encroachments
|
||||||
|
imperio
|
||||||
|
contradistinguished
|
||||||
|
mischiefs
|
||||||
|
rivalships
|
||||||
|
superintending
|
||||||
|
improprieties
|
||||||
|
sovereignties
|
||||||
|
orbs
|
||||||
|
intrusted
|
||||||
|
delinquencies
|
||||||
|
PUBLIUS
|
||||||
|
confederacies
|
||||||
|
suffrages
|
||||||
|
delinquencies
|
||||||
|
aggressing
|
||||||
|
delinquencies
|
||||||
|
instigations
|
||||||
|
confederacies
|
||||||
|
intrusted
|
||||||
|
illhumors
|
||||||
|
dismemberments
|
||||||
|
PUBLIUS
|
||||||
|
intrusted
|
||||||
|
allurements
|
||||||
|
transcendant
|
||||||
|
unfrequently
|
||||||
|
confederacies
|
||||||
|
feudatories
|
||||||
|
demesnes
|
||||||
|
feudatories
|
||||||
|
oppressions
|
||||||
|
fiefs
|
||||||
|
clanship
|
||||||
|
encroachments
|
||||||
|
rivalship
|
||||||
|
PUBLIUS
|
||||||
|
confederacies
|
||||||
|
Amphictyonic
|
||||||
|
aggressing
|
||||||
|
Amphictyons
|
||||||
|
Delphos
|
||||||
|
Amphictyons
|
||||||
|
Lacedaemonians
|
||||||
|
Thebans
|
||||||
|
Lacedaemonians
|
||||||
|
Lacedaemonians
|
||||||
|
orbs
|
||||||
|
Milot
|
||||||
|
hatreds
|
||||||
|
dissentions
|
||||||
|
Phocians
|
||||||
|
Amphictyonic
|
||||||
|
Phocians
|
||||||
|
Thebans
|
||||||
|
Amphictyons
|
||||||
|
Amphictyonic
|
||||||
|
praetors
|
||||||
|
Philopoemen
|
||||||
|
Achaeans
|
||||||
|
Amphictyonic
|
||||||
|
Aratus
|
||||||
|
Mably
|
||||||
|
Amphictyonic
|
||||||
|
Achaeans
|
||||||
|
Achaeans
|
||||||
|
usurpers
|
||||||
|
Peloponnesus
|
||||||
|
Achaeans
|
||||||
|
Cleomenes
|
||||||
|
unprovoked
|
||||||
|
Achaeans
|
||||||
|
Achaeans
|
||||||
|
Cleomenes
|
||||||
|
intermeddling
|
||||||
|
Cleomenes
|
||||||
|
Achaeans
|
||||||
|
tyrannies
|
||||||
|
Achaeans
|
||||||
|
AEtolians
|
||||||
|
Achaeans
|
||||||
|
Achaia
|
||||||
|
PUBLIUS
|
||||||
|
confederacies
|
||||||
|
Gauls
|
||||||
|
fiefs
|
||||||
|
Suabian
|
||||||
|
disturbers
|
||||||
|
electorates
|
||||||
|
inbecility
|
||||||
|
defaulters
|
||||||
|
Thuanus
|
||||||
|
Donawerth
|
||||||
|
Suabia
|
||||||
|
Abb
|
||||||
|
reannexed
|
||||||
|
heriditary
|
||||||
|
accomodating
|
||||||
|
bailages
|
||||||
|
Luzerne
|
||||||
|
PUBLIUS
|
||||||
|
Pfeffel
|
||||||
|
Nouvel
|
||||||
|
Abreg
|
||||||
|
Chronol
|
||||||
|
l'Hist
|
||||||
|
d'Allemagne
|
||||||
|
aristocracies
|
||||||
|
superintends
|
||||||
|
admiralties
|
||||||
|
florins
|
||||||
|
Belgic
|
||||||
|
confedracy
|
||||||
|
Mably
|
||||||
|
contradistinguished
|
||||||
|
PUBLIUS
|
||||||
|
mulcts
|
||||||
|
encroachments
|
||||||
|
distempers
|
||||||
|
usurpations
|
||||||
|
King's
|
||||||
|
PUBLIUS
|
||||||
|
Jenkinson
|
||||||
|
expedients
|
||||||
|
reget
|
||||||
|
Deleware
|
||||||
|
confederated
|
||||||
|
nonattendance
|
||||||
|
mischiefs
|
||||||
|
suffrages
|
||||||
|
prevalency
|
||||||
|
major's
|
||||||
|
judicatories
|
||||||
|
prepossessions
|
||||||
|
infirmities
|
||||||
|
PUBLIUS
|
||||||
|
intrusted
|
||||||
|
intrusted
|
||||||
|
cavils
|
||||||
|
confederacies
|
||||||
|
indispensible
|
||||||
|
PUBLIUS
|
||||||
|
proprietory
|
||||||
|
overflowings
|
||||||
|
superadded
|
||||||
|
expedients
|
||||||
|
countenanced
|
||||||
|
disconcertion
|
||||||
|
encroachments
|
||||||
|
PUBLIUS
|
||||||
|
bils
|
||||||
|
LEGISLATURE''
|
||||||
|
rivalship
|
||||||
|
perserverance
|
||||||
|
Lacedaemonians
|
||||||
|
PUBLIUS
|
||||||
|
prevalency
|
||||||
|
expedients
|
||||||
|
wellinformed
|
||||||
|
encroachments
|
||||||
|
calamaties
|
||||||
|
PUBLIUS
|
||||||
|
inexplicitness
|
||||||
|
expedients
|
||||||
|
delinquencies
|
||||||
|
PUBLIUS
|
||||||
|
seditions
|
||||||
|
scourges
|
||||||
|
Confederacies
|
||||||
|
Confederacies
|
||||||
|
expedients
|
||||||
|
usurpations
|
||||||
|
intrusted
|
||||||
|
usurpers
|
||||||
|
usurpers
|
||||||
|
usurpers
|
||||||
|
usurpations
|
||||||
|
PUBLIUS
|
||||||
|
superintending
|
||||||
|
COMITATUS
|
||||||
|
COMITATUS
|
||||||
|
intrusted
|
||||||
|
COMITATUS
|
||||||
|
Gorgons
|
||||||
|
hydras
|
||||||
|
chimeras
|
||||||
|
dire''
|
||||||
|
d'ors
|
||||||
|
ducats
|
||||||
|
intrenchments
|
||||||
|
usurpers
|
||||||
|
usurpations
|
||||||
|
distempered
|
||||||
|
superadded
|
||||||
|
selfpreservation
|
||||||
|
PUBLIUS
|
||||||
|
bashaws
|
||||||
|
fatuus
|
||||||
|
embarrassments
|
||||||
|
expedients
|
||||||
|
usurers
|
||||||
|
deficiences
|
||||||
|
sightedness
|
||||||
|
PUBLIUS
|
||||||
|
DISQUISITIONS
|
||||||
|
geometricians
|
||||||
|
untractableness
|
||||||
|
disingenuity
|
||||||
|
superintending
|
||||||
|
usurpations
|
||||||
|
encroachments
|
||||||
|
PUBLIUS
|
||||||
|
resentments
|
||||||
|
LEGISLATION''
|
||||||
|
EXCISES''
|
||||||
|
forbearances
|
||||||
|
PUBLIUS
|
||||||
|
ingrafted
|
||||||
|
thereof''
|
||||||
|
railings
|
||||||
|
culumniated
|
||||||
|
landtax
|
||||||
|
reasoners
|
||||||
|
intrusted
|
||||||
|
PUBLIUS
|
||||||
|
CENTURIATA
|
||||||
|
TRIBUTA
|
||||||
|
intrusted
|
||||||
|
fifteenths
|
||||||
|
twentieths
|
||||||
|
PUBLIUS
|
||||||
|
overstocked
|
||||||
|
expedients
|
||||||
|
acquirements
|
||||||
|
rivalships
|
||||||
|
suffrages
|
||||||
|
expedients
|
||||||
|
PUBLIUS
|
||||||
|
rivalships
|
||||||
|
bypaths
|
||||||
|
monly
|
||||||
|
taxations
|
||||||
|
tyrannies
|
||||||
|
expedients
|
||||||
|
PUBLIUS
|
||||||
|
rejudging
|
||||||
|
confederacies
|
||||||
|
rectifying
|
||||||
|
intrusted
|
||||||
|
naturalists
|
||||||
|
infirmities
|
||||||
|
animosities
|
||||||
|
Zaleucus
|
||||||
|
Locrians
|
||||||
|
Numa
|
||||||
|
Tullius
|
||||||
|
Hostilius
|
||||||
|
Tullius
|
||||||
|
Hostilius
|
||||||
|
Achaeus
|
||||||
|
Aratus
|
||||||
|
intrusted
|
||||||
|
expedients
|
||||||
|
selfpreservation
|
||||||
|
protracting
|
||||||
|
unpardonable
|
||||||
|
impeachments
|
||||||
|
impeachments
|
||||||
|
overleaping
|
||||||
|
PUBLIUS
|
||||||
|
disquisitions
|
||||||
|
oppressions
|
||||||
|
PUBLIUS
|
||||||
|
expositors
|
||||||
|
ungranted
|
||||||
|
pretermitting
|
||||||
|
sixtieths
|
||||||
|
PUBLIUS
|
||||||
|
misthinking
|
||||||
|
usurpations
|
||||||
|
Confederacies
|
||||||
|
animosities
|
||||||
|
intrusted
|
||||||
|
unvaried
|
||||||
|
Confederacies
|
||||||
|
PUBLIUS
|
||||||
|
piracies
|
||||||
|
felonies
|
||||||
|
disembarrassed
|
||||||
|
usurpations
|
||||||
|
piracies
|
||||||
|
felonies
|
||||||
|
piracies
|
||||||
|
felonies
|
||||||
|
piracies
|
||||||
|
felonies
|
||||||
|
felonies
|
||||||
|
upbraided
|
||||||
|
oppressions
|
||||||
|
emigrations
|
||||||
|
secureties
|
||||||
|
animosities
|
||||||
|
superintending
|
||||||
|
confederated
|
||||||
|
mischiefs
|
||||||
|
paupers
|
||||||
|
superadding
|
||||||
|
inhabitants''
|
||||||
|
embarrassments
|
||||||
|
interdicts
|
||||||
|
PUBLIUS
|
||||||
|
dockyards
|
||||||
|
suffrages
|
||||||
|
treasons
|
||||||
|
wreaked
|
||||||
|
superintending
|
||||||
|
Amphictyons
|
||||||
|
antirepublican
|
||||||
|
confederacies
|
||||||
|
superintending
|
||||||
|
infirmities
|
||||||
|
reciprocality
|
||||||
|
PUBLIUS
|
||||||
|
animosities
|
||||||
|
mischiefs
|
||||||
|
proper''
|
||||||
|
EXPRESSLY''
|
||||||
|
usurpers
|
||||||
|
unredressed
|
||||||
|
PUBLIUS
|
||||||
|
Fournal
|
||||||
|
unsacrificed
|
||||||
|
confederacies
|
||||||
|
encroachments
|
||||||
|
rivalship
|
||||||
|
encroachments
|
||||||
|
countenancing
|
||||||
|
PUBLIUS
|
||||||
|
superintending
|
||||||
|
prepossessions
|
||||||
|
prepossessions
|
||||||
|
prepossessions
|
||||||
|
preorgatives
|
||||||
|
defalcations
|
||||||
|
encroachments
|
||||||
|
embarrassments
|
||||||
|
encroachments
|
||||||
|
PUBLIUS
|
||||||
|
selfappointed
|
||||||
|
emphatical
|
||||||
|
impeachments
|
||||||
|
appointable
|
||||||
|
impeachments
|
||||||
|
impeachments
|
||||||
|
appointable
|
||||||
|
appointable
|
||||||
|
PUBLIUS
|
||||||
|
usurpations
|
||||||
|
usurpations
|
||||||
|
encroachments
|
||||||
|
unfrequently
|
||||||
|
encroachments
|
||||||
|
p
|
||||||
|
encroachments
|
||||||
|
PUBLIUS
|
||||||
|
Encroachments
|
||||||
|
subjoined
|
||||||
|
encroachments
|
||||||
|
encroachments
|
||||||
|
grantors
|
||||||
|
bestows
|
||||||
|
prepossessions
|
||||||
|
numberous
|
||||||
|
usurpations
|
||||||
|
prepossessions
|
||||||
|
PUBLIUS
|
||||||
|
expedients
|
||||||
|
PUBLIUS
|
||||||
|
magistracies
|
||||||
|
encroachments
|
||||||
|
encroachments
|
||||||
|
usurpations
|
||||||
|
Confederacies
|
||||||
|
oppressions
|
||||||
|
PUBLIUS
|
||||||
|
antiquaries
|
||||||
|
usurpations
|
||||||
|
PUBLIUS
|
||||||
|
votaries
|
||||||
|
t
|
||||||
|
e
|
||||||
|
regulatious
|
||||||
|
acquirements
|
||||||
|
reelections
|
||||||
|
PUBLIUS
|
||||||
|
confederacies
|
||||||
|
PUBLIUS
|
||||||
|
sixtyfive
|
||||||
|
fellowcitizens
|
||||||
|
allbe
|
||||||
|
extravagancies
|
||||||
|
PUBLIUS
|
||||||
|
constitutents
|
||||||
|
constitutents
|
||||||
|
PUBLIUS
|
||||||
|
Burgh's
|
||||||
|
Disquisitions
|
||||||
|
unpropitious
|
||||||
|
suffrages
|
||||||
|
PUBLIUS
|
||||||
|
rivalship
|
||||||
|
reapportionments
|
||||||
|
reapportionments
|
||||||
|
infirmities
|
||||||
|
secessions
|
||||||
|
PUBLIUS
|
||||||
|
distempered
|
||||||
|
intrusting
|
||||||
|
rivalship
|
||||||
|
confederacies
|
||||||
|
PUBLIUS
|
||||||
|
Ist
|
||||||
|
Ist
|
||||||
|
votaries
|
||||||
|
primative
|
||||||
|
importuned
|
||||||
|
expedients
|
||||||
|
PUBLIUS
|
||||||
|
opposers
|
||||||
|
suffrages
|
||||||
|
suffrages
|
||||||
|
unpardonable
|
||||||
|
PUBLIUS
|
||||||
|
V
|
||||||
|
prepossessions
|
||||||
|
mischiefs
|
||||||
|
embarrassments
|
||||||
|
impeachments
|
||||||
|
indiscretions
|
||||||
|
PUBLIUS
|
||||||
|
unenlightened
|
||||||
|
confederated
|
||||||
|
Archons
|
||||||
|
suffrages
|
||||||
|
Ephori
|
||||||
|
Cosmi
|
||||||
|
usurpations
|
||||||
|
encroachments
|
||||||
|
Ephori
|
||||||
|
usurpations
|
||||||
|
PUBLIUS
|
||||||
|
impeachments
|
||||||
|
PUBLIUS
|
||||||
|
impeachments
|
||||||
|
impeachments
|
||||||
|
animosities
|
||||||
|
partialities
|
||||||
|
inquisitors
|
||||||
|
impeachments
|
||||||
|
unawed
|
||||||
|
impeachments
|
||||||
|
impeachments
|
||||||
|
impeachments
|
||||||
|
disposers
|
||||||
|
impeachments
|
||||||
|
overbalanced
|
||||||
|
impeachments
|
||||||
|
impeachments
|
||||||
|
reprobated
|
||||||
|
PUBLIUS
|
||||||
|
Impeachments
|
||||||
|
impeachments
|
||||||
|
wellestablished
|
||||||
|
encroachments
|
||||||
|
impeachments
|
||||||
|
encroachments
|
||||||
|
prevalency
|
||||||
|
impeachments
|
||||||
|
impeachments
|
||||||
|
disquisitions
|
||||||
|
impeachments
|
||||||
|
counterpoises
|
||||||
|
impeachments
|
||||||
|
suffrages
|
||||||
|
impeachments
|
||||||
|
impeachments
|
||||||
|
prostituted
|
||||||
|
PUBLIUS
|
||||||
|
Pennsylvanis
|
||||||
|
impeachments
|
||||||
|
inveighed
|
||||||
|
mistresses
|
||||||
|
voluptuousness
|
||||||
|
visages
|
||||||
|
janizaries
|
||||||
|
disingenuity
|
||||||
|
expedients
|
||||||
|
applauses
|
||||||
|
LAW''
|
||||||
|
officers''
|
||||||
|
session''
|
||||||
|
years''
|
||||||
|
palliated
|
||||||
|
PUBLIUS
|
||||||
|
V
|
||||||
|
preestablished
|
||||||
|
PUBLIUS
|
||||||
|
Confederated
|
||||||
|
crown's
|
||||||
|
comfort''
|
||||||
|
preferments
|
||||||
|
PUBLIUS
|
||||||
|
TAMONY
|
||||||
|
Blackstone's
|
||||||
|
p
|
||||||
|
seditions
|
||||||
|
repub
|
||||||
|
lican
|
||||||
|
intrusted
|
||||||
|
votaries
|
||||||
|
Achaeans
|
||||||
|
Praetors
|
||||||
|
mischiefs
|
||||||
|
plebeians
|
||||||
|
rivalships
|
||||||
|
caprices
|
||||||
|
jarrings
|
||||||
|
anycounterbalancing
|
||||||
|
weightiest
|
||||||
|
scrunity
|
||||||
|
mischiefs
|
||||||
|
lic
|
||||||
|
ONE''
|
||||||
|
nattainable
|
||||||
|
Decemvirs
|
||||||
|
PUBLIUS
|
||||||
|
Lolme
|
||||||
|
seditions
|
||||||
|
repub
|
||||||
|
lican
|
||||||
|
intrusted
|
||||||
|
votaries
|
||||||
|
Achaeans
|
||||||
|
Praetors
|
||||||
|
mischiefs
|
||||||
|
plebeians
|
||||||
|
rivalships
|
||||||
|
caprices
|
||||||
|
jarrings
|
||||||
|
anycounterbalancing
|
||||||
|
weightiest
|
||||||
|
scrunity
|
||||||
|
mischiefs
|
||||||
|
lic
|
||||||
|
ONE''
|
||||||
|
nattainable
|
||||||
|
Decemvirs
|
||||||
|
PUBLIUS
|
||||||
|
Lolme
|
||||||
|
comports
|
||||||
|
indued
|
||||||
|
years'
|
||||||
|
encroachments
|
||||||
|
PUBLIUS
|
||||||
|
expedients
|
||||||
|
fellowcitizens
|
||||||
|
readmission
|
||||||
|
resentments
|
||||||
|
suffrages
|
||||||
|
overbalanced
|
||||||
|
PUBLIUS
|
||||||
|
largesses
|
||||||
|
allurements
|
||||||
|
selfdefense
|
||||||
|
enaction
|
||||||
|
missteps
|
||||||
|
mischiefs
|
||||||
|
opposers
|
||||||
|
PUBLIUS
|
||||||
|
seditions
|
||||||
|
resentments
|
||||||
|
welltimed
|
||||||
|
PUBLIUS
|
||||||
|
enaction
|
||||||
|
years'
|
||||||
|
intrusted
|
||||||
|
intrusted
|
||||||
|
PUBLIUS
|
||||||
|
partialities
|
||||||
|
antipathies
|
||||||
|
animosities
|
||||||
|
suffrages
|
||||||
|
partialities
|
||||||
|
antipathies
|
||||||
|
animosities
|
||||||
|
suffrages
|
||||||
|
venalty
|
||||||
|
venalty
|
||||||
|
PUBLIUS
|
||||||
|
uncomplying
|
||||||
|
mischiefs
|
||||||
|
embarrassments
|
||||||
|
cavils
|
||||||
|
PUBLIUS
|
||||||
|
encroachments
|
||||||
|
oppressions
|
||||||
|
bulwarks
|
||||||
|
encroachments
|
||||||
|
oppressions
|
||||||
|
mischiefs
|
||||||
|
PUBLIUS
|
||||||
|
Martin's
|
||||||
|
impeachments
|
||||||
|
PUBLIUS
|
||||||
|
judicary
|
||||||
|
unredressed
|
||||||
|
bickerings
|
||||||
|
animosities
|
||||||
|
cognizances
|
||||||
|
States''
|
||||||
|
emited
|
||||||
|
judicatories
|
||||||
|
inconviences
|
||||||
|
mischiefs
|
||||||
|
wellinformed
|
||||||
|
mischiefs
|
||||||
|
PUBLIUS
|
||||||
|
is''
|
||||||
|
impeachments
|
||||||
|
judical
|
||||||
|
usurpations
|
||||||
|
encroachments
|
||||||
|
contraventions
|
||||||
|
usurpations
|
||||||
|
impeachments
|
||||||
|
usurpations
|
||||||
|
intrusted
|
||||||
|
impeachments
|
||||||
|
AUTHORUZE
|
||||||
|
prevalency
|
||||||
|
sovereignties
|
||||||
|
inconveniencies
|
||||||
|
PUBLIUS
|
||||||
|
COURT''
|
||||||
|
DICTIO
|
||||||
|
juris
|
||||||
|
dictio
|
||||||
|
judicatories
|
||||||
|
sovereignties
|
||||||
|
T
|
||||||
|
intrusted
|
||||||
|
judicatories
|
||||||
|
establish''
|
||||||
|
PUBLIUS
|
||||||
|
generals''
|
||||||
|
oppressions
|
||||||
|
impeachments
|
||||||
|
intrusted
|
||||||
|
heretofore''
|
||||||
|
wellregulated
|
||||||
|
litigations
|
||||||
|
judicatories
|
||||||
|
embarrassments
|
||||||
|
unpardonable
|
||||||
|
encroachments
|
||||||
|
encroachments
|
||||||
|
PUBLIUS
|
||||||
|
opposers
|
||||||
|
attainted
|
||||||
|
Usays
|
||||||
|
e
|
||||||
|
emphatical
|
||||||
|
abridgements
|
||||||
|
preserved''
|
||||||
|
intrusted
|
||||||
|
overbalanced
|
||||||
|
rivalship
|
||||||
|
defaulters
|
||||||
|
railings
|
||||||
|
PUBLIUS
|
||||||
|
Blackstone's
|
||||||
|
p
|
||||||
|
Blackstone's
|
||||||
|
p
|
||||||
|
asperities
|
||||||
|
disputants
|
||||||
|
concealments
|
||||||
|
intemperances
|
||||||
|
T
|
||||||
|
encroachments
|
||||||
|
Usays
|
||||||
|
PUBLIUS
|
||||||
|
Hume's
|
||||||
|
Etext
|
||||||
|
|
||||||
|
WORDS MISSPELLED: 935
|
||||||
|
WORDS IN DICTIONARY: 143091
|
||||||
|
WORDS IN TEXT: 196784
|
||||||