mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-05-28 18:26:54 +00:00
feat(learn): add catalog (#65596)
Co-authored-by: jdwilkin4 <jwilkin4@hotmail.com>
This commit is contained in:
@@ -10,8 +10,9 @@ import {
|
||||
LangCodes
|
||||
} from '@freecodecamp/shared/config/i18n';
|
||||
import {
|
||||
catalogSuperBlocks,
|
||||
SuperBlocks
|
||||
SuperBlocks,
|
||||
superBlockStages,
|
||||
SuperBlockStage
|
||||
} from '@freecodecamp/shared/config/curriculum';
|
||||
import intro from './locales/english/intro.json';
|
||||
|
||||
@@ -85,13 +86,14 @@ describe('Locale tests:', () => {
|
||||
describe('Intro file structure tests:', () => {
|
||||
const typedIntro = intro as unknown as Intro;
|
||||
const superblocks = Object.values(SuperBlocks);
|
||||
const catalogSuperBlocks = superBlockStages[SuperBlockStage.Catalog];
|
||||
for (const superBlock of superblocks) {
|
||||
test(`superBlock ${superBlock} has required properties`, () => {
|
||||
expect(typeof typedIntro[superBlock].title).toBe('string');
|
||||
|
||||
// catalog superblocks should have a summary
|
||||
if (catalogSuperBlocks.includes(superBlock)) {
|
||||
expect(typedIntro[superBlock].intro).toBeInstanceOf(Array);
|
||||
expect(typedIntro[superBlock].summary).toBeInstanceOf(Array);
|
||||
}
|
||||
|
||||
expect(typedIntro[superBlock].intro).toBeInstanceOf(Array);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -204,6 +204,10 @@
|
||||
],
|
||||
"cta": "Start Learning Now (it's free)"
|
||||
},
|
||||
"catalog": {
|
||||
"heading": "Explore Course Catalog",
|
||||
"seeAll": "See All Courses"
|
||||
},
|
||||
"certification-heading": "Earn free verified certifications in:",
|
||||
"core-certs-heading": "Recommended curriculum:",
|
||||
"learn-english-heading": "Learn English for Developers:",
|
||||
@@ -710,7 +714,8 @@
|
||||
"exam": "Exam",
|
||||
"warm-up": "Warm-up",
|
||||
"learn": "Learn",
|
||||
"practice": "Practice"
|
||||
"practice": "Practice",
|
||||
"video": "Video"
|
||||
},
|
||||
"archive": {
|
||||
"title": "Archived Coursework",
|
||||
@@ -1257,6 +1262,7 @@
|
||||
"college-algebra-with-python-v8-cert": "College Algebra with Python Certification",
|
||||
"foundational-c-sharp-with-microsoft": "Foundational C# with Microsoft",
|
||||
"foundational-c-sharp-with-microsoft-cert": "Foundational C# with Microsoft Certification",
|
||||
"learn-python-for-beginners": "Learn Python for Beginners",
|
||||
"a2-english-for-developers": "A2 English for Developers",
|
||||
"a2-english-for-developers-cert": "A2 English for Developers Certification (Beta)",
|
||||
"b1-english-for-developers": "B1 English for Developers",
|
||||
@@ -1429,6 +1435,21 @@
|
||||
"beginner": "Beginner",
|
||||
"intermediate": "Intermediate",
|
||||
"advanced": "Advanced"
|
||||
},
|
||||
"duration": "{{duration}} hours",
|
||||
"no-results": "No courses found. Try adjusting your filters to see more results.",
|
||||
"topic": {
|
||||
"html": "HTML",
|
||||
"css": "CSS",
|
||||
"js": "JavaScript",
|
||||
"react": "React",
|
||||
"python": "Python",
|
||||
"data-analysis": "Data Analysis",
|
||||
"machine-learning": "Machine Learning",
|
||||
"d3": "D3",
|
||||
"api": "APIs",
|
||||
"information-security": "Information Security",
|
||||
"computer-fundamentals": "Computer Fundamentals"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,6 +56,31 @@ const iconMap = {
|
||||
[SuperBlocks.SemanticHtml]: Code,
|
||||
[SuperBlocks.FullStackOpen]: Code,
|
||||
[SuperBlocks.DevPlayground]: Code,
|
||||
[SuperBlocks.HtmlFormsAndTables]: ResponsiveDesign,
|
||||
[SuperBlocks.LabSurveyForm]: Code,
|
||||
[SuperBlocks.HtmlAndAccessibility]: ResponsiveDesign,
|
||||
[SuperBlocks.ComputerBasics]: Code,
|
||||
[SuperBlocks.BasicCss]: Code,
|
||||
[SuperBlocks.DesignForDevelopers]: Code,
|
||||
[SuperBlocks.AbsoluteAndRelativeUnits]: Code,
|
||||
[SuperBlocks.PseudoClassesAndElements]: Code,
|
||||
[SuperBlocks.CssColors]: Code,
|
||||
[SuperBlocks.StylingForms]: Code,
|
||||
[SuperBlocks.CssBoxModel]: Code,
|
||||
[SuperBlocks.CssFlexbox]: Code,
|
||||
[SuperBlocks.LabPageOfPlayingCards]: Code,
|
||||
[SuperBlocks.CssTypography]: Code,
|
||||
[SuperBlocks.CssAndAccessibility]: ResponsiveDesign,
|
||||
[SuperBlocks.CssPositioning]: Code,
|
||||
[SuperBlocks.AttributeSelectors]: Code,
|
||||
[SuperBlocks.LabBookInventoryApp]: Code,
|
||||
[SuperBlocks.ResponsiveDesign]: ResponsiveDesign,
|
||||
[SuperBlocks.LabTechnicalDocumentationPage]: Code,
|
||||
[SuperBlocks.CssVariables]: Code,
|
||||
[SuperBlocks.CssGrid]: Code,
|
||||
[SuperBlocks.LabProductLandingPage]: Code,
|
||||
[SuperBlocks.CssAnimations]: Code,
|
||||
[SuperBlocks.LearnPythonForBeginners]: PythonIcon,
|
||||
[SuperBlocks.RespWebDesignV9]: ResponsiveDesign,
|
||||
[SuperBlocks.JsV9]: JavaScriptIcon,
|
||||
[SuperBlocks.FrontEndDevLibsV9]: ReactIcon,
|
||||
|
||||
@@ -94,7 +94,11 @@ function Map({ forLanding = false }: MapProps) {
|
||||
showUpcomingChanges
|
||||
})
|
||||
// remove legacy superblocks from main maps - shown in archive map only
|
||||
.filter(stage => stage !== SuperBlockStage.Legacy)
|
||||
.filter(
|
||||
stage =>
|
||||
stage !== SuperBlockStage.Legacy &&
|
||||
stage !== SuperBlockStage.Catalog
|
||||
)
|
||||
.map(stage => {
|
||||
const superblocks = superBlockStages[stage];
|
||||
if (superblocks.length === 0) {
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
import React from 'react';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import { faClock, faStairs } from '@fortawesome/free-solid-svg-icons';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Link } from './helpers';
|
||||
|
||||
interface CatalogItemProps {
|
||||
superBlock: string;
|
||||
level: string;
|
||||
hours: number;
|
||||
topic: string;
|
||||
showAllSummaries?: boolean;
|
||||
}
|
||||
|
||||
const CatalogItem: React.FC<CatalogItemProps> = ({
|
||||
superBlock,
|
||||
level,
|
||||
hours,
|
||||
topic,
|
||||
showAllSummaries = false
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { title, summary } = t(`intro:${superBlock}`, {
|
||||
returnObjects: true
|
||||
}) as {
|
||||
title: string;
|
||||
summary: string[];
|
||||
};
|
||||
|
||||
return (
|
||||
<Link to={`/learn/${superBlock}`} key={superBlock} className='catalog-item'>
|
||||
<div className='catalog-item-top'>
|
||||
<div className={`block-label block-label-${topic}`}>
|
||||
{t(`curriculum.catalog.topic.${topic}`)}
|
||||
</div>
|
||||
<h3>{title}</h3>
|
||||
{showAllSummaries ? (
|
||||
summary.map((text, i) => <p key={i}>{text}</p>)
|
||||
) : summary && summary.length > 0 ? (
|
||||
<p>{summary[0]}</p>
|
||||
) : null}
|
||||
</div>
|
||||
<div className='catalog-item-bottom'>
|
||||
<div>
|
||||
<FontAwesomeIcon icon={faStairs} />
|
||||
{t(`curriculum.catalog.levels.${level}`)}
|
||||
</div>
|
||||
<div>
|
||||
<FontAwesomeIcon icon={faClock} />
|
||||
{' '}
|
||||
{showAllSummaries
|
||||
? t('curriculum.catalog.duration', { duration: hours })
|
||||
: `${hours} hours`}
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
);
|
||||
};
|
||||
|
||||
export default CatalogItem;
|
||||
@@ -22,6 +22,7 @@ const Faq = (): JSX.Element => {
|
||||
xs={12}
|
||||
className='faq-section'
|
||||
>
|
||||
<Spacer size='l' />
|
||||
<h2 className='big-heading'>{t('landing.faq')}</h2>
|
||||
<Spacer size='xs' />
|
||||
{faqItems.map((faq, i) => (
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
import React, { useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Col, Row, Container } from '@freecodecamp/ui';
|
||||
import { Link } from '../../helpers';
|
||||
import { catalog } from '@freecodecamp/shared/config/catalog';
|
||||
import { SuperBlocks } from '@freecodecamp/shared/config/curriculum';
|
||||
import CatalogItem from '../../catalog-item';
|
||||
|
||||
import '../landing.css';
|
||||
import LinkButton from '../../../assets/icons/link-button';
|
||||
|
||||
const LandingCatalog = (): JSX.Element => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const featuredCourses = useMemo(() => {
|
||||
// Get featured courses: Learn Python for Beginners, Computer Basics, Basic HTML
|
||||
const featuredSuperBlocks = [
|
||||
SuperBlocks.LearnPythonForBeginners,
|
||||
SuperBlocks.ComputerBasics,
|
||||
SuperBlocks.BasicHtml
|
||||
];
|
||||
const courses = catalog.filter(course =>
|
||||
featuredSuperBlocks.includes(course.superBlock)
|
||||
);
|
||||
// Sort by the order in featuredSuperBlocks
|
||||
return courses.sort(
|
||||
(a, b) =>
|
||||
featuredSuperBlocks.indexOf(a.superBlock) -
|
||||
featuredSuperBlocks.indexOf(b.superBlock)
|
||||
);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className='landing-catalog landing-catalog-container'>
|
||||
<Container>
|
||||
<Row>
|
||||
<Col xs={12}>
|
||||
<h2 className='big-heading text-center'>
|
||||
{t('landing.catalog.heading')}
|
||||
</h2>
|
||||
</Col>
|
||||
</Row>
|
||||
</Container>
|
||||
<Container fluid={true} className='landing-catalog-container'>
|
||||
<Col md={10} mdOffset={1} sm={12} xs={12}>
|
||||
<section className='landing-catalog-wrap'>
|
||||
{featuredCourses.map(course => {
|
||||
const { superBlock, level, hours, topic } = course;
|
||||
|
||||
return (
|
||||
<CatalogItem
|
||||
key={superBlock}
|
||||
superBlock={superBlock}
|
||||
level={level}
|
||||
hours={hours}
|
||||
topic={topic}
|
||||
showAllSummaries={false}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
<Link to='/catalog' className='catalog-item catalog-item-see-all'>
|
||||
<h3>{t('landing.catalog.seeAll')}</h3>
|
||||
<LinkButton />
|
||||
</Link>
|
||||
</section>
|
||||
</Col>
|
||||
</Container>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
LandingCatalog.displayName = 'LandingCatalog';
|
||||
export default LandingCatalog;
|
||||
@@ -455,3 +455,28 @@ figcaption.caption {
|
||||
font-weight: normal;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* Landing Catalog Styles */
|
||||
.landing-catalog-container {
|
||||
background-color: var(--primary-background);
|
||||
padding-top: 3rem;
|
||||
padding-bottom: 3rem;
|
||||
}
|
||||
|
||||
.landing-catalog-wrap {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||
width: 100%;
|
||||
gap: 2rem;
|
||||
}
|
||||
|
||||
.landing-catalog .catalog-item.catalog-item-see-all {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 280px;
|
||||
text-align: center;
|
||||
fill: var(--secondary-color);
|
||||
flex-direction: row;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
@@ -1,22 +1,83 @@
|
||||
.catalog-wrap {
|
||||
display: flex;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||
width: 100%;
|
||||
gap: 2rem;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
|
||||
.catalog-filters {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
justify-content: flex-start;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.catalog-filters .dropdown {
|
||||
min-width: 250px;
|
||||
}
|
||||
|
||||
.catalog-filters .dropdown-menu {
|
||||
max-height: 300px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.catalog-filters .dropdown-item {
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
padding: 0.5rem 1rem;
|
||||
}
|
||||
|
||||
.catalog-filters button {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.catalog-filters .dropdown-menu .dropdown-item input[type='checkbox'] {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.filter-checkbox {
|
||||
cursor: pointer;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
margin: 0 0.5rem 0 0;
|
||||
vertical-align: middle;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.catalog-item-top {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.catalog-item {
|
||||
text-decoration: none;
|
||||
padding: 1rem;
|
||||
background-color: var(--primary-background);
|
||||
width: 400px;
|
||||
min-height: 300px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
border: 1px solid var(--background-quaternary);
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
.catalog-item h3 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.catalog-item-bottom {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-end;
|
||||
color: var(--quaternary-color);
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.catalog-item p {
|
||||
margin-bottom: 0.9rem;
|
||||
}
|
||||
|
||||
+146
-35
@@ -1,55 +1,166 @@
|
||||
import React from 'react';
|
||||
import React, { useState, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Col, Spacer } from '@freecodecamp/ui';
|
||||
import { ButtonLink } from '../components/helpers';
|
||||
import { Col, Spacer, Dropdown, MenuItem, Alert } from '@freecodecamp/ui';
|
||||
import { catalog } from '@freecodecamp/shared/config/catalog';
|
||||
import { showUpcomingChanges } from '../../config/env.json';
|
||||
import FourOhFour from '../components/FourOhFour';
|
||||
import CatalogItem from '../components/catalog-item';
|
||||
|
||||
import './catalog.css';
|
||||
|
||||
const CatalogPage = () => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [selectedLevels, setSelectedLevels] = useState<string[]>(['all']);
|
||||
const [selectedTopics, setSelectedTopics] = useState<string[]>(['all']);
|
||||
|
||||
// Extract unique levels and topics from catalog
|
||||
const uniqueLevels = useMemo(() => {
|
||||
const levels = [...new Set(catalog.map(item => item.level))];
|
||||
return levels.sort();
|
||||
}, []);
|
||||
|
||||
const uniqueTopics = useMemo(() => {
|
||||
const topics = [...new Set(catalog.map(item => item.topic))];
|
||||
return topics.sort();
|
||||
}, []);
|
||||
|
||||
// Handle level filter change
|
||||
const handleLevelChange = (level: string) => {
|
||||
if (level === 'all') {
|
||||
setSelectedLevels(['all']);
|
||||
} else {
|
||||
setSelectedLevels(prev => {
|
||||
const filtered = prev.filter(l => l !== 'all');
|
||||
if (filtered.includes(level)) {
|
||||
const updated = filtered.filter(l => l !== level);
|
||||
return updated.length === 0 ? ['all'] : updated;
|
||||
} else {
|
||||
return [...filtered, level];
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Handle topic filter change
|
||||
const handleTopicChange = (topic: string) => {
|
||||
if (topic === 'all') {
|
||||
setSelectedTopics(['all']);
|
||||
} else {
|
||||
setSelectedTopics(prev => {
|
||||
const filtered = prev.filter(t => t !== 'all');
|
||||
if (filtered.includes(topic)) {
|
||||
const updated = filtered.filter(t => t !== topic);
|
||||
return updated.length === 0 ? ['all'] : updated;
|
||||
} else {
|
||||
return [...filtered, topic];
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const filteredCatalog = useMemo(() => {
|
||||
return catalog.filter(course => {
|
||||
const levelMatch =
|
||||
selectedLevels.includes('all') || selectedLevels.includes(course.level);
|
||||
const topicMatch =
|
||||
selectedTopics.includes('all') || selectedTopics.includes(course.topic);
|
||||
return levelMatch && topicMatch;
|
||||
});
|
||||
}, [selectedLevels, selectedTopics]);
|
||||
|
||||
return showUpcomingChanges ? (
|
||||
<main>
|
||||
<Spacer size='l' />
|
||||
<h1 className='text-center'>{t('curriculum.catalog.title')}</h1>
|
||||
<Spacer size='l' />
|
||||
|
||||
<Col md={8} mdOffset={2} sm={10} smOffset={1} xs={12}>
|
||||
<section className='catalog-wrap'>
|
||||
{catalog.map(course => {
|
||||
const { superBlock, level, hours } = course;
|
||||
<div className='catalog-filters'>
|
||||
<Dropdown block={true}>
|
||||
<Dropdown.Toggle id='level-filter-dropdown'>
|
||||
Level:{' '}
|
||||
{selectedLevels.includes('all')
|
||||
? 'All'
|
||||
: `${selectedLevels.length} selected`}
|
||||
</Dropdown.Toggle>
|
||||
<Dropdown.Menu>
|
||||
<MenuItem onClick={() => handleLevelChange('all')}>
|
||||
<input
|
||||
type='checkbox'
|
||||
checked={selectedLevels.includes('all')}
|
||||
onChange={() => {}}
|
||||
className='filter-checkbox'
|
||||
/>
|
||||
All
|
||||
</MenuItem>
|
||||
{uniqueLevels.map(level => (
|
||||
<MenuItem key={level} onClick={() => handleLevelChange(level)}>
|
||||
<input
|
||||
type='checkbox'
|
||||
checked={selectedLevels.includes(level)}
|
||||
onChange={() => {}}
|
||||
className='filter-checkbox'
|
||||
/>
|
||||
{t(`curriculum.catalog.levels.${level}`)}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Dropdown.Menu>
|
||||
</Dropdown>
|
||||
<Dropdown block={true}>
|
||||
<Dropdown.Toggle id='topic-filter-dropdown'>
|
||||
Topic:{' '}
|
||||
{selectedTopics.includes('all')
|
||||
? 'All'
|
||||
: `${selectedTopics.length} selected`}
|
||||
</Dropdown.Toggle>
|
||||
<Dropdown.Menu>
|
||||
<MenuItem onClick={() => handleTopicChange('all')}>
|
||||
<input
|
||||
type='checkbox'
|
||||
checked={selectedTopics.includes('all')}
|
||||
onChange={() => {}}
|
||||
className='filter-checkbox'
|
||||
/>
|
||||
All
|
||||
</MenuItem>
|
||||
{uniqueTopics.map(topic => (
|
||||
<MenuItem key={topic} onClick={() => handleTopicChange(topic)}>
|
||||
<input
|
||||
type='checkbox'
|
||||
checked={selectedTopics.includes(topic)}
|
||||
onChange={() => {}}
|
||||
className='filter-checkbox'
|
||||
/>
|
||||
{t(`curriculum.catalog.topic.${topic}`)}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Dropdown.Menu>
|
||||
</Dropdown>
|
||||
</div>
|
||||
</Col>
|
||||
<Spacer size='m' />
|
||||
<Col md={8} mdOffset={2} sm={10} smOffset={1} xs={12}>
|
||||
{filteredCatalog.length === 0 ? (
|
||||
<Alert variant='info'>{t('curriculum.catalog.no-results')}</Alert>
|
||||
) : (
|
||||
<section className='catalog-wrap'>
|
||||
{filteredCatalog.map(course => {
|
||||
const { superBlock, level, hours, topic } = course;
|
||||
|
||||
const { title, summary } = t(`intro:${superBlock}`, {
|
||||
returnObjects: true
|
||||
}) as {
|
||||
title: string;
|
||||
summary: string[];
|
||||
};
|
||||
|
||||
return (
|
||||
<div className='catalog-item' key={superBlock}>
|
||||
<div className='catalog-item-top'>
|
||||
<h2>{title}</h2>
|
||||
<hr />
|
||||
{summary.map((text, i) => (
|
||||
<p key={i}>{text}</p>
|
||||
))}
|
||||
</div>
|
||||
<div className='catalog-item-bottom'>
|
||||
<div>
|
||||
{t(`curriculum.catalog.levels.${level}`)} • {hours}{' '}
|
||||
hours
|
||||
</div>
|
||||
<ButtonLink href={`/learn/${superBlock}`}>
|
||||
{t('buttons.go-to-course')}
|
||||
</ButtonLink>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</section>
|
||||
return (
|
||||
<CatalogItem
|
||||
key={superBlock}
|
||||
superBlock={superBlock}
|
||||
level={level}
|
||||
hours={hours}
|
||||
topic={topic}
|
||||
showAllSummaries={true}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</section>
|
||||
)}
|
||||
</Col>
|
||||
<Spacer size='l' />
|
||||
</main>
|
||||
|
||||
@@ -6,9 +6,11 @@ import { Loader } from '../components/helpers';
|
||||
import LandingTop from '../components/landing/components/landing-top';
|
||||
import Testimonials from '../components/landing/components/testimonials';
|
||||
import Certifications from '../components/landing/components/certifications';
|
||||
import LandingCatalog from '../components/landing/components/landing-catalog';
|
||||
import Faq from '../components/landing/components/faq';
|
||||
import Benefits from '../components/landing/components/benefits';
|
||||
import { useClaimableCertsNotification } from '../components/helpers/use-claimable-certs-notification';
|
||||
import { showUpcomingChanges } from '../../config/env.json';
|
||||
|
||||
import '../components/landing/landing.css';
|
||||
|
||||
@@ -22,6 +24,7 @@ const Landing = () => (
|
||||
<Benefits />
|
||||
<Testimonials />
|
||||
<Certifications />
|
||||
{showUpcomingChanges && <LandingCatalog />}
|
||||
<Faq />
|
||||
</main>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: Absolute and Relative Units
|
||||
superBlock: absolute-and-relative-units
|
||||
certification: absolute-and-relative-units
|
||||
---
|
||||
|
||||
## Absolute and Relative Units
|
||||
|
||||
Understand when to use absolute and relative CSS units to build flexible layouts.
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: Attribute Selectors
|
||||
superBlock: attribute-selectors
|
||||
certification: attribute-selectors
|
||||
---
|
||||
|
||||
## Attribute Selectors
|
||||
|
||||
Target elements precisely with CSS attribute selectors.
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: Basic CSS
|
||||
superBlock: basic-css
|
||||
certification: basic-css
|
||||
---
|
||||
|
||||
## Basic CSS
|
||||
|
||||
Learn core CSS concepts and start styling real-world layouts.
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: Computer Basics
|
||||
superBlock: computer-basics
|
||||
certification: computer-basics
|
||||
---
|
||||
|
||||
## Computer Basics
|
||||
|
||||
Build a foundation in computer, internet, and tooling basics for web development.
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: Accessibility
|
||||
superBlock: css-and-accessibility
|
||||
certification: css-and-accessibility
|
||||
---
|
||||
|
||||
## CSS and Accessibility
|
||||
|
||||
Apply CSS techniques that support accessible and inclusive interfaces.
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: Animations
|
||||
superBlock: css-animations
|
||||
certification: css-animations
|
||||
---
|
||||
|
||||
## CSS Animations
|
||||
|
||||
Create engaging UI motion with accessible CSS animations.
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: The Box Model
|
||||
superBlock: css-box-model
|
||||
certification: css-box-model
|
||||
---
|
||||
|
||||
## CSS Box Model
|
||||
|
||||
Master the CSS box model, spacing, and layout effects for precise designs.
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: Colors
|
||||
superBlock: css-colors
|
||||
certification: css-colors
|
||||
---
|
||||
|
||||
## CSS Colors
|
||||
|
||||
Work with CSS color formats and build cohesive color palettes.
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: Flexbox
|
||||
superBlock: css-flexbox
|
||||
certification: css-flexbox
|
||||
---
|
||||
|
||||
## CSS Flexbox
|
||||
|
||||
Build responsive layouts using the Flexbox model and alignment tools.
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: Grid
|
||||
superBlock: css-grid
|
||||
certification: css-grid
|
||||
---
|
||||
|
||||
## CSS Grid
|
||||
|
||||
Design complex layouts using the CSS Grid system.
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: Positioning
|
||||
superBlock: css-positioning
|
||||
certification: css-positioning
|
||||
---
|
||||
|
||||
## CSS Positioning
|
||||
|
||||
Use positioning and floats to control layout and element flow.
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: Typography
|
||||
superBlock: css-typography
|
||||
certification: css-typography
|
||||
---
|
||||
|
||||
## CSS Typography
|
||||
|
||||
Learn how to style text for readability, hierarchy, and visual balance.
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: Variables
|
||||
superBlock: css-variables
|
||||
certification: css-variables
|
||||
---
|
||||
|
||||
## CSS Variables
|
||||
|
||||
Use CSS variables to build reusable, theme-friendly styles.
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: Design
|
||||
superBlock: design-for-developers
|
||||
certification: design-for-developers
|
||||
---
|
||||
|
||||
## Design for Developers
|
||||
|
||||
Explore UI design fundamentals and user-centered design principles for developers.
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: Accessibility
|
||||
superBlock: html-and-accessibility
|
||||
certification: html-and-accessibility
|
||||
---
|
||||
|
||||
## HTML and Accessibility
|
||||
|
||||
Learn how to write inclusive HTML using accessibility best practices and ARIA.
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: HTML Forms and Tables
|
||||
superBlock: html-forms-and-tables
|
||||
certification: html-forms-and-tables
|
||||
---
|
||||
|
||||
## Introduction to HTML Forms and Tables
|
||||
|
||||
Learn how to build accessible forms and data tables with semantic HTML.
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: Build a Book Inventory App
|
||||
superBlock: lab-book-inventory-app
|
||||
certification: lab-book-inventory-app
|
||||
---
|
||||
|
||||
## Build a Book Inventory App
|
||||
|
||||
Build a structured layout for managing a book inventory.
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: Build a Page of Playing Cards
|
||||
superBlock: lab-page-of-playing-cards
|
||||
certification: lab-page-of-playing-cards
|
||||
---
|
||||
|
||||
## Build a Page of Playing Cards
|
||||
|
||||
Create a multi-card layout to practice flexible CSS composition.
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: Build a Product Landing Page
|
||||
superBlock: lab-product-landing-page
|
||||
certification: lab-product-landing-page
|
||||
---
|
||||
|
||||
## Build a Product Landing Page
|
||||
|
||||
Build a complete landing page and apply layout, typography, and responsive design.
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: Build a Survey Form
|
||||
superBlock: lab-survey-form
|
||||
certification: lab-survey-form
|
||||
---
|
||||
|
||||
## Build a Survey Form
|
||||
|
||||
Create a complete survey form while practicing HTML structure and accessible form controls.
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: Build a Technical Documentation Page
|
||||
superBlock: lab-technical-documentation-page
|
||||
certification: lab-technical-documentation-page
|
||||
---
|
||||
|
||||
## Build a Technical Documentation Page
|
||||
|
||||
Create a documentation page and practice responsive structure and layout.
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: Learn Python for Beginners
|
||||
superBlock: learn-python-for-beginners
|
||||
certification: learn-python-for-beginners
|
||||
---
|
||||
|
||||
## Introduction to Learn Python for Beginners
|
||||
|
||||
Learn the fundamentals of Python programming from the ground up. Python is one of the most popular programming languages today and is great for beginners.
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: Pseudo Classes and Elements
|
||||
superBlock: pseudo-classes-and-elements
|
||||
certification: pseudo-classes-and-elements
|
||||
---
|
||||
|
||||
## Pseudo Classes and Elements
|
||||
|
||||
Use pseudo-classes and pseudo-elements to create richer, more interactive styles.
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: Responsive Design
|
||||
superBlock: responsive-design
|
||||
certification: responsive-design
|
||||
---
|
||||
|
||||
## Responsive Design
|
||||
|
||||
Learn responsive design principles and build layouts that adapt to any screen.
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: Styling Forms
|
||||
superBlock: styling-forms
|
||||
certification: styling-forms
|
||||
---
|
||||
|
||||
## Styling Forms
|
||||
|
||||
Apply CSS techniques to create clean, usable form layouts.
|
||||
@@ -96,20 +96,27 @@ function SuperBlockIntro({
|
||||
const { t } = useTranslation();
|
||||
const superBlockIntroObj: {
|
||||
title: string;
|
||||
intro: string[];
|
||||
intro: string[] | string;
|
||||
note: string;
|
||||
} = t(`intro:${superBlock}`, { returnObjects: true }) as {
|
||||
title: string;
|
||||
intro: string[];
|
||||
intro: string[] | string;
|
||||
note: string;
|
||||
};
|
||||
|
||||
const {
|
||||
title: i18nSuperBlock,
|
||||
intro: superBlockIntroText,
|
||||
intro: introRaw,
|
||||
note: superBlockNoteText
|
||||
} = superBlockIntroObj;
|
||||
|
||||
// Ensure intro is always an array
|
||||
const superBlockIntroText = Array.isArray(introRaw)
|
||||
? introRaw
|
||||
: typeof introRaw === 'string'
|
||||
? [introRaw]
|
||||
: [''];
|
||||
|
||||
const IntroTopDefault = ({ fsd }: { fsd: boolean }) => (
|
||||
<>
|
||||
{archivedSuperBlocks.includes(superBlock) && <ArchivedWarning />}
|
||||
|
||||
@@ -13,8 +13,9 @@
|
||||
}
|
||||
|
||||
.block-label {
|
||||
align-self: center;
|
||||
align-self: start;
|
||||
height: fit-content;
|
||||
width: fit-content;
|
||||
padding: 1px 6px 2px;
|
||||
font-size: 0.85rem;
|
||||
border: 1px solid;
|
||||
@@ -27,26 +28,31 @@
|
||||
background-color: var(--tertiary-background);
|
||||
}
|
||||
|
||||
.block-label-html,
|
||||
.block-label-lecture {
|
||||
border-color: var(--yellow-color);
|
||||
color: var(--yellow-color);
|
||||
}
|
||||
|
||||
.block-label-css,
|
||||
.block-label-workshop {
|
||||
border-color: var(--highlight-color);
|
||||
color: var(--highlight-color);
|
||||
}
|
||||
|
||||
.block-label-python,
|
||||
.block-label-lab {
|
||||
border-color: var(--success-color);
|
||||
color: var(--success-color);
|
||||
}
|
||||
|
||||
.block-label-javascript,
|
||||
.block-label-review {
|
||||
border-color: var(--purple-color);
|
||||
color: var(--purple-color);
|
||||
}
|
||||
|
||||
.block-label-computer-fundamentals,
|
||||
.block-label-quiz {
|
||||
border-color: var(--danger-color);
|
||||
color: var(--danger-color);
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
---
|
||||
id: 669aff9f5488f1bea056416d
|
||||
title: Step 1
|
||||
challengeType: 0
|
||||
dashedName: step-1
|
||||
demoType: onLoad
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In this workshop, you will practice working with semantic HTML by building a blog page dedicated to Mr. Whiskers the cat.
|
||||
|
||||
To begin the project, add the `<!DOCTYPE html>`, and an `html` element with a `lang` attribute of `en`.
|
||||
|
||||
Remember that you learned how to build a basic HTML boilerplate like this in the previous module.
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<!--all other elements go here-->
|
||||
</html>
|
||||
```
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have the `<!DOCTYPE html>`.
|
||||
|
||||
```js
|
||||
assert.match(code, /<!DOCTYPE\s+html>/i);
|
||||
```
|
||||
|
||||
You should have an opening `html` tag with the language set to english.
|
||||
|
||||
```js
|
||||
assert.match(code, /<html\s+lang\s*=\s*('|")en\1\s*>/gi);
|
||||
```
|
||||
|
||||
You should have a closing `html` tag.
|
||||
|
||||
```js
|
||||
assert.match(code, /<\/html>/i);
|
||||
```
|
||||
|
||||
Your `DOCTYPE` should come before the `html` element.
|
||||
|
||||
```js
|
||||
assert.match(code, /<!DOCTYPE\s+html>[.\n\s]*<html\s+lang\s*=\s*('|")en\1\s*>/im)
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -1,43 +0,0 @@
|
||||
---
|
||||
id: 669fc7e141e4703748c558bf
|
||||
title: Step 2
|
||||
challengeType: 0
|
||||
dashedName: step-2
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Inside the `html` element, add a `head` element.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have an opening `head` tag.
|
||||
|
||||
```js
|
||||
assert.match(code, /<head>/i);
|
||||
```
|
||||
|
||||
You should have a closing `head` tag.
|
||||
|
||||
```js
|
||||
assert.match(code, /<\/head>/i);
|
||||
```
|
||||
|
||||
Your opening `head` tag should come before the closing `head` tag.
|
||||
|
||||
```js
|
||||
assert.match(code, /<head>[.\n\s]*<\/head>/im)
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
</html>
|
||||
```
|
||||
@@ -1,87 +0,0 @@
|
||||
---
|
||||
id: 669fc938d38e6e38ace9251e
|
||||
title: Step 3
|
||||
challengeType: 0
|
||||
dashedName: step-3
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Inside your `head` element, nest a `meta` element with the `charset` attribute set to the value `"UTF-8"`.
|
||||
|
||||
Below that `meta` element, add a `title` element.
|
||||
|
||||
The `title` element's text should be `Mr. Whiskers' Blog`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have a `meta` element.
|
||||
|
||||
```js
|
||||
assert.isNotNull(document.querySelector("meta"));
|
||||
```
|
||||
|
||||
The `meta` element is a void element, it should not have an end tag `</meta>`.
|
||||
|
||||
```js
|
||||
assert.notMatch(code, /<\/meta>/i);
|
||||
```
|
||||
|
||||
Your `meta` tag should have a `charset` attribute.
|
||||
|
||||
```js
|
||||
assert.match(code, /<meta\s+charset\s*/i);
|
||||
```
|
||||
|
||||
Your `charset` attribute should have a value of `"UTF-8"`.
|
||||
|
||||
```js
|
||||
assert.match(code, /charset\s*=\s*('|")UTF-8\1/i);
|
||||
```
|
||||
|
||||
Your `meta` element should be nested inside your `head` element.
|
||||
|
||||
```js
|
||||
const meta = document.querySelector('head > meta');
|
||||
assert.strictEqual(meta?.parentElement?.tagName, 'HEAD');
|
||||
```
|
||||
|
||||
You should have an opening `title` tag.
|
||||
|
||||
```js
|
||||
assert.match(code, /<title>/i);
|
||||
```
|
||||
|
||||
You should have a closing `title` tag.
|
||||
|
||||
```js
|
||||
assert.match(code, /<\/title>/i);
|
||||
```
|
||||
|
||||
Your `title` element should be nested in your `head` element.
|
||||
|
||||
```js
|
||||
assert.match(code, /<head>.*\s*<title>.*<\/title>.*\s*<\/head>/si);
|
||||
```
|
||||
|
||||
Your `title` element should have the text `Mr. Whiskers' Blog`. You may need to check your spelling.
|
||||
|
||||
```js
|
||||
const titleText = document.querySelector('title')?.innerText
|
||||
assert.strictEqual(titleText, "Mr. Whiskers' Blog");
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
--fcc-editable-region--
|
||||
<head>
|
||||
|
||||
</head>
|
||||
--fcc-editable-region--
|
||||
</html>
|
||||
```
|
||||
@@ -1,69 +0,0 @@
|
||||
---
|
||||
id: 669fcb06c3034a39f5431a38
|
||||
title: Step 4
|
||||
challengeType: 0
|
||||
dashedName: step-4
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
To prepare creating some actual content, add a `body` element below the `head` element.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have an opening `<body>` tag.
|
||||
|
||||
```js
|
||||
assert.match(code, /<body>/i);
|
||||
```
|
||||
|
||||
You should have a closing `</body>` tag.
|
||||
|
||||
```js
|
||||
assert.match(code, /<\/body>/i);
|
||||
```
|
||||
|
||||
You should not change your `head` element. Make sure you did not delete your closing tag.
|
||||
|
||||
```js
|
||||
assert.match(code, /<head>/i);
|
||||
assert.match(code, /<\/head>/i);
|
||||
```
|
||||
|
||||
Your `body` element should come after your `head` element.
|
||||
|
||||
```js
|
||||
assert.match(code, /<\/head>[.\n\s]*<body>/im)
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
--fcc-editable-region--
|
||||
<head>
|
||||
<title>Mr. Whiskers' Blog</title>
|
||||
<meta charset="UTF-8" />
|
||||
</head>
|
||||
|
||||
--fcc-editable-region--
|
||||
</html>
|
||||
```
|
||||
|
||||
|
||||
# --solutions--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Mr. Whiskers' Blog</title>
|
||||
<meta charset="UTF-8" />
|
||||
</head>
|
||||
|
||||
<body></body>
|
||||
</html>
|
||||
```
|
||||
@@ -1,60 +0,0 @@
|
||||
---
|
||||
id: 5dc174fcf86c76b9248c6eb2
|
||||
title: Step 1
|
||||
challengeType: 0
|
||||
dashedName: step-1
|
||||
demoType: onLoad
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In this workshop, you will continue working with basic HTML elements like headings, paragraphs, and lists by building a cat photo app.
|
||||
|
||||
Begin the workshop by adding an `h1` element with the text of `CatPhotoApp`.
|
||||
|
||||
# --hints--
|
||||
|
||||
The text `CatPhotoApp` should be present in the code. You may want to check your spelling.
|
||||
|
||||
```js
|
||||
assert.match(code, /catphotoapp/i);
|
||||
```
|
||||
|
||||
Your `h1` element should have an opening tag. Opening tags have this syntax: `<elementName>`.
|
||||
|
||||
```js
|
||||
assert.exists(document.querySelector('h1'));
|
||||
```
|
||||
|
||||
Your `h1` tags should be in lowercase. By convention, all HTML tags are written in lowercase.
|
||||
|
||||
```js
|
||||
assert.notMatch(code, /<\/?H1>/);
|
||||
```
|
||||
|
||||
Your `h1` element should have a closing tag. Closing tags have this syntax: `</elementName>`.
|
||||
|
||||
```js
|
||||
assert.match(code, /<\/h1\>/);
|
||||
```
|
||||
|
||||
Your `h1` element's text should be `CatPhotoApp`. You have either omitted the text, have a typo, or it is not between the `h1` element's opening and closing tags.
|
||||
|
||||
```js
|
||||
assert.equal(document.querySelector('h1')?.innerText.toLowerCase(), 'catphotoapp');
|
||||
```
|
||||
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
@@ -1,86 +0,0 @@
|
||||
---
|
||||
id: 5dc1798ff86c76b9248c6eb3
|
||||
title: Step 2
|
||||
challengeType: 0
|
||||
dashedName: step-2
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Below the `h1` element, add an `h2` element with this text:
|
||||
|
||||
`Cat Photos`
|
||||
|
||||
# --hints--
|
||||
|
||||
Your `h1` element should have an opening tag. Opening tags have this syntax: `<elementName>`.
|
||||
|
||||
```js
|
||||
assert.exists(document.querySelector('h1'));
|
||||
```
|
||||
|
||||
Your `h1` element should have a closing tag. Closing tags have this syntax: `</elementName>`.
|
||||
|
||||
```js
|
||||
assert.match(code, /<\/h1\>/);
|
||||
```
|
||||
|
||||
You should only have one `h1` element. Remove the extra.
|
||||
|
||||
```js
|
||||
assert.lengthOf(document.querySelectorAll('h1'), 1);
|
||||
```
|
||||
|
||||
Your `h1` element's text should be 'CatPhotoApp'. You have either omitted the text or have a typo.
|
||||
|
||||
```js
|
||||
assert.equal(document.querySelector('h1')?.innerText.toLowerCase(), 'catphotoapp');
|
||||
```
|
||||
|
||||
Your `h2` tags should be in lowercase. By convention, all HTML tags are written in lowercase.
|
||||
|
||||
```js
|
||||
assert.notMatch(code, /<\/?H2>/);
|
||||
```
|
||||
|
||||
Your `h2` element should have an opening tag. Opening tags have this syntax: `<elementName>`.
|
||||
|
||||
```js
|
||||
assert.exists(document.querySelector('h2'));
|
||||
```
|
||||
|
||||
Your `h2` element should have a closing tag. Closing tags have a `/` just after the `<` character.
|
||||
|
||||
```js
|
||||
assert.match(code, /<\/h2\>/);
|
||||
```
|
||||
|
||||
Your `h2` element's text should be `Cat Photos`. Only place the text `Cat Photos` between the opening and closing `h2` tags.
|
||||
|
||||
```js
|
||||
assert.equal(document.querySelector('h2')?.innerText.toLowerCase(), 'cat photos');
|
||||
```
|
||||
|
||||
Your `h2` element should be below the `h1` element. The `h1` element has greater importance and must be above the `h2` element.
|
||||
|
||||
```js
|
||||
const collection = [...document.querySelectorAll('h1,h2')].map(
|
||||
(node) => node.nodeName
|
||||
);
|
||||
assert.isBelow(collection.indexOf('H1'), collection.indexOf('H2'));
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
--fcc-editable-region--
|
||||
<h1>CatPhotoApp</h1>
|
||||
|
||||
--fcc-editable-region--
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
@@ -1,66 +0,0 @@
|
||||
---
|
||||
id: 5dc17d3bf86c76b9248c6eb4
|
||||
title: Step 3
|
||||
challengeType: 0
|
||||
dashedName: step-3
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Create a `p` element below your `h2` element and give it the following text:
|
||||
|
||||
`Everyone loves cute cats online!`
|
||||
|
||||
# --hints--
|
||||
|
||||
Your `p` element should have an opening tag. Opening tags have the following syntax: `<elementName>`.
|
||||
|
||||
```js
|
||||
assert.exists(document.querySelector('p'));
|
||||
```
|
||||
|
||||
Your `p` tags should be in lowercase. By convention, all HTML tags are written in lowercase.
|
||||
|
||||
```js
|
||||
assert.notMatch(code, /<\/?P>/);
|
||||
```
|
||||
|
||||
Your `p` element should have a closing tag. Closing tags have a `/` just after the `<` character.
|
||||
|
||||
```js
|
||||
assert.match(code, /<\/p\>/);
|
||||
```
|
||||
|
||||
Your `p` element's text should be `Everyone loves cute cats online!` You have either omitted the text or have a typo.
|
||||
|
||||
```js
|
||||
const extraSpacesRemoved = document
|
||||
.querySelector('p')
|
||||
?.innerText.replace(/\s+/g, ' ');
|
||||
assert.match(extraSpacesRemoved, /everyone loves cute cats online!$/i);
|
||||
```
|
||||
|
||||
Your `p` element should be below the `h2` element. You have them in the wrong order.
|
||||
|
||||
```js
|
||||
const collection = [...document.querySelectorAll('h2,p')].map(
|
||||
(node) => node.nodeName
|
||||
);
|
||||
assert.isBelow(collection.indexOf('H2'), collection.indexOf('P'));
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
<h1>CatPhotoApp</h1>
|
||||
--fcc-editable-region--
|
||||
<h2>Cat Photos</h2>
|
||||
|
||||
--fcc-editable-region--
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
@@ -1,88 +0,0 @@
|
||||
---
|
||||
id: 5dc17dc8f86c76b9248c6eb5
|
||||
title: Step 4
|
||||
challengeType: 0
|
||||
dashedName: step-4
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Commenting allows you to leave messages without affecting the browser display. It also allows you to make code inactive. A comment in HTML starts with `<!--`, contains any number of lines of text, and ends with `-->`.
|
||||
|
||||
Here is an example of a comment with the `TODO: Remove h1`:
|
||||
|
||||
```html
|
||||
<!-- TODO: Remove h1 -->
|
||||
```
|
||||
|
||||
Add a comment above the `p` element with this text:
|
||||
|
||||
`TODO: Add link to cat photos`
|
||||
|
||||
# --hints--
|
||||
|
||||
Your comment should start with `<!--`. You are missing one or more of the characters that define the start of a comment.
|
||||
|
||||
```js
|
||||
assert.match(code, /<!--/);
|
||||
```
|
||||
|
||||
Your comment should end with `-->`. You are missing one or more of the characters that define the end of a comment.
|
||||
|
||||
```js
|
||||
assert.match(code, /-->/);
|
||||
```
|
||||
|
||||
Your code should not have extra opening/closing comment characters. You have an extra `<!--` or `-->` displaying in the browser.
|
||||
|
||||
```js
|
||||
const noSpaces = code.replace(/\s/g, '');
|
||||
assert.isBelow(noSpaces.match(/<!--/g)?.length, 2)
|
||||
assert.isBelow(noSpaces.match(/-->/g)?.length, 2);
|
||||
```
|
||||
|
||||
Your comment should be above the `p` element. You have them in the wrong order.
|
||||
|
||||
```js
|
||||
assert.match(
|
||||
code.replace(/\s/g, ''),
|
||||
/<!--(.*?)--><p>everyonelovescutecatsonline!<\/p>/i
|
||||
);
|
||||
```
|
||||
|
||||
Your comment should contain the text `TODO: Add link to cat photos`.
|
||||
|
||||
```js
|
||||
assert.match(code, /<!--\s*todo:\s+add\s+link\s+to\s+cat\s+photos\s*-->/i);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
<h1>CatPhotoApp</h1>
|
||||
<h2>Cat Photos</h2>
|
||||
--fcc-editable-region--
|
||||
|
||||
<p>Everyone loves cute cats online!</p>
|
||||
|
||||
--fcc-editable-region--
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
<h1>CatPhotoApp</h1>
|
||||
<h2>Cat Photos</h2>
|
||||
<!-- TODO: Add link to cat photos -->
|
||||
<p>Everyone loves cute cats online!</p>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
@@ -1,335 +0,0 @@
|
||||
---
|
||||
id: 66ebd4ae2812430bb883c787
|
||||
title: Build an Event Hub
|
||||
challengeType: 25
|
||||
dashedName: lab-event-hub
|
||||
demoType: onClick
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In this lab you will utilize the semantic HTML elements to create the structure of a web page. You'll add content and images to make it look like a real event hub.
|
||||
|
||||
Fulfill the user stories below and get all the tests to pass to complete the lab.
|
||||
|
||||
**User Stories:**
|
||||
|
||||
1. You should have a `header` element.
|
||||
1. Inside the `header` element, you should have an `h1` element that contains the text `Event Hub`, and a `nav` element.
|
||||
1. Inside the `nav` element, you should have an unordered list of two items containing links to different sections of the page. The first item should have the text `Upcoming Events`, and the second item should have the text `Past Events`.
|
||||
1. Each link should be represented by an `a` element with an `href` attribute that links to the corresponding section of the page, `#upcoming-events` and `#past-events` respectively.
|
||||
1. You should have a `main` element that contains the different sections of the page.
|
||||
1. Inside the `main` element, you should have two `section` elements.
|
||||
1. The first `section` element should have an `id` attribute with the value `upcoming-events`
|
||||
1. Inside the `#upcoming-events` section, you should have:
|
||||
|
||||
- An `h2` element with the text `Upcoming Events`.
|
||||
- Two `article` elements. Each article should represent an event, and it should have :
|
||||
- An `h3` element for the event title.
|
||||
- A `p` element for the event description. You can add a date at the bottom if you like.
|
||||
|
||||
1. The second `section` element should have an `id` attribute with the value `past-events`.
|
||||
1. Inside the `#past-events` section, you should have:
|
||||
|
||||
- An `h2` element with the text `Past Events`.
|
||||
- Two `article` elements. Each article element should represent a past event, and it should have:
|
||||
- An `h3` element for the event title,
|
||||
- A `p` element for the event description. You can add a date at the bottom if you like.
|
||||
- An image element with the `src` attribute pointing to an image file and the `alt` attribute with a description of the image.
|
||||
|
||||
**Note:** You can use any text for the event descriptions and dates. You can use the following image URLs for the images if you like:
|
||||
|
||||
- `https://cdn.freecodecamp.org/curriculum/labs/past-event1.jpg`.
|
||||
- `https://cdn.freecodecamp.org/curriculum/labs/past-event2.jpg`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have a `header` element.
|
||||
|
||||
```js
|
||||
assert.isNotNull(document.querySelector("header"));
|
||||
```
|
||||
|
||||
Your `header` element should come after the opening `body` tag.
|
||||
|
||||
```js
|
||||
assert.equal(document.querySelector("body")?.firstElementChild?.tagName, "HEADER");
|
||||
```
|
||||
|
||||
Inside the `header` element, you should have an `h1` element that contains the text `Event Hub`.
|
||||
|
||||
```js
|
||||
const h1Element = document.querySelector('header h1');
|
||||
assert.strictEqual(h1Element?.innerText, "Event Hub");
|
||||
```
|
||||
|
||||
Inside the `header` element, after the `h1` element, you should have a `nav` element.
|
||||
|
||||
```js
|
||||
assert.isNotNull(document.querySelector("header>h1+nav"));
|
||||
```
|
||||
|
||||
Your `nav` element should contain an unordered list of two items.
|
||||
|
||||
```js
|
||||
const liElements = document.querySelectorAll('header nav>ul>li');
|
||||
|
||||
assert.isNotNull('header nav>ul');
|
||||
assert.strictEqual(liElements.length, 2);
|
||||
```
|
||||
|
||||
The first item in the unordered list should be a link.
|
||||
|
||||
```js
|
||||
const firstLink = document.querySelectorAll('header nav ul li a')[0];
|
||||
assert.exists(firstLink);
|
||||
```
|
||||
|
||||
The second item in the unordered list should be a link.
|
||||
|
||||
```js
|
||||
const secondLink = document.querySelectorAll('header nav ul li a')[1];
|
||||
assert.exists(secondLink);
|
||||
```
|
||||
|
||||
The text of the first item in the unordered list should be `Upcoming Events`.
|
||||
|
||||
```js
|
||||
const firstLink = document.querySelectorAll('header nav>ul>li>a')[0];
|
||||
assert.strictEqual(firstLink.innerText, "Upcoming Events");
|
||||
```
|
||||
|
||||
The first item in the unordered list should have the `href` set to `#upcoming-events`.
|
||||
|
||||
```js
|
||||
const anchorElement = document.querySelectorAll("header nav>ul>li>a")[0];
|
||||
const hrefAttribute = anchorElement?.getAttribute("href");
|
||||
assert.strictEqual(hrefAttribute, "#upcoming-events");
|
||||
```
|
||||
|
||||
The text of the second item in the unordered list should be `Past Events`.
|
||||
|
||||
```js
|
||||
const secondLink = document.querySelectorAll('header nav>ul>li>a')[1];
|
||||
assert.strictEqual(secondLink.innerText, "Past Events");
|
||||
```
|
||||
|
||||
The second item in the unordered list should have the `href` set to `#past-events`.
|
||||
|
||||
```js
|
||||
const anchorElement = document.querySelectorAll("header nav>ul>li>a")[1];
|
||||
const hrefAttribute = anchorElement?.getAttribute("href");
|
||||
assert.strictEqual(hrefAttribute, "#past-events");
|
||||
```
|
||||
|
||||
You should have a `main` element after the `header` element closing tag.
|
||||
|
||||
```js
|
||||
const mainElement = document.querySelector("body>header+main");
|
||||
assert.isNotNull(mainElement);
|
||||
```
|
||||
|
||||
Inside the `main` element, you should have two `section` elements.
|
||||
|
||||
```js
|
||||
const sectionElements = document.querySelectorAll('body>header+main>section');
|
||||
assert.strictEqual(sectionElements.length, 2);
|
||||
```
|
||||
|
||||
Your first `section` element should have an `id` attribute with the value `upcoming-events`.
|
||||
|
||||
```js
|
||||
const firstSection = document.querySelectorAll('body>header+main>section')[0];
|
||||
const idAttribute = firstSection?.getAttribute("id");
|
||||
assert.strictEqual(idAttribute, "upcoming-events");
|
||||
```
|
||||
|
||||
Your second `section` element should have an `id` attribute with the value `past-events`.
|
||||
|
||||
```js
|
||||
const secondSection = document.querySelectorAll('body>header+main>section')[1];
|
||||
const idAttribute = secondSection?.getAttribute("id");
|
||||
assert.strictEqual(idAttribute, "past-events");
|
||||
```
|
||||
|
||||
Inside the `#upcoming-events` section, you should have an `h2` element with the text `Upcoming Events`.
|
||||
|
||||
```js
|
||||
const h2Element = document.querySelector('#upcoming-events h2');
|
||||
assert.strictEqual(h2Element?.innerText, "Upcoming Events");
|
||||
```
|
||||
|
||||
Inside the `#upcoming-events` section, you should have two `article` elements below the `h2` element.
|
||||
|
||||
```js
|
||||
const articleElements = document.querySelectorAll('#upcoming-events h2 ~ article');
|
||||
assert.strictEqual(articleElements.length, 2);
|
||||
```
|
||||
|
||||
Both of the `article` elements inside the `#upcoming-events` section should have an `h3` element for the event title.
|
||||
|
||||
```js
|
||||
const h3Elements = document.querySelectorAll('#upcoming-events article h3');
|
||||
assert.strictEqual(h3Elements.length, 2);
|
||||
```
|
||||
|
||||
Both of the `article` elements inside the `#upcoming-events` section should have a paragraph element for the event description.
|
||||
|
||||
```js
|
||||
const articles = document.querySelectorAll('#upcoming-events article');
|
||||
assert.isNotEmpty(articles);
|
||||
articles.forEach(article => {
|
||||
assert.isAtLeast(article.querySelectorAll('h3 ~ p').length, 1);
|
||||
});
|
||||
```
|
||||
|
||||
Inside the `#past-events` section, you should have an `h2` element with the text `Past Events`.
|
||||
|
||||
```js
|
||||
const h2Element = document.querySelector('#past-events h2');
|
||||
assert.strictEqual(h2Element?.innerText, "Past Events");
|
||||
```
|
||||
|
||||
Inside the `#past-events` section, you should have two `article` elements below the `h2` element.
|
||||
|
||||
```js
|
||||
const articleElements = document.querySelectorAll('#past-events h2 ~ article');
|
||||
assert.strictEqual(articleElements.length, 2);
|
||||
```
|
||||
|
||||
Both of the `article` elements inside the `#past-events` section should have an `h3` element for the event title.
|
||||
|
||||
```js
|
||||
const h3Elements = document.querySelectorAll('#past-events article h3');
|
||||
assert.strictEqual(h3Elements.length, 2);
|
||||
```
|
||||
|
||||
Both of the `article` elements inside the `#past-events` section should have a paragraph element for the event description.
|
||||
|
||||
```js
|
||||
const articles = document.querySelectorAll('#past-events article');
|
||||
assert.isNotEmpty(articles);
|
||||
articles.forEach(article => {
|
||||
assert.isAtLeast(article.querySelectorAll('h3 ~ p').length, 1);
|
||||
});
|
||||
```
|
||||
|
||||
Both of the `article` elements inside the `#past-events` section should have an image element.
|
||||
|
||||
```js
|
||||
const imgElements = document.querySelectorAll('#past-events article img');
|
||||
assert.strictEqual(imgElements.length, 2);
|
||||
```
|
||||
|
||||
Both of the image elements inside the `#past-events` section should have the `src` attribute pointing to an image file.
|
||||
|
||||
```js
|
||||
const imgElements = document.querySelectorAll('#past-events article img');
|
||||
assert.strictEqual(imgElements.length, 2);
|
||||
|
||||
for (let img of imgElements) {
|
||||
assert.exists(img.getAttribute("src"));
|
||||
}
|
||||
```
|
||||
|
||||
Both of the image elements inside the `#past-events` section should have the `alt` attribute with a description of the image.
|
||||
|
||||
```js
|
||||
const imgElements = document.querySelectorAll('#past-events article img');
|
||||
assert.strictEqual(imgElements.length, 2);
|
||||
|
||||
for (let img of imgElements) {
|
||||
assert.exists(img.getAttribute("alt"));
|
||||
}
|
||||
```
|
||||
|
||||
Each `h3` element should have the event title.
|
||||
|
||||
```js
|
||||
const eventTitles = document.querySelectorAll('h3');
|
||||
assert.isNotEmpty(eventTitles);
|
||||
eventTitles.forEach((eventTitle => assert.isNotEmpty(eventTitle.innerText)));
|
||||
```
|
||||
|
||||
Each `p` element should have the event description.
|
||||
|
||||
```js
|
||||
const eventDescriptions = document.querySelectorAll('p');
|
||||
assert.isNotEmpty(eventDescriptions);
|
||||
eventDescriptions.forEach((eventDescription => assert.isNotEmpty(eventDescription.innerText)));
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Event Hub</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Event Hub</title>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<h1>Event Hub</h1>
|
||||
<nav>
|
||||
<ul>
|
||||
<li><a href="#upcoming-events">Upcoming Events</a></li>
|
||||
<li><a href="#past-events">Past Events</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
<main>
|
||||
<section id="upcoming-events">
|
||||
<h2>Upcoming Events</h2>
|
||||
<article>
|
||||
<h3>AI & Machine Learning Conference 2024</h3>
|
||||
<p>Join us for a deep dive into the latest advancements in artificial intelligence and machine learning. Industry leaders will share insights and case studies on how AI is transforming various sectors.</p>
|
||||
<p>Date: August 10, 2024</p>
|
||||
</article>
|
||||
<article>
|
||||
<h3>Web Development Bootcamp</h3>
|
||||
<p>A hands-on workshop designed for developers looking to enhance their skills in modern web technologies including React, Node.js, and GraphQL. Perfect for both beginners and experienced developers.</p>
|
||||
<p>Date: September 5, 2024</p>
|
||||
</article>
|
||||
</section>
|
||||
<section id="past-events">
|
||||
<h2>Past Events</h2>
|
||||
<article>
|
||||
<h3>Cybersecurity Summit 2024</h3>
|
||||
<p>An event focusing on the latest trends and threats in cybersecurity. Experts discussed strategies for protecting data and ensuring privacy in an increasingly digital world.</p>
|
||||
<p>Date: June 15, 2024</p>
|
||||
<img src="https://cdn.freecodecamp.org/curriculum/labs/past-event1.jpg" alt="Image from Cybersecurity Summit 2024">
|
||||
</article>
|
||||
<article>
|
||||
<h3>Blockchain Expo 2024</h3>
|
||||
<p>A comprehensive event covering the future of blockchain technology. Topics included decentralized finance (DeFi), smart contracts, and the impact of blockchain on various industries.</p>
|
||||
<p>Date: July 20, 2024</p>
|
||||
<img src="https://cdn.freecodecamp.org/curriculum/labs/past-event2.jpg" alt="Image from Blockchain Expo 2024">
|
||||
</article>
|
||||
</section>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
---
|
||||
id: a9f9c5bf295034800d6c77ad
|
||||
title: Building a Better Calculator
|
||||
challengeType: 11
|
||||
videoId: lOltMrA6kuY
|
||||
dashedName: building-a-better-calculator-learn-python-full-course-for-beginners
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In this video, you will learn how to build an improved calculator program using if statements.
|
||||
|
||||
# --questions--
|
||||
|
||||
## --text--
|
||||
|
||||
Which of the following built-in functions is used to convert a string to a float?
|
||||
|
||||
## --answers--
|
||||
|
||||
`floats()`
|
||||
|
||||
---
|
||||
|
||||
`floating_point()`
|
||||
|
||||
---
|
||||
|
||||
`float()`
|
||||
|
||||
---
|
||||
|
||||
`fl()`
|
||||
|
||||
## --video-solution--
|
||||
|
||||
3
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
---
|
||||
id: 58d5d031e969765037c1bebb
|
||||
title: Functions
|
||||
challengeType: 11
|
||||
videoId: QN3UNoJVS9g
|
||||
dashedName: functions-learn-python-full-course-for-beginners
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In this video, you will learn how to define and call a function.
|
||||
|
||||
# --questions--
|
||||
|
||||
## --text--
|
||||
|
||||
Which of the following is the correct way to call a function?
|
||||
|
||||
## --answers--
|
||||
|
||||
```python
|
||||
def sayhi():
|
||||
print("Hello World")
|
||||
|
||||
sayhi()()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```python
|
||||
def sayhi():
|
||||
print("Hello World")
|
||||
|
||||
()sayhi()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```python
|
||||
def sayhi():
|
||||
print("Hello World")
|
||||
|
||||
sayhi
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```python
|
||||
def sayhi():
|
||||
print("Hello World")
|
||||
|
||||
sayhi()
|
||||
```
|
||||
|
||||
## --video-solution--
|
||||
|
||||
4
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
---
|
||||
id: 8314d0bbddb0aa027a144705
|
||||
title: If Statements and Comparisons
|
||||
challengeType: 11
|
||||
videoId: frb0CCrS9X8
|
||||
dashedName: if-statements-and-comparisons-learn-python-full-course-for-beginners
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In this video, you will learn about comparison operators.
|
||||
|
||||
# --questions--
|
||||
|
||||
## --text--
|
||||
|
||||
Which of the following operators is used to check if one number is greater than or equal to another number?
|
||||
|
||||
## --answers--
|
||||
|
||||
`<`
|
||||
|
||||
---
|
||||
|
||||
`<=`
|
||||
|
||||
---
|
||||
|
||||
`>`
|
||||
|
||||
---
|
||||
|
||||
`>=`
|
||||
|
||||
## --video-solution--
|
||||
|
||||
4
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
---
|
||||
id: 08854a2c6f052efa1e5270d2
|
||||
title: If Statements
|
||||
challengeType: 11
|
||||
videoId: lruoyNlItfg
|
||||
dashedName: if-statements-learn-python-full-course-for-beginners
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In this video, you will learn how to use if statements to control the flow of your Python programs based on conditions.
|
||||
|
||||
# --questions--
|
||||
|
||||
## --text--
|
||||
|
||||
What will be the output for the following code?
|
||||
|
||||
```python
|
||||
is_male = True
|
||||
is_tall = True
|
||||
|
||||
if is_male or is_tall:
|
||||
print("You are a male")
|
||||
else:
|
||||
print("You are not a male")
|
||||
```
|
||||
|
||||
## --answers--
|
||||
|
||||
`"You are not a male"`
|
||||
|
||||
---
|
||||
|
||||
`"You are a male"`
|
||||
|
||||
---
|
||||
|
||||
`"You are not a male" and "You are a male"`
|
||||
|
||||
---
|
||||
|
||||
`None`
|
||||
|
||||
## --video-solution--
|
||||
|
||||
2
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
---
|
||||
id: c6c9dae4017830e187eeaf42
|
||||
title: Return Statement
|
||||
challengeType: 11
|
||||
videoId: Gx3VTsaMCHU
|
||||
dashedName: return-statement-learn-python-full-course-for-beginners
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In this video, you will learn how to use the return statement in functions.
|
||||
|
||||
# --questions--
|
||||
|
||||
## --text--
|
||||
|
||||
What will be the output for the following code?
|
||||
|
||||
```python
|
||||
def cube(num):
|
||||
num*num*num
|
||||
|
||||
print(cube(3))
|
||||
```
|
||||
|
||||
## --answers--
|
||||
|
||||
`None`
|
||||
|
||||
---
|
||||
|
||||
`Undefined`
|
||||
|
||||
---
|
||||
|
||||
`3`
|
||||
|
||||
---
|
||||
|
||||
`27`
|
||||
|
||||
## --video-solution--
|
||||
|
||||
1
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
---
|
||||
id: 62baa9d28e8723f635a0093e
|
||||
title: Drawing a Shape
|
||||
challengeType: 11
|
||||
videoId: vcNZZSeyZkY
|
||||
dashedName: drawing-a-shape-learn-python-full-course-for-beginners
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In this video, you will learn how to print a basic shape to the console using `print` statements.
|
||||
|
||||
# --questions--
|
||||
|
||||
## --text--
|
||||
|
||||
Which of the following is the correct way to print a triangle to the console?
|
||||
|
||||
## --answers--
|
||||
|
||||
```python
|
||||
print(" /| / | / | /___|")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```python
|
||||
print( /|)
|
||||
print( / |)
|
||||
print( / |)
|
||||
print(/___|)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```python
|
||||
print(" /|")
|
||||
print(" / |")
|
||||
print(" / |")
|
||||
print("/___|")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```python
|
||||
print(" /|")
|
||||
print(" / |")
|
||||
print(" / |")
|
||||
print("/___|")
|
||||
```
|
||||
|
||||
## --video-solution--
|
||||
|
||||
4
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
---
|
||||
id: 8ad37ddb7a23050f71cc9cc9
|
||||
title: Working with Numbers
|
||||
challengeType: 11
|
||||
videoId: C7sxe5GAArQ
|
||||
dashedName: working-with-numbers-learn-python-full-course-for-beginners
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In this video, you will learn how to work with basic arithmetic operations and built-in number functions.
|
||||
|
||||
# --questions--
|
||||
|
||||
## --text--
|
||||
|
||||
Which of the following built-in functions is used to return the base number raised to a power?
|
||||
|
||||
## --answers--
|
||||
|
||||
`base()`
|
||||
|
||||
---
|
||||
|
||||
`power()`
|
||||
|
||||
---
|
||||
|
||||
`pow()`
|
||||
|
||||
---
|
||||
|
||||
`exp()`
|
||||
|
||||
## --video-solution--
|
||||
|
||||
3
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
---
|
||||
id: 0e2f4bd857b1edc70bfcd1f9
|
||||
title: Working with Strings
|
||||
challengeType: 11
|
||||
videoId: OrejgL7kP3M
|
||||
dashedName: working-with-strings-learn-python-full-course-for-beginners
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In this video, you will learn about string concatenation, indexing, and useful string methods.
|
||||
|
||||
# --questions--
|
||||
|
||||
## --text--
|
||||
|
||||
Which of the following is the correct way to access the first character of a string?
|
||||
|
||||
## --answers--
|
||||
|
||||
```python
|
||||
phrase = "Giraffe Academy"
|
||||
print(phrase[1])
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```python
|
||||
phrase = "Giraffe Academy"
|
||||
print(phrase[0])
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```python
|
||||
phrase = "Giraffe Academy"
|
||||
print(phrase[-1])
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```python
|
||||
phrase = "Giraffe Academy"
|
||||
print(phrase[2])
|
||||
```
|
||||
|
||||
## --video-solution--
|
||||
|
||||
2
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
---
|
||||
id: 155ca30775751b78a860a79b
|
||||
title: Getting Input from Users
|
||||
challengeType: 11
|
||||
videoId: C0L4cnqKqDw
|
||||
dashedName: getting-input-from-users-learn-python-full-course-for-beginners
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In this video, you will learn how to get input from the user.
|
||||
|
||||
# --questions--
|
||||
|
||||
## --text--
|
||||
|
||||
Which of the following built-in functions is used to get input from the user?
|
||||
|
||||
## --answers--
|
||||
|
||||
`input()`
|
||||
|
||||
---
|
||||
|
||||
`os.stdin()`
|
||||
|
||||
---
|
||||
|
||||
`stdin()`
|
||||
|
||||
---
|
||||
|
||||
`prompt()`
|
||||
|
||||
## --video-solution--
|
||||
|
||||
1
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
---
|
||||
id: 315017f4457c19d45c2be034
|
||||
title: Variables and Data Types
|
||||
challengeType: 11
|
||||
videoId: sIw317W39X0
|
||||
dashedName: variables-and-data-types-learn-python-full-course-for-beginners
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In this video, you will learn about the different data types in Python including integers, strings and booleans.
|
||||
|
||||
# --questions--
|
||||
|
||||
## --text--
|
||||
|
||||
What is a boolean?
|
||||
|
||||
## --answers--
|
||||
|
||||
It is a data type that represents an `undefined` value.
|
||||
|
||||
---
|
||||
|
||||
It is a data type that represents a sequence of characters.
|
||||
|
||||
---
|
||||
|
||||
It is a data type that represents `True` or `False`.
|
||||
|
||||
---
|
||||
|
||||
It is a data type that represents a float.
|
||||
|
||||
## --video-solution--
|
||||
|
||||
3
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
---
|
||||
id: 24a45b3960b3aa68dff2cd9e
|
||||
title: List Functions
|
||||
challengeType: 11
|
||||
videoId: _5FQ5f3RW5U
|
||||
dashedName: list-functions-learn-python-full-course-for-beginners
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In this video, you will learn how to work with useful methods including the `append()`, `index()`, `clear()`, `sort()`, and `reverse()` methods.
|
||||
|
||||
# --questions--
|
||||
|
||||
## --text--
|
||||
|
||||
What will be the output for the following code?
|
||||
|
||||
```python
|
||||
friends = ["Kevin", "Karen", "Jim", "Oscar", "Toby"]
|
||||
|
||||
print(friends.index("Oscar"))
|
||||
```
|
||||
|
||||
## --answers--
|
||||
|
||||
4
|
||||
|
||||
---
|
||||
|
||||
1
|
||||
|
||||
---
|
||||
|
||||
2
|
||||
|
||||
---
|
||||
|
||||
3
|
||||
|
||||
## --video-solution--
|
||||
|
||||
4
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
---
|
||||
id: 39a400e9163c5a0b33587e18
|
||||
title: Lists
|
||||
challengeType: 11
|
||||
videoId: DtMPzGOHZ2M
|
||||
dashedName: lists-learn-python-full-course-for-beginners
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In this video, you will learn about lists, list indexing, slicing, and basic list operations.
|
||||
|
||||
# --questions--
|
||||
|
||||
## --text--
|
||||
|
||||
What will be the output for the following code?
|
||||
|
||||
```python
|
||||
friends = ["Kevin", "Karen", "Jim"]
|
||||
print(friends[-1])
|
||||
```
|
||||
|
||||
## --answers--
|
||||
|
||||
`"Kevin"`
|
||||
|
||||
---
|
||||
|
||||
`"Jim"`
|
||||
|
||||
---
|
||||
|
||||
`"Karen"`
|
||||
|
||||
---
|
||||
|
||||
`Error`
|
||||
|
||||
## --video-solution--
|
||||
|
||||
2
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
---
|
||||
id: 5ed596ba3306cf2c1a94bb92
|
||||
title: Tuples
|
||||
challengeType: 11
|
||||
videoId: g6fwjiEFG-Y
|
||||
dashedName: tuples-learn-python-full-course-for-beginners
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In this video, you will learn about tuples in Python and how they differ from lists.
|
||||
|
||||
# --questions--
|
||||
|
||||
## --text--
|
||||
|
||||
Which of the following is the correct way to create a tuple?
|
||||
|
||||
## --answers--
|
||||
|
||||
```python
|
||||
coordinates = [4, 5]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```python
|
||||
coordinates = (4, 5)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```python
|
||||
coordinates = <4, 5>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```python
|
||||
coordinates = /4, 5/
|
||||
```
|
||||
|
||||
## --video-solution--
|
||||
|
||||
2
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
---
|
||||
id: a0339c4075344cbfc2cd939c
|
||||
title: Classes and Objects
|
||||
challengeType: 11
|
||||
videoId: fR3dh5_MPJs
|
||||
dashedName: classes-and-objects-learn-python-full-course-for-beginners
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In this video, you will learn how to create classes and objects in Python to write object-oriented programs.
|
||||
|
||||
# --questions--
|
||||
|
||||
## --text--
|
||||
|
||||
What is the role of `def __init__(self):` inside of a class?
|
||||
|
||||
## --answers--
|
||||
|
||||
It represents a function for calling the method.
|
||||
|
||||
---
|
||||
|
||||
It specifies the type of the class.
|
||||
|
||||
---
|
||||
|
||||
It allows a class to inherit methods from another class.
|
||||
|
||||
---
|
||||
|
||||
It represents an initializer method.
|
||||
|
||||
## --video-solution--
|
||||
|
||||
4
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
---
|
||||
id: 697fe5c032baa3841ab62a64
|
||||
title: Inheritance
|
||||
challengeType: 11
|
||||
videoId: uHdNSULVpgY
|
||||
dashedName: inheritance-learn-python-full-course-for-beginners
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In this video, you will learn about inheritance in object oriented programming.
|
||||
|
||||
# --questions--
|
||||
|
||||
## --text--
|
||||
|
||||
What is inheritance in object oriented programming?
|
||||
|
||||
## --answers--
|
||||
|
||||
This is when a class reuses code from a function.
|
||||
|
||||
---
|
||||
|
||||
This is when a class creates a copy of another class.
|
||||
|
||||
---
|
||||
|
||||
This is when a class inherits properties and behaviors from another class.
|
||||
|
||||
---
|
||||
|
||||
This is when a class hides its methods and variables from other classes.
|
||||
|
||||
## --video-solution--
|
||||
|
||||
3
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
---
|
||||
id: 697fe6c932baa3841ab62a65
|
||||
title: Python Interpreter
|
||||
challengeType: 11
|
||||
videoId: -c1vFEsIod4
|
||||
dashedName: python-interpreter-learn-python-full-course-for-beginners
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In this video, you will learn how to work with the Python interpreter.
|
||||
|
||||
# --questions--
|
||||
|
||||
## --text--
|
||||
|
||||
What is the Python interpreter?
|
||||
|
||||
## --answers--
|
||||
|
||||
This is a program that writes Python code for you.
|
||||
|
||||
---
|
||||
|
||||
This is a tool that compiles Python into Java or C++.
|
||||
|
||||
---
|
||||
|
||||
This is a library that stores Python functions.
|
||||
|
||||
---
|
||||
|
||||
This is a program that reads and executes Python code.
|
||||
|
||||
## --video-solution--
|
||||
|
||||
4
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
---
|
||||
id: 697fe3cb32baa3841ab62a63
|
||||
title: Object Functions
|
||||
challengeType: 11
|
||||
videoId: 3Mla2uUDSu8
|
||||
dashedName: object-functions-learn-python-full-course-for-beginners
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In this video, you will learn how to work with functions inside of classes.
|
||||
|
||||
# --questions--
|
||||
|
||||
## --text--
|
||||
|
||||
Which of the following is the correct way to create a function inside of a class?
|
||||
|
||||
## --answers--
|
||||
|
||||
```python
|
||||
class Student:
|
||||
def __init__(self, name, age):
|
||||
self.name = name
|
||||
self.age = age
|
||||
|
||||
def greet(self.function):
|
||||
return f"Hello, my name is {self.name} and I am {self.age} years old."
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```python
|
||||
class Student:
|
||||
def __init__(self, name, age):
|
||||
self.name = name
|
||||
self.age = age
|
||||
|
||||
def greet(self):
|
||||
return f"Hello, my name is {self.name} and I am {self.age} years old."
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```python
|
||||
class Student:
|
||||
def __init__(self, name, age):
|
||||
self.name = name
|
||||
self.age = age
|
||||
|
||||
def greet(self):
|
||||
self.pass
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```python
|
||||
class Student:
|
||||
def __init__(self, name, age):
|
||||
self.name = name
|
||||
self.age = age
|
||||
|
||||
greet = (self):
|
||||
return f"Hello, my name is {self.name} and I am {self.age} years old."
|
||||
```
|
||||
|
||||
## --video-solution--
|
||||
|
||||
2
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
---
|
||||
id: 9afe5e8141b13e9f1d59d46e
|
||||
title: Building a Multiple Choice Quiz
|
||||
challengeType: 11
|
||||
videoId: GJMmSaB8RN0
|
||||
dashedName: building-a-multiple-choice-quiz-learn-python-full-course-for-beginners
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In this video, you will practice what you have learned about classes and objects by building a multiple choice quiz.
|
||||
|
||||
# --questions--
|
||||
|
||||
## --text--
|
||||
|
||||
Which of the following is the correct way to import the `Question` class from the `Question` module?
|
||||
|
||||
## --answers--
|
||||
|
||||
`Question import`
|
||||
|
||||
---
|
||||
|
||||
`from Question`
|
||||
|
||||
---
|
||||
|
||||
`from Question import Question`
|
||||
|
||||
---
|
||||
|
||||
`import Question.py`
|
||||
|
||||
## --video-solution--
|
||||
|
||||
3
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
---
|
||||
id: 71ac60e6488b40e997219f15
|
||||
title: Comments
|
||||
challengeType: 11
|
||||
videoId: CY-CMJIt1z8
|
||||
dashedName: comments-learn-python-full-course-for-beginners
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In this video, you will learn how to write comments in Python to document your code and make it more readable.
|
||||
|
||||
# --questions--
|
||||
|
||||
## --text--
|
||||
|
||||
Which of the following is a single line comment in Python?
|
||||
|
||||
## --answers--
|
||||
|
||||
`# This program is cool`
|
||||
|
||||
---
|
||||
|
||||
`> This program is cool`
|
||||
|
||||
---
|
||||
|
||||
`''' This program is cool`
|
||||
|
||||
---
|
||||
|
||||
`// This program is cool`
|
||||
|
||||
## --video-solution--
|
||||
|
||||
1
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
---
|
||||
id: 2ccc34bd3f7bb4ae97a67ea3
|
||||
title: Modules and pip
|
||||
challengeType: 11
|
||||
videoId: HJ-dHUXmpcg
|
||||
dashedName: modules-and-pip-learn-python-full-course-for-beginners
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In this video, you will learn how to use modules and pip to extend Python's functionality with external packages.
|
||||
|
||||
# --questions--
|
||||
|
||||
## --text--
|
||||
|
||||
What is pip used for?
|
||||
|
||||
## --answers--
|
||||
|
||||
It is used to sort python modules.
|
||||
|
||||
---
|
||||
|
||||
It is used to explain python modules.
|
||||
|
||||
---
|
||||
|
||||
It is used to install python modules.
|
||||
|
||||
---
|
||||
|
||||
It is used to lint Python programs.
|
||||
|
||||
## --video-solution--
|
||||
|
||||
3
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
---
|
||||
id: 04e25c4fdc9ee0e71a844fd6
|
||||
title: Reading Files
|
||||
challengeType: 11
|
||||
videoId: enOW7u6LWyg
|
||||
dashedName: reading-files-learn-python-full-course-for-beginners
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In this video, you will learn how to read files in Python and process their contents.
|
||||
|
||||
# --questions--
|
||||
|
||||
## --text--
|
||||
|
||||
What is the role of the `"r"` in the `open()` function?
|
||||
|
||||
## --answers--
|
||||
|
||||
It specifies the range mode.
|
||||
|
||||
---
|
||||
|
||||
It specifies the rename mode.
|
||||
|
||||
---
|
||||
|
||||
It specifies the random access mode.
|
||||
|
||||
---
|
||||
|
||||
It specifies the read mode.
|
||||
|
||||
## --video-solution--
|
||||
|
||||
4
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
---
|
||||
id: 2a486e3e521b79b874fb5e9a
|
||||
title: Try/Except
|
||||
challengeType: 11
|
||||
videoId: 1tkhMom_SZw
|
||||
dashedName: try-except-learn-python-full-course-for-beginners
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In this video, you will learn how to handle exceptions using try/except blocks to make your programs more robust.
|
||||
|
||||
# --questions--
|
||||
|
||||
## --text--
|
||||
|
||||
What will be the result for the following code if the user provides the string `"random"`?
|
||||
|
||||
```python
|
||||
try:
|
||||
number = int(input("Enter a number: "))
|
||||
print(number)
|
||||
except:
|
||||
print("Invalid Input")
|
||||
```
|
||||
|
||||
## --answers--
|
||||
|
||||
Nothing will be output to the console.
|
||||
|
||||
---
|
||||
|
||||
The string `"random"` will be output to the console.
|
||||
|
||||
---
|
||||
|
||||
The string `"Invalid Input"` will be output to the console.
|
||||
|
||||
---
|
||||
|
||||
The program will crash.
|
||||
|
||||
## --video-solution--
|
||||
|
||||
3
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
---
|
||||
id: bfab38e6a6c1165f7774514d
|
||||
title: Writing to Files
|
||||
challengeType: 11
|
||||
videoId: QR95sRxsehY
|
||||
dashedName: writing-to-files-learn-python-full-course-for-beginners
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In this video, you will learn how to write data to files in Python.
|
||||
|
||||
# --questions--
|
||||
|
||||
## --text--
|
||||
|
||||
What is the role of the `"a"` in the `open()` function?
|
||||
|
||||
## --answers--
|
||||
|
||||
It specifies the append mode.
|
||||
|
||||
---
|
||||
|
||||
It specifies the alternate mode.
|
||||
|
||||
---
|
||||
|
||||
It specifies the access mode.
|
||||
|
||||
---
|
||||
|
||||
It specifies the apply mode.
|
||||
|
||||
## --video-solution--
|
||||
|
||||
1
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
---
|
||||
id: 28119f9dc5f93e3ac5d7c58a
|
||||
title: 2D Lists and Nested Loops
|
||||
challengeType: 11
|
||||
videoId: 2lKgjX3gzmM
|
||||
dashedName: 2d-lists-and-nested-loops-learn-python-full-course-for-beginners
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In this video, you will learn how to create 2D lists and use nested loops to work with multi-dimensional data structures.
|
||||
|
||||
# --questions--
|
||||
|
||||
## --text--
|
||||
|
||||
What will be the output for the following code?
|
||||
|
||||
```python
|
||||
number_grid = [
|
||||
[1, 2, 3],
|
||||
[4, 5, 6],
|
||||
[7, 8, 9]
|
||||
]
|
||||
|
||||
print(number_grid[2][1])
|
||||
```
|
||||
|
||||
## --answers--
|
||||
|
||||
8
|
||||
|
||||
---
|
||||
|
||||
7
|
||||
|
||||
---
|
||||
|
||||
9
|
||||
|
||||
---
|
||||
|
||||
1
|
||||
|
||||
## --video-solution--
|
||||
|
||||
1
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
---
|
||||
id: 3625fbc38b9428ae98d98f23
|
||||
title: Dictionaries
|
||||
challengeType: 11
|
||||
videoId: FBfYADu3CIo
|
||||
dashedName: dictionaries-learn-python-full-course-for-beginners
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In this video, you will learn how to work with dictionaries in Python to store key-value pairs.
|
||||
|
||||
# --questions--
|
||||
|
||||
## --text--
|
||||
|
||||
Which of the following will correctly output the string `"March"` to the console?
|
||||
|
||||
## --answers--
|
||||
|
||||
```python
|
||||
month_conversions = {
|
||||
"Jan": "January",
|
||||
"Feb": "February",
|
||||
"Mar": "March",
|
||||
"Apr": "April",
|
||||
"May": "May",
|
||||
"Jun": "June",
|
||||
"Jul": "July",
|
||||
"Aug": "August",
|
||||
"Sep": "September",
|
||||
"Oct": "October",
|
||||
"Nov": "November",
|
||||
"Dec": "December"
|
||||
}
|
||||
|
||||
print(month_conversions<"Mar">)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```python
|
||||
month_conversions = {
|
||||
"Jan": "January",
|
||||
"Feb": "February",
|
||||
"Mar": "March",
|
||||
"Apr": "April",
|
||||
"May": "May",
|
||||
"Jun": "June",
|
||||
"Jul": "July",
|
||||
"Aug": "August",
|
||||
"Sep": "September",
|
||||
"Oct": "October",
|
||||
"Nov": "November",
|
||||
"Dec": "December"
|
||||
}
|
||||
|
||||
print(month_conversions("Mar"))
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```python
|
||||
month_conversions = {
|
||||
"Jan": "January",
|
||||
"Feb": "February",
|
||||
"Mar": "March",
|
||||
"Apr": "April",
|
||||
"May": "May",
|
||||
"Jun": "June",
|
||||
"Jul": "July",
|
||||
"Aug": "August",
|
||||
"Sep": "September",
|
||||
"Oct": "October",
|
||||
"Nov": "November",
|
||||
"Dec": "December"
|
||||
}
|
||||
|
||||
print(month_conversions["March"])
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```python
|
||||
month_conversions = {
|
||||
"Jan": "January",
|
||||
"Feb": "February",
|
||||
"Mar": "March",
|
||||
"Apr": "April",
|
||||
"May": "May",
|
||||
"Jun": "June",
|
||||
"Jul": "July",
|
||||
"Aug": "August",
|
||||
"Sep": "September",
|
||||
"Oct": "October",
|
||||
"Nov": "November",
|
||||
"Dec": "December"
|
||||
}
|
||||
|
||||
print(month_conversions["Mar"])
|
||||
```
|
||||
|
||||
## --video-solution--
|
||||
|
||||
4
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
---
|
||||
id: a4cfb218d22efcfa7cc49d80
|
||||
title: Exponent Functions
|
||||
challengeType: 11
|
||||
videoId: KLDvy0wFFX4
|
||||
dashedName: exponent-functions-learn-python-full-course-for-beginners
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In this video, you will learn how to write a function that calculates exponents and powers in Python.
|
||||
|
||||
# --questions--
|
||||
|
||||
## --text--
|
||||
|
||||
What does the `range()` function in Python do?
|
||||
|
||||
## --answers--
|
||||
|
||||
It returns a number from a list.
|
||||
|
||||
---
|
||||
|
||||
It creates a list of random numbers.
|
||||
|
||||
---
|
||||
|
||||
It generates a sequence of integers between a starting and stopping point.
|
||||
|
||||
---
|
||||
|
||||
It generates a sequence of floats between a starting and stopping point.
|
||||
|
||||
## --video-solution--
|
||||
|
||||
3
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
---
|
||||
id: 030401977064585ddd4c7746
|
||||
title: For Loops
|
||||
challengeType: 11
|
||||
videoId: x13V1UMMQeI
|
||||
dashedName: for-loops-learn-python-full-course-for-beginners
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In this video, you will learn how to use for loops to iterate over sequences like lists and ranges.
|
||||
|
||||
# --questions--
|
||||
|
||||
## --text--
|
||||
|
||||
Which of the following is the correct way to iterate over each letter in the string `"Giraffe Academy"`?
|
||||
|
||||
## --answers--
|
||||
|
||||
```python
|
||||
for (letter) in "Giraffe Academy":
|
||||
print(letter)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```python
|
||||
for key, letter in "Giraffe Academy":
|
||||
print(letter)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```python
|
||||
for letter in "Giraffe Academy":
|
||||
print(letter)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```python
|
||||
for letter, value in "Giraffe Academy":
|
||||
print(letter)
|
||||
```
|
||||
|
||||
## --video-solution--
|
||||
|
||||
3
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
---
|
||||
id: d4876f74547b26d5c330423e
|
||||
title: Building a Guessing Game
|
||||
challengeType: 11
|
||||
videoId: sHyQCBFRoug
|
||||
dashedName: building-a-guessing-game-learn-python-full-course-for-beginners
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In this video, you will build a guessing game that uses loops and conditionals.
|
||||
|
||||
# --questions--
|
||||
|
||||
## --text--
|
||||
|
||||
What does the condition `guess != secret_word` mean in this code?
|
||||
|
||||
```python
|
||||
secret_word = "giraffe"
|
||||
guess = ""
|
||||
|
||||
while guess != secret_word:
|
||||
guess = input("Enter guess: ")
|
||||
```
|
||||
|
||||
## --answers--
|
||||
|
||||
If `guess` is not equal to `secret_word`.
|
||||
|
||||
---
|
||||
|
||||
If `guess` is equal to `secret_word`.
|
||||
|
||||
---
|
||||
|
||||
If `guess` is greater than `secret_word`.
|
||||
|
||||
---
|
||||
|
||||
If `guess` is less than `secret_word`.
|
||||
|
||||
## --video-solution--
|
||||
|
||||
1
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
---
|
||||
id: 703bcd12c0edae7773eeec64
|
||||
title: Building a Translator
|
||||
challengeType: 11
|
||||
videoId: 3Sa5rwlKdGQ
|
||||
dashedName: building-a-translator-learn-python-full-course-for-beginners
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In this video, you will build a simple translator program using dictionaries and user input.
|
||||
|
||||
# --questions--
|
||||
|
||||
## --text--
|
||||
|
||||
Which of the following methods is used to check if all characters in a string are uppercase?
|
||||
|
||||
## --answers--
|
||||
|
||||
`upper()`
|
||||
|
||||
---
|
||||
|
||||
`isupper()`
|
||||
|
||||
---
|
||||
|
||||
`toupper()`
|
||||
|
||||
---
|
||||
|
||||
`hasupper()`
|
||||
|
||||
## --video-solution--
|
||||
|
||||
2
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
---
|
||||
id: 474c23ec0df6e7af920e0526
|
||||
title: While Loop
|
||||
challengeType: 11
|
||||
videoId: s6yz4Ew8dwQ
|
||||
dashedName: while-loop-learn-python-full-course-for-beginners
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In this video, you will learn how to work with while loops to repeat code blocks as long as a condition is `True`.
|
||||
|
||||
# --questions--
|
||||
|
||||
## --text--
|
||||
|
||||
What will be the output for the following code?
|
||||
|
||||
```python
|
||||
i = 1
|
||||
|
||||
while i <= 10:
|
||||
print(i)
|
||||
i += 1
|
||||
print("Done with loop")
|
||||
```
|
||||
|
||||
## --answers--
|
||||
|
||||
```md
|
||||
1
|
||||
3
|
||||
5
|
||||
7
|
||||
9
|
||||
Done with loop
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```md
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
8
|
||||
9
|
||||
10
|
||||
Done with loop
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```md
|
||||
2
|
||||
4
|
||||
6
|
||||
8
|
||||
10
|
||||
Done with loop
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```md
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
8
|
||||
9
|
||||
Done with loop
|
||||
```
|
||||
|
||||
## --video-solution--
|
||||
|
||||
2
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
---
|
||||
id: 8ca3a380a75d00443d9e09bd
|
||||
title: Hello World Program
|
||||
challengeType: 11
|
||||
videoId: H2WnzGCeydQ
|
||||
dashedName: hello-world-program-learn-python-full-course-for-beginners
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In this video, you will learn how to write your first program in Python.
|
||||
|
||||
# --questions--
|
||||
|
||||
## --text--
|
||||
|
||||
Which of the following is the correct way to print `"Hello World"` to the console?
|
||||
|
||||
## --answers--
|
||||
|
||||
`print("Hello World")`
|
||||
|
||||
---
|
||||
|
||||
`printf("Hello World")`
|
||||
|
||||
---
|
||||
|
||||
`prints("Hello World")`
|
||||
|
||||
---
|
||||
|
||||
`printing("Hello World")`
|
||||
|
||||
## --video-solution--
|
||||
|
||||
1
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
---
|
||||
id: edeae16d4bf9505165740c75
|
||||
title: Installing Python and PyCharm
|
||||
challengeType: 11
|
||||
videoId: RgGQJDOms1M
|
||||
dashedName: installing-python-and-pycharm-learn-python-full-course-for-beginners
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In this video, you will learn how to install Python and PyCharm onto your computer.
|
||||
|
||||
# --questions--
|
||||
|
||||
## --text--
|
||||
|
||||
What is PyCharm used for?
|
||||
|
||||
## --answers--
|
||||
|
||||
It is a programming language similar to Python used for developing mobile apps.
|
||||
|
||||
---
|
||||
|
||||
It is a Python library used for data analysis.
|
||||
|
||||
---
|
||||
|
||||
It is an IDE used to run Python programs.
|
||||
|
||||
---
|
||||
|
||||
It is an operating system designed for developers.
|
||||
|
||||
## --video-solution--
|
||||
|
||||
3
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
---
|
||||
id: 05b8c9b04c6df84636956fab
|
||||
title: Introduction
|
||||
challengeType: 11
|
||||
videoId: EgQZWE8in68
|
||||
dashedName: introduction-learn-python-full-course-for-beginners
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In this video, instructor Mike Dane explains why you should learn Python.
|
||||
|
||||
# --questions--
|
||||
|
||||
## --text--
|
||||
|
||||
What is one reason to learn Python?
|
||||
|
||||
## --answers--
|
||||
|
||||
It is required to be learned before any other programming language.
|
||||
|
||||
---
|
||||
|
||||
It is one of the most popular programming languages used in the industry.
|
||||
|
||||
---
|
||||
|
||||
It is the fastest programming language for all types of applications.
|
||||
|
||||
---
|
||||
|
||||
It is only useful for complex gaming applications.
|
||||
|
||||
## --video-solution--
|
||||
|
||||
2
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
---
|
||||
id: 6ec8578710ffa3471b74888e
|
||||
title: Building a Basic Calculator
|
||||
challengeType: 11
|
||||
videoId: vA10XU1O3QQ
|
||||
dashedName: building-a-basic-calculator-learn-python-full-course-for-beginners
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In this video, you will build a basic calculator program that can perform addition, subtraction, multiplication, and division operations.
|
||||
|
||||
# --questions--
|
||||
|
||||
## --text--
|
||||
|
||||
Which function is used to convert a string to an integer?
|
||||
|
||||
## --answers--
|
||||
|
||||
`convert()`
|
||||
|
||||
---
|
||||
|
||||
`str()`
|
||||
|
||||
---
|
||||
|
||||
`integer()`
|
||||
|
||||
---
|
||||
|
||||
`int()`
|
||||
|
||||
## --video-solution--
|
||||
|
||||
4
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
---
|
||||
id: 024ffa91a50a44335be33ee7
|
||||
title: Mad Libs Game
|
||||
challengeType: 11
|
||||
videoId: XRmMTKa-xlc
|
||||
dashedName: mad-libs-game-learn-python-full-course-for-beginners
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In this video, you will create a Mad Libs game that takes user input and creates funny stories.
|
||||
|
||||
# --questions--
|
||||
|
||||
## --text--
|
||||
|
||||
Which of the following is the correct way to get input from a user and print the result to the console?
|
||||
|
||||
## --answers--
|
||||
|
||||
```python
|
||||
color = input("Enter a color: ")
|
||||
print(Roses are + color)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```python
|
||||
color = input("Enter a color: ")
|
||||
print("Roses are " + "color")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```python
|
||||
color = input("Enter a color: ")
|
||||
print("Roses are " + color)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```python
|
||||
color = prompt("Enter a color: ")
|
||||
print("Roses are " + color)
|
||||
```
|
||||
|
||||
## --video-solution--
|
||||
|
||||
3
|
||||
@@ -1,224 +0,0 @@
|
||||
---
|
||||
id: 668f08ea07b99b1f4a91acab
|
||||
title: Build a Recipe Page
|
||||
challengeType: 25
|
||||
dashedName: build-a-recipe-page
|
||||
demoType: onClick
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Fulfill the user stories below and get all the tests to pass to complete the lab.
|
||||
|
||||
**User Stories:**
|
||||
|
||||
1. You should have a `!DOCTYPE html` declaration.
|
||||
1. You should have an `html` element with `lang` set to `en`.
|
||||
1. You should have a `head` element containing a `title` element with the name of your recipe, and a `meta` element with a `charset` attribute set to `UTF-8`.
|
||||
1. You should have a `body` element.
|
||||
1. You should have an `h1` element with the name of your recipe.
|
||||
1. You should have a `p` element that introduces the recipe below the `h1`.
|
||||
1. You should have one `h2` element with the text `Ingredients` for the ingredients section.
|
||||
1. You should have an unordered list (`ul` element) with at least four list items (`li` elements) that lists your ingredients below the first `h2` element.
|
||||
1. You should have a second `h2` element with the text `Instructions` for the instructions section.
|
||||
1. You should have an ordered list (`ol` element) with at least four list items that lists the recipe steps in order, below the second `h2`.
|
||||
1. You should have one `img` element with a `src` attribute set to a valid image, you can use `https://cdn.freecodecamp.org/curriculum/labs/recipe.jpg` if you would like, and an `alt` attribute describing the image.
|
||||
|
||||
# --hints--
|
||||
|
||||
Your recipe page should have a `!DOCTYPE html` declaration.
|
||||
|
||||
```js
|
||||
assert.match(code, /<!DOCTYPE html>/i);
|
||||
```
|
||||
|
||||
You should have an `html` element with `lang` set to `en`.
|
||||
|
||||
```js
|
||||
assert.match(code, /<html\s+lang\s*=\s*('|")en\1\s*>[\s\S]*<\/\s*html\s*>/gi);
|
||||
```
|
||||
|
||||
You should have a `head` element within the `html` element.
|
||||
|
||||
```js
|
||||
assert.match(code, /<html[\s\S]*>[\s\S]*<\s*head\s*>[\s\S]*<\/\s*head\s*>[\s\S]*<\/\s*html\s*>/i);
|
||||
```
|
||||
|
||||
You should have `title` element within your `head` element.
|
||||
|
||||
```js
|
||||
assert.match(code, /<\s*head\s*>[\s\S]*<\s*title\s*>[\s\S]*<\/\s*title\s*>[\s\S]*<\/\s*head\s*>/i);
|
||||
```
|
||||
|
||||
Your `title` element should have your recipe title.
|
||||
|
||||
```js
|
||||
assert.isAbove(document.querySelector('title')?.innerText.trim().length, 0);
|
||||
```
|
||||
|
||||
You should have a `meta` element within your `head` element.
|
||||
|
||||
```js
|
||||
assert.match(code, /<\s*head\s*>[\s\S]*<\s*meta[\s\S]*>[\s\S]*<\/\s*head\s*>/i);
|
||||
```
|
||||
|
||||
Your `meta` element should have its `charset` attribute set to `UTF-8`.
|
||||
|
||||
```js
|
||||
assert.match(code, /<\s*meta[\s\S]+?charset\s*=\s*('|")UTF-8\1/i);
|
||||
```
|
||||
|
||||
You should have a `body` element within your `html` element.
|
||||
|
||||
```js
|
||||
assert.match(code, /<\s*html[\s\S]*>[\s\S]*<\s*head\s*>[\s\S]*<\/\s*head\s*>[\s\S]*<\s*body\s*>[\s\S]*<\/\s*body\s*>[\s\S]*<\/\s*html\s*>/i);
|
||||
```
|
||||
|
||||
You should have an `h1` element with the name of your recipe.
|
||||
|
||||
```js
|
||||
assert.isAbove(document.querySelector('h1')?.innerText.length, 0);
|
||||
```
|
||||
|
||||
You should only have one `h1` element.
|
||||
|
||||
```js
|
||||
assert.lengthOf(document.querySelectorAll('h1'), 1);
|
||||
```
|
||||
|
||||
You should have a `p` element below your `h1` element.
|
||||
|
||||
```js
|
||||
assert.strictEqual(document.querySelector('h1')?.nextElementSibling, document.querySelector('p'));
|
||||
```
|
||||
|
||||
Your first `p` element should describe your recipe.
|
||||
|
||||
```js
|
||||
assert.isNotEmpty(document.querySelector('p')?.textContent?.trim());
|
||||
```
|
||||
|
||||
Your first `h2` element should have the text `Ingredients`.
|
||||
|
||||
```js
|
||||
assert.equal(document.querySelectorAll('h2')[0]?.innerText, 'Ingredients');
|
||||
```
|
||||
|
||||
You should have an unordered list element below your first `h2` element.
|
||||
|
||||
```js
|
||||
assert.strictEqual(document.querySelector('ul')?.previousElementSibling.tagName, 'H2');
|
||||
```
|
||||
|
||||
You should have at least four list item elements in your unordered list with the ingredients.
|
||||
|
||||
```js
|
||||
const els = document.querySelectorAll('ul > li');
|
||||
assert.isAbove(els.length, 3);
|
||||
els.forEach(el => assert.isAbove(el.innerText.trim().length, 0))
|
||||
```
|
||||
|
||||
Your second `h2` element should have the text `Instructions`.
|
||||
|
||||
```js
|
||||
assert.equal(document.querySelectorAll('h2')[1]?.innerText, 'Instructions');
|
||||
```
|
||||
|
||||
You should have an ordered list element below your second `h2` element.
|
||||
|
||||
```js
|
||||
assert.strictEqual(document.querySelectorAll('h2')?.[1]?.nextElementSibling?.tagName, "OL");
|
||||
```
|
||||
|
||||
You should have at least four list item elements in your ordered list with the instructions.
|
||||
|
||||
```js
|
||||
const els = document.querySelectorAll('ol > li');
|
||||
assert.isAbove(els.length, 3);
|
||||
els.forEach(el => assert.isAbove(el.innerText.trim().length, 0))
|
||||
```
|
||||
|
||||
You should have at least one `img` element.
|
||||
|
||||
```js
|
||||
assert.exists(document.querySelector('img'));
|
||||
```
|
||||
|
||||
All your `img` elements should have a valid `src` attribute and value.
|
||||
|
||||
```js
|
||||
const img = document.querySelector('img');
|
||||
const rawSrc = img?.getAttribute('src');
|
||||
const resolvedSrc = img?.src;
|
||||
const re = new RegExp(window.location.href, "ig");
|
||||
|
||||
assert.isAbove(rawSrc?.trim().length, 0, "The 'src' attribute must be explicitly set.");
|
||||
assert.notMatch(resolvedSrc, re, "The 'src' should not start with the current page URL");
|
||||
|
||||
img.onload = () => {
|
||||
console.log('Image loaded successfully.');
|
||||
};
|
||||
|
||||
img.onerror = (error) => {
|
||||
console.error('Image failed to load:', error);
|
||||
assert.fail("Your image's URL should be valid."); // Make the test instafail
|
||||
};
|
||||
|
||||
if (img.complete) {
|
||||
img.onload && img.onload();
|
||||
};
|
||||
```
|
||||
|
||||
All your `img` elements should have an `alt` attribute to describe the image.
|
||||
|
||||
```js
|
||||
assert.isAbove(document.querySelector('img')?.alt.length, 0);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Chocolate chip cookies recipe</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Chocolate Chip Cookies</h1>
|
||||
<p>Welcome to the ultimate guide for making mini chocolate chip cookies! These bite-sized treats are perfect for
|
||||
satisfying your sweet tooth without overindulging. Follow this simple recipe to create delicious,
|
||||
crispy-on-the-outside, chewy-on-the-inside mini chocolate chip cookies that everyone will love.</p>
|
||||
<img src="https://cdn.freecodecamp.org/curriculum/labs/recipe.jpg" alt="Ingredients for baking: three eggs, a bowl of flour, a glass of milk, and a whisk arranged on a wooden table.">
|
||||
<h2>Ingredients</h2>
|
||||
<ul>
|
||||
<li>1 cup all-purpose flour</li>
|
||||
<li>1/2 teaspoon baking soda</li>
|
||||
<li>1/4 cup unsalted butter, softened</li>
|
||||
<li>1/4 cup granulated sugar</li>
|
||||
<li>1/2 teaspoon vanilla extract</li>
|
||||
<li>1/2 cup mini chocolate chips</li>
|
||||
</ul>
|
||||
<h2>Instructions</h2>
|
||||
<ol>
|
||||
<li>Preheat your oven to 350°F (175°C) and line a baking sheet with parchment paper.</li>
|
||||
<li>In a bowl, whisk together the flour and baking soda.</li>
|
||||
<li>In another bowl, beat the butter, sugar, and vanilla extract until creamy.</li>
|
||||
<li>Gradually add the dry ingredients to the wet mixture, then fold in the mini chocolate chips.</li>
|
||||
<li>Drop small spoonfuls of dough onto the baking sheet.</li>
|
||||
<li>Bake for 8-10 minutes, then let cool before enjoying!</li>
|
||||
</ol>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
```
|
||||
@@ -6,7 +6,6 @@ const {
|
||||
} = require('@freecodecamp/shared/config/challenge-types');
|
||||
const {
|
||||
chapterBasedSuperBlocks,
|
||||
catalogSuperBlocks,
|
||||
languageSuperBlocks,
|
||||
SuperBlocks
|
||||
} = require('@freecodecamp/shared/config/curriculum');
|
||||
@@ -135,7 +134,7 @@ const schema = Joi.object().keys({
|
||||
block: Joi.string().regex(slugRE).required(),
|
||||
blockId: Joi.objectId(),
|
||||
blockLabel: Joi.when('superBlock', {
|
||||
is: [...chapterBasedSuperBlocks, ...catalogSuperBlocks],
|
||||
is: [...chapterBasedSuperBlocks],
|
||||
then: Joi.valid(
|
||||
'workshop',
|
||||
'lab',
|
||||
|
||||
@@ -33,7 +33,30 @@ const superblocks = [
|
||||
'college-algebra-with-python',
|
||||
'project-euler',
|
||||
'2022/responsive-web-design',
|
||||
'the-odin-project'
|
||||
'the-odin-project',
|
||||
'lab-survey-form',
|
||||
'html-and-accessibility',
|
||||
'computer-basics',
|
||||
'basic-css',
|
||||
'design-for-developers',
|
||||
'absolute-and-relative-units',
|
||||
'pseudo-classes-and-elements',
|
||||
'css-colors',
|
||||
'styling-forms',
|
||||
'css-box-model',
|
||||
'css-flexbox',
|
||||
'lab-page-of-playing-cards',
|
||||
'css-typography',
|
||||
'css-and-accessibility',
|
||||
'css-positioning',
|
||||
'attribute-selectors',
|
||||
'lab-book-inventory-app',
|
||||
'responsive-design',
|
||||
'lab-technical-documentation-page',
|
||||
'css-variables',
|
||||
'css-grid',
|
||||
'lab-product-landing-page',
|
||||
'css-animations'
|
||||
];
|
||||
|
||||
const schema = Joi.object().keys(
|
||||
|
||||
@@ -202,7 +202,32 @@ export const superBlockNames = {
|
||||
'python-v9': SuperBlocks.PythonV9,
|
||||
'relational-databases-v9': SuperBlocks.RelationalDbV9,
|
||||
'back-end-development-and-apis-v9': SuperBlocks.BackEndDevApisV9,
|
||||
'full-stack-developer-v9': SuperBlocks.FullStackDeveloperV9
|
||||
'full-stack-developer-v9': SuperBlocks.FullStackDeveloperV9,
|
||||
'html-forms-and-tables': SuperBlocks.HtmlFormsAndTables,
|
||||
'learn-python-for-beginners': SuperBlocks.LearnPythonForBeginners,
|
||||
'lab-survey-form': SuperBlocks.LabSurveyForm,
|
||||
'html-and-accessibility': SuperBlocks.HtmlAndAccessibility,
|
||||
'computer-basics': SuperBlocks.ComputerBasics,
|
||||
'basic-css': SuperBlocks.BasicCss,
|
||||
'design-for-developers': SuperBlocks.DesignForDevelopers,
|
||||
'absolute-and-relative-units': SuperBlocks.AbsoluteAndRelativeUnits,
|
||||
'pseudo-classes-and-elements': SuperBlocks.PseudoClassesAndElements,
|
||||
'css-colors': SuperBlocks.CssColors,
|
||||
'styling-forms': SuperBlocks.StylingForms,
|
||||
'css-box-model': SuperBlocks.CssBoxModel,
|
||||
'css-flexbox': SuperBlocks.CssFlexbox,
|
||||
'lab-page-of-playing-cards': SuperBlocks.LabPageOfPlayingCards,
|
||||
'css-typography': SuperBlocks.CssTypography,
|
||||
'css-and-accessibility': SuperBlocks.CssAndAccessibility,
|
||||
'css-positioning': SuperBlocks.CssPositioning,
|
||||
'attribute-selectors': SuperBlocks.AttributeSelectors,
|
||||
'lab-book-inventory-app': SuperBlocks.LabBookInventoryApp,
|
||||
'responsive-design': SuperBlocks.ResponsiveDesign,
|
||||
'lab-technical-documentation-page': SuperBlocks.LabTechnicalDocumentationPage,
|
||||
'css-variables': SuperBlocks.CssVariables,
|
||||
'css-grid': SuperBlocks.CssGrid,
|
||||
'lab-product-landing-page': SuperBlocks.LabProductLandingPage,
|
||||
'css-animations': SuperBlocks.CssAnimations
|
||||
};
|
||||
|
||||
export const superBlockToFilename = Object.entries(superBlockNames).reduce(
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
{
|
||||
"name": "Build a Cat Blog Page",
|
||||
"blockLabel": "workshop",
|
||||
"blockLayout": "challenge-grid",
|
||||
"isUpcomingChange": true,
|
||||
"usesMultifileEditor": true,
|
||||
"hasEditableBoundaries": true,
|
||||
"dashedName": "cat-blog-page",
|
||||
"challengeOrder": [
|
||||
{
|
||||
"id": "669aff9f5488f1bea056416d",
|
||||
"title": "Step 1"
|
||||
},
|
||||
{
|
||||
"id": "669fc7e141e4703748c558bf",
|
||||
"title": "Step 2"
|
||||
},
|
||||
{
|
||||
"id": "669fc938d38e6e38ace9251e",
|
||||
"title": "Step 3"
|
||||
},
|
||||
{
|
||||
"id": "669fcb06c3034a39f5431a38",
|
||||
"title": "Step 4"
|
||||
}
|
||||
],
|
||||
"helpCategory": "HTML-CSS"
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
{
|
||||
"name": "Build a Cat Photo App",
|
||||
"blockLabel": "workshop",
|
||||
"blockLayout": "challenge-grid",
|
||||
"isUpcomingChange": true,
|
||||
"usesMultifileEditor": true,
|
||||
"hasEditableBoundaries": true,
|
||||
"dashedName": "cat-photo-app",
|
||||
"challengeOrder": [
|
||||
{
|
||||
"id": "5dc174fcf86c76b9248c6eb2",
|
||||
"title": "Step 1"
|
||||
},
|
||||
{
|
||||
"id": "5dc1798ff86c76b9248c6eb3",
|
||||
"title": "Step 2"
|
||||
},
|
||||
{
|
||||
"id": "5dc17d3bf86c76b9248c6eb4",
|
||||
"title": "Step 3"
|
||||
},
|
||||
{
|
||||
"id": "5dc17dc8f86c76b9248c6eb5",
|
||||
"title": "Step 4"
|
||||
}
|
||||
],
|
||||
"helpCategory": "HTML-CSS"
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"name": "Build an Event Hub",
|
||||
"blockLabel": "lab",
|
||||
"blockLayout": "link",
|
||||
"isUpcomingChange": true,
|
||||
"usesMultifileEditor": true,
|
||||
"dashedName": "event-hub",
|
||||
"challengeOrder": [
|
||||
{ "id": "66ebd4ae2812430bb883c787", "title": "Build an Event Hub" }
|
||||
],
|
||||
"helpCategory": "HTML-CSS"
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"name": "Control Flow and Functions",
|
||||
"blockLabel": "lecture",
|
||||
"blockLayout": "challenge-list",
|
||||
"isUpcomingChange": false,
|
||||
"dashedName": "learn-python-control-flow-functions",
|
||||
"helpCategory": "Python",
|
||||
"challengeOrder": [
|
||||
{
|
||||
"id": "58d5d031e969765037c1bebb",
|
||||
"title": "Functions"
|
||||
},
|
||||
{
|
||||
"id": "c6c9dae4017830e187eeaf42",
|
||||
"title": "Return Statement"
|
||||
},
|
||||
{
|
||||
"id": "08854a2c6f052efa1e5270d2",
|
||||
"title": "If Statements"
|
||||
},
|
||||
{
|
||||
"id": "8314d0bbddb0aa027a144705",
|
||||
"title": "If Statements and Comparisons"
|
||||
},
|
||||
{
|
||||
"id": "a9f9c5bf295034800d6c77ad",
|
||||
"title": "Building a Better Calculator"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"name": "Core Primitives: Variables, Types, Basic I/O",
|
||||
"blockLabel": "lecture",
|
||||
"blockLayout": "challenge-list",
|
||||
"isUpcomingChange": false,
|
||||
"dashedName": "learn-python-core-primitives",
|
||||
"helpCategory": "Python",
|
||||
"challengeOrder": [
|
||||
{
|
||||
"id": "62baa9d28e8723f635a0093e",
|
||||
"title": "Drawing a Shape"
|
||||
},
|
||||
{
|
||||
"id": "315017f4457c19d45c2be034",
|
||||
"title": "Variables and Data Types"
|
||||
},
|
||||
{
|
||||
"id": "0e2f4bd857b1edc70bfcd1f9",
|
||||
"title": "Working with Strings"
|
||||
},
|
||||
{
|
||||
"id": "8ad37ddb7a23050f71cc9cc9",
|
||||
"title": "Working with Numbers"
|
||||
},
|
||||
{
|
||||
"id": "155ca30775751b78a860a79b",
|
||||
"title": "Getting Input from Users"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "Data Structures: Lists and Tuples",
|
||||
"blockLabel": "lecture",
|
||||
"blockLayout": "challenge-list",
|
||||
"isUpcomingChange": false,
|
||||
"dashedName": "learn-python-data-structures",
|
||||
"helpCategory": "Python",
|
||||
"challengeOrder": [
|
||||
{
|
||||
"id": "39a400e9163c5a0b33587e18",
|
||||
"title": "Lists"
|
||||
},
|
||||
{
|
||||
"id": "24a45b3960b3aa68dff2cd9e",
|
||||
"title": "List Functions"
|
||||
},
|
||||
{
|
||||
"id": "5ed596ba3306cf2c1a94bb92",
|
||||
"title": "Tuples"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"name": "Object Oriented Programming",
|
||||
"blockLabel": "lecture",
|
||||
"blockLayout": "challenge-list",
|
||||
"isUpcomingChange": false,
|
||||
"dashedName": "learn-python-oop",
|
||||
"helpCategory": "Python",
|
||||
"challengeOrder": [
|
||||
{
|
||||
"id": "a0339c4075344cbfc2cd939c",
|
||||
"title": "Classes and Objects"
|
||||
},
|
||||
{
|
||||
"id": "9afe5e8141b13e9f1d59d46e",
|
||||
"title": "Building a Multiple Choice Quiz"
|
||||
},
|
||||
{
|
||||
"id": "697fe3cb32baa3841ab62a63",
|
||||
"title": "Object Functions"
|
||||
},
|
||||
{
|
||||
"id": "697fe5c032baa3841ab62a64",
|
||||
"title": "Inheritance"
|
||||
},
|
||||
{
|
||||
"id": "697fe6c932baa3841ab62a65",
|
||||
"title": "Python Interpreter"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"name": "Practical Python: Errors, Files and Modules",
|
||||
"blockLabel": "lecture",
|
||||
"blockLayout": "challenge-list",
|
||||
"isUpcomingChange": false,
|
||||
"dashedName": "learn-python-practical-errors-files",
|
||||
"helpCategory": "Python",
|
||||
"challengeOrder": [
|
||||
{
|
||||
"id": "71ac60e6488b40e997219f15",
|
||||
"title": "Comments"
|
||||
},
|
||||
{
|
||||
"id": "2a486e3e521b79b874fb5e9a",
|
||||
"title": "Try/Except"
|
||||
},
|
||||
{
|
||||
"id": "04e25c4fdc9ee0e71a844fd6",
|
||||
"title": "Reading Files"
|
||||
},
|
||||
{
|
||||
"id": "bfab38e6a6c1165f7774514d",
|
||||
"title": "Writing to Files"
|
||||
},
|
||||
{
|
||||
"id": "2ccc34bd3f7bb4ae97a67ea3",
|
||||
"title": "Modules and pip"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"name": "Dictionaries and Loops",
|
||||
"blockLabel": "lecture",
|
||||
"blockLayout": "challenge-list",
|
||||
"isUpcomingChange": false,
|
||||
"dashedName": "learn-python-projects-loops",
|
||||
"helpCategory": "Python",
|
||||
"challengeOrder": [
|
||||
{
|
||||
"id": "3625fbc38b9428ae98d98f23",
|
||||
"title": "Dictionaries"
|
||||
},
|
||||
{
|
||||
"id": "474c23ec0df6e7af920e0526",
|
||||
"title": "While Loop"
|
||||
},
|
||||
{
|
||||
"id": "d4876f74547b26d5c330423e",
|
||||
"title": "Building a Guessing Game"
|
||||
},
|
||||
{
|
||||
"id": "030401977064585ddd4c7746",
|
||||
"title": "For Loops"
|
||||
},
|
||||
{
|
||||
"id": "a4cfb218d22efcfa7cc49d80",
|
||||
"title": "Exponent Functions"
|
||||
},
|
||||
{
|
||||
"id": "28119f9dc5f93e3ac5d7c58a",
|
||||
"title": "2D Lists and Nested Loops"
|
||||
},
|
||||
{
|
||||
"id": "703bcd12c0edae7773eeec64",
|
||||
"title": "Building a Translator"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "Setup & First Steps",
|
||||
"blockLabel": "lecture",
|
||||
"blockLayout": "challenge-list",
|
||||
"isUpcomingChange": false,
|
||||
"dashedName": "learn-python-setup-first-steps",
|
||||
"helpCategory": "Python",
|
||||
"challengeOrder": [
|
||||
{
|
||||
"id": "05b8c9b04c6df84636956fab",
|
||||
"title": "Introduction"
|
||||
},
|
||||
{
|
||||
"id": "edeae16d4bf9505165740c75",
|
||||
"title": "Installing Python and PyCharm"
|
||||
},
|
||||
{
|
||||
"id": "8ca3a380a75d00443d9e09bd",
|
||||
"title": "Hello World Program"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "Small Projects: Using Basics",
|
||||
"blockLabel": "lecture",
|
||||
"blockLayout": "challenge-list",
|
||||
"isUpcomingChange": false,
|
||||
"dashedName": "learn-python-small-projects-basics",
|
||||
"helpCategory": "Python",
|
||||
"challengeOrder": [
|
||||
{
|
||||
"id": "6ec8578710ffa3471b74888e",
|
||||
"title": "Building a Basic Calculator"
|
||||
},
|
||||
{
|
||||
"id": "024ffa91a50a44335be33ee7",
|
||||
"title": "Mad Libs Game"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
{
|
||||
"name": "Build a Recipe Page",
|
||||
"blockLabel": "lab",
|
||||
"blockLayout": "link",
|
||||
"isUpcomingChange": true,
|
||||
"usesMultifileEditor": true,
|
||||
"dashedName": "recipe-page",
|
||||
"challengeOrder": [
|
||||
{
|
||||
"id": "668f08ea07b99b1f4a91acab",
|
||||
"title": "Build a Recipe Page"
|
||||
}
|
||||
],
|
||||
"helpCategory": "HTML-CSS"
|
||||
}
|
||||
@@ -36,7 +36,32 @@
|
||||
"python-v9",
|
||||
"relational-databases-v9",
|
||||
"back-end-development-and-apis-v9",
|
||||
"full-stack-developer-v9"
|
||||
"full-stack-developer-v9",
|
||||
"html-forms-and-tables",
|
||||
"learn-python-for-beginners",
|
||||
"lab-survey-form",
|
||||
"html-and-accessibility",
|
||||
"computer-basics",
|
||||
"basic-css",
|
||||
"design-for-developers",
|
||||
"absolute-and-relative-units",
|
||||
"pseudo-classes-and-elements",
|
||||
"css-colors",
|
||||
"styling-forms",
|
||||
"css-box-model",
|
||||
"css-flexbox",
|
||||
"lab-page-of-playing-cards",
|
||||
"css-typography",
|
||||
"css-and-accessibility",
|
||||
"css-positioning",
|
||||
"attribute-selectors",
|
||||
"lab-book-inventory-app",
|
||||
"responsive-design",
|
||||
"lab-technical-documentation-page",
|
||||
"css-variables",
|
||||
"css-grid",
|
||||
"lab-product-landing-page",
|
||||
"css-animations"
|
||||
],
|
||||
"certifications": [
|
||||
"a2-english-for-developers",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user