pages/static/anatomy-quiz.html

647 lines
21 KiB
HTML

<!DOCTYPE html>
<body>
<h1>MillironX's Anatomy Quiz Generator</h1>
<h2>Quiz material weighting</h2>
<div id="weights"></div>
<hr />
<div>
<label for="num-questions">Number of questions </label>
<input id="num-questions" type="number" value="15" />
</div>
<hr />
<button id="generator">Generate!</button>
<hr />
<h2>Quiz</h2>
<ul id="quiz-terms"></ul>
<script>
const BoldTerms = {
bones: {
scapula: {
asymmetric: true,
features: {
"glenoid cavity": {
articulation: "head of humerus",
},
spine: {},
acromion: {
attachment: "deltoideus",
},
"supraspinous fossa": {},
"infraspinous fossa": {},
"serrated face": {
insertion: "serratus ventralis",
},
"subscapular fossa": {
attachment: "subscapularis",
},
"cranial border": {},
"scapular notch": {},
"cranial angle": {},
"dorsal border": {},
"caudal angle": {
attachment: "rhomboideus",
},
"caudal border": {
attachment: "teres major",
},
"infraglenoid tubercle": {
attachment: "teres minor and long head of the triceps",
},
"ventral angle": {},
neck: {},
"supraglenoid tubercle": {},
"coracoid process": {
attachment: "coracobrachialis",
},
},
},
humerus: {
asymmetric: true,
features: {
head: {
articulation: "glenoid cavity",
},
"intertubercular groove": {
originates: "biceps brachii",
},
"greater tubercle": {
insertion: "infraspinatus",
},
neck: {},
"cranial surface": {
attachment: "brachiocephalicus",
},
"crest of the greater tubercle": {
insertion: "pectorals and cleidobrachialis",
},
"lateral surface": {},
"deltoid tuberosity": {
insertion: "deltoideus",
},
"tricipital line": {
attachment: "lateral head of triceps",
},
"tuberosity of the teres minor": {},
"brachialis groove": {},
"lateral supracondylar crest": {
attachment: "extensor carpi radialis and anconeus",
},
"caudal surface": {},
"crest of the lesser tubercle": {},
"medial surface": {},
"teres major tuberosity": {
insertion: "teres major and latissimus dorsi",
},
"humeral condyle": {},
trochlea: {
articulation: "radius and ulna",
},
capitulum: { articulation: "head of the radius" },
"lateral epicondyle": {
originates:
"common digital extensor, lateral digital extensor, ulnaris lateralis, supinator",
attachment: "lateral collateral ligament",
},
"medial epicondyle": {
originates:
"flexor carpi radialis, flexor carpi ulnaris, pronator teres, superficial and deep digital flexor",
attachment: "medial collateral ligament",
},
"olecranon fossa": { articulation: "anconeal process of ulna" },
"radial fossa": {},
"supratrochlear foramen": {},
},
},
radius: {
asymmetric: true,
features: {
head: {},
"fovea capitis": {
articulation: "capitulum of humerus",
},
"articular circumference": {
articulation: "radial notch of ulna",
},
"radial tuberosity": {
insertion: "biceps brachii and brachialis",
},
body: {},
trochlea: {},
"ulnar notch": { articulation: "ulna" },
"styloid process": { attachment: "medial collateral ligament" },
},
ulna: {
asymmetric: true,
features: {
"trochlear notch": {
articulation: "trochlea of humerus",
},
"radial notch": {
articulation: "articular circumference of radius",
},
olecranon: {},
"olecranon tuber": {},
"anconeal process": {},
"medial coronoid process": {},
"lateral coronoid process": {},
body: {},
"ulnar tuberosity": {},
"interosseous border": {},
"styloid process": {},
},
"intermedioradial carpal": {},
"ulnar carpal": {},
"accessory carpal": {},
"proximal phalanx": {},
"middle phalanx": {
features: {
"ungual crest": {},
"ungual process": {},
"flexor tubercle": {},
},
},
"distal phalanx": {},
"carpal bones": {
features: {
I: {},
II: {},
III: {},
IV: {},
V: {},
},
},
"metacarpal bones": {
features: {
base: {},
body: {},
head: {},
},
},
},
},
},
muscles: {
"cutaneous trunci": {},
"preputial muscle": {},
"superficial pectoral": {
features: {
"descending pectoral": {
origin: "cranial sternebrae",
insertion: "greater tubercle of humerus",
action: "adduct forelimb",
},
"transverse pectoral": {
origin: "cranial sternebrae",
insertion: "greater tubercle of humerus",
action: "adduct forelimb",
},
},
},
"deep pectoral": {
origin: "ventral sternum",
insertion: "fleshy",
action: "flex and extend shoulder joint",
},
brachiocephalicus: {
features: {
cleidobrachialis: {
origin: "clavicle",
insertion: "cranial border of humerus",
action: "extend shoulder joint",
},
cleidocephalicus: {
origin: "clavicle",
insertion: "occipital bone",
action: "extend shoulder joint",
},
},
},
sternocephalicus: {
features: {
"mastoid part": {
origin: "first sternebra",
insertion: "mastoid part of temporal bone",
action: "draw head and neck to the side",
},
"occipital part": {
origin: "first sternebra",
insertion: "nuchal crest of occipital bone",
action: "draw head and neck to the side",
},
},
},
sternohyoideus: {
origin: "first sternebra and first costal cartilage",
insertion: "basihyoid bone",
action: "pull the tongue and larynx caudally",
},
sternothyroideus: {
origin: "first costal cartilage",
insertion: "caudolateral surface of thyroid cartilage",
action: "pull the tongue and larynx caudally",
},
omotransversarius: {
attachment:
"distal end of spine of the scapula and the transverse process of the atlas",
action: "advance the limb or flex the neck laterally",
},
trapezius: {
features: {
"cervical part": {
origin: "supraspinous ligament",
insertion: "spine of scapula",
action: "abduction of forelimb",
},
"thoracic part": {
origin: "supraspinous ligament",
insertion: "spine of scapula",
action: "abduction of forelimb",
},
},
},
rhomboideus: {
features: {
"rhomboideus capitis": {
origin: "nuchal crest of occipital bone",
insertion: "dorsal border of scapula",
action: "elevate the forelimb",
},
"rhomboideus cervicis": {
origin: "median fibrous raphe of neck",
insertion: "dorsal border of scapula",
action: "elevate the forelimb",
},
"rhomboideus thoracis": {
origin: "spinous process of first seven thoracic vertebrae",
insertion: "dorsal border of scapula",
action: "elevate the forelimb",
},
},
},
"latissimus dorsi": {
origin: "thoracolumbar fascia",
insertion: "teres major tuberosity",
action: "flexion of shoulder joint",
},
"serratus ventralis": {
origin: "transverse processes of cervical vertebrae and ribs",
insertion: "serrated face of the scapula",
action: "to support the trunk",
},
deltoideus: {
features: {
"scapular part": {
origin: "spine of the scapula",
insertion: "deltoid tuberosity",
action: "flexion of shoulder joint",
},
"acromial part": {
origin: "acromion of the scapula",
insertion: "deltoid tuberosity",
action: "flexion of shoulder joint",
},
},
},
infraspinatus: {
origin: "infraspinous fossa of scapula",
insertion: "greater tubercle of humerus",
action:
"to abduct the shoulder, flex or extend the shoulder joint, or to rotate the humerus laterally",
},
"teres minor": {
origin: "infraglenoid tubercle",
insertion: "teres minor tuberosity",
action: "flexion of shoulder",
},
supraspinatus: {
origin: "supraspinous fossa",
insertion: "greater tubercle of humerus",
action: "extension of shoulder joint",
},
subscapularis: {
origin: "subscapular fossa",
insertion: "lesser tubercle of humerus",
action: "adduction and extension of shoulder joint",
},
"teres major": {
origin: "caudal angle of scapula",
insertion: "teres major tuberosity",
action: "flexion of shoulder joint",
},
coracobrachialis: {
origin: "coracoid process",
insertion: "lesser tubercle of humerus",
action: "adduction and extension of shoulder joint",
},
"tensor fasciae antebrachii": {
origin: "lateral fascia of latissimus dorsi",
insertion: "olecranon",
action: "extension of elbow joint",
},
"triceps brachii": {
features: {
"long head": {
origin: "caudal border of scapula",
insertion: "olecranon tuber",
action: "extension of elbow joint",
},
"lateral head": {
origin: "tricipital line of humerus",
insertion: "olecranon tuber",
action: "extension of elbow joint",
},
"accessory head": {
origin: "neck of humerus",
insertion: "olecranon tuber",
action: "extension of elbow joint",
},
"medial head": {
origin: "lesser tubercle of humerus",
insertion: "olecranon",
action: "extension of elbow joint",
},
},
},
anconeus: {
origin:
"lateral supracondylar crest, lateral and medial epicondyles of humerus",
insertion: "olecranon",
action: "extension of elbow joint",
},
"biceps brachii": {
origin: "supraglenoid tubercle",
insertion: "ulnar and radial tuberosities",
action: "flexion of elbow joint and extension of shoulder joint",
},
brachialis: {
origin: "lateral surface of humerus",
insertion: "ulnar and radial tuberosities",
action: "flexion of elbow joint",
},
"extensor carpi radialis": {
origin: "lateral supracondylar crest",
insertion: "base of metacarpals II and III",
action: "extension of carpal joints",
},
"common digital extensor": {
origin: "lateral epicondyle of humerus",
insertion: "distal phalanges II, III, IV, and V",
action: "extension of phalanges",
},
"lateral digital extensor": {
origin: "lateral epicondyle of humerus",
insertion: "proximal phalanges III, IV, and V",
action: "extension of carpal joints",
},
"ulnaris lateralis": {
origin: "lateral epicondyle of humerus",
insertion: "proximal metacarpal V and accessory carpal bone",
action: "flexion of carpal joints",
},
supinator: {
origin: "lateral epicondyle of humerus",
insertion: "cranial surface of radius",
action: "supinate forelimb",
},
"abductor digiti longus I": {
origin: "lateral border of ulna",
insertion: "proximal metacarpal I",
action: "abduction of digit I",
},
"pronator teres": {
origin: "medial epicondyle of humerus",
insertion: "medial border of radius",
action: "pronate forelimb",
},
"flexor carpi radialis": {
origin: "medial epicondyle of humerus",
insertion: "base of metacarpals II and III",
action: "flexion of carpal joints",
},
"superficial digital flexor": {
origin: "medial epicondyle of humerus",
insertion: "base of middle phalanges II, II, IV, and V",
action: "flexion of carpal joints",
},
"flexor carpi ulnaris": {
features: {
"ulnar head": {
origin: "caudal border of olecranon",
insertion: "accessory carpal bone",
action: "flexion of carpus",
},
"humeral head": {
origin: "medial epicondyle of humerus",
insertion: "accessory carpal bone",
action: "flexion of carpus",
},
},
},
"deep digital flexor": {
features: {
"humeral head": {
origin: "medial epicondyle of humerus",
insertion: "distal phalanges",
action: "flexion of carpal and metacarpophalangeal joints",
},
"radial head": {
origin: "medial border of radius",
insertion: "distal phalanges",
action: "flexion of carpal and metacarpophalangeal joints",
},
"ulnar head": {
origin: "caudal border of ulna",
insertion: "distal phalanges",
action: "flexion of carpal and metacarpophalangeal joints",
},
},
},
"pronator quadratus": {
attachment: "surface of radius and ulna",
action: "pronation of paw",
},
},
joints: {
humeral: {},
cubiti: {},
metacarpophalangeal: {},
"antebrachiocarpal joint": {},
"middle carpal joint": {},
"carpometacarpal joint": {},
"proximal interphalangeal joint": {},
"distal interphalangeal joint": {},
},
ligaments: {
"supraspinous ligament": {},
"nuchal ligament": {},
"palmar annular ligament": {},
"annular digital ligament": {},
"medial glenohumeral ligament": {},
"lateral glenohumeral ligament": {},
"lateral collateral ligament": {},
"medial collateral ligament": {},
"interosseous ligament": {},
"palmar carpal ligament": {},
},
other: {
"superficial cervical lymph node": {},
"carotid sheath": {},
"thoracic mammae": {
features: {
"cranial thoracic mammae": {},
"caudal thoracic mammae": {},
},
},
"abdominal mammae": {
features: {
"cranial abdominal mammae": {},
"caudal abdominal mammae": {},
},
},
"inguinal mammae": {},
"costal arch": {},
"subtendious synovial bursa": {},
"transverse humeral retinaculum": {},
"intertubercular bursa": {},
"extensor retinaculum": {},
"flexor retinaculum": {},
"flexor manica": {},
"digital synovial sheath": {},
"transverse humeral retinaculum": {},
},
};
function structure_question(structure, props) {
let quiz_list = [];
quiz_list.push(`id: ${structure}`);
let questions = [];
if ("features" in props) {
for (feature in props["features"]) {
questions = feature_question(
`${feature} of ${structure}`,
props["features"][feature]
);
}
} else {
questions = feature_question(structure, props);
}
for (const question of questions) {
quiz_list.push(question);
}
return quiz_list;
}
function feature_question(feature, props) {
let quiz_list = [];
quiz_list.push(`id: ${feature}`);
for (const prop in props) {
if (prop != "asymmetric") {
quiz_list.push(property_question(feature, prop, props[prop]));
}
}
return quiz_list;
}
function property_question(feature, prop_name, prop_content) {
return `${prop_name}: ${feature} (${prop_content})`;
}
const weights_spinner_div = document.getElementById("weights");
for (structure_type in BoldTerms) {
const form_div = document.createElement("div");
const weight_spinner = document.createElement("input");
weight_spinner.setAttribute("id", `${structure_type}-weight`);
weight_spinner.setAttribute("type", "number");
weight_spinner.setAttribute("value", "10");
const weight_spinner_label = document.createElement("label");
weight_spinner_label.setAttribute("for", `${structure_type}-weight`);
weight_spinner_label.textContent = `${structure_type} `;
form_div.appendChild(weight_spinner_label);
form_div.appendChild(weight_spinner);
weights_spinner_div.append(form_div);
}
// Shamelessly stolen from
// https://github.com/trekhleb/javascript-algorithms/blob/master/src/algorithms/statistics/weighted-random/weightedRandom.js
function weighted_random(items, weights) {
const cumulativeWeights = [];
for (let i = 0; i < weights.length; i += 1) {
cumulativeWeights[i] = weights[i] + (cumulativeWeights[i - 1] || 0);
}
const maxCumulativeWeight =
cumulativeWeights[cumulativeWeights.length - 1];
const randomNumber = maxCumulativeWeight * Math.random();
for (let itemIndex = 0; itemIndex < items.length; itemIndex += 1) {
if (cumulativeWeights[itemIndex] >= randomNumber) {
return items[itemIndex];
}
}
}
// Shamelessly stolen from
// https://stackoverflow.com/a/15106541
function random_child(object) {
const keys = Object.keys(object);
const i = Math.floor(Math.random() * keys.length);
return {
key: keys[i],
object: object[keys[i]],
};
}
const terms_list = document.getElementById("quiz-terms");
function generate_quiz() {
terms_list.innerHTML = "";
let weights = [];
let types = [];
for (structure_type in BoldTerms) {
weights.push(
parseInt(document.getElementById(`${structure_type}-weight`).value)
);
types.push(structure_type);
}
const num_questions = document.getElementById("num-questions").value;
for (let i = 0; i <= num_questions; i += 1) {
// Pick the random category
const structure_type = weighted_random(types, weights);
// Pick a random structure from that category
const rand_structure = random_child(BoldTerms[structure_type]);
// Get the list of questions for that structure
const questions = structure_question(
rand_structure.key,
rand_structure.object
);
// Get a random question from that list
const rand_question =
questions[Math.floor(Math.random() * questions.length)];
// Add that structure to the list
let term_item = document.createElement("li");
term_item.innerHTML = rand_question;
terms_list.appendChild(term_item);
}
}
document
.getElementById("generator")
.addEventListener("click", generate_quiz);
generate_quiz();
</script>
</body>