diff --git a/README.md b/README.md new file mode 100644 index 0000000..b3e4737 --- /dev/null +++ b/README.md @@ -0,0 +1,224 @@ +# COP3530 Course Website + +A modern, responsive course dashboard built with Tailwind CSS for the COP3530 Data Structures and Algorithms course. This website provides an intuitive interface for accessing course materials, programming problems, schedules, and announcements. + +## ๐Ÿš€ Live Demo + +Visit the deployed site: [https://cop3530.github.io/cop3530.github.io](https://cop3530.github.io/cop3530.github.io) + +## ๐Ÿ“‹ Features + +### ๐ŸŽจ Modern Design +- **Responsive Dashboard**: Clean, card-based layout that works on all devices +- **Dark Mode**: Toggle between light and dark themes with system preference detection +- **Sidebar Navigation**: Persistent navigation with mobile-friendly collapsible menu +- **Tailwind CSS**: Utility-first styling with CDN delivery for rapid development + +### ๐Ÿ“š Content Management +- **Course Modules**: Browse weekly topics with links to instructional content +- **Programming Problems**: Searchable, filterable problem bank with difficulty ratings +- **Announcements**: Chronological course updates with relative timestamps +- **Schedule**: Week-by-week breakdown of topics, assignments, and due dates +- **Resources**: Development tools, textbooks, and learning materials +- **Syllabus**: Comprehensive course information and policies + +### ๐Ÿ” Interactive Features +- **Real-time Search**: Filter content across all sections +- **Tag-based Filtering**: Multi-select tag filtering for programming problems +- **Client-side Rendering**: Fast, responsive interface with vanilla JavaScript +- **Cross-repo Integration**: Links to external course repositories + +### โ™ฟ Accessibility +- **Semantic HTML**: Proper heading structure and ARIA labels +- **Keyboard Navigation**: Full keyboard accessibility +- **Screen Reader Support**: Skip links and descriptive text +- **Color Contrast**: WCAG compliant color schemes in both themes + +## ๐Ÿ— Project Structure + +``` +cop3530.github.io/ +โ”œโ”€โ”€ index.html # Dashboard home page +โ”œโ”€โ”€ modules.html # Course modules browser +โ”œโ”€โ”€ problems.html # Programming problems catalog +โ”œโ”€โ”€ announcements.html # Course announcements +โ”œโ”€โ”€ schedule.html # Weekly schedule table +โ”œโ”€โ”€ resources.html # Learning resources and tools +โ”œโ”€โ”€ syllabus.html # Course syllabus and policies +โ”œโ”€โ”€ assets/ +โ”‚ โ”œโ”€โ”€ css/ +โ”‚ โ”‚ โ””โ”€โ”€ custom.css # Custom styles and theme overrides +โ”‚ โ””โ”€โ”€ js/ +โ”‚ โ”œโ”€โ”€ components.js # Shared UI components and utilities +โ”‚ โ”œโ”€โ”€ theme.js # Dark mode management +โ”‚ โ”œโ”€โ”€ search.js # Generic search and filtering +โ”‚ โ”œโ”€โ”€ modules.js # Module page functionality +โ”‚ โ”œโ”€โ”€ problems.js # Problems page with tag filtering +โ”‚ โ””โ”€โ”€ announcements.js # Announcements rendering +โ”œโ”€โ”€ data/ +โ”‚ โ”œโ”€โ”€ modules.json # Course module data +โ”‚ โ”œโ”€โ”€ problems.json # Programming problems database +โ”‚ โ””โ”€โ”€ announcements.json # Course announcements +โ””โ”€โ”€ README.md # Project documentation +``` + +## ๐Ÿ›  Tech Stack + +- **Framework**: Static HTML/CSS/JavaScript (GitHub Pages compatible) +- **CSS Framework**: Tailwind CSS 3.x (via CDN) +- **JavaScript**: Vanilla ES6+ (no build process required) +- **Data Format**: JSON files for content management +- **Hosting**: GitHub Pages (automatic deployment) + +## ๐Ÿ“– Content Management + +### Adding New Modules + +Edit `data/modules.json` to add new course modules: + +```json +{ + "id": "week05-heaps", + "title": "Heaps and Priority Queues", + "week": 5, + "topics": ["Binary Heaps", "Priority Queues", "Heap Operations"], + "summary": "Understanding heap data structure and priority queue implementations.", + "contentUrl": "https://github.com/COP3530/Instructional-Content/tree/main/Week05", + "resources": [ + {"label": "Slides", "url": "https://github.com/..."}, + {"label": "Video Lecture", "url": "https://youtube.com/..."} + ] +} +``` + +### Adding Programming Problems + +Edit `data/problems.json` to add new coding challenges: + +```json +{ + "id": "pp-009", + "title": "Heap Sort Implementation", + "topic": "Sorting", + "difficulty": "Medium", + "tags": ["heap", "sorting", "in-place"], + "repoPath": "https://github.com/COP3530/Programming-Problems/tree/main/sorting/heap-sort", + "description": "Implement heap sort algorithm with in-place sorting and analyze time complexity." +} +``` + +### Publishing Announcements + +Edit `data/announcements.json` to add course updates: + +```json +{ + "id": "2025-02-01-midterm", + "title": "Midterm Exam Information", + "body": "

The midterm exam is scheduled for February 21st during regular class time...

", + "posted_at": "2025-02-01T09:00:00Z" +} +``` + +## ๐ŸŽฏ Usage Guide + +### For Students +1. **Dashboard**: Start here for quick access to recent announcements and upcoming content +2. **Modules**: Browse weekly course materials and access instructional content +3. **Problems**: Search and filter programming assignments by topic, difficulty, or tags +4. **Schedule**: View assignment due dates and exam schedules +5. **Resources**: Find development tools, textbooks, and study materials + +### For Instructors +1. Update JSON files in the `data/` directory to modify course content +2. All changes are automatically reflected on the live site +3. No build process required - just commit and push changes +4. Use the GitHub repository interface for quick content updates + +## ๐Ÿ”ง Development + +### Local Development +```bash +# Clone the repository +git clone https://github.com/COP3530/cop3530.github.io.git +cd cop3530.github.io + +# Serve locally (any HTTP server works) +python -m http.server 8000 +# or +npx serve . +# or +php -S localhost:8000 +``` + +### Customization +- **Colors**: Modify Tailwind color classes in HTML files +- **Styling**: Add custom CSS to `assets/css/custom.css` +- **Functionality**: Extend JavaScript files in `assets/js/` +- **Content**: Update JSON files in `data/` directory + +### Browser Support +- Modern browsers (Chrome, Firefox, Safari, Edge) +- ES6+ JavaScript features required +- CSS Grid and Flexbox support needed + +## ๐Ÿš€ Deployment + +The site automatically deploys to GitHub Pages when changes are pushed to the main branch. No build process is required. + +### Manual Deployment +1. Ensure all files are committed to the repository +2. Push changes to the main branch +3. GitHub Pages will automatically update the live site +4. Changes typically appear within 1-5 minutes + +## ๐Ÿ”ฎ Future Enhancements + +### Planned Features (TODOs) +- [ ] **Build Process**: Migrate from CDN to compiled Tailwind CSS for smaller file sizes +- [ ] **GitHub API Integration**: Fetch live content from course repositories +- [ ] **Offline Support**: Add service worker for offline functionality +- [ ] **Markdown Support**: Enable markdown rendering for announcements and syllabus +- [ ] **Search Indexing**: Implement full-text search across all content +- [ ] **Static Site Generator**: Consider migration to Eleventy or similar tool +- [ ] **Progressive Enhancement**: Enhanced features for modern browsers + +### Potential Improvements +- Assignment submission interface +- Grade tracking dashboard +- Student progress visualization +- Discussion forum integration +- Calendar sync (Google Calendar, Outlook) +- Email notification system +- Mobile app companion + +## ๐Ÿ“ Contributing + +1. Fork the repository +2. Create a feature branch (`git checkout -b feature/new-feature`) +3. Make your changes following the existing code style +4. Test your changes locally +5. Commit with descriptive messages +6. Push to your fork and create a pull request + +### Content Guidelines +- Use semantic HTML structure +- Follow existing JavaScript patterns +- Maintain consistent styling with Tailwind utilities +- Ensure accessibility standards are met +- Test on multiple devices and browsers + +## ๐Ÿ“„ License + +This project is open source and available under the [MIT License](LICENSE). + +## ๐Ÿค Support + +- **Issues**: Report bugs and request features via GitHub Issues +- **Discussions**: Join project discussions on GitHub Discussions +- **Documentation**: Comprehensive guides available in the Wiki +- **Contact**: Reach out to course instructors for academic content questions + +--- + +**Built with โค๏ธ for COP3530 students at the University of Florida** \ No newline at end of file diff --git a/announcements.html b/announcements.html new file mode 100644 index 0000000..360b9c6 --- /dev/null +++ b/announcements.html @@ -0,0 +1,245 @@ + + + + + + Announcements - COP3530 + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ + + + +
+ + + +
+ + +
+ +
+

Course Announcements

+

Stay updated with important course information and deadlines.

+
+ + +
+ +
+
+ + + +
+ +
+
+ + +
+ +
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + + \ No newline at end of file diff --git a/assets/css/custom.css b/assets/css/custom.css new file mode 100644 index 0000000..441945b --- /dev/null +++ b/assets/css/custom.css @@ -0,0 +1,118 @@ +/* Custom CSS for COP3530 Course Website */ + +/* Smooth transitions for theme switching */ +* { + transition: background-color 0.3s ease, border-color 0.3s ease, color 0.3s ease; +} + +/* Custom scrollbar styling */ +::-webkit-scrollbar { + width: 8px; + height: 8px; +} + +::-webkit-scrollbar-track { + @apply bg-gray-100 dark:bg-gray-800; +} + +::-webkit-scrollbar-thumb { + @apply bg-gray-400 dark:bg-gray-600 rounded-full; +} + +::-webkit-scrollbar-thumb:hover { + @apply bg-gray-500 dark:bg-gray-500; +} + +/* Skip to content link for accessibility */ +.skip-link { + position: absolute; + top: -40px; + left: 6px; + background: #000; + color: #fff; + padding: 8px; + text-decoration: none; + z-index: 1000; +} + +.skip-link:focus { + top: 6px; +} + +/* Custom focus styles for better accessibility */ +.focus-visible:focus-visible { + @apply outline-2 outline-offset-2 outline-blue-500; +} + +/* Print styles */ +@media print { + .sidebar, .mobile-menu-button, .theme-toggle { + display: none !important; + } + + .main-content { + margin-left: 0 !important; + } + + .print-break { + page-break-after: always; + } +} + +/* Animation for mobile sidebar */ +.sidebar-transition { + transition: transform 0.3s ease-in-out; +} + +/* Custom card hover effects */ +.card-hover { + transition: transform 0.2s ease, box-shadow 0.2s ease; +} + +.card-hover:hover { + transform: translateY(-2px); + @apply shadow-lg; +} + +/* Tag pill styling */ +.tag-pill { + @apply inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium; + cursor: pointer; + transition: all 0.2s ease; +} + +.tag-pill:hover { + transform: scale(1.05); +} + +.tag-pill.active { + @apply ring-2 ring-offset-2 ring-blue-500; +} + +/* Difficulty badges */ +.difficulty-easy { + @apply bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200; +} + +.difficulty-medium { + @apply bg-amber-100 text-amber-800 dark:bg-amber-900 dark:text-amber-200; +} + +.difficulty-hard { + @apply bg-rose-100 text-rose-800 dark:bg-rose-900 dark:text-rose-200; +} + +/* Search input styling */ +.search-input { + @apply w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent dark:bg-gray-700 dark:border-gray-600 dark:text-white; +} + +/* Loading state */ +.loading { + @apply animate-pulse; +} + +/* Error state */ +.error-message { + @apply text-red-600 dark:text-red-400 bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg p-4; +} \ No newline at end of file diff --git a/assets/js/announcements.js b/assets/js/announcements.js new file mode 100644 index 0000000..49a2354 --- /dev/null +++ b/assets/js/announcements.js @@ -0,0 +1,119 @@ +// Announcements page functionality +class AnnouncementsPage { + constructor() { + this.announcements = []; + this.searchFilter = null; + this.init(); + } + + async init() { + await this.loadAnnouncements(); + this.setupSearch(); + this.renderAnnouncements(); + } + + async loadAnnouncements() { + const { data, error } = await Components.fetchJSON('/data/announcements.json'); + + if (error) { + this.showError('Failed to load announcements. Please try again later.'); + return; + } + + // Sort announcements by date (newest first) + this.announcements = data.sort((a, b) => + new Date(b.posted_at) - new Date(a.posted_at) + ); + } + + setupSearch() { + const searchInput = document.getElementById('announcements-search'); + const container = document.getElementById('announcements-container'); + + if (!searchInput || !container) return; + + this.searchFilter = new SearchFilter({ + items: this.announcements, + searchInput: searchInput, + container: container, + renderFunction: (announcement) => this.createAnnouncementCard(announcement), + searchFields: ['title', 'body'] + }); + } + + createAnnouncementCard(announcement) { + const card = document.createElement('article'); + card.className = 'bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-6 mb-4'; + + const relativeTime = Components.formatRelativeTime(announcement.posted_at); + const formattedDate = new Date(announcement.posted_at).toLocaleDateString('en-US', { + year: 'numeric', + month: 'long', + day: 'numeric', + hour: '2-digit', + minute: '2-digit' + }); + + card.innerHTML = ` +
+

+ ${announcement.title} +

+
+ + + + +
+
+ +
+ ${announcement.body} +
+ `; + + return card; + } + + renderAnnouncements() { + const container = document.getElementById('announcements-container'); + if (!container) return; + + if (this.announcements.length === 0) { + container.innerHTML = ` +
+
+ + + +
+

No announcements available yet.

+
+ `; + return; + } + + container.innerHTML = ''; + this.announcements.forEach(announcement => { + container.appendChild(this.createAnnouncementCard(announcement)); + }); + } + + showError(message) { + const container = document.getElementById('announcements-container'); + if (container) { + container.appendChild(Components.createErrorMessage(message, { + title: 'Loading Error' + })); + } + } +} + +// Initialize when DOM is loaded +document.addEventListener('DOMContentLoaded', () => { + if (document.getElementById('announcements-container')) { + new AnnouncementsPage(); + } +}); \ No newline at end of file diff --git a/assets/js/components.js b/assets/js/components.js new file mode 100644 index 0000000..7d6c029 --- /dev/null +++ b/assets/js/components.js @@ -0,0 +1,248 @@ +// Shared UI components for COP3530 website + +const Components = { + // Generic fetch function with error handling + async fetchJSON(path) { + try { + const response = await fetch(path); + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + const data = await response.json(); + return { data, error: null }; + } catch (error) { + console.error(`Error fetching ${path}:`, error); + return { data: null, error: error.message }; + } + }, + + // Create a reusable card component + createCard(options = {}) { + const { + title = '', + subtitle = '', + content = '', + footer = '', + href = null, + className = '', + onClick = null + } = options; + + const card = document.createElement(href ? 'a' : 'div'); + + if (href) { + card.href = href; + card.target = '_blank'; + card.rel = 'noopener noreferrer'; + } + + card.className = `block bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-6 card-hover ${className}`; + + if (onClick) { + card.addEventListener('click', onClick); + card.style.cursor = 'pointer'; + } + + let cardContent = ''; + + if (title) { + cardContent += `

${title}

`; + } + + if (subtitle) { + cardContent += `

${subtitle}

`; + } + + if (content) { + cardContent += `
${content}
`; + } + + if (footer) { + cardContent += `
${footer}
`; + } + + card.innerHTML = cardContent; + return card; + }, + + // Create a badge/tag component + createBadge(text, options = {}) { + const { + variant = 'default', + size = 'sm', + clickable = false, + onClick = null, + dataTag = null + } = options; + + const badge = document.createElement(clickable ? 'button' : 'span'); + + let baseClasses = 'inline-flex items-center font-medium rounded-full'; + + // Size classes + const sizeClasses = { + xs: 'px-2 py-0.5 text-xs', + sm: 'px-2.5 py-0.5 text-xs', + md: 'px-3 py-1 text-sm', + lg: 'px-3 py-1.5 text-base' + }; + + // Variant classes + const variantClasses = { + default: 'bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-300', + primary: 'bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200', + secondary: 'bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-300', + success: 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200', + warning: 'bg-amber-100 text-amber-800 dark:bg-amber-900 dark:text-amber-200', + error: 'bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200' + }; + + badge.className = `${baseClasses} ${sizeClasses[size]} ${variantClasses[variant]}`; + + if (clickable) { + badge.className += ' tag-pill cursor-pointer hover:scale-105 transition-transform'; + badge.type = 'button'; + } + + if (dataTag) { + badge.setAttribute('data-tag', dataTag); + } + + if (onClick) { + badge.addEventListener('click', onClick); + } + + badge.textContent = text; + return badge; + }, + + // Create difficulty badge with predefined styling + createDifficultyBadge(difficulty) { + const variants = { + 'Easy': 'success', + 'Medium': 'warning', + 'Hard': 'error' + }; + + return this.createBadge(difficulty, { + variant: variants[difficulty] || 'default', + size: 'sm' + }); + }, + + // Format relative time (e.g., "3 days ago") + formatRelativeTime(dateString) { + const date = new Date(dateString); + const now = new Date(); + const diffInSeconds = Math.floor((now - date) / 1000); + + const intervals = { + year: 31536000, + month: 2592000, + week: 604800, + day: 86400, + hour: 3600, + minute: 60 + }; + + for (const [unit, seconds] of Object.entries(intervals)) { + const interval = Math.floor(diffInSeconds / seconds); + if (interval >= 1) { + return `${interval} ${unit}${interval === 1 ? '' : 's'} ago`; + } + } + + return 'Just now'; + }, + + // Create a loading skeleton + createLoadingSkeleton(lines = 3) { + const skeleton = document.createElement('div'); + skeleton.className = 'animate-pulse'; + + let content = ''; + for (let i = 0; i < lines; i++) { + const width = i === lines - 1 ? 'w-3/4' : 'w-full'; + content += `
`; + } + + skeleton.innerHTML = content; + return skeleton; + }, + + // Create an error message component + createErrorMessage(message, options = {}) { + const { + title = 'Error', + dismissible = false, + onDismiss = null + } = options; + + const errorDiv = document.createElement('div'); + errorDiv.className = 'error-message flex items-start justify-between'; + + let content = ` +
+
+ + + +
+
+

${title}

+

${message}

+
+
+ `; + + if (dismissible) { + content += ` + + `; + } + + errorDiv.innerHTML = content; + + if (dismissible && onDismiss) { + const dismissButton = errorDiv.querySelector('button'); + dismissButton?.addEventListener('click', () => { + errorDiv.remove(); + onDismiss(); + }); + } + + return errorDiv; + }, + + // Smooth scroll to element + scrollToElement(element, offset = 0) { + const elementPosition = element.offsetTop - offset; + window.scrollTo({ + top: elementPosition, + behavior: 'smooth' + }); + }, + + // Debounce utility + debounce(func, wait) { + let timeout; + return function executedFunction(...args) { + const later = () => { + clearTimeout(timeout); + func(...args); + }; + clearTimeout(timeout); + timeout = setTimeout(later, wait); + }; + } +}; + +// Export for use in other scripts +if (typeof window !== 'undefined') { + window.Components = Components; +} \ No newline at end of file diff --git a/assets/js/modules.js b/assets/js/modules.js new file mode 100644 index 0000000..9b128e7 --- /dev/null +++ b/assets/js/modules.js @@ -0,0 +1,126 @@ +// Modules page functionality +class ModulesPage { + constructor() { + this.modules = []; + this.searchFilter = null; + this.init(); + } + + async init() { + await this.loadModules(); + this.setupSearch(); + this.renderModules(); + } + + async loadModules() { + const { data, error } = await Components.fetchJSON('/data/modules.json'); + + if (error) { + this.showError('Failed to load modules. Please try again later.'); + return; + } + + this.modules = data.sort((a, b) => a.week - b.week); + } + + setupSearch() { + const searchInput = document.getElementById('module-search'); + const container = document.getElementById('modules-container'); + + if (!searchInput || !container) return; + + this.searchFilter = new SearchFilter({ + items: this.modules, + searchInput: searchInput, + container: container, + renderFunction: (module) => this.createModuleCard(module), + searchFields: ['title', 'summary', 'topics'] + }); + } + + createModuleCard(module) { + const card = document.createElement('div'); + card.className = 'bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-6 card-hover'; + + // Create topics badges + const topicBadges = module.topics.map(topic => + Components.createBadge(topic, { variant: 'primary', size: 'sm' }) + ); + + // Create resources links + const resourceLinks = module.resources.map(resource => + ` + ${resource.label} โ†’ + ` + ).join(' ยท '); + + card.innerHTML = ` +
+
+
+ Week ${module.week} +
+

${module.title}

+

${module.summary}

+
+
+ +
+ ${topicBadges.map(badge => badge.outerHTML).join('')} +
+ +
+
+ ${resourceLinks} +
+ + View Content โ†’ + +
+ `; + + // Add the topic badges to the DOM + const topicContainer = card.querySelector('.flex.flex-wrap'); + topicContainer.innerHTML = ''; + topicBadges.forEach(badge => topicContainer.appendChild(badge)); + + return card; + } + + renderModules() { + const container = document.getElementById('modules-container'); + if (!container) return; + + if (this.modules.length === 0) { + container.innerHTML = ` +
+

No modules available yet.

+
+ `; + return; + } + + container.innerHTML = ''; + this.modules.forEach(module => { + container.appendChild(this.createModuleCard(module)); + }); + } + + showError(message) { + const container = document.getElementById('modules-container'); + if (container) { + container.appendChild(Components.createErrorMessage(message, { + title: 'Loading Error' + })); + } + } +} + +// Initialize when DOM is loaded +document.addEventListener('DOMContentLoaded', () => { + if (document.getElementById('modules-container')) { + new ModulesPage(); + } +}); \ No newline at end of file diff --git a/assets/js/problems.js b/assets/js/problems.js new file mode 100644 index 0000000..ae2e7c1 --- /dev/null +++ b/assets/js/problems.js @@ -0,0 +1,244 @@ +// Problems page functionality +class ProblemsPage { + constructor() { + this.problems = []; + this.searchFilter = null; + this.selectedTags = new Set(); + this.init(); + } + + async init() { + await this.loadProblems(); + this.setupSearch(); + this.setupTagFiltering(); + this.renderProblems(); + this.renderTagCloud(); + } + + async loadProblems() { + const { data, error } = await Components.fetchJSON('/data/problems.json'); + + if (error) { + this.showError('Failed to load problems. Please try again later.'); + return; + } + + // Sort problems alphabetically by title + this.problems = data.sort((a, b) => a.title.localeCompare(b.title)); + } + + setupSearch() { + const searchInput = document.getElementById('problems-search'); + const container = document.getElementById('problems-container'); + + if (!searchInput || !container) return; + + this.searchFilter = new SearchFilter({ + items: this.problems, + searchInput: searchInput, + container: container, + renderFunction: (problem) => this.createProblemCard(problem), + searchFields: ['title', 'description', 'topic', 'tags'] + }); + } + + setupTagFiltering() { + // Override the SearchFilter's toggleTag method to use our custom logic + if (this.searchFilter) { + this.searchFilter.toggleTag = (tag) => { + if (this.selectedTags.has(tag)) { + this.selectedTags.delete(tag); + } else { + this.selectedTags.add(tag); + } + + this.updateTagUI(tag); + this.applyFilters(); + }; + } + } + + updateTagUI(tag) { + const tagElements = document.querySelectorAll(`[data-tag="${tag}"]`); + tagElements.forEach(element => { + if (this.selectedTags.has(tag)) { + element.classList.add('active'); + element.classList.add('ring-2', 'ring-offset-2', 'ring-blue-500'); + } else { + element.classList.remove('active'); + element.classList.remove('ring-2', 'ring-offset-2', 'ring-blue-500'); + } + }); + } + + applyFilters() { + let filteredProblems = this.problems; + + // Apply tag filters + if (this.selectedTags.size > 0) { + filteredProblems = this.problems.filter(problem => { + const problemTags = problem.tags || []; + return Array.from(this.selectedTags).every(tag => problemTags.includes(tag)); + }); + } + + // Apply search filter if there's a search term + const searchInput = document.getElementById('problems-search'); + if (searchInput && searchInput.value.trim()) { + const searchTerm = searchInput.value.toLowerCase().trim(); + filteredProblems = filteredProblems.filter(problem => { + return ['title', 'description', 'topic'].some(field => { + const value = problem[field]; + return value && value.toLowerCase().includes(searchTerm); + }) || (problem.tags && problem.tags.some(tag => tag.toLowerCase().includes(searchTerm))); + }); + } + + this.renderFilteredProblems(filteredProblems); + } + + createProblemCard(problem) { + const card = document.createElement('div'); + card.className = 'bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-6 card-hover'; + + // Create difficulty badge + const difficultyBadge = Components.createDifficultyBadge(problem.difficulty); + + // Create tag badges + const tagBadges = (problem.tags || []).map(tag => + Components.createBadge(tag, { + variant: 'default', + size: 'xs', + clickable: true, + dataTag: tag, + onClick: () => this.searchFilter.toggleTag(tag) + }) + ); + + card.innerHTML = ` +
+
+
+ ${problem.topic} + ${difficultyBadge.outerHTML} +
+

${problem.title}

+

${problem.description}

+
+
+ +
+ +
+ +
+ ID: ${problem.id} + + View Problem โ†’ + +
+ `; + + // Add tag badges to the DOM + const tagContainer = card.querySelector('.tag-container'); + tagBadges.forEach(badge => tagContainer.appendChild(badge)); + + return card; + } + + renderFilteredProblems(problems) { + const container = document.getElementById('problems-container'); + if (!container) return; + + container.innerHTML = ''; + + if (problems.length === 0) { + container.innerHTML = ` +
+

No problems found matching your criteria.

+ +
+ `; + return; + } + + problems.forEach(problem => { + container.appendChild(this.createProblemCard(problem)); + }); + } + + renderProblems() { + this.renderFilteredProblems(this.problems); + } + + renderTagCloud() { + const tagCloudContainer = document.getElementById('tag-cloud'); + if (!tagCloudContainer) return; + + // Collect all unique tags + const tagCounts = {}; + this.problems.forEach(problem => { + (problem.tags || []).forEach(tag => { + tagCounts[tag] = (tagCounts[tag] || 0) + 1; + }); + }); + + // Sort tags by frequency (most used first) + const sortedTags = Object.entries(tagCounts) + .sort(([,a], [,b]) => b - a) + .map(([tag]) => tag); + + tagCloudContainer.innerHTML = ''; + + if (sortedTags.length === 0) { + tagCloudContainer.innerHTML = '

No tags available.

'; + return; + } + + sortedTags.forEach(tag => { + const tagBadge = Components.createBadge(tag, { + variant: 'default', + size: 'sm', + clickable: true, + dataTag: tag, + onClick: () => this.searchFilter.toggleTag(tag) + }); + + tagCloudContainer.appendChild(tagBadge); + }); + } + + clearAllFilters() { + this.selectedTags.clear(); + document.querySelectorAll('[data-tag]').forEach(element => { + element.classList.remove('active', 'ring-2', 'ring-offset-2', 'ring-blue-500'); + }); + + const searchInput = document.getElementById('problems-search'); + if (searchInput) { + searchInput.value = ''; + } + + this.renderProblems(); + } + + showError(message) { + const container = document.getElementById('problems-container'); + if (container) { + container.appendChild(Components.createErrorMessage(message, { + title: 'Loading Error' + })); + } + } +} + +// Initialize when DOM is loaded +document.addEventListener('DOMContentLoaded', () => { + if (document.getElementById('problems-container')) { + window.problemsPage = new ProblemsPage(); + } +}); \ No newline at end of file diff --git a/assets/js/search.js b/assets/js/search.js new file mode 100644 index 0000000..d4cd47e --- /dev/null +++ b/assets/js/search.js @@ -0,0 +1,170 @@ +// Generic search and filter functionality for COP3530 website + +class SearchFilter { + constructor(options = {}) { + this.items = options.items || []; + this.searchInput = options.searchInput; + this.container = options.container; + this.renderFunction = options.renderFunction; + this.searchFields = options.searchFields || ['title']; + this.filterTags = new Set(); + this.init(); + } + + init() { + if (this.searchInput) { + this.setupSearchInput(); + } + this.render(); + } + + setupSearchInput() { + this.searchInput.addEventListener('input', (e) => { + this.search(e.target.value); + }); + } + + search(query) { + const searchTerm = query.toLowerCase().trim(); + + if (!searchTerm) { + this.render(this.items); + return; + } + + const filteredItems = this.items.filter(item => { + return this.searchFields.some(field => { + const value = this.getNestedValue(item, field); + if (Array.isArray(value)) { + return value.some(v => v.toLowerCase().includes(searchTerm)); + } + return value && value.toLowerCase().includes(searchTerm); + }); + }); + + this.render(filteredItems); + } + + filterByTags(tags) { + if (!tags || tags.length === 0) { + this.render(this.items); + return; + } + + const filteredItems = this.items.filter(item => { + const itemTags = item.tags || []; + return tags.every(tag => itemTags.includes(tag)); + }); + + this.render(filteredItems); + } + + toggleTag(tag) { + if (this.filterTags.has(tag)) { + this.filterTags.delete(tag); + } else { + this.filterTags.add(tag); + } + + this.updateTagUI(tag); + this.filterByTags(Array.from(this.filterTags)); + } + + updateTagUI(tag) { + const tagElements = document.querySelectorAll(`[data-tag="${tag}"]`); + tagElements.forEach(element => { + if (this.filterTags.has(tag)) { + element.classList.add('active'); + } else { + element.classList.remove('active'); + } + }); + } + + clearFilters() { + this.filterTags.clear(); + document.querySelectorAll('[data-tag]').forEach(element => { + element.classList.remove('active'); + }); + this.render(this.items); + } + + render(itemsToRender = this.items) { + if (!this.container || !this.renderFunction) { + console.warn('SearchFilter: container or renderFunction not provided'); + return; + } + + this.container.innerHTML = ''; + + if (itemsToRender.length === 0) { + this.container.innerHTML = ` +
+

No items found matching your criteria.

+
+ `; + return; + } + + itemsToRender.forEach(item => { + const element = this.renderFunction(item); + this.container.appendChild(element); + }); + } + + getNestedValue(obj, path) { + return path.split('.').reduce((current, key) => { + return current && current[key] !== undefined ? current[key] : null; + }, obj); + } + + updateItems(newItems) { + this.items = newItems; + this.render(); + } +} + +// Utility functions for common search scenarios +const SearchUtils = { + // Create a case-insensitive substring matcher + createSubstringMatcher: (fields) => { + return (item, query) => { + const searchTerm = query.toLowerCase(); + return fields.some(field => { + const value = item[field]; + if (Array.isArray(value)) { + return value.some(v => v.toLowerCase().includes(searchTerm)); + } + return value && value.toLowerCase().includes(searchTerm); + }); + }; + }, + + // Create a tag-based filter + createTagFilter: (tagField = 'tags') => { + return (item, selectedTags) => { + if (!selectedTags || selectedTags.length === 0) return true; + const itemTags = item[tagField] || []; + return selectedTags.every(tag => itemTags.includes(tag)); + }; + }, + + // Debounce function for search input + debounce: (func, wait) => { + let timeout; + return function executedFunction(...args) { + const later = () => { + clearTimeout(timeout); + func(...args); + }; + clearTimeout(timeout); + timeout = setTimeout(later, wait); + }; + } +}; + +// Export for use in other scripts +if (typeof window !== 'undefined') { + window.SearchFilter = SearchFilter; + window.SearchUtils = SearchUtils; +} \ No newline at end of file diff --git a/assets/js/theme.js b/assets/js/theme.js new file mode 100644 index 0000000..cf35329 --- /dev/null +++ b/assets/js/theme.js @@ -0,0 +1,83 @@ +// Theme management for COP3530 website +class ThemeManager { + constructor() { + this.theme = this.getStoredTheme() || this.getPreferredTheme(); + this.init(); + } + + init() { + this.updateTheme(); + this.setupToggleButton(); + this.setupSystemThemeListener(); + } + + getStoredTheme() { + return localStorage.getItem('theme'); + } + + getPreferredTheme() { + return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'; + } + + updateTheme() { + const html = document.documentElement; + + if (this.theme === 'dark') { + html.classList.add('dark'); + } else { + html.classList.remove('dark'); + } + + // Update toggle button icon if it exists + this.updateToggleIcon(); + } + + updateToggleIcon() { + const toggleButton = document.getElementById('theme-toggle'); + if (!toggleButton) return; + + const sunIcon = toggleButton.querySelector('.sun-icon'); + const moonIcon = toggleButton.querySelector('.moon-icon'); + + if (this.theme === 'dark') { + sunIcon?.classList.remove('hidden'); + moonIcon?.classList.add('hidden'); + } else { + sunIcon?.classList.add('hidden'); + moonIcon?.classList.remove('hidden'); + } + } + + toggle() { + this.theme = this.theme === 'dark' ? 'light' : 'dark'; + localStorage.setItem('theme', this.theme); + this.updateTheme(); + } + + setupToggleButton() { + const toggleButton = document.getElementById('theme-toggle'); + if (toggleButton) { + toggleButton.addEventListener('click', () => this.toggle()); + } + } + + setupSystemThemeListener() { + window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => { + // Only update if user hasn't manually set a preference + if (!this.getStoredTheme()) { + this.theme = e.matches ? 'dark' : 'light'; + this.updateTheme(); + } + }); + } +} + +// Initialize theme manager when DOM is loaded +document.addEventListener('DOMContentLoaded', () => { + window.themeManager = new ThemeManager(); +}); + +// Export for use in other scripts +if (typeof module !== 'undefined' && module.exports) { + module.exports = ThemeManager; +} \ No newline at end of file diff --git a/data/announcements.json b/data/announcements.json new file mode 100644 index 0000000..6d42ab2 --- /dev/null +++ b/data/announcements.json @@ -0,0 +1,32 @@ +[ + { + "id": "2025-01-10-welcome", + "title": "Welcome to COP3530 Spring 2025!", + "body": "

Welcome to Data Structures and Algorithms! This semester we'll explore fundamental computer science concepts including linear data structures, trees, graphs, sorting algorithms, and more.

Important first steps:

", + "posted_at": "2025-01-10T12:00:00Z" + }, + { + "id": "2025-01-15-setup", + "title": "Development Environment Setup", + "body": "

Please make sure you have your C++ development environment ready by next week. We recommend:

If you need help with setup, attend office hours or post in the discussion forum.

", + "posted_at": "2025-01-15T10:30:00Z" + }, + { + "id": "2025-01-18-first-assignment", + "title": "Programming Assignment 1 Released", + "body": "

The first programming assignment is now available in the Programming Problems section. This assignment covers basic algorithm analysis and implementation of simple data structures.

Due Date: February 1st, 11:59 PM

Topics: Array operations, time complexity analysis

Start early and don't hesitate to ask questions during office hours!

", + "posted_at": "2025-01-18T14:15:00Z" + }, + { + "id": "2025-01-22-office-hours", + "title": "Office Hours Update", + "body": "

Office hours for this week have been updated:

Zoom link is available in Canvas.

", + "posted_at": "2025-01-22T09:00:00Z" + }, + { + "id": "2025-01-25-quiz-reminder", + "title": "Quiz 1 This Friday", + "body": "

Don't forget about Quiz 1 this Friday covering:

The quiz will be held during regular class time and is closed-book. Review the practice problems in Module 1.

", + "posted_at": "2025-01-25T16:45:00Z" + } +] \ No newline at end of file diff --git a/data/modules.json b/data/modules.json new file mode 100644 index 0000000..b849b93 --- /dev/null +++ b/data/modules.json @@ -0,0 +1,50 @@ +[ + { + "id": "week01-intro", + "title": "Introduction & Algorithm Analysis", + "week": 1, + "topics": ["Algorithms", "Complexity"], + "summary": "Course overview, Big-O basics, introduction to algorithm analysis and complexity theory.", + "contentUrl": "https://github.com/COP3530/Instructional-Content/tree/main/Week01", + "resources": [ + {"label": "Slides", "url": "https://github.com/COP3530/Instructional-Content/blob/main/Week01/slides.pdf"}, + {"label": "Notes", "url": "https://github.com/COP3530/Instructional-Content/blob/main/Week01/notes.md"} + ] + }, + { + "id": "week02-linear", + "title": "Linear Data Structures", + "week": 2, + "topics": ["Arrays", "Lists", "Stacks", "Queues"], + "summary": "Introduction to fundamental linear data structures: arrays, linked lists, stacks, and queues.", + "contentUrl": "https://github.com/COP3530/Instructional-Content/tree/main/Week02", + "resources": [ + {"label": "Slides", "url": "https://github.com/COP3530/Instructional-Content/blob/main/Week02/slides.pdf"}, + {"label": "Code Examples", "url": "https://github.com/COP3530/Instructional-Content/tree/main/Week02/examples"} + ] + }, + { + "id": "week03-trees", + "title": "Trees and Binary Search Trees", + "week": 3, + "topics": ["Trees", "BST", "Tree Traversal"], + "summary": "Understanding tree structures, binary search trees, and various traversal algorithms.", + "contentUrl": "https://github.com/COP3530/Instructional-Content/tree/main/Week03", + "resources": [ + {"label": "Slides", "url": "https://github.com/COP3530/Instructional-Content/blob/main/Week03/slides.pdf"}, + {"label": "Visualization Tool", "url": "https://visualgo.net/en/bst"} + ] + }, + { + "id": "week04-hashing", + "title": "Hash Tables and Hash Functions", + "week": 4, + "topics": ["Hashing", "Hash Tables", "Collision Resolution"], + "summary": "Hash functions, hash tables implementation, and collision resolution techniques.", + "contentUrl": "https://github.com/COP3530/Instructional-Content/tree/main/Week04", + "resources": [ + {"label": "Slides", "url": "https://github.com/COP3530/Instructional-Content/blob/main/Week04/slides.pdf"}, + {"label": "Hash Function Demo", "url": "https://github.com/COP3530/Instructional-Content/blob/main/Week04/hash_demo.cpp"} + ] + } +] \ No newline at end of file diff --git a/data/problems.json b/data/problems.json new file mode 100644 index 0000000..01966bf --- /dev/null +++ b/data/problems.json @@ -0,0 +1,74 @@ +[ + { + "id": "pp-001", + "title": "Two Sum Variant", + "topic": "Arrays", + "difficulty": "Easy", + "tags": ["array", "hash-map", "two-pointers"], + "repoPath": "https://github.com/COP3530/Programming-Problems/tree/main/arrays/two-sum-variant", + "description": "Find two indices whose values sum to target with O(n) time complexity using hashing techniques." + }, + { + "id": "pp-002", + "title": "Balanced Parentheses", + "topic": "Stacks", + "difficulty": "Easy", + "tags": ["stack", "string", "parsing"], + "repoPath": "https://github.com/COP3530/Programming-Problems/tree/main/stacks/balanced-parentheses", + "description": "Determine if a string of parentheses is balanced using stack data structure." + }, + { + "id": "pp-003", + "title": "Binary Tree Traversal", + "topic": "Trees", + "difficulty": "Medium", + "tags": ["tree", "traversal", "recursion", "dfs"], + "repoPath": "https://github.com/COP3530/Programming-Problems/tree/main/trees/binary-tree-traversal", + "description": "Implement inorder, preorder, and postorder traversal of binary trees both recursively and iteratively." + }, + { + "id": "pp-004", + "title": "Hash Table Implementation", + "topic": "Hashing", + "difficulty": "Medium", + "tags": ["hash-table", "collision-resolution", "implementation"], + "repoPath": "https://github.com/COP3530/Programming-Problems/tree/main/hashing/hash-table-impl", + "description": "Build a hash table from scratch with chaining collision resolution and dynamic resizing." + }, + { + "id": "pp-005", + "title": "Graph Shortest Path", + "topic": "Graphs", + "difficulty": "Hard", + "tags": ["graph", "dijkstra", "shortest-path", "priority-queue"], + "repoPath": "https://github.com/COP3530/Programming-Problems/tree/main/graphs/shortest-path", + "description": "Implement Dijkstra's algorithm to find shortest paths in weighted graphs." + }, + { + "id": "pp-006", + "title": "Merge Sort Implementation", + "topic": "Sorting", + "difficulty": "Medium", + "tags": ["sorting", "divide-conquer", "merge-sort"], + "repoPath": "https://github.com/COP3530/Programming-Problems/tree/main/sorting/merge-sort", + "description": "Implement merge sort algorithm with O(n log n) time complexity and analyze space usage." + }, + { + "id": "pp-007", + "title": "AVL Tree Operations", + "topic": "Trees", + "difficulty": "Hard", + "tags": ["avl-tree", "self-balancing", "rotations"], + "repoPath": "https://github.com/COP3530/Programming-Problems/tree/main/trees/avl-tree", + "description": "Implement a self-balancing AVL tree with insertion, deletion, and rotation operations." + }, + { + "id": "pp-008", + "title": "Dynamic Programming - Knapsack", + "topic": "Dynamic Programming", + "difficulty": "Hard", + "tags": ["dynamic-programming", "optimization", "knapsack"], + "repoPath": "https://github.com/COP3530/Programming-Problems/tree/main/dp/knapsack", + "description": "Solve the 0/1 knapsack problem using dynamic programming with space optimization." + } +] \ No newline at end of file diff --git a/index.html b/index.html index 6dab14a..cfb8c0f 100644 --- a/index.html +++ b/index.html @@ -1,3 +1,379 @@ - -Test2 + + + + + + COP3530 - Data Structures and Algorithms + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ + + + +
+ + + +
+ + +
+ +
+
+

Welcome to COP3530

+

Data Structures and Algorithms โ€ข Spring 2025

+

Master fundamental computer science concepts including linear data structures, trees, graphs, sorting algorithms, and algorithmic analysis.

+ + +
+
+ + +
+ +
+
+

Latest Announcements

+ View all +
+
+ +
+
+ + +
+
+

Next Module

+ View all +
+
+ +
+
+ + +
+
+

Recent Problems

+ View all +
+
+ +
+
+
+ + + +
+
+ + + + + + + + diff --git a/modules.html b/modules.html new file mode 100644 index 0000000..1a1cc0b --- /dev/null +++ b/modules.html @@ -0,0 +1,255 @@ + + + + + + Modules - COP3530 + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ + + + +
+ + + +
+ + +
+ +
+

Course Modules

+

Explore instructional content organized by week and topic.

+
+ + +
+
+
+ +
+
+ + + +
+ +
+
+
+ Loading... +
+
+
+ + +
+ +
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + + \ No newline at end of file diff --git a/problems.html b/problems.html new file mode 100644 index 0000000..f8d484e --- /dev/null +++ b/problems.html @@ -0,0 +1,291 @@ + + + + + + Programming Problems - COP3530 + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ + + + +
+ + + +
+ + +
+ +
+

Programming Problems

+

Practice data structures and algorithms with these coding challenges.

+
+ + +
+ +
+ +
+
+ + + +
+ +
+
+ + +
+

Filter by tags:

+
+ +
+
+ + +
+
+ Loading... +
+ +
+
+ + +
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + + \ No newline at end of file diff --git a/resources.html b/resources.html new file mode 100644 index 0000000..2700d01 --- /dev/null +++ b/resources.html @@ -0,0 +1,520 @@ + + + + + + Resources - COP3530 + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ + + + +
+ + + +
+ + +
+ +
+

Course Resources

+

Essential tools, references, and materials to help you succeed in COP3530.

+
+ + +
+

Development Environment

+ + +
+ + +
+

Learning Resources

+ +
+ +
+
+
+ + + +
+

Textbooks & References

+
+ +
+ + + +
+
+ + +
+

Academic Policies

+ +
+
+
+

Academic Honesty

+
    +
  • + โœ“ + Collaborate on understanding concepts +
  • +
  • + โœ“ + Discuss approaches and algorithms +
  • +
  • + โœ“ + Use online references with proper citation +
  • +
  • + โœ— + Copy code from classmates or online +
  • +
  • + โœ— + Submit identical or substantially similar work +
  • +
  • + โœ— + Use AI tools to write code without disclosure +
  • +
+
+ +
+

Coding Style Guide

+
    +
  • + โ€ข + Use meaningful variable and function names +
  • +
  • + โ€ข + Consistent indentation (4 spaces or tabs) +
  • +
  • + โ€ข + Comment complex algorithms and logic +
  • +
  • + โ€ข + Include header comments with author info +
  • +
  • + โ€ข + Avoid magic numbers, use named constants +
  • +
  • + โ€ข + Handle edge cases and error conditions +
  • +
+
+
+
+
+ + +
+

Getting Help

+ +
+
+
+
+ + + +
+

Office Hours

+

+ Mon/Wed: 2:00-4:00 PM
+ Friday: 10:00 AM-12:00 PM +

+

Room CSE 301 & Virtual

+
+ +
+
+ + + + +
+

Email Support

+

+ Response within 24 hours
+ Include course number in subject +

+

professor@university.edu

+
+ +
+
+ + + +
+

Discussion Forum

+

+ Canvas discussions
+ Peer and instructor help +

+

Available 24/7

+
+
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/schedule.html b/schedule.html new file mode 100644 index 0000000..7512fe7 --- /dev/null +++ b/schedule.html @@ -0,0 +1,366 @@ + + + + + + Schedule - COP3530 + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ + + + +
+ + + +
+ + +
+ +
+

Course Schedule

+

Weekly breakdown of topics, assignments, and important dates.

+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
COP3530 Course Schedule
WeekDatesTopicsAssignmentsDue Dates
1Jan 13-17 +
Introduction & Algorithm Analysis
+
Course overview, Big-O notation
+
+ + Reading + + Ch 1-2 + -
2Jan 20-24 +
Linear Data Structures
+
Arrays, linked lists, stacks, queues
+
+ + Programming Assignment 1 + + + Jan 31 +
3Jan 27-31 +
Trees & Binary Search Trees
+
Tree structures, BST operations, traversals
+
+ + Quiz 1 + + + Jan 31 +
4Feb 3-7 +
Hash Tables
+
Hash functions, collision resolution
+
+ + Programming Assignment 2 + + + Feb 14 +
5Feb 10-14 +
Advanced Tree Structures
+
AVL trees, red-black trees
+
+ + Reading + + Ch 7-8 + -
6Feb 17-21 +
Heaps & Priority Queues
+
Binary heaps, heap operations
+
+ + Midterm Exam + + + Feb 21 +
7Feb 24-28 +
Sorting Algorithms
+
Merge sort, quick sort, heap sort
+
+ + Programming Assignment 3 + + + Mar 7 +
8Mar 3-7 +
Graph Algorithms I
+
Graph representation, BFS, DFS
+
+ + Reading + + Ch 13-14 + -
+
+
+ + +
+

Legend

+
+
+ + Reading + + Textbook chapters +
+
+ + Assignment + + Programming tasks +
+
+ + Quiz + + In-class assessment +
+
+ + Exam + + Major examination +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/syllabus.html b/syllabus.html new file mode 100644 index 0000000..d8e6a83 --- /dev/null +++ b/syllabus.html @@ -0,0 +1,476 @@ + + + + + + Syllabus - COP3530 + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ + + + +
+ + + +
+ + +
+ +
+

COP3530 - Data Structures and Algorithms

+
+

Spring 2025 โ€ข University of Florida

+

Credits: 3 โ€ข Prerequisites: COP3503 (Programming 2) with grade of C or better

+
+
+ + +
+
+

Course Information

+ +
+
+

Instructor

+
+

Professor John Smith

+

Email: jsmith@ufl.edu

+

Office: CSE 301

+

Phone: (352) 555-0123

+
+
+ +
+

Class Schedule

+
+

Lectures: MWF 10:40-11:30 AM

+

Location: Little Hall 101

+

Lab: Thursday 2:00-4:00 PM

+

Lab Location: CSE 120

+
+
+
+
+
+ + +
+
+

Course Description

+
+

+ This course provides a comprehensive introduction to data structures and algorithms essential for computer science. + Students will learn to analyze, design, and implement fundamental data structures including arrays, linked lists, + stacks, queues, trees, heaps, hash tables, and graphs. The course emphasizes algorithm analysis, complexity theory, + and the selection of appropriate data structures for solving computational problems. +

+ +

Learning Objectives

+
    +
  • Understand and analyze time and space complexity using Big-O notation
  • +
  • Implement fundamental data structures in C++
  • +
  • Design and analyze recursive and iterative algorithms
  • +
  • Apply appropriate data structures to solve real-world problems
  • +
  • Understand graph algorithms including traversal and shortest path
  • +
  • Implement and analyze various sorting algorithms
  • +
  • Develop problem-solving skills for algorithmic challenges
  • +
+
+
+
+ + +
+
+

Grading Policy

+ +
+
+

Grade Distribution

+
+
+ Programming Assignments + 40% +
+
+ Midterm Exam + 20% +
+
+ Final Exam + 25% +
+
+ Quizzes + 10% +
+
+ Participation + 5% +
+
+
+ +
+

Letter Grade Scale

+
+
+ A + 93-100% +
+
+ A- + 90-92% +
+
+ B+ + 87-89% +
+
+ B + 83-86% +
+
+ B- + 80-82% +
+
+ C+ + 77-79% +
+
+ C + 70-76% +
+
+ F + < 70% +
+
+
+
+
+
+ + +
+
+

Course Policies

+ +
+
+

Attendance Policy

+

+ Regular attendance is strongly encouraged but not mandatory. However, students are responsible for all material covered in class, + including announcements and schedule changes. If you miss class, please check with classmates for notes and announcements. +

+
+ +
+

Late Assignment Policy

+

+ Programming assignments lose 10% per day late (including weekends). No assignments accepted more than 5 days late without + prior arrangement. Medical emergencies and university-sanctioned activities may qualify for extensions with appropriate documentation. +

+
+ +
+

Make-up Exam Policy

+

+ Make-up exams will only be given in case of documented emergencies or university-sanctioned activities. + Students must contact the instructor as soon as possible to arrange a make-up exam. +

+
+ +
+

Academic Integrity

+
+

+ All work submitted must be your own. Collaboration on understanding concepts is encouraged, + but code must be written independently. Plagiarism, copying code, or unauthorized collaboration will result + in failure of the assignment and may result in failure of the course. When in doubt, ask the instructor. +

+
+
+
+
+
+ + +
+
+

Required Materials

+ +
+
+

Textbook (Required)

+

+ Data Structures and Algorithm Analysis in C++ (4th Edition)
+ by Mark Allen Weiss
+ ISBN: 978-0132847377 +

+
+ +
+

Software Requirements

+
    +
  • C++ compiler (GCC 9.0+ or equivalent)
  • +
  • Text editor or IDE (VS Code, CLion, or similar)
  • +
  • Git for version control (recommended)
  • +
  • Access to Canvas LMS
  • +
+
+ +
+

Recommended Resources

+
    +
  • Introduction to Algorithms by CLRS (reference)
  • +
  • VisuAlgo.net for algorithm visualizations
  • +
  • LeetCode for additional practice problems
  • +
  • Stack Overflow for programming help
  • +
+
+
+
+
+ + +
+
+

University Policies

+ +
+
+

Disability Accommodations

+

+ Students with disabilities who experience learning barriers are encouraged to contact the Disability Resource Center + to discuss options. All discussions remain confidential. Students must register with DRC and provide appropriate + documentation to receive accommodations. +

+
+ +
+

Counseling and Mental Health

+

+ Students experiencing personal problems or lacking clear career and academic goals are encouraged to contact the + Student Mental Health unit of the Student Health Care Center (352-392-1575) or the Counseling & Wellness Center (352-392-1575). +

+
+ +
+

Course Evaluation

+

+ Students are expected to provide feedback on the quality of instruction through online course evaluations. + Evaluations are typically open during the last 2-3 weeks of the semester and are completely anonymous. +

+
+
+
+
+ + +
+
+

Important Dates

+ +
+
+
+ Classes Begin + January 13 +
+
+ Drop/Add Deadline + January 20 +
+
+ Midterm Exam + February 21 +
+
+ +
+
+ Spring Break + March 10-14 +
+
+ Withdrawal Deadline + March 28 +
+
+ Final Exam + TBD +
+
+
+
+
+
+
+ + + + + + + + + \ No newline at end of file