diff --git a/tutorials/.gitignore b/tutorials/.gitignore deleted file mode 100644 index 5800e14..0000000 --- a/tutorials/.gitignore +++ /dev/null @@ -1,17 +0,0 @@ -**/.DS_Store -**/.env -**/node_modules - -# Python -**/__pycache__/ -**/*.py[cod] -**/*$py.class -**/.pytest_cache/ -**/.coverage -**/venv/ -**/env/ -**/.venv/ -**/.env/ - -# Data files (embeddings) -**/*_embeddings.json \ No newline at end of file diff --git a/tutorials/README.md b/tutorials/README.md deleted file mode 100644 index 0ab082b..0000000 --- a/tutorials/README.md +++ /dev/null @@ -1,20 +0,0 @@ -# Tutorials - -We provide stand-alone example apps in **Python** and **JavaScript** that demonstrate how Knowledge Graph data can be applied to different use cases. - -## Prerequisites - -- A [Learning Commons Platform](https://platform.learningcommons.org/) account -- An API key generated in the Learning Commons Platform - -## Tutorials - -See the README in each tutorial folder for language-specific setup instructions. - -> **Note:** These tutorials use the Knowledge Graph REST API, which is currently available as Early Access and is actively evolving. Breaking changes may occur as we expand capabilities and improve reliability. - -| Tutorial | Description | Python | JavaScript | -| :------------------------------------------------------ | :------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------- | :------------------------------------ | -| [compare_standards](./compare_standards/) | Compare standards between Common Core (CCSSM) and state frameworks using crosswalk data, Jaccard scores, and learning components | [python/](./compare_standards/python/) | [js/](./compare_standards/js/) | -| [generate_prereq_practice](./generate_prereq_practice/) | Generate prerequisite-based practice questions by querying standards, learning progressions, and learning components | [python/](./generate_prereq_practice/python/) | [js/](./generate_prereq_practice/js/) | -| [working_with_standards](./working_with_standards/) | Query state educational standards by jurisdiction, grade level, and type | [python/](./working_with_standards/python/) | [js/](./working_with_standards/js/) | diff --git a/tutorials/compare_standards/js/.env.example b/tutorials/compare_standards/js/.env.example deleted file mode 100644 index 3c86715..0000000 --- a/tutorials/compare_standards/js/.env.example +++ /dev/null @@ -1,3 +0,0 @@ -# Knowledge Graph API credentials - get these from the Learning Commons Platform -API_KEY=your_api_key_here -BASE_URL=https://api.learningcommons.org/knowledge-graph/v0 diff --git a/tutorials/compare_standards/js/README.md b/tutorials/compare_standards/js/README.md deleted file mode 100644 index b6d809e..0000000 --- a/tutorials/compare_standards/js/README.md +++ /dev/null @@ -1,40 +0,0 @@ -# Compare Standards - -Demonstrates how to use crosswalk data to compare standards between the Common Core State Standards (CCSSM) and state frameworks using the Knowledge Graph REST API, covering: -- **API Integration**: Using REST API to query crosswalk data -- **Standards Comparison**: Finding state standards that align with CCSS standards -- **Jaccard Scoring**: Understanding alignment strength using Jaccard scores -- **Learning Components**: Analyzing shared and unique learning components - -> **Note:** The API is in limited early release and is only available to some private beta users. Because the API is an early release, current users should expect occasional breaking changes. - -## Prerequisites - -- Node.js 18 or higher (for native fetch API support) -- A Learning Commons Platform account -- An API key generated in the Learning Commons Platform - -## Dependencies - -- **dotenv**: Environment variable management - -## Quick Start - -1. **Clone and Install**: - ```bash - git clone git@github.com:learning-commons-org/knowledge-graph.git - cd tutorials/compare_standards/js - npm install - ``` - -2. **Set Environment Variables** (create `.env` file): - ```bash - # Knowledge Graph API credentials - get these from the Learning Commons Platform - API_KEY=your_api_key_here - BASE_URL=https://api.learningcommons.org/knowledge-graph/v0 - ``` - -3. **Run Tutorial**: - ```bash - npm start - ``` diff --git a/tutorials/compare_standards/js/compare-standards.js b/tutorials/compare_standards/js/compare-standards.js deleted file mode 100644 index 0101f84..0000000 --- a/tutorials/compare_standards/js/compare-standards.js +++ /dev/null @@ -1,248 +0,0 @@ -/* ================================ - CONFIGURATION & SETUP - ================================ */ - -// Dependencies -require('dotenv').config(); - -// Domain Constants -// Pick a CCSSM standard to find its best state standard matches -const TARGET_CCSSM_STANDARD_CODE = '6.EE.B.5'; // Common Core 6th grade math standard on solving equations and inequalities -const TARGET_CCSSM_JURISDICTION = 'Multi-State'; - -// Environment setup -const apiKey = process.env.API_KEY; -const baseUrl = process.env.BASE_URL; - -if (!apiKey) { - console.error('❌ API_KEY environment variable is not set.'); - process.exit(1); -} - -if (!baseUrl) { - console.error('❌ BASE_URL environment variable is not set.'); - process.exit(1); -} - -/* ================================ - HELPER FUNCTIONS - ================================ */ - -async function makeApiRequest(endpoint, params = {}) { - try { - const url = new URL(`${baseUrl}${endpoint}`); - - // Handle array parameters - Object.entries(params).forEach(([key, value]) => { - if (Array.isArray(value)) { - value.forEach(v => url.searchParams.append(key, v)); - } else { - url.searchParams.append(key, value); - } - }); - - const response = await fetch(url.toString(), { - method: 'GET', - headers: { - 'x-api-key': apiKey - } - }); - - if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`); - } - - return await response.json(); - } catch (error) { - console.error(`❌ Error making API request to ${endpoint}: ${error.message}`); - throw error; - } -} - -/* ================================ - STEP 2: FIND THE BEST-MATCHING STATE STANDARDS - ================================ */ - -async function findBestStateMatches() { - // Find the CCSSM standard by its statement code and jurisdiction - const searchResult = await makeApiRequest('/academic-standards/search', { - statementCode: TARGET_CCSSM_STANDARD_CODE, - jurisdiction: TARGET_CCSSM_JURISDICTION - }); - - const ccssmStandard = searchResult[0] || null; - - if (!ccssmStandard) { - console.log(`❌ CCSSM standard not found: ${TARGET_CCSSM_STANDARD_CODE}`); - return { ccssmStandard: null, texasMatches: null }; - } - - const ccssmStandardUuid = ccssmStandard.caseIdentifierUUID; - console.log(`✅ Found CCSSM standard: ${TARGET_CCSSM_STANDARD_CODE}`); - console.log(` Case UUID: ${ccssmStandardUuid}`); - console.log(` Description: ${ccssmStandard.description}`); - - // Get Texas standards that align with this CCSSM standard - const crosswalkResult = await makeApiRequest( - `/academic-standards/${ccssmStandardUuid}/crosswalks`, - { jurisdiction: 'Texas' } - ); - - const texasMatches = crosswalkResult.data; - - if (!texasMatches || texasMatches.length === 0) { - console.log(`\n❌ No Texas standard matches found for ${TARGET_CCSSM_STANDARD_CODE}`); - return { ccssmStandard, texasMatches: null }; - } - - // Sort by Jaccard score (highest first) - const texasMatchesSorted = texasMatches.sort((a, b) => b.jaccard - a.jaccard); - - console.log(`\n✅ Found ${texasMatchesSorted.length} Texas standard matches`); - console.log(`\n📊 Top Texas match (highest Jaccard score):`); - - const topMatch = texasMatchesSorted[0]; - console.log(` Statement Code: ${topMatch.statementCode}`); - console.log(` Jaccard Score: ${topMatch.jaccard.toFixed(4)}`); - console.log(` Shared LC Count: ${topMatch.sharedLCCount}`); - console.log(` State LC Count: ${topMatch.stateLCCount}`); - console.log(` CCSS LC Count: ${topMatch.ccssLCCount}`); - - return { ccssmStandard, texasMatches: texasMatchesSorted }; -} - -/* ================================ - STEP 3: INTERPRET THE RELATIONSHIP METRICS - ================================ */ - -function interpretRelationshipMetrics(matches) { - if (!matches || matches.length === 0) { - return; - } - - console.log(`\n📊 INTERPRETATION OF TOP MATCHES:\n`); - - // Show top 5 matches with interpretation - matches.slice(0, 5).forEach((match, idx) => { - const jaccard = match.jaccard; - const stateLc = match.stateLCCount; - const ccssLc = match.ccssLCCount; - const sharedLc = match.sharedLCCount; - - console.log(`Match #${idx + 1}:`); - console.log(` Statement Code: ${match.statementCode}`); - console.log(` Jaccard Score: ${jaccard.toFixed(4)}`); - console.log(` State LC Count: ${stateLc}`); - console.log(` CCSS LC Count: ${ccssLc}`); - console.log(` Shared LC Count: ${sharedLc}`); - - // Interpret the metrics - let interpretation; - if (jaccard >= 0.9) { - interpretation = "Very strong overlap; standards share nearly all skills"; - } else if (jaccard >= 0.7) { - interpretation = "Strong overlap; substantial shared skills"; - } else if (jaccard >= 0.5) { - interpretation = "Moderate overlap; many shared skills"; - } else if (jaccard >= 0.3) { - interpretation = "Partial overlap; some shared skills"; - } else { - interpretation = "Weak overlap; few shared skills"; - } - - // Check scope balance - let scopeNote; - if (Math.abs(stateLc - ccssLc) <= 2) { - scopeNote = "Both standards have similar scope"; - } else if (stateLc > ccssLc) { - scopeNote = "State standard covers more content"; - } else { - scopeNote = "CCSS standard covers more content"; - } - - console.log(` Interpretation: ${interpretation}`); - console.log(` Scope: ${scopeNote}`); - console.log(); - }); -} - -/* ================================ - STEP 4: INSPECT SHARED LEARNING COMPONENTS - ================================ */ - -async function showSharedLearningComponents(ccssmStandard, topMatch) { - const ccssmStandardUuid = ccssmStandard.caseIdentifierUUID; - const stateStandardUuid = topMatch.caseIdentifierUUID; - - // Get LCs that support the CCSS standard - const ccssLcResult = await makeApiRequest( - `/academic-standards/${ccssmStandardUuid}/learning-components` - ); - const ccssLcs = ccssLcResult.data; - - // Get LCs that support the state standard - const stateLcResult = await makeApiRequest( - `/academic-standards/${stateStandardUuid}/learning-components` - ); - const stateLcs = stateLcResult.data; - - // Create sets of LC identifiers for comparison - const ccssLcIds = new Set(ccssLcs.map(lc => lc.identifier)); - const stateLcIds = new Set(stateLcs.map(lc => lc.identifier)); - - // Find shared and unique LCs - const sharedLcIds = new Set([...ccssLcIds].filter(id => stateLcIds.has(id))); - const ccssOnlyIds = new Set([...ccssLcIds].filter(id => !stateLcIds.has(id))); - const stateOnlyIds = new Set([...stateLcIds].filter(id => !ccssLcIds.has(id))); - - // Get LC descriptions - const sharedLcs = ccssLcs.filter(lc => sharedLcIds.has(lc.identifier)); - const ccssOnlyLcs = ccssLcs.filter(lc => ccssOnlyIds.has(lc.identifier)); - const stateOnlyLcs = stateLcs.filter(lc => stateOnlyIds.has(lc.identifier)); - - console.log(`\n✅ LEARNING COMPONENTS ANALYSIS:`); - console.log(`CCSS Standard: ${ccssmStandard.statementCode}`); - console.log(`State Standard: ${topMatch.statementCode}`); - console.log(); - - console.log(`📊 SHARED LEARNING COMPONENTS (${sharedLcs.length}):`); - sharedLcs.forEach((lc, idx) => { - console.log(` ✅ ${idx + 1}. ${lc.description}`); - }); - console.log(); - - console.log(`📊 CCSS-ONLY LEARNING COMPONENTS (${ccssOnlyLcs.length}):`); - ccssOnlyLcs.forEach((lc, idx) => { - console.log(` ➕ ${idx + 1}. ${lc.description}`); - }); - console.log(); - - console.log(`📊 STATE-ONLY LEARNING COMPONENTS (${stateOnlyLcs.length}):`); - stateOnlyLcs.forEach((lc, idx) => { - console.log(` ➖ ${idx + 1}. ${lc.description}`); - }); - console.log(); -} - -/* ================================ - MAIN EXECUTION - ================================ */ - -async function main() { - console.log('\n=== USING CROSSWALKS TO COMPARE STATE STANDARDS TO COMMON CORE ===\n'); - - console.log('🔄 Step 2: Find the best-matching state standards for a CCSSM standard...\n'); - const { ccssmStandard, texasMatches } = await findBestStateMatches(); - - if (texasMatches) { - console.log('\n' + '='.repeat(70)); - console.log('🔄 Step 3: Interpret the relationship metrics...'); - interpretRelationshipMetrics(texasMatches); - - console.log('='.repeat(70)); - console.log('🔄 Step 4: Inspect shared learning components...'); - await showSharedLearningComponents(ccssmStandard, texasMatches[0]); - } -} - -main().catch(console.error); diff --git a/tutorials/compare_standards/js/package-lock.json b/tutorials/compare_standards/js/package-lock.json deleted file mode 100644 index 3d81c01..0000000 --- a/tutorials/compare_standards/js/package-lock.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "name": "compare-standards", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "compare-standards", - "version": "1.0.0", - "license": "ISC", - "dependencies": { - "dotenv": "^16.3.1" - } - }, - "node_modules/dotenv": { - "version": "16.6.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", - "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://dotenvx.com" - } - } - } -} diff --git a/tutorials/compare_standards/js/package.json b/tutorials/compare_standards/js/package.json deleted file mode 100644 index 02d654e..0000000 --- a/tutorials/compare_standards/js/package.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "compare-standards", - "version": "1.0.0", - "description": "Compare educational standards across different states and jurisdictions using Knowledge Graph REST API", - "main": "compare-standards.js", - "scripts": { - "start": "node compare-standards.js", - "test": "echo \"Error: no test specified\" && exit 1" - }, - "dependencies": { - "dotenv": "^16.3.1" - }, - "keywords": [ - "education", - "standards", - "knowledge-graph", - "comparison", - "analysis", - "rest-api" - ], - "author": "", - "license": "ISC" -} diff --git a/tutorials/compare_standards/python/.env.example b/tutorials/compare_standards/python/.env.example deleted file mode 100644 index 3c86715..0000000 --- a/tutorials/compare_standards/python/.env.example +++ /dev/null @@ -1,3 +0,0 @@ -# Knowledge Graph API credentials - get these from the Learning Commons Platform -API_KEY=your_api_key_here -BASE_URL=https://api.learningcommons.org/knowledge-graph/v0 diff --git a/tutorials/compare_standards/python/README.md b/tutorials/compare_standards/python/README.md deleted file mode 100644 index 5b0983a..0000000 --- a/tutorials/compare_standards/python/README.md +++ /dev/null @@ -1,43 +0,0 @@ -# Compare Standards - -Demonstrates how to use crosswalk data to compare standards between the Common Core State Standards (CCSSM) and state frameworks using the Knowledge Graph REST API, covering: -- **API Integration**: Using REST API to query crosswalk data -- **Standards Comparison**: Finding state standards that align with CCSS standards -- **Jaccard Scoring**: Understanding alignment strength using Jaccard scores -- **Learning Components**: Analyzing shared and unique learning components - -> **Note:** The API is in limited early release and is only available to some private beta users. Because the API is an early release, current users should expect occasional breaking changes. - -## Prerequisites - -- Python 3.8 or higher -- A Learning Commons Platform account -- An API key generated in the Learning Commons Platform - -## Dependencies - -- **requests**: HTTP library for API calls -- **python-dotenv**: Environment variable management - -## Quick Start - -1. **Clone and Set Up Virtual Environment**: - ```bash - git clone git@github.com:learning-commons-org/knowledge-graph.git - cd tutorials/compare_standards/python - python -m venv venv - source venv/bin/activate - pip install -r requirements.txt - ``` - -2. **Set Environment Variables** (create `.env` file): - ```bash - # Knowledge Graph API credentials - get these from the Learning Commons Platform - API_KEY=your_api_key_here - BASE_URL=https://api.learningcommons.org/knowledge-graph/v0 - ``` - -3. **Run Tutorial**: - ```bash - python compare_standards.py - ``` diff --git a/tutorials/compare_standards/python/compare_standards.py b/tutorials/compare_standards/python/compare_standards.py deleted file mode 100644 index 10c1ab0..0000000 --- a/tutorials/compare_standards/python/compare_standards.py +++ /dev/null @@ -1,290 +0,0 @@ -#!/usr/bin/env python3 -""" -Using crosswalks to compare state standards to Common Core - -This tutorial demonstrates how to use the crosswalk data in Knowledge Graph to compare -standards between the Common Core State Standards (CCSSM) and state frameworks. These -crosswalks help determine which state standards are most similar to a given CCSSM standard -and understand the similarities and differences between them. - -Crosswalks are evidence-based relationships between state standards and CCSSM standards, -derived from overlapping sets of Learning Components (LCs). Each crosswalk includes -similarity metrics, such as the Jaccard score and relative LC counts, to help interpret -how closely two standards align. -""" - -""" -================================ -CONFIGURATION & SETUP -================================ -""" - -# Dependencies -import os -import sys -import requests -from dotenv import load_dotenv - -# Load environment variables -load_dotenv() - -# Domain Constants -# Pick a CCSSM standard to find its best state standard matches -TARGET_CCSSM_STANDARD_CODE = '6.EE.B.5' # Common Core 6th grade math standard on solving equations and inequalities -TARGET_CCSSM_JURISDICTION = 'Multi-State' - -# Environment Setup -api_key = os.getenv('API_KEY') -base_url = os.getenv('BASE_URL') - -if not api_key: - print('❌ API_KEY environment variable is not set.') - sys.exit(1) - -if not base_url: - print('❌ BASE_URL environment variable is not set.') - sys.exit(1) - -# Setup headers for API requests -headers = {"x-api-key": api_key} - - -""" -================================ -HELPER FUNCTIONS -================================ -""" - -def make_api_request(endpoint, params=None): - """Make API request to Knowledge Graph API""" - try: - url = f"{base_url}{endpoint}" - response = requests.get(url, headers=headers, params=params) - response.raise_for_status() - return response.json() - except requests.exceptions.RequestException as error: - print(f'❌ Error making API request to {endpoint}: {str(error)}') - raise error - - -""" -================================ -STEP 2: FIND THE BEST-MATCHING STATE STANDARDS -================================ -""" - -def find_best_state_matches(): - """ - Find the best state standard matches for a CCSSM standard - - Returns: - tuple: (ccssm_standard, texas_matches) - """ - # Find the CCSSM standard by its statement code and jurisdiction - search_result = make_api_request( - '/academic-standards/search', - params={ - 'statementCode': TARGET_CCSSM_STANDARD_CODE, - 'jurisdiction': TARGET_CCSSM_JURISDICTION - } - ) - - ccssm_standard = search_result[0] if search_result else None - - if not ccssm_standard: - print(f'❌ CCSSM standard not found: {TARGET_CCSSM_STANDARD_CODE}') - return None, None - - ccssm_standard_uuid = ccssm_standard['caseIdentifierUUID'] - print(f'✅ Found CCSSM standard: {TARGET_CCSSM_STANDARD_CODE}') - print(f' Case UUID: {ccssm_standard_uuid}') - print(f' Description: {ccssm_standard["description"]}') - - # Get Texas standards that align with this CCSSM standard - crosswalk_result = make_api_request( - f'/academic-standards/{ccssm_standard_uuid}/crosswalks', - params={'jurisdiction': 'Texas'} - ) - - texas_matches = crosswalk_result['data'] - - if not texas_matches: - print(f'\n❌ No Texas standard matches found for {TARGET_CCSSM_STANDARD_CODE}') - return ccssm_standard, None - - # Sort by Jaccard score (highest first) - texas_matches_sorted = sorted(texas_matches, key=lambda x: x['jaccard'], reverse=True) - - print(f'\n✅ Found {len(texas_matches_sorted)} Texas standard matches') - print(f'\n📊 Top Texas match (highest Jaccard score):') - - top_match = texas_matches_sorted[0] - print(f' Statement Code: {top_match["statementCode"]}') - print(f' Jaccard Score: {top_match["jaccard"]:.4f}') - print(f' Shared LC Count: {top_match["sharedLCCount"]}') - print(f' State LC Count: {top_match["stateLCCount"]}') - print(f' CCSS LC Count: {top_match["ccssLCCount"]}') - - return ccssm_standard, texas_matches_sorted - - -""" -================================ -STEP 3: INTERPRET THE RELATIONSHIP METRICS -================================ -""" - -def interpret_relationship_metrics(matches): - """ - Interpret the relationship metrics for crosswalk matches - - Purpose: Each crosswalk relationship carries additional context about the degree - of overlap: - - sharedLCCount shows how many deconstructed skills are shared - - stateLCCount and ccssLCCount show how many total skills support each standard - - Together with the Jaccard score, these counts help interpret the strength and - balance of the overlap - - Args: - matches (list): Crosswalk matches from Step 2 - """ - if not matches: - return - - print(f'\n📊 INTERPRETATION OF TOP MATCHES:\n') - - # Show top 5 matches with interpretation - for idx, match in enumerate(matches[:5], 1): - jaccard = match['jaccard'] - state_lc = match['stateLCCount'] - ccss_lc = match['ccssLCCount'] - shared_lc = match['sharedLCCount'] - - print(f'Match #{idx}:') - print(f' Statement Code: {match["statementCode"]}') - print(f' Jaccard Score: {jaccard:.4f}') - print(f' State LC Count: {state_lc}') - print(f' CCSS LC Count: {ccss_lc}') - print(f' Shared LC Count: {shared_lc}') - - # Interpret the metrics - if jaccard >= 0.9: - interpretation = "Very strong overlap; standards share nearly all skills" - elif jaccard >= 0.7: - interpretation = "Strong overlap; substantial shared skills" - elif jaccard >= 0.5: - interpretation = "Moderate overlap; many shared skills" - elif jaccard >= 0.3: - interpretation = "Partial overlap; some shared skills" - else: - interpretation = "Weak overlap; few shared skills" - - # Check scope balance - if abs(state_lc - ccss_lc) <= 2: - scope_note = "Both standards have similar scope" - elif state_lc > ccss_lc: - scope_note = "State standard covers more content" - else: - scope_note = "CCSS standard covers more content" - - print(f' Interpretation: {interpretation}') - print(f' Scope: {scope_note}') - print() - - -""" -================================ -STEP 4: INSPECT SHARED LEARNING COMPONENTS -================================ -""" - -def show_shared_learning_components(ccssm_standard, top_match): - """ - Show shared learning components between CCSS and state standards - - Purpose: Now that you have crosswalk pairs (CCSSM → state), you can see the - actual skills behind each match by retrieving the Learning Components that - support each standard. We'll then identify which LCs are shared (the evidence - behind the crosswalk) and which are unique to each standard. - - Args: - ccssm_standard (dict): CCSSM standard from Step 2 - top_match (dict): Top Texas match from Step 2 - """ - ccssm_standard_uuid = ccssm_standard['caseIdentifierUUID'] - state_standard_uuid = top_match['caseIdentifierUUID'] - - # Get LCs that support the CCSS standard - ccss_lc_result = make_api_request( - f'/academic-standards/{ccssm_standard_uuid}/learning-components' - ) - ccss_lcs = ccss_lc_result['data'] - - # Get LCs that support the state standard - state_lc_result = make_api_request( - f'/academic-standards/{state_standard_uuid}/learning-components' - ) - state_lcs = state_lc_result['data'] - - # Create sets of LC identifiers for comparison - ccss_lc_ids = {lc['identifier'] for lc in ccss_lcs} - state_lc_ids = {lc['identifier'] for lc in state_lcs} - - # Find shared and unique LCs - shared_lc_ids = ccss_lc_ids & state_lc_ids - ccss_only_ids = ccss_lc_ids - state_lc_ids - state_only_ids = state_lc_ids - ccss_lc_ids - - # Get LC descriptions - shared_lcs = [lc for lc in ccss_lcs if lc['identifier'] in shared_lc_ids] - ccss_only_lcs = [lc for lc in ccss_lcs if lc['identifier'] in ccss_only_ids] - state_only_lcs = [lc for lc in state_lcs if lc['identifier'] in state_only_ids] - - print(f'\n✅ LEARNING COMPONENTS ANALYSIS:') - print(f'CCSS Standard: {ccssm_standard["statementCode"]}') - print(f'State Standard: {top_match["statementCode"]}') - print() - - print(f'📊 SHARED LEARNING COMPONENTS ({len(shared_lcs)}):') - for idx, lc in enumerate(shared_lcs, 1): - print(f' ✅ {idx}. {lc["description"]}') - print() - - print(f'📊 CCSS-ONLY LEARNING COMPONENTS ({len(ccss_only_lcs)}):') - for idx, lc in enumerate(ccss_only_lcs, 1): - print(f' ➕ {idx}. {lc["description"]}') - print() - - print(f'📊 STATE-ONLY LEARNING COMPONENTS ({len(state_only_lcs)}):') - for idx, lc in enumerate(state_only_lcs, 1): - print(f' ➖ {idx}. {lc["description"]}') - print() - - -""" -================================ -MAIN EXECUTION -================================ -""" - -def main(): - """ - Main execution function - orchestrates all tutorial steps - """ - print('\n=== USING CROSSWALKS TO COMPARE STATE STANDARDS TO COMMON CORE ===\n') - - print('🔄 Step 2: Find the best-matching state standards for a CCSSM standard...\n') - ccssm_standard, matches = find_best_state_matches() - - if matches: - print('\n' + '='*70) - print('🔄 Step 3: Interpret the relationship metrics...') - interpret_relationship_metrics(matches) - - print('='*70) - print('🔄 Step 4: Inspect shared learning components...') - show_shared_learning_components(ccssm_standard, matches[0]) - - -if __name__ == '__main__': - main() diff --git a/tutorials/compare_standards/python/requirements.txt b/tutorials/compare_standards/python/requirements.txt deleted file mode 100644 index fdbb17d..0000000 --- a/tutorials/compare_standards/python/requirements.txt +++ /dev/null @@ -1,5 +0,0 @@ -# HTTP requests -requests>=2.31.0 - -# Environment variable management -python-dotenv>=1.0.0 diff --git a/tutorials/generate_prereq_practice/js/.env.example b/tutorials/generate_prereq_practice/js/.env.example deleted file mode 100644 index 533ba61..0000000 --- a/tutorials/generate_prereq_practice/js/.env.example +++ /dev/null @@ -1,6 +0,0 @@ -# Knowledge Graph API credentials - get these from the Learning Commons Platform -API_KEY=your_api_key_here -BASE_URL=https://api.learningcommons.org/knowledge-graph/v0 - -# OpenAI API key for generating practice questions -OPENAI_API_KEY=your_openai_api_key_here diff --git a/tutorials/generate_prereq_practice/js/README.md b/tutorials/generate_prereq_practice/js/README.md deleted file mode 100644 index c61fb54..0000000 --- a/tutorials/generate_prereq_practice/js/README.md +++ /dev/null @@ -1,45 +0,0 @@ -# Generate Prerequisite Practice - -Demonstrates how to generate prerequisite-based practice questions using the Knowledge Graph REST API, covering: -- **API Integration**: Using REST API to query standards and learning progressions -- **Prerequisite Analysis**: Finding standards that build towards a target standard -- **Learning Components**: Discovering granular learning components that support standards -- **Practice Generation**: Creating structured practice questions based on prerequisite knowledge using AI - -> **Note:** The API is in limited early release and is only available to some private beta users. Because the API is an early release, current users should expect occasional breaking changes. - -## Prerequisites - -- Node.js 18 or higher (for native fetch API support) -- A Learning Commons Platform account -- An API key generated in the Learning Commons Platform -- OpenAI API key - -## Dependencies - -- **openai**: OpenAI API for generating practice questions -- **dotenv**: Environment variable management - -## Quick Start - -1. **Clone and Install**: - ```bash - git clone git@github.com:learning-commons-org/knowledge-graph.git - cd tutorials/generate_prereq_practice/js - npm install - ``` - -2. **Set Environment Variables** (create `.env` file): - ```bash - # Knowledge Graph API credentials - get these from the Learning Commons Platform - API_KEY=your_api_key_here - BASE_URL=https://api.learningcommons.org/knowledge-graph/v0 - - # OpenAI API key for generating practice questions - OPENAI_API_KEY=your_openai_api_key_here - ``` - -3. **Run Tutorial**: - ```bash - npm start - ``` diff --git a/tutorials/generate_prereq_practice/js/generate-prereq-practice.js b/tutorials/generate_prereq_practice/js/generate-prereq-practice.js deleted file mode 100644 index 575dbe6..0000000 --- a/tutorials/generate_prereq_practice/js/generate-prereq-practice.js +++ /dev/null @@ -1,253 +0,0 @@ -/* ================================ - CONFIGURATION & SETUP - ================================ */ - -// Dependencies -const OpenAI = require('openai'); -require('dotenv').config(); - -// Constants -const GENERATE_PRACTICE = true; -const TARGET_CODE = '6.NS.B.4'; -// OpenAI configuration -const OPENAI_MODEL = 'gpt-4'; -const OPENAI_TEMPERATURE = 0.7; - -// Environment setup -const apiKey = process.env.API_KEY; -const baseUrl = process.env.BASE_URL; - -if (!apiKey) { - console.error('❌ API_KEY environment variable is not set.'); - process.exit(1); -} - -if (!baseUrl) { - console.error('❌ BASE_URL environment variable is not set.'); - process.exit(1); -} - -const openai = new OpenAI({ - apiKey: process.env.OPENAI_API_KEY, -}); - -/* ================================ - HELPER FUNCTIONS - ================================ */ - -async function makeApiRequest(endpoint, params = {}) { - try { - const url = new URL(`${baseUrl}${endpoint}`); - - // Handle array parameters (like gradeLevel) - Object.entries(params).forEach(([key, value]) => { - if (Array.isArray(value)) { - value.forEach(v => url.searchParams.append(key, v)); - } else { - url.searchParams.append(key, value); - } - }); - - const response = await fetch(url.toString(), { - method: 'GET', - headers: { - 'x-api-key': apiKey - } - }); - - if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`); - } - - return await response.json(); - } catch (error) { - console.error(`❌ Error making API request to ${endpoint}: ${error.message}`); - throw error; - } -} - -/* ================================ - STEP 2: GET PREREQUISITE STANDARDS - ================================ */ - -async function getStandardAndPrerequisites() { - // Find the target standard by statement code - const searchResult = await makeApiRequest('/academic-standards/search', { - statementCode: TARGET_CODE, - jurisdiction: 'Multi-State' - }); - - const targetStandard = searchResult[0] || null; - - if (!targetStandard) { - console.error(`❌ No standard found for ${TARGET_CODE}`); - return null; - } - - console.log(`✅ Found standard ${TARGET_CODE}:`); - console.log(` UUID: ${targetStandard.caseIdentifierUUID}`); - console.log(` Description: ${targetStandard.description}`); - - // Get prerequisites - const prereqResult = await makeApiRequest( - `/academic-standards/${targetStandard.caseIdentifierUUID}/prerequisites` - ); - - const prerequisiteStandards = prereqResult.data; - console.log(`✅ Found ${prerequisiteStandards.length} prerequisite(s):`); - prerequisiteStandards.forEach(prereq => { - const description = prereq.description || 'No description'; - const truncated = description.length > 80 ? description.substring(0, 80) + '...' : description; - console.log(` ${prereq.statementCode}: ${truncated}`); - }); - - return { targetStandard, prerequisiteStandards }; -} - -async function getLearningComponentsForPrerequisites(prerequisiteStandards) { - const prerequisiteLearningComponents = []; - - for (const prereq of prerequisiteStandards) { - const lcResult = await makeApiRequest( - `/academic-standards/${prereq.caseIdentifierUUID}/learning-components` - ); - - for (const lc of lcResult.data) { - prerequisiteLearningComponents.push({ - caseIdentifierUUID: prereq.caseIdentifierUUID, - statementCode: prereq.statementCode, - standardDescription: prereq.description, - learningComponentDescription: lc.description - }); - } - } - - console.log(`✅ Found ${prerequisiteLearningComponents.length} supporting learning components for prerequisites:`); - prerequisiteLearningComponents.slice(0, 5).forEach(lc => { - const description = lc.learningComponentDescription || 'No description'; - const truncated = description.length > 80 ? description.substring(0, 80) + '...' : description; - console.log(` ${truncated}`); - }); - - return prerequisiteLearningComponents; -} - -/* ================================ - STEP 3: GENERATE PRACTICE - ================================ */ - -function packageContextData(targetStandard, prerequisiteLearningComponents) { - /* Package the standards and learning components data for text generation - * This creates a structured context that can be used for generating practice questions - */ - - const standardsMap = new Map(); - - // Group learning components by standard for context - for (const row of prerequisiteLearningComponents) { - if (!standardsMap.has(row.caseIdentifierUUID)) { - standardsMap.set(row.caseIdentifierUUID, { - statementCode: row.statementCode, - description: row.standardDescription || '(no statement)', - supportingLearningComponents: [] - }); - } - - standardsMap.get(row.caseIdentifierUUID).supportingLearningComponents.push({ - description: row.learningComponentDescription || '(no description)' - }); - } - - const fullStandardsContext = { - targetStandard: { - statementCode: targetStandard.statementCode, - description: targetStandard.description || '(no statement)' - }, - prereqStandards: Array.from(standardsMap.values()) - }; - - console.log('✅ Packaged full standards context for text generation'); - return fullStandardsContext; -} - -async function generatePractice(fullStandardsContext) { - console.log(`🔄 Generating practice questions for ${fullStandardsContext.targetStandard.statementCode}...`); - - try { - // Build prompt inline - let prerequisiteText = ''; - for (const prereq of fullStandardsContext.prereqStandards) { - prerequisiteText += `- ${prereq.statementCode}: ${prereq.description}\n`; - prerequisiteText += ' Supporting Learning Components:\n'; - for (const lc of prereq.supportingLearningComponents) { - prerequisiteText += ` • ${lc.description}\n`; - } - } - - const prompt = `You are a math tutor helping middle school students. Based on the following information, generate 3 practice questions for the target standard. Questions should help reinforce the key concept and build on prerequisite knowledge. - -Target Standard: -- ${fullStandardsContext.targetStandard.statementCode}: ${fullStandardsContext.targetStandard.description} - -Prerequisite Standards & Supporting Learning Components: -${prerequisiteText}`; - - const response = await openai.chat.completions.create({ - model: OPENAI_MODEL, - messages: [ - { role: 'system', content: 'You are an expert middle school math tutor.' }, - { role: 'user', content: prompt } - ], - temperature: OPENAI_TEMPERATURE - }); - - const practiceQuestions = response.choices[0].message.content.trim(); - - console.log(`✅ Generated practice questions:\n`); - console.log(practiceQuestions); - - return { - aiGenerated: practiceQuestions, - targetStandard: fullStandardsContext.targetStandard.statementCode, - prerequisiteCount: fullStandardsContext.prereqStandards.length - }; - } catch (err) { - console.error('❌ Error generating practice questions:', err.message); - throw err; - } -} - -/* ================================ - MAIN EXECUTION - ================================ */ - -async function main() { - console.log('\n=== GENERATE PREREQUISITE PRACTICE TUTORIAL ===\n'); - - console.log('🔄 Step 2: Get prerequisite standards for 6.NS.B.4...\n'); - - // Get target standard and prerequisites - const prerequisiteData = await getStandardAndPrerequisites(); - - if (!prerequisiteData) { - console.error('❌ Failed to find prerequisite data'); - return; - } - - const { targetStandard, prerequisiteStandards } = prerequisiteData; - - // Get learning components for prerequisites - console.log(); - const prerequisiteLearningComponents = await getLearningComponentsForPrerequisites(prerequisiteStandards); - - console.log('\n🔄 Step 3: Generate practice problems...\n'); - const fullStandardsContext = packageContextData(targetStandard, prerequisiteLearningComponents); - - if (GENERATE_PRACTICE) { - await generatePractice(fullStandardsContext); - } else { - console.log('🚫 Practice question generation disabled'); - } -} - -main().catch(console.error); diff --git a/tutorials/generate_prereq_practice/js/package-lock.json b/tutorials/generate_prereq_practice/js/package-lock.json deleted file mode 100644 index 0069616..0000000 --- a/tutorials/generate_prereq_practice/js/package-lock.json +++ /dev/null @@ -1,479 +0,0 @@ -{ - "name": "generate-prereq-practice", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "generate-prereq-practice", - "version": "1.0.0", - "license": "ISC", - "dependencies": { - "dotenv": "^16.3.1", - "openai": "^4.0.0" - } - }, - "node_modules/@types/node": { - "version": "24.3.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.3.0.tgz", - "integrity": "sha512-aPTXCrfwnDLj4VvXrm+UUCQjNEvJgNA8s5F1cvwQU+3KNltTOkBm1j30uNLyqqPNe7gE3KFzImYoZEfLhp4Yow==", - "license": "MIT", - "dependencies": { - "undici-types": "~7.10.0" - } - }, - "node_modules/@types/node-fetch": { - "version": "2.6.13", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.13.tgz", - "integrity": "sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "form-data": "^4.0.4" - } - }, - "node_modules/abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "license": "MIT", - "dependencies": { - "event-target-shim": "^5.0.0" - }, - "engines": { - "node": ">=6.5" - } - }, - "node_modules/agentkeepalive": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz", - "integrity": "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==", - "license": "MIT", - "dependencies": { - "humanize-ms": "^1.2.1" - }, - "engines": { - "node": ">= 8.0.0" - } - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "license": "MIT" - }, - "node_modules/call-bind-apply-helpers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "license": "MIT", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/dotenv": { - "version": "16.6.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", - "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://dotenvx.com" - } - }, - "node_modules/dunder-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-define-property": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-object-atoms": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-set-tostringtag": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", - "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/form-data": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", - "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", - "license": "MIT", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "es-set-tostringtag": "^2.1.0", - "hasown": "^2.0.2", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/form-data-encoder": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz", - "integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==", - "license": "MIT" - }, - "node_modules/formdata-node": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-4.4.1.tgz", - "integrity": "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==", - "license": "MIT", - "dependencies": { - "node-domexception": "1.0.0", - "web-streams-polyfill": "4.0.0-beta.3" - }, - "engines": { - "node": ">= 12.20" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-intrinsic": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "function-bind": "^1.1.2", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "math-intrinsics": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "license": "MIT", - "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/gopd": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "license": "MIT", - "dependencies": { - "has-symbols": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/humanize-ms": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", - "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", - "license": "MIT", - "dependencies": { - "ms": "^2.0.0" - } - }, - "node_modules/math-intrinsics": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/node-domexception": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", - "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", - "deprecated": "Use your platform's native DOMException instead", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - }, - { - "type": "github", - "url": "https://paypal.me/jimmywarting" - } - ], - "license": "MIT", - "engines": { - "node": ">=10.5.0" - } - }, - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "license": "MIT", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/openai": { - "version": "4.104.0", - "resolved": "https://registry.npmjs.org/openai/-/openai-4.104.0.tgz", - "integrity": "sha512-p99EFNsA/yX6UhVO93f5kJsDRLAg+CTA2RBqdHK4RtK8u5IJw32Hyb2dTGKbnnFmnuoBv5r7Z2CURI9sGZpSuA==", - "license": "Apache-2.0", - "dependencies": { - "@types/node": "^18.11.18", - "@types/node-fetch": "^2.6.4", - "abort-controller": "^3.0.0", - "agentkeepalive": "^4.2.1", - "form-data-encoder": "1.7.2", - "formdata-node": "^4.3.2", - "node-fetch": "^2.6.7" - }, - "bin": { - "openai": "bin/cli" - }, - "peerDependencies": { - "ws": "^8.18.0", - "zod": "^3.23.8" - }, - "peerDependenciesMeta": { - "ws": { - "optional": true - }, - "zod": { - "optional": true - } - } - }, - "node_modules/openai/node_modules/@types/node": { - "version": "18.19.123", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.123.tgz", - "integrity": "sha512-K7DIaHnh0mzVxreCR9qwgNxp3MH9dltPNIEddW9MYUlcKAzm+3grKNSTe2vCJHI1FaLpvpL5JGJrz1UZDKYvDg==", - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/openai/node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "license": "MIT" - }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "license": "MIT" - }, - "node_modules/undici-types": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.10.0.tgz", - "integrity": "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==", - "license": "MIT" - }, - "node_modules/web-streams-polyfill": { - "version": "4.0.0-beta.3", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", - "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==", - "license": "MIT", - "engines": { - "node": ">= 14" - } - }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "license": "BSD-2-Clause" - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "license": "MIT", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - } - } -} diff --git a/tutorials/generate_prereq_practice/js/package.json b/tutorials/generate_prereq_practice/js/package.json deleted file mode 100644 index e1104d6..0000000 --- a/tutorials/generate_prereq_practice/js/package.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "name": "generate-prereq-practice", - "version": "1.0.0", - "description": "Generate prerequisite practice questions using Knowledge Graph REST API", - "main": "generate-prereq-practice.js", - "scripts": { - "start": "node generate-prereq-practice.js", - "test": "echo \"Error: no test specified\" && exit 1" - }, - "dependencies": { - "openai": "^4.0.0", - "dotenv": "^16.3.1" - }, - "keywords": [ - "education", - "prerequisites", - "knowledge-graph", - "practice-questions", - "ai", - "rest-api" - ], - "author": "", - "license": "ISC" -} diff --git a/tutorials/generate_prereq_practice/python/.env.example b/tutorials/generate_prereq_practice/python/.env.example deleted file mode 100644 index 533ba61..0000000 --- a/tutorials/generate_prereq_practice/python/.env.example +++ /dev/null @@ -1,6 +0,0 @@ -# Knowledge Graph API credentials - get these from the Learning Commons Platform -API_KEY=your_api_key_here -BASE_URL=https://api.learningcommons.org/knowledge-graph/v0 - -# OpenAI API key for generating practice questions -OPENAI_API_KEY=your_openai_api_key_here diff --git a/tutorials/generate_prereq_practice/python/README.md b/tutorials/generate_prereq_practice/python/README.md deleted file mode 100644 index d3cc33f..0000000 --- a/tutorials/generate_prereq_practice/python/README.md +++ /dev/null @@ -1,48 +0,0 @@ -# Generate Prerequisite Practice - -Demonstrates how to generate prerequisite-based practice questions using the Knowledge Graph REST API, covering: -- **API Integration**: Using REST API to query standards and learning progressions -- **Prerequisite Analysis**: Finding standards that build towards a target standard -- **Learning Components**: Discovering granular learning components that support standards -- **Practice Generation**: Creating structured practice questions based on prerequisite knowledge using AI - -> **Note:** The API is in limited early release and is only available to some private beta users. Because the API is an early release, current users should expect occasional breaking changes. - -## Prerequisites - -- Python 3.8 or higher -- A Learning Commons Platform account -- An API key generated in the Learning Commons Platform -- OpenAI API key - -## Dependencies - -- **requests**: HTTP library for API calls -- **openai**: OpenAI API for generating practice questions -- **python-dotenv**: Environment variable management - -## Quick Start - -1. **Clone and Set Up Virtual Environment**: - ```bash - git clone git@github.com:learning-commons-org/knowledge-graph.git - cd tutorials/generate_prereq_practice/python - python -m venv venv - source venv/bin/activate - pip install -r requirements.txt - ``` - -2. **Set Environment Variables** (create `.env` file): - ```bash - # Knowledge Graph API credentials - get these from the Learning Commons Platform - API_KEY=your_api_key_here - BASE_URL=https://api.learningcommons.org/knowledge-graph/v0 - - # OpenAI API key for generating practice questions - OPENAI_API_KEY=your_openai_api_key_here - ``` - -3. **Run Tutorial**: - ```bash - python generate_prereq_practice.py - ``` diff --git a/tutorials/generate_prereq_practice/python/generate_prereq_practice.py b/tutorials/generate_prereq_practice/python/generate_prereq_practice.py deleted file mode 100644 index 427b62a..0000000 --- a/tutorials/generate_prereq_practice/python/generate_prereq_practice.py +++ /dev/null @@ -1,254 +0,0 @@ -#!/usr/bin/env python3 -""" -================================ -CONFIGURATION & SETUP -================================ -""" - -# Dependencies -import os -import sys -import requests -from dotenv import load_dotenv -from openai import OpenAI - -# Load environment variables -load_dotenv() - -# Domain Constants -GENERATE_PRACTICE = True -TARGET_CODE = '6.NS.B.4' -# OpenAI configuration -OPENAI_MODEL = 'gpt-4' -OPENAI_TEMPERATURE = 0.7 - -# Environment Setup -api_key = os.getenv('API_KEY') -base_url = os.getenv('BASE_URL') - -if not api_key: - print('❌ API_KEY environment variable is not set.') - sys.exit(1) - -if not base_url: - print('❌ BASE_URL environment variable is not set.') - sys.exit(1) - -openai_client = OpenAI( - api_key=os.getenv('OPENAI_API_KEY') -) - -# Setup headers for API requests -headers = {"x-api-key": api_key} - - -""" -================================ -HELPER FUNCTIONS -================================ -""" - -def make_api_request(endpoint, params=None): - """Make API request to Knowledge Graph API""" - try: - url = f"{base_url}{endpoint}" - response = requests.get(url, headers=headers, params=params) - response.raise_for_status() - return response.json() - except requests.exceptions.RequestException as error: - print(f'❌ Error making API request to {endpoint}: {str(error)}') - raise error - - -""" -================================ -STEP 2: GET PREREQUISITE STANDARDS -================================ -""" - -def get_standard_and_prerequisites(): - """Find the target standard and its prerequisites""" - - # Find the target standard by statement code - search_result = make_api_request( - '/academic-standards/search', - params={ - 'statementCode': TARGET_CODE, - 'jurisdiction': 'Multi-State' - } - ) - - target_standard = search_result[0] if search_result else None - - if not target_standard: - print(f'❌ No standard found for {TARGET_CODE}') - return None - - print(f'✅ Found standard {TARGET_CODE}:') - print(f' UUID: {target_standard["caseIdentifierUUID"]}') - print(f' Description: {target_standard["description"]}') - - # Get prerequisites - prereq_result = make_api_request( - f'/academic-standards/{target_standard["caseIdentifierUUID"]}/prerequisites' - ) - - prerequisite_standards = prereq_result['data'] - print(f'✅ Found {len(prerequisite_standards)} prerequisite(s):') - for prereq in prerequisite_standards: - description = prereq.get('description', 'No description') - truncated = description[:80] + '...' if len(description) > 80 else description - print(f' {prereq["statementCode"]}: {truncated}') - - return {'target_standard': target_standard, 'prerequisite_standards': prerequisite_standards} - - -def get_learning_components_for_prerequisites(prerequisite_standards): - """Get learning components for each prerequisite standard""" - - prerequisite_learning_components = [] - - for prereq in prerequisite_standards: - lc_result = make_api_request( - f'/academic-standards/{prereq["caseIdentifierUUID"]}/learning-components' - ) - - for lc in lc_result['data']: - prerequisite_learning_components.append({ - 'caseIdentifierUUID': prereq['caseIdentifierUUID'], - 'statementCode': prereq['statementCode'], - 'standardDescription': prereq['description'], - 'learningComponentDescription': lc['description'] - }) - - print(f'✅ Found {len(prerequisite_learning_components)} supporting learning components for prerequisites:') - for lc in prerequisite_learning_components[:5]: - description = lc.get('learningComponentDescription', 'No description') - truncated = description[:80] + '...' if len(description) > 80 else description - print(f' {truncated}') - - return prerequisite_learning_components - - -""" -================================ -STEP 3: GENERATE PRACTICE -================================ -""" - -def package_context_data(target_standard, prerequisite_learning_components): - """ - Package the standards and learning components data for text generation - This creates a structured context that can be used for generating practice questions - """ - - standards_map = {} - - # Group learning components by standard for context - for row in prerequisite_learning_components: - case_id = row['caseIdentifierUUID'] - if case_id not in standards_map: - standards_map[case_id] = { - 'statementCode': row['statementCode'], - 'description': row['standardDescription'] or '(no statement)', - 'supportingLearningComponents': [] - } - - standards_map[case_id]['supportingLearningComponents'].append({ - 'description': row['learningComponentDescription'] or '(no description)' - }) - - full_standards_context = { - 'targetStandard': { - 'statementCode': target_standard['statementCode'], - 'description': target_standard['description'] or '(no statement)' - }, - 'prereqStandards': list(standards_map.values()) - } - - print('✅ Packaged full standards context for text generation') - return full_standards_context - - -def generate_practice(full_standards_context): - """Generate practice questions using OpenAI API""" - print(f'🔄 Generating practice questions for {full_standards_context["targetStandard"]["statementCode"]}...') - - try: - # Build prompt inline - prerequisite_text = '' - for prereq in full_standards_context['prereqStandards']: - prerequisite_text += f'- {prereq["statementCode"]}: {prereq["description"]}\n' - prerequisite_text += ' Supporting Learning Components:\n' - for lc in prereq['supportingLearningComponents']: - prerequisite_text += f' • {lc["description"]}\n' - - prompt = f"""You are a math tutor helping middle school students. Based on the following information, generate 3 practice questions for the target standard. Questions should help reinforce the key concept and build on prerequisite knowledge. - -Target Standard: -- {full_standards_context["targetStandard"]["statementCode"]}: {full_standards_context["targetStandard"]["description"]} - -Prerequisite Standards & Supporting Learning Components: -{prerequisite_text}""" - - response = openai_client.chat.completions.create( - model=OPENAI_MODEL, - messages=[ - {'role': 'system', 'content': 'You are an expert middle school math tutor.'}, - {'role': 'user', 'content': prompt} - ], - temperature=OPENAI_TEMPERATURE - ) - - practice_questions = response.choices[0].message.content.strip() - - print('✅ Generated practice questions:\n') - print(practice_questions) - - return { - 'aiGenerated': practice_questions, - 'targetStandard': full_standards_context['targetStandard']['statementCode'], - 'prerequisiteCount': len(full_standards_context['prereqStandards']) - } - except Exception as err: - print(f'❌ Error generating practice questions: {str(err)}') - raise err - - -""" -================================ -MAIN EXECUTION -================================ -""" - -def main(): - """Main execution function - orchestrates all tutorial steps""" - print('\n=== GENERATE PREREQUISITE PRACTICE TUTORIAL ===\n') - - print('🔄 Step 2: Get prerequisite standards for 6.NS.B.4...\n') - - # Get target standard and prerequisites - prerequisite_data = get_standard_and_prerequisites() - - if not prerequisite_data: - print('❌ Failed to find prerequisite data') - return - - target_standard = prerequisite_data['target_standard'] - prerequisite_standards = prerequisite_data['prerequisite_standards'] - - # Get learning components for prerequisites - print() - prerequisite_learning_components = get_learning_components_for_prerequisites(prerequisite_standards) - - print('\n🔄 Step 3: Generate practice problems...\n') - full_standards_context = package_context_data(target_standard, prerequisite_learning_components) - - if GENERATE_PRACTICE: - generate_practice(full_standards_context) - else: - print('🚫 Practice question generation disabled') - - -if __name__ == '__main__': - main() diff --git a/tutorials/generate_prereq_practice/python/requirements.txt b/tutorials/generate_prereq_practice/python/requirements.txt deleted file mode 100644 index 53c4e86..0000000 --- a/tutorials/generate_prereq_practice/python/requirements.txt +++ /dev/null @@ -1,8 +0,0 @@ -# HTTP requests -requests>=2.31.0 - -# Environment variable management -python-dotenv>=1.0.0 - -# OpenAI API for generating practice questions -openai>=1.0.0 diff --git a/tutorials/working_with_standards/js/.env.example b/tutorials/working_with_standards/js/.env.example deleted file mode 100644 index 3c86715..0000000 --- a/tutorials/working_with_standards/js/.env.example +++ /dev/null @@ -1,3 +0,0 @@ -# Knowledge Graph API credentials - get these from the Learning Commons Platform -API_KEY=your_api_key_here -BASE_URL=https://api.learningcommons.org/knowledge-graph/v0 diff --git a/tutorials/working_with_standards/js/README.md b/tutorials/working_with_standards/js/README.md deleted file mode 100644 index 8330180..0000000 --- a/tutorials/working_with_standards/js/README.md +++ /dev/null @@ -1,36 +0,0 @@ -Demonstrates how to work with state educational standards data using the Knowledge Graph REST API, covering: -- **API Integration**: Using REST API to query standards frameworks and items -- **Standards Querying**: Filtering standards by jurisdiction, grade level, and type - -> **Note:** The API is in limited early release and is only available to some private beta users. Because the API is an early release, current users should expect occasional breaking changes. - -## Prerequisites - -- Node.js 18 or higher (for native fetch API support) -- A Learning Commons Platform account -- An API key generated in the Learning Commons Platform - -## Dependencies - -- **dotenv**: Environment variable management - -## Quick Start - -1. **Clone and Install**: - ```bash - git clone git@github.com:learning-commons-org/knowledge-graph.git - cd tutorials/working_with_standards/js - npm install - ``` - -2. **Set Environment Variables** (create `.env` file): - ```bash - # Knowledge Graph API credentials - get these from the Learning Commons Platform - API_KEY=your_api_key_here - BASE_URL=https://api.learningcommons.org/knowledge-graph/v0 - ``` - -3. **Run Tutorial**: - ```bash - npm start - ``` diff --git a/tutorials/working_with_standards/js/package-lock.json b/tutorials/working_with_standards/js/package-lock.json deleted file mode 100644 index d7b435f..0000000 --- a/tutorials/working_with_standards/js/package-lock.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "name": "work-with-state-standards", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "work-with-state-standards", - "version": "1.0.0", - "license": "ISC", - "dependencies": { - "dotenv": "^16.3.1" - } - }, - "node_modules/dotenv": { - "version": "16.6.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", - "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://dotenvx.com" - } - } - } -} diff --git a/tutorials/working_with_standards/js/package.json b/tutorials/working_with_standards/js/package.json deleted file mode 100644 index df4a222..0000000 --- a/tutorials/working_with_standards/js/package.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "name": "work-with-state-standards", - "version": "1.0.0", - "description": "Working with state standards data using Knowledge Graph REST API", - "main": "work-with-state-standards.js", - "scripts": { - "start": "node work-with-state-standards.js", - "test": "echo \"Error: no test specified\" && exit 1" - }, - "dependencies": { - "dotenv": "^16.3.1" - }, - "keywords": [ - "education", - "standards", - "knowledge-graph", - "rest-api" - ], - "author": "", - "license": "ISC" -} diff --git a/tutorials/working_with_standards/js/work-with-state-standards.js b/tutorials/working_with_standards/js/work-with-state-standards.js deleted file mode 100644 index 1582f46..0000000 --- a/tutorials/working_with_standards/js/work-with-state-standards.js +++ /dev/null @@ -1,146 +0,0 @@ -/* ================================ - CONFIGURATION & SETUP - ================================ */ - -// Dependencies -require('dotenv').config(); - -// Constants -const MIDDLE_SCHOOL_GRADES = ['6', '7', '8']; - -// Environment setup -const apiKey = process.env.API_KEY; -const baseUrl = process.env.BASE_URL; - -if (!apiKey) { - console.error('❌ API_KEY environment variable is not set.'); - process.exit(1); -} - -if (!baseUrl) { - console.error('❌ BASE_URL environment variable is not set.'); - process.exit(1); -} - -/* ================================ - HELPER FUNCTIONS - ================================ */ - -async function makeApiRequest(endpoint, params = {}) { - try { - const url = new URL(`${baseUrl}${endpoint}`); - - // Handle array parameters (like gradeLevel) - Object.entries(params).forEach(([key, value]) => { - if (Array.isArray(value)) { - value.forEach(v => url.searchParams.append(key, v)); - } else { - url.searchParams.append(key, value); - } - }); - - const response = await fetch(url.toString(), { - method: 'GET', - headers: { - 'x-api-key': apiKey - } - }); - - if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`); - } - - return await response.json(); - } catch (error) { - console.error(`❌ Error making API request to ${endpoint}: ${error.message}`); - throw error; - } -} - -/* ================================ - STEP 2: QUERY FOR STANDARDS DATA - ================================ */ - -async function getCaliforniaFramework() { - const result = await makeApiRequest('/standards-frameworks', { - jurisdiction: 'California', - academicSubject: 'Mathematics' - }); - - const californiaFramework = result.data[0] || null; - - console.log('✅ Retrieved California math standards framework:'); - if (californiaFramework) { - console.log(californiaFramework); - } - - return californiaFramework; -} - -async function getMiddleSchoolStandardsGroupings(frameworkUuid) { - const result = await makeApiRequest('/academic-standards', { - standardsFrameworkCaseIdentifierUUID: frameworkUuid, - normalizedStatementType: 'Standard Grouping', - gradeLevel: MIDDLE_SCHOOL_GRADES - }); - - const groupings = result.data; - - console.log(`✅ Retrieved ${groupings.length} standard groupings for middle school math in California`); - groupings.slice(0, 5).forEach(grouping => { - const description = grouping.description || 'No description'; - const truncated = description.length > 80 ? description.substring(0, 80) + '...' : description; - console.log(` ${grouping.statementCode || 'N/A'}: ${truncated}`); - }); - - return groupings; -} - -async function getMiddleSchoolStandards(frameworkUuid) { - const result = await makeApiRequest('/academic-standards', { - standardsFrameworkCaseIdentifierUUID: frameworkUuid, - normalizedStatementType: 'Standard', - gradeLevel: MIDDLE_SCHOOL_GRADES - }); - - const standards = result.data; - - console.log(`✅ Retrieved ${standards.length} standards for California middle school mathematics`); - standards.slice(0, 5).forEach(standard => { - const description = standard.description || 'No description'; - const truncated = description.length > 80 ? description.substring(0, 80) + '...' : description; - console.log(` ${standard.statementCode || 'N/A'}: ${truncated}`); - }); - - return standards; -} - -/* ================================ - MAIN EXECUTION - ================================ */ - -async function main() { - console.log('\n=== WORKING WITH STATE STANDARDS TUTORIAL ===\n'); - - console.log('🔄 Step 2: Querying for standards data...\n'); - - // 1. Get California math standards framework - const californiaFramework = await getCaliforniaFramework(); - - if (!californiaFramework) { - console.error('❌ Could not retrieve California framework'); - process.exit(1); - } - - const frameworkUuid = californiaFramework.caseIdentifierUUID; - - // 2. Get middle school standard groupings - console.log(); - await getMiddleSchoolStandardsGroupings(frameworkUuid); - - // 3. Get middle school standards - console.log(); - await getMiddleSchoolStandards(frameworkUuid); -} - -main().catch(console.error); diff --git a/tutorials/working_with_standards/python/.env.example b/tutorials/working_with_standards/python/.env.example deleted file mode 100644 index 3c86715..0000000 --- a/tutorials/working_with_standards/python/.env.example +++ /dev/null @@ -1,3 +0,0 @@ -# Knowledge Graph API credentials - get these from the Learning Commons Platform -API_KEY=your_api_key_here -BASE_URL=https://api.learningcommons.org/knowledge-graph/v0 diff --git a/tutorials/working_with_standards/python/README.md b/tutorials/working_with_standards/python/README.md deleted file mode 100644 index 6ec508b..0000000 --- a/tutorials/working_with_standards/python/README.md +++ /dev/null @@ -1,39 +0,0 @@ -Demonstrates how to work with state educational standards data using the Knowledge Graph REST API, covering: -- **API Integration**: Using REST API to query standards frameworks and items -- **Standards Querying**: Filtering standards by jurisdiction, grade level, and type - -> **Note:** The API is in limited early release and is only available to some private beta users. Because the API is an early release, current users should expect occasional breaking changes. - -## Prerequisites - -- Python 3.8 or higher -- A Learning Commons Platform account -- An API key generated in the Learning Commons Platform - -## Dependencies - -- **requests**: HTTP library for API calls -- **python-dotenv**: Environment variable management - -## Quick Start - -1. **Clone and Set Up Virtual Environment**: - ```bash - git clone git@github.com:learning-commons-org/knowledge-graph.git - cd tutorials/working_with_standards/python - python -m venv venv - source venv/bin/activate - pip install -r requirements.txt - ``` - -2. **Set Environment Variables** (create `.env` file): - ```bash - # Knowledge Graph API credentials - get these from the Learning Commons Platform - API_KEY=your_api_key_here - BASE_URL=https://api.learningcommons.org/knowledge-graph/v0 - ``` - -3. **Run Tutorial**: - ```bash - python work_with_state_standards.py - ``` diff --git a/tutorials/working_with_standards/python/requirements.txt b/tutorials/working_with_standards/python/requirements.txt deleted file mode 100644 index fdbb17d..0000000 --- a/tutorials/working_with_standards/python/requirements.txt +++ /dev/null @@ -1,5 +0,0 @@ -# HTTP requests -requests>=2.31.0 - -# Environment variable management -python-dotenv>=1.0.0 diff --git a/tutorials/working_with_standards/python/work_with_state_standards.py b/tutorials/working_with_standards/python/work_with_state_standards.py deleted file mode 100644 index 07c0cee..0000000 --- a/tutorials/working_with_standards/python/work_with_state_standards.py +++ /dev/null @@ -1,150 +0,0 @@ -#!/usr/bin/env python3 -""" -================================ -CONFIGURATION & SETUP -================================ -""" - -# Dependencies -import os -import sys -import requests -from dotenv import load_dotenv - -# Load environment variables -load_dotenv() - -# Domain Constants -MIDDLE_SCHOOL_GRADES = ['6', '7', '8'] - -# Environment Setup -api_key = os.getenv('API_KEY') -base_url = os.getenv('BASE_URL') - -if not api_key: - print('❌ API_KEY environment variable is not set.') - sys.exit(1) - -if not base_url: - print('❌ BASE_URL environment variable is not set.') - sys.exit(1) - -# Setup headers for API requests -headers = {"x-api-key": api_key} - - -""" -================================ -HELPER FUNCTIONS -================================ -""" - -def make_api_request(endpoint, params=None): - """Make API request to Knowledge Graph API""" - try: - url = f"{base_url}{endpoint}" - response = requests.get(url, headers=headers, params=params) - response.raise_for_status() - return response.json() - except requests.exceptions.RequestException as error: - print(f'❌ Error making API request to {endpoint}: {str(error)}') - raise error - - -""" -================================ -STEP 2: QUERY FOR STANDARDS DATA -================================ -""" - -def get_california_framework(): - """Get California math standards framework""" - result = make_api_request( - '/standards-frameworks', - params={ - 'jurisdiction': 'California', - 'academicSubject': 'Mathematics' - } - ) - - california_framework = result['data'][0] if result['data'] else None - - print(f'✅ Retrieved California math standards framework:') - if california_framework: - print(california_framework) - - return california_framework - - -def get_middle_school_standards_groupings(framework_uuid): - """Get middle school standard groupings from California framework""" - params = { - 'standardsFrameworkCaseIdentifierUUID': framework_uuid, - 'normalizedStatementType': 'Standard Grouping', - 'gradeLevel': MIDDLE_SCHOOL_GRADES - } - - result = make_api_request('/academic-standards', params=params) - groupings = result['data'] - - print(f'✅ Retrieved {len(groupings)} standard groupings for middle school math in California') - for grouping in groupings[:5]: - description = grouping.get('description', 'No description') - truncated = description[:80] + '...' if len(description) > 80 else description - print(f' {grouping.get("statementCode", "N/A")}: {truncated}') - - return groupings - - -def get_middle_school_standards(framework_uuid): - """Get all standards for California middle school mathematics""" - params = { - 'standardsFrameworkCaseIdentifierUUID': framework_uuid, - 'normalizedStatementType': 'Standard', - 'gradeLevel': MIDDLE_SCHOOL_GRADES - } - - result = make_api_request('/academic-standards', params=params) - standards = result['data'] - - print(f'✅ Retrieved {len(standards)} standards for California middle school mathematics') - for standard in standards[:5]: - description = standard.get('description', 'No description') - truncated = description[:80] + '...' if len(description) > 80 else description - print(f' {standard.get("statementCode", "N/A")}: {truncated}') - - return standards - - -""" -================================ -MAIN EXECUTION -================================ -""" - -def main(): - """Main execution function - orchestrates all tutorial steps""" - print('\n=== WORKING WITH STATE STANDARDS TUTORIAL ===\n') - - print('🔄 Step 2: Querying for standards data...\n') - - # 1. Get California math standards framework - california_framework = get_california_framework() - - if not california_framework: - print('❌ Could not retrieve California framework') - sys.exit(1) - - framework_uuid = california_framework['caseIdentifierUUID'] - - # 2. Get middle school standard groupings - print() - groupings = get_middle_school_standards_groupings(framework_uuid) - - # 3. Get middle school standards - print() - standards = get_middle_school_standards(framework_uuid) - - -if __name__ == '__main__': - main()