feat(learn): add python video challenges (#38424)

This commit is contained in:
Beau Carnes
2020-04-06 14:49:56 -04:00
committed by Mrugesh Mohapatra
parent 22afc2a0ca
commit e776529ed0
218 changed files with 3411 additions and 114 deletions

View File

@ -167,6 +167,16 @@
"description": "Camper is information security and quality assurance certified", "description": "Camper is information security and quality assurance certified",
"default": false "default": false
}, },
"isQaCert": {
"type": "boolean",
"description": "Camper is quality assurance certified",
"default": false
},
"isInfosecCert": {
"type": "boolean",
"description": "Camper is information security certified",
"default": false
},
"is2018FullStackCert": { "is2018FullStackCert": {
"type": "boolean", "type": "boolean",
"description": "Camper is full stack certified (2018)", "description": "Camper is full stack certified (2018)",

View File

@ -19,6 +19,8 @@ import {
dataVis2018Id, dataVis2018Id,
apisMicroservicesId, apisMicroservicesId,
infosecQaId, infosecQaId,
infosecId,
qaId,
fullStackId, fullStackId,
sciCompPyId, sciCompPyId,
dataAnalysisPyId, dataAnalysisPyId,
@ -107,6 +109,8 @@ function createCertTypeIds(app) {
Challenge Challenge
), ),
[certTypes.infosecQa]: getIdsForCert$(infosecQaId, Challenge), [certTypes.infosecQa]: getIdsForCert$(infosecQaId, Challenge),
[certTypes.qa]: getIdsForCert$(qaId, Challenge),
[certTypes.infosec]: getIdsForCert$(infosecId, Challenge),
[certTypes.fullStack]: getIdsForCert$(fullStackId, Challenge), [certTypes.fullStack]: getIdsForCert$(fullStackId, Challenge),
[certTypes.sciCompPy]: getIdsForCert$(sciCompPyId, Challenge), [certTypes.sciCompPy]: getIdsForCert$(sciCompPyId, Challenge),
[certTypes.dataAnalysisPy]: getIdsForCert$(dataAnalysisPyId, Challenge), [certTypes.dataAnalysisPy]: getIdsForCert$(dataAnalysisPyId, Challenge),
@ -133,6 +137,8 @@ const certIds = {
[certTypes.dataVis2018]: dataVis2018Id, [certTypes.dataVis2018]: dataVis2018Id,
[certTypes.apisMicroservices]: apisMicroservicesId, [certTypes.apisMicroservices]: apisMicroservicesId,
[certTypes.infosecQa]: infosecQaId, [certTypes.infosecQa]: infosecQaId,
[certTypes.qa]: qaId,
[certTypes.infosec]: infosecId,
[certTypes.fullStack]: fullStackId, [certTypes.fullStack]: fullStackId,
[certTypes.sciCompPy]: sciCompPyId, [certTypes.sciCompPy]: sciCompPyId,
[certTypes.dataAnalysisPy]: dataAnalysisPyId, [certTypes.dataAnalysisPy]: dataAnalysisPyId,
@ -150,6 +156,8 @@ const certText = {
[certTypes.dataVis2018]: 'Data Visualization', [certTypes.dataVis2018]: 'Data Visualization',
[certTypes.apisMicroservices]: 'APIs and Microservices', [certTypes.apisMicroservices]: 'APIs and Microservices',
[certTypes.infosecQa]: 'Information Security and Quality Assurance', [certTypes.infosecQa]: 'Information Security and Quality Assurance',
[certTypes.qa]: 'Quality Assurance',
[certTypes.infosec]: 'Information Security',
[certTypes.sciCompPy]: 'Scientific Computing with Python', [certTypes.sciCompPy]: 'Scientific Computing with Python',
[certTypes.dataAnalysisPy]: 'Data Analysis with Python', [certTypes.dataAnalysisPy]: 'Data Analysis with Python',
[certTypes.machineLearningPy]: 'Machine Learning with Python' [certTypes.machineLearningPy]: 'Machine Learning with Python'
@ -166,6 +174,8 @@ const completionHours = {
[certTypes.dataVis2018]: 300, [certTypes.dataVis2018]: 300,
[certTypes.apisMicroservices]: 300, [certTypes.apisMicroservices]: 300,
[certTypes.infosecQa]: 300, [certTypes.infosecQa]: 300,
[certTypes.qa]: 300,
[certTypes.infosec]: 300,
[certTypes.sciCompPy]: 400, [certTypes.sciCompPy]: 400,
[certTypes.dataAnalysisPy]: 400, [certTypes.dataAnalysisPy]: 400,
[certTypes.machineLearningPy]: 400 [certTypes.machineLearningPy]: 400
@ -193,6 +203,8 @@ function sendCertifiedEmail(
isDataVisCert, isDataVisCert,
isApisMicroservicesCert, isApisMicroservicesCert,
isInfosecQaCert, isInfosecQaCert,
isQaCert,
isInfosecCert,
isSciCompPyCert, isSciCompPyCert,
isDataAnalysisPyCert, isDataAnalysisPyCert,
isMachineLearningPyCert isMachineLearningPyCert
@ -207,6 +219,8 @@ function sendCertifiedEmail(
!isDataVisCert || !isDataVisCert ||
!isApisMicroservicesCert || !isApisMicroservicesCert ||
!isInfosecQaCert || !isInfosecQaCert ||
!isQaCert ||
!isInfosecCert ||
!isSciCompPyCert || !isSciCompPyCert ||
!isDataAnalysisPyCert || !isDataAnalysisPyCert ||
!isMachineLearningPyCert !isMachineLearningPyCert
@ -237,6 +251,8 @@ function getUserIsCertMap(user) {
is2018DataVisCert = false, is2018DataVisCert = false,
isApisMicroservicesCert = false, isApisMicroservicesCert = false,
isInfosecQaCert = false, isInfosecQaCert = false,
isQaCert = false,
isInfosecCert = false,
isFrontEndCert = false, isFrontEndCert = false,
isBackEndCert = false, isBackEndCert = false,
isDataVisCert = false, isDataVisCert = false,
@ -253,6 +269,8 @@ function getUserIsCertMap(user) {
is2018DataVisCert, is2018DataVisCert,
isApisMicroservicesCert, isApisMicroservicesCert,
isInfosecQaCert, isInfosecQaCert,
isQaCert,
isInfosecCert,
isFrontEndCert, isFrontEndCert,
isBackEndCert, isBackEndCert,
isDataVisCert, isDataVisCert,
@ -380,6 +398,8 @@ function createShowCert(app) {
is2018DataVisCert: true, is2018DataVisCert: true,
isApisMicroservicesCert: true, isApisMicroservicesCert: true,
isInfosecQaCert: true, isInfosecQaCert: true,
isQaCert: true,
isInfosecCert: true,
isSciCompPyCert: true, isSciCompPyCert: true,
isDataAnalysisPyCert: true, isDataAnalysisPyCert: true,
isMachineLearningPyCert: true, isMachineLearningPyCert: true,

View File

@ -162,6 +162,8 @@ function postResetProgress(req, res, next) {
isJsAlgoDataStructCert: false, isJsAlgoDataStructCert: false,
isApisMicroservicesCert: false, isApisMicroservicesCert: false,
isInfosecQaCert: false, isInfosecQaCert: false,
isQaCert: false,
isInfosecCert: false,
is2018FullStackCert: false, is2018FullStackCert: false,
isFrontEndCert: false, isFrontEndCert: false,
isBackEndCert: false, isBackEndCert: false,

View File

@ -8,6 +8,8 @@
"jsAlgoDataStruct": "isJsAlgoDataStructCert", "jsAlgoDataStruct": "isJsAlgoDataStructCert",
"apisMicroservices": "isApisMicroservicesCert", "apisMicroservices": "isApisMicroservicesCert",
"infosecQa": "isInfosecQaCert", "infosecQa": "isInfosecQaCert",
"qa": "isQaCert",
"infosec": "isInfosecCert",
"fullStack": "isFullStackCert", "fullStack": "isFullStackCert",
"sciCompPy": "isSciCompPyCert", "sciCompPy": "isSciCompPyCert",
"dataAnalysisPy": "isDataAnalysisPyCert", "dataAnalysisPy": "isDataAnalysisPyCert",

View File

@ -8,6 +8,8 @@
"dataVisCert": "Data Visualisation Certification", "dataVisCert": "Data Visualisation Certification",
"apisMicroservicesCert": "APIs and Microservices Certification", "apisMicroservicesCert": "APIs and Microservices Certification",
"infosecQaCert": "Information Security and Quality Assurance Certification", "infosecQaCert": "Information Security and Quality Assurance Certification",
"qaCert": "Quality Assurance Certification",
"infosecCert": "Information Security Certification",
"sciCompPyCert": "Scientific Computing with Python Certification", "sciCompPyCert": "Scientific Computing with Python Certification",
"dataAnalysisPyCert": "Data Analysis with Python Certification", "dataAnalysisPyCert": "Data Analysis with Python Certification",
"machineLearningPyCert": "Machine Learning with Python Certification" "machineLearningPyCert": "Machine Learning with Python Certification"

View File

@ -18,6 +18,8 @@ export function completeCommitment$(user) {
isDataVisCert, isDataVisCert,
isApisMicroservicesCert, isApisMicroservicesCert,
isInfosecQaCert, isInfosecQaCert,
isQaCert,
isInfosecCert,
isSciCompPyCert, isSciCompPyCert,
isDataAnalysisPyCert, isDataAnalysisPyCert,
isMachineLearningPyCert isMachineLearningPyCert
@ -40,6 +42,8 @@ export function completeCommitment$(user) {
(isDataVisCert && goal === commitGoals.dataVisCert) || (isDataVisCert && goal === commitGoals.dataVisCert) ||
(isApisMicroservicesCert && goal === commitGoals.apisMicroservicesCert) || (isApisMicroservicesCert && goal === commitGoals.apisMicroservicesCert) ||
(isInfosecQaCert && goal === commitGoals.infosecQaCert) || (isInfosecQaCert && goal === commitGoals.infosecQaCert) ||
(isQaCert && goal === commitGoals.QaCert) ||
(isInfosecCert && goal === commitGoals.infosecCert) ||
(isSciCompPyCert && goal === commitGoals.sciCompPyCert) || (isSciCompPyCert && goal === commitGoals.sciCompPyCert) ||
(isDataAnalysisPyCert && goal === commitGoals.dataAnalysisPyCert) || (isDataAnalysisPyCert && goal === commitGoals.dataAnalysisPyCert) ||
(isMachineLearningPyCert && goal === commitGoals.machineLearningPyCert) (isMachineLearningPyCert && goal === commitGoals.machineLearningPyCert)

View File

@ -11,6 +11,8 @@
"jsAlgoDataStructId": "561abd10cb81ac38a17513bc", "jsAlgoDataStructId": "561abd10cb81ac38a17513bc",
"apisMicroservicesId": "561add10cb82ac38a17523bc", "apisMicroservicesId": "561add10cb82ac38a17523bc",
"infosecQaId": "561add10cb82ac38a17213bc", "infosecQaId": "561add10cb82ac38a17213bc",
"qaId": "5e611829481575a52dc59c0e",
"infosecId": "5e6021435ac9d0ecd8b94b00",
"fullStackId": "561add10cb82ac38a17213bd", "fullStackId": "561add10cb82ac38a17213bd",
"sciCompPyId": "5e44431b903586ffb414c951", "sciCompPyId": "5e44431b903586ffb414c951",
"dataAnalysisPyId": "5e46fc95ac417301a38fb934", "dataAnalysisPyId": "5e46fc95ac417301a38fb934",

View File

@ -4,6 +4,8 @@ function getCompletedCertCount(user) {
'is2018DataVisCert', 'is2018DataVisCert',
'isFrontEndLibsCert', 'isFrontEndLibsCert',
'isInfosecQaCert', 'isInfosecQaCert',
'isQaCert',
'isInfosecCert',
'isJsAlgoDataStructCert', 'isJsAlgoDataStructCert',
'isRespWebDesignCert', 'isRespWebDesignCert',
'isSciCompPyCert', 'isSciCompPyCert',

View File

@ -23,6 +23,8 @@ export const publicUserProps = [
'isFrontEndLibsCert', 'isFrontEndLibsCert',
'isHonest', 'isHonest',
'isInfosecQaCert', 'isInfosecQaCert',
'isQaCert',
'isInfosecCert',
'isJsAlgoDataStructCert', 'isJsAlgoDataStructCert',
'isRespWebDesignCert', 'isRespWebDesignCert',
'isSciCompPyCert', 'isSciCompPyCert',

View File

@ -13,6 +13,8 @@ const superBlockCertTypeMap = {
'data-visualization': certTypes.dataVis2018, 'data-visualization': certTypes.dataVis2018,
'apis-and-microservices': certTypes.apisMicroservices, 'apis-and-microservices': certTypes.apisMicroservices,
'information-security-and-quality-assurance': certTypes.infosecQa, 'information-security-and-quality-assurance': certTypes.infosecQa,
'quality-assurance': certTypes.qa,
'information-security': certTypes.infosec,
'full-stack': certTypes.fullStack, 'full-stack': certTypes.fullStack,
'scientific-computing-with-python': certTypes.sciCompPy, 'scientific-computing-with-python': certTypes.sciCompPy,
'data-analysis-with-python': certTypes.dataAnalysisPy, 'data-analysis-with-python': certTypes.dataAnalysisPy,

View File

@ -143,6 +143,8 @@ function getCompletedCertCount(user) {
'is2018DataVisCert', 'is2018DataVisCert',
'isFrontEndLibsCert', 'isFrontEndLibsCert',
'isInfosecQaCert', 'isInfosecQaCert',
'isQaCert',
'isInfosecCert',
'isJsAlgoDataStructCert', 'isJsAlgoDataStructCert',
'isRespWebDesignCert', 'isRespWebDesignCert',
'isSciCompPyCert', 'isSciCompPyCert',

View File

@ -60,6 +60,8 @@ const propTypes = {
isFullStackCert: PropTypes.bool, isFullStackCert: PropTypes.bool,
isHonest: PropTypes.bool, isHonest: PropTypes.bool,
isInfosecQaCert: PropTypes.bool, isInfosecQaCert: PropTypes.bool,
isQaCert: PropTypes.bool,
isInfosecCert: PropTypes.bool,
isJsAlgoDataStructCert: PropTypes.bool, isJsAlgoDataStructCert: PropTypes.bool,
isRespWebDesignCert: PropTypes.bool, isRespWebDesignCert: PropTypes.bool,
isSciCompPyCert: PropTypes.bool, isSciCompPyCert: PropTypes.bool,
@ -132,6 +134,8 @@ export function ShowSettings(props) {
isDataVisCert, isDataVisCert,
isFrontEndCert, isFrontEndCert,
isInfosecQaCert, isInfosecQaCert,
isQaCert,
isInfosecCert,
isFrontEndLibsCert, isFrontEndLibsCert,
isFullStackCert, isFullStackCert,
isRespWebDesignCert, isRespWebDesignCert,
@ -245,9 +249,11 @@ export function ShowSettings(props) {
isFrontEndLibsCert={isFrontEndLibsCert} isFrontEndLibsCert={isFrontEndLibsCert}
isFullStackCert={isFullStackCert} isFullStackCert={isFullStackCert}
isHonest={isHonest} isHonest={isHonest}
isInfosecCert={isInfosecCert}
isInfosecQaCert={isInfosecQaCert} isInfosecQaCert={isInfosecQaCert}
isJsAlgoDataStructCert={isJsAlgoDataStructCert} isJsAlgoDataStructCert={isJsAlgoDataStructCert}
isMachineLearningPyCert={isMachineLearningPyCert} isMachineLearningPyCert={isMachineLearningPyCert}
isQaCert={isQaCert}
isRespWebDesignCert={isRespWebDesignCert} isRespWebDesignCert={isRespWebDesignCert}
isSciCompPyCert={isSciCompPyCert} isSciCompPyCert={isSciCompPyCert}
username={username} username={username}

View File

@ -40,7 +40,7 @@ const AsFeaturedSection = () => (
export const Landing = ({ edges }) => { export const Landing = ({ edges }) => {
const superBlocks = uniq(edges.map(element => element.node.superBlock)); const superBlocks = uniq(edges.map(element => element.node.superBlock));
const interviewPrep = superBlocks.splice(9, 1); const interviewPrep = superBlocks.splice(10, 1);
return ( return (
<Fragment> <Fragment>
<Helmet> <Helmet>

View File

@ -50,9 +50,11 @@ const propTypes = {
isFrontEndLibsCert: PropTypes.bool, isFrontEndLibsCert: PropTypes.bool,
isFullStackCert: PropTypes.bool, isFullStackCert: PropTypes.bool,
isHonest: PropTypes.bool, isHonest: PropTypes.bool,
isInfosecCert: PropTypes.bool,
isInfosecQaCert: PropTypes.bool, isInfosecQaCert: PropTypes.bool,
isJsAlgoDataStructCert: PropTypes.bool, isJsAlgoDataStructCert: PropTypes.bool,
isMachineLearningPyCert: PropTypes.bool, isMachineLearningPyCert: PropTypes.bool,
isQaCert: PropTypes.bool,
isRespWebDesignCert: PropTypes.bool, isRespWebDesignCert: PropTypes.bool,
isSciCompPyCert: PropTypes.bool, isSciCompPyCert: PropTypes.bool,
updateLegacyCert: PropTypes.func.isRequired, updateLegacyCert: PropTypes.func.isRequired,
@ -70,6 +72,8 @@ const isCertSelector = ({
isDataVisCert, isDataVisCert,
isFrontEndCert, isFrontEndCert,
isInfosecQaCert, isInfosecQaCert,
isQaCert,
isInfosecCert,
isFrontEndLibsCert, isFrontEndLibsCert,
isFullStackCert, isFullStackCert,
isRespWebDesignCert, isRespWebDesignCert,
@ -84,6 +88,8 @@ const isCertSelector = ({
isDataVisCert, isDataVisCert,
isFrontEndCert, isFrontEndCert,
isInfosecQaCert, isInfosecQaCert,
isQaCert,
isInfosecCert,
isFrontEndLibsCert, isFrontEndLibsCert,
isFullStackCert, isFullStackCert,
isRespWebDesignCert, isRespWebDesignCert,
@ -99,6 +105,8 @@ const isCertMapSelector = createSelector(
isApisMicroservicesCert, isApisMicroservicesCert,
isJsAlgoDataStructCert, isJsAlgoDataStructCert,
isInfosecQaCert, isInfosecQaCert,
isQaCert,
isInfosecCert,
isFrontEndLibsCert, isFrontEndLibsCert,
isRespWebDesignCert, isRespWebDesignCert,
isDataVisCert, isDataVisCert,
@ -114,6 +122,8 @@ const isCertMapSelector = createSelector(
'Data Visualization': is2018DataVisCert, 'Data Visualization': is2018DataVisCert,
"API's and Microservices": isApisMicroservicesCert, "API's and Microservices": isApisMicroservicesCert,
'Information Security And Quality Assurance': isInfosecQaCert, 'Information Security And Quality Assurance': isInfosecQaCert,
'Quality Assurance': isQaCert,
'Information Security': isInfosecCert,
'Scientific Computing with Python': isSciCompPyCert, 'Scientific Computing with Python': isSciCompPyCert,
'Data Analysis with Python': isDataAnalysisPyCert, 'Data Analysis with Python': isDataAnalysisPyCert,
'Machine Learning with Python': isMachineLearningPyCert, 'Machine Learning with Python': isMachineLearningPyCert,
@ -462,7 +472,7 @@ export class CertificationSettings extends Component {
is2018DataVisCert, is2018DataVisCert,
isApisMicroservicesCert, isApisMicroservicesCert,
isFrontEndLibsCert, isFrontEndLibsCert,
isInfosecQaCert, isQaCert,
isJsAlgoDataStructCert, isJsAlgoDataStructCert,
isRespWebDesignCert isRespWebDesignCert
} = this.props; } = this.props;
@ -471,7 +481,7 @@ export class CertificationSettings extends Component {
is2018DataVisCert && is2018DataVisCert &&
isApisMicroservicesCert && isApisMicroservicesCert &&
isFrontEndLibsCert && isFrontEndLibsCert &&
isInfosecQaCert && isQaCert &&
isJsAlgoDataStructCert && isJsAlgoDataStructCert &&
isRespWebDesignCert; isRespWebDesignCert;
@ -509,7 +519,7 @@ export class CertificationSettings extends Component {
<li>Front End Libraries</li> <li>Front End Libraries</li>
<li>Data Visualization</li> <li>Data Visualization</li>
<li>APIs and Microservices</li> <li>APIs and Microservices</li>
<li>Information Security and Quality Assurance</li> <li>Quality Assurance</li>
</ul> </ul>
</div> </div>

View File

@ -189,6 +189,8 @@ const defaultTestProps = {
isFullStackCert: false, isFullStackCert: false,
isHonest: false, isHonest: false,
isInfosecQaCert: false, isInfosecQaCert: false,
isQaCert: false,
isInfosecCert: false,
isJsAlgoDataStructCert: false, isJsAlgoDataStructCert: false,
isRespWebDesignCert: false, isRespWebDesignCert: false,
isSciCompPyCert: false, isSciCompPyCert: false,

View File

@ -1,7 +0,0 @@
---
title: Information Security and Quality Assurance
superBlock: Information Security and Quality Assurance
---
## Introduction to Information Security and Quality Assurance
This is a stub introduction for Information Security and Quality Assurance

View File

@ -1,19 +0,0 @@
---
title: Introduction to the Information Security and Quality Assurance Projects
block: Information Security and Quality Assurance Projects
superBlock: Information Security and Quality Assurance
---
## Introduction to the Information Security and Quality Assurance Projects
Now its time to put your newly learned skills to work! By working on these projects, you will have the opportunity of applying all the skills, principles, and concepts from the Information Security and Quality Assurance sections.
In this section you get the chance to:
* Build a Metric-Imperial Converter
* Build an Issue Tracker
* Build a Personal Library
* Build a Stock Price Checker
* Build an Anonymous Message Board
* Port Scanner
* Packet Capturer
When you are done, you will have plenty of Information Security & Quality Assurance projects under your belt along with a certification that you can show off to friends, family, and employers. Have fun and remember to use the [Read-Search-Ask](https://www.freecodecamp.org/forum/t/how-to-get-help-when-you-are-stuck/19514) method if you get stuck.

View File

@ -0,0 +1,7 @@
---
title: Information Security
superBlock: Information Security
---
## Introduction to Information Security
This is a stub introduction for Information Security

View File

@ -0,0 +1,17 @@
---
title: Introduction to the Information Security Projects
block: Information Security Projects
superBlock: Information Security
---
## Introduction to the Information Security Projects
Now its time to put your newly learned skills to work! By working on these projects, you will have the opportunity of applying all the skills, principles, and concepts from the Information Security sections.
In this section you get the chance to:
* Build a Stock Price Checker
* Build an Anonymous Message Board
* Secure Real Time Multiplayer Game
* Port Scanner
* Packet Capturer
When you are done, you will have plenty of Information Security projects under your belt along with a certification that you can show off to friends, family, and employers. Have fun and remember to use the [Read-Search-Ask](https://www.freecodecamp.org/forum/t/how-to-get-help-when-you-are-stuck/19514) method if you get stuck.

View File

@ -1,7 +1,7 @@
--- ---
title: Introduction to Information Security with HelmetJS Challenges title: Introduction to Information Security with HelmetJS Challenges
block: Information Security with HelmetJS block: Information Security with HelmetJS
superBlock: Information Security and Quality Assurance superBlock: Information Security
--- ---
## Introduction to Information Security with HelmetJS Challenges ## Introduction to Information Security with HelmetJS Challenges

View File

@ -1,7 +1,7 @@
--- ---
title: Introduction to the Advanced Node and Express Challenges title: Introduction to the Advanced Node and Express Challenges
block: Advanced Node and Express block: Advanced Node and Express
superBlock: Information Security and Quality Assurance superBlock: Quality Assurance
--- ---
## Introduction to Advanced Node and Express Challenges ## Introduction to Advanced Node and Express Challenges

View File

@ -0,0 +1,7 @@
---
title: Quality Assurance
superBlock: Quality Assurance
---
## Introduction to Quality Assurance
This is a stub introduction for Quality Assurance

View File

@ -1,7 +1,7 @@
--- ---
title: Introduction to the Quality Assurance with Chai Challenges title: Introduction to the Quality Assurance with Chai Challenges
block: Quality Assurance and Testing with Chai block: Quality Assurance and Testing with Chai
superBlock: Information Security and Quality Assurance superBlock: Quality Assurance
--- ---
## Introduction to Quality Assurance with Chai Challenges ## Introduction to Quality Assurance with Chai Challenges

View File

@ -0,0 +1,17 @@
---
title: Introduction to the Quality Assurance Projects
block: Quality Assurance Projects
superBlock: Quality Assurance
---
## Introduction to the Quality Assurance Projects
Now its time to put your newly learned skills to work! By working on these projects, you will have the opportunity of applying all the skills, principles, and concepts from the Quality Assurance sections.
In this section you get the chance to:
* Build a Metric-Imperial Converter
* Build an Issue Tracker
* Build a Personal Library
* Sudoku Solver
* American British Translator
When you are done, you will have plenty of Quality Assurance projects under your belt along with a certification that you can show off to friends, family, and employers. Have fun and remember to use the [Read-Search-Ask](https://www.freecodecamp.org/forum/t/how-to-get-help-when-you-are-stuck/19514) method if you get stuck.

View File

@ -0,0 +1,12 @@
---
title: Introduction to Python for Everybody
block: Python for Everybody
superBlock: Scientific Computing with Python
---
## Introduction to Python for Everybody
Python for Everybody is a video course that teaches the basics of programming computers using Python 3.
The course was created by Dr. Charles Severance (a.k.a. Dr. Chuck). He is a Clinical Professor at the University of Michigan School of Information, where he teaches various technology-oriented courses including programming, database design, and Web development.

View File

@ -213,6 +213,8 @@ export const certificatesByNameSelector = username => state => {
isJsAlgoDataStructCert, isJsAlgoDataStructCert,
isApisMicroservicesCert, isApisMicroservicesCert,
isInfosecQaCert, isInfosecQaCert,
isQaCert,
isInfosecCert,
isFrontEndCert, isFrontEndCert,
isBackEndCert, isBackEndCert,
isDataVisCert, isDataVisCert,
@ -229,6 +231,8 @@ export const certificatesByNameSelector = username => state => {
isJsAlgoDataStructCert || isJsAlgoDataStructCert ||
isApisMicroservicesCert || isApisMicroservicesCert ||
isInfosecQaCert || isInfosecQaCert ||
isQaCert ||
isInfosecCert ||
isFullStackCert || isFullStackCert ||
isSciCompPyCert || isSciCompPyCert ||
isDataAnalysisPyCert || isDataAnalysisPyCert ||
@ -270,6 +274,16 @@ export const certificatesByNameSelector = username => state => {
title: 'Information Security and Quality Assurance Certification', title: 'Information Security and Quality Assurance Certification',
showURL: 'information-security-and-quality-assurance' showURL: 'information-security-and-quality-assurance'
}, },
{
show: isQaCert,
title: ' Quality Assurance Certification',
showURL: 'information-security-and-quality-assurance'
},
{
show: isInfosecCert,
title: 'Information Security Certification',
showURL: 'information-security-and-quality-assurance'
},
{ {
show: isSciCompPyCert, show: isSciCompPyCert,
title: 'Scientific Computing with Python Certification', title: 'Scientific Computing with Python Certification',

View File

@ -7,9 +7,8 @@ const feLibsBase = '/learn/front-end-libraries/front-end-libraries-projects';
const dataVisBase = '/learn/data-visualization/data-visualization-projects'; const dataVisBase = '/learn/data-visualization/data-visualization-projects';
const apiMicroBase = const apiMicroBase =
'/learn/apis-and-microservices/apis-and-microservices-projects'; '/learn/apis-and-microservices/apis-and-microservices-projects';
const infoSecBase = const qaBase = 'learn/quality-assurance/quality-assurance-projects';
'/learn/information-security-and-quality-assurance/' + const infoSecBase = '/learn/information-security/information-security-projects';
'information-security-and-quality-assurance-projects';
const sciCompPyBase = const sciCompPyBase =
'/learn/scientific-computing-with-python/' + '/learn/scientific-computing-with-python/' +
'scientific-computing-with-python-projects'; 'scientific-computing-with-python-projects';
@ -371,48 +370,68 @@ export const projectMap = {
superBlock: 'apis-and-microservices' superBlock: 'apis-and-microservices'
} }
], ],
'Information Security And Quality Assurance': [ 'Quality Assurance': [
{ {
id: '587d8249367417b2b2512c41', id: '587d8249367417b2b2512c41',
title: 'Metric-Imperial Converter', title: 'Metric-Imperial Converter',
link: `${infoSecBase}/metric-imperial-converter`, link: `${qaBase}/metric-imperial-converter`,
superBlock: 'information-security-and-quality-assurance' superBlock: 'quality-assurance'
}, },
{ {
id: '587d8249367417b2b2512c42', id: '587d8249367417b2b2512c42',
title: 'Issue Tracker', title: 'Issue Tracker',
link: `${infoSecBase}/issue-tracker`, link: `${qaBase}/issue-tracker`,
superBlock: 'information-security-and-quality-assurance' superBlock: 'quality-assurance'
}, },
{ {
id: '587d824a367417b2b2512c43', id: '587d824a367417b2b2512c43',
title: 'Personal Library', title: 'Personal Library',
link: `${infoSecBase}/personal-library`, link: `${qaBase}/personal-library`,
superBlock: 'information-security-and-quality-assurance' superBlock: 'quality-assurance'
}, },
{
id: '5e601bf95ac9d0ecd8b94afd',
title: 'Sudoku Solver',
link: `${qaBase}/sudoku-solver`,
superBlock: 'quality-assurance'
},
{
id: '5e601c0d5ac9d0ecd8b94afe',
title: 'American British Translator',
link: `${qaBase}/american-british-translator`,
superBlock: 'quality-assurance'
}
],
'Information Security': [
{ {
id: '587d824a367417b2b2512c44', id: '587d824a367417b2b2512c44',
title: 'Stock Price Checker', title: 'Stock Price Checker',
link: `${infoSecBase}/stock-price-checker`, link: `${infoSecBase}/stock-price-checker`,
superBlock: 'information-security-and-quality-assurance' superBlock: 'information-security'
}, },
{ {
id: '587d824a367417b2b2512c45', id: '587d824a367417b2b2512c45',
title: 'Anonymous Message Board', title: 'Anonymous Message Board',
link: `${infoSecBase}/anonymous-message-board`, link: `${infoSecBase}/anonymous-message-board`,
superBlock: 'information-security-and-quality-assurance' superBlock: 'information-security'
}, },
{ {
id: '5e46f979ac417301a38fb932', id: '5e46f979ac417301a38fb932',
title: 'Port Scanner', title: 'Port Scanner',
link: `${infoSecBase}/port-scanner`, link: `${infoSecBase}/port-scanner`,
superBlock: 'information-security-and-quality-assurance' superBlock: 'information-security'
}, },
{ {
id: '5e46f983ac417301a38fb933', id: '5e46f983ac417301a38fb933',
title: 'SHA-1 Password Cracker', title: 'SHA-1 Password Cracker',
link: `${infoSecBase}/sha-1-password-cracker`, link: `${infoSecBase}/sha-1-password-cracker`,
superBlock: 'information-security-and-quality-assurance' superBlock: 'information-security'
},
{
id: '5e601c775ac9d0ecd8b94aff',
title: 'Real Time Multiplayer Game',
link: `${infoSecBase}/real-time-multiplayer-game`,
superBlock: 'information-security'
} }
], ],
'Scientific Computing with Python': [ 'Scientific Computing with Python': [

View File

@ -0,0 +1,301 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import noop from 'lodash/noop';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { Button, Modal } from '@freecodecamp/react-bootstrap';
import { useStaticQuery, graphql } from 'gatsby';
import SanitizedSpan from '../components/SanitizedSpan';
import Login from '../../../components/Header/components/Login';
import './completion-modal.css';
import {
closeModal,
submitChallenge,
completedChallengesIds,
isCompletionModalOpenSelector,
challengeFilesSelector,
challengeMetaSelector,
lastBlockChalSubmitted
} from '../redux';
import { isSignedInSelector, executeGA } from '../../../redux';
const mapStateToProps = createSelector(
challengeFilesSelector,
challengeMetaSelector,
completedChallengesIds,
isCompletionModalOpenSelector,
isSignedInSelector,
(files, { title, id }, completedChallengesIds, isOpen, isSignedIn) => ({
files,
title,
id,
completedChallengesIds,
isOpen,
isSignedIn
})
);
const mapDispatchToProps = function(dispatch) {
const dispatchers = {
close: () => dispatch(closeModal('completion')),
submitChallenge: () => {
dispatch(submitChallenge());
},
lastBlockChalSubmitted: () => {
dispatch(lastBlockChalSubmitted());
},
executeGA
};
return () => dispatchers;
};
const propTypes = {
answers: PropTypes.array,
blockName: PropTypes.string,
close: PropTypes.func.isRequired,
completedChallengesIds: PropTypes.array,
currentBlockIds: PropTypes.array,
executeGA: PropTypes.func,
files: PropTypes.object.isRequired,
id: PropTypes.string,
isOpen: PropTypes.bool,
isSignedIn: PropTypes.bool.isRequired,
lastBlockChalSubmitted: PropTypes.func,
question: PropTypes.string,
solution: PropTypes.number,
submitChallenge: PropTypes.func.isRequired,
title: PropTypes.string
};
export function getCompletedPercent(
completedChallengesIds = [],
currentBlockIds = [],
currentChallengeId
) {
completedChallengesIds = completedChallengesIds.includes(currentChallengeId)
? completedChallengesIds
: [...completedChallengesIds, currentChallengeId];
const completedChallengesInBlock = completedChallengesIds.filter(id => {
return currentBlockIds.includes(id);
});
const completedPercent = Math.round(
(completedChallengesInBlock.length / currentBlockIds.length) * 100
);
return completedPercent > 100 ? 100 : completedPercent;
}
export class CompletionModalInner extends Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
this.handleKeypress = this.handleKeypress.bind(this);
}
state = {
downloadURL: null,
completedPercent: 0,
selectedOption: 0,
answer: 1,
showWrong: false
};
static getDerivedStateFromProps(props, state) {
const { files, isOpen } = props;
if (!isOpen) {
return null;
}
const { downloadURL } = state;
if (downloadURL) {
URL.revokeObjectURL(downloadURL);
}
let newURL = null;
if (Object.keys(files).length) {
const filesForDownload = Object.keys(files)
.map(key => files[key])
.reduce((allFiles, { path, contents }) => {
const beforeText = `** start of ${path} **\n\n`;
const afterText = `\n\n** end of ${path} **\n\n`;
allFiles +=
files.length > 1 ? beforeText + contents + afterText : contents;
return allFiles;
}, '');
const blob = new Blob([filesForDownload], {
type: 'text/json'
});
newURL = URL.createObjectURL(blob);
}
const { completedChallengesIds, currentBlockIds, id, isSignedIn } = props;
let completedPercent = isSignedIn
? getCompletedPercent(completedChallengesIds, currentBlockIds, id)
: 0;
return { downloadURL: newURL, completedPercent: completedPercent };
}
handleKeypress(e) {
if (e.keyCode === 13 && (e.ctrlKey || e.metaKey)) {
e.preventDefault();
// Since Hotkeys also listens to Ctrl + Enter we have to stop this event
// getting to it.
e.stopPropagation();
this.handleSubmit();
}
}
handleSubmit() {
if (this.props.solution - 1 === this.state.selectedOption) {
this.setState({
showWrong: false
});
this.props.submitChallenge();
this.checkBlockCompletion();
} else {
this.setState({
showWrong: true
});
}
}
// check block completion for donation
checkBlockCompletion() {
if (
this.state.completedPercent === 100 &&
!this.props.completedChallengesIds.includes(this.props.id)
) {
this.props.lastBlockChalSubmitted();
}
}
componentWillUnmount() {
if (this.state.downloadURL) {
URL.revokeObjectURL(this.state.downloadURL);
}
this.props.close();
}
handleOptionChange = changeEvent => {
console.log(this.state.selectedOption);
this.setState({
selectedOption: parseInt(changeEvent.target.value, 10)
});
};
render() {
const { close, isOpen, isSignedIn, question, answers } = this.props;
if (isOpen) {
executeGA({ type: 'modal', data: '/completion-modal' });
}
return (
<Modal
animation={false}
bsSize='lg'
dialogClassName='challenge-success-modal'
keyboard={true}
onHide={close}
onKeyDown={isOpen ? this.handleKeypress : noop}
show={isOpen}
>
<Modal.Header
className='challenge-list-header fcc-modal'
closeButton={true}
>
<Modal.Title className='completion-message'>Video Quiz</Modal.Title>
</Modal.Header>
<Modal.Body className='question-modal-body'>
<SanitizedSpan text={question} />
<form>
{answers.map((option, index) => (
<div className='form-check'>
<label>
<input
checked={this.state.selectedOption === index}
name='quiz'
onChange={this.handleOptionChange}
type='radio'
value={index}
/>{' '}
<SanitizedSpan text={option} />
</label>
</div>
))}
</form>
<div
style={{
visibility: this.state.showWrong ? 'visible' : 'hidden'
}}
>
Wrong. Try again.
</div>
</Modal.Body>
<Modal.Footer>
{isSignedIn ? null : (
<Login
block={true}
bsSize='lg'
bsStyle='primary'
className='btn-cta'
>
Sign in to save your progress
</Login>
)}
<Button
block={true}
bsSize='large'
bsStyle='primary'
onClick={this.handleSubmit}
>
Submit answer <span className='hidden-xs'>(Ctrl + Enter)</span>
</Button>
</Modal.Footer>
</Modal>
);
}
}
CompletionModalInner.propTypes = propTypes;
const useCurrentBlockIds = blockName => {
const {
allChallengeNode: { edges }
} = useStaticQuery(graphql`
query getCurrentBlockNodesVid {
allChallengeNode(sort: { fields: [superOrder, order, challengeOrder] }) {
edges {
node {
fields {
blockName
}
id
}
}
}
}
`);
const currentBlockIds = edges
.filter(edge => edge.node.fields.blockName === blockName)
.map(edge => edge.node.id);
return currentBlockIds;
};
const CompletionModal = props => {
const currentBlockIds = useCurrentBlockIds(props.blockName || '');
return <CompletionModalInner currentBlockIds={currentBlockIds} {...props} />;
};
CompletionModal.displayName = 'CompletionModal';
CompletionModal.propTypes = propTypes;
export default connect(
mapStateToProps,
mapDispatchToProps
)(CompletionModal);

View File

@ -0,0 +1,19 @@
import React from 'react';
import PropTypes from 'prop-types';
import sanitizeHtml from 'sanitize-html';
const propTypes = {
text: PropTypes.string.isRequired
};
function SanitizedSpan({ text = '' }) {
const sanitizedText = sanitizeHtml(text, {
allowedTags: ['b', 'i', 'em', 'strong', 'code', 'wbr', 'br', 'pre']
});
return <span dangerouslySetInnerHTML={{ __html: sanitizedText }} />;
}
SanitizedSpan.displayName = 'SanitizedSpan';
SanitizedSpan.propTypes = propTypes;
export default SanitizedSpan;

View File

@ -0,0 +1,41 @@
/* global expect */
import React from 'react';
import { render } from '@testing-library/react';
import SanitizedSpan from './SanitizedSpan';
describe('<SanitizedSpan />', () => {
it('matches the snapshot', () => {
const { container } = render(
<SanitizedSpan
text={`some text <script>dangerous code</script>
more <wbr>text <br> <img alt='danger' src='https://attack.com'>`}
/>
);
expect(container).toMatchSnapshot();
});
it('removes scripts, images, etc', () => {
const { queryByAltText, queryByText } = render(
<SanitizedSpan
text={`some text <script>dangerous code</script>
more text <img alt='danger' src='https://attack.com'>`}
/>
);
expect(queryByText('dangerous code', { ignore: false })).toBeNull();
expect(queryByAltText('danger')).toBeNull();
});
it('leaves in line breaks', () => {
const { container } = render(
<SanitizedSpan
text={`some text <br>
more text`}
/>
);
expect(container.querySelector('br')).not.toBeNull();
});
});

View File

@ -0,0 +1,14 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<SanitizedSpan /> matches the snapshot 1`] = `
<div>
<span>
some text
more
<wbr />
text
<br />
</span>
</div>
`;

View File

@ -11,6 +11,14 @@
justify-content: space-evenly; justify-content: space-evenly;
} }
.video-modal-body {
min-height: 400px;
display: flex;
flex-direction: column;
justify-content: space-evenly;
padding-left: 30px;
}
.completion-challenge-details { .completion-challenge-details {
display: flex; display: flex;
flex-direction: column; flex-direction: column;

View File

@ -0,0 +1,205 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Button, Grid, Col, Row } from '@freecodecamp/react-bootstrap';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { graphql } from 'gatsby';
import Helmet from 'react-helmet';
import YouTube from 'react-youtube';
import { ChallengeNode } from '../../../redux/propTypes';
import {
challengeMounted,
updateChallengeMeta,
openModal,
updateProjectFormValues
} from '../redux';
import LearnLayout from '../../../components/layouts/Learn';
import ChallengeTitle from '../components/Challenge-Title';
import ChallengeDescription from '../components/Challenge-Description';
import Spacer from '../../../components/helpers/Spacer';
import CompletionVideoModal from '../components/CompletionVideoModal';
import HelpModal from '../components/HelpModal';
import Hotkeys from '../components/Hotkeys';
const mapStateToProps = () => ({});
const mapDispatchToProps = dispatch =>
bindActionCreators(
{
updateChallengeMeta,
challengeMounted,
updateProjectFormValues,
openCompletionModal: () => openModal('completion')
},
dispatch
);
const propTypes = {
challengeMounted: PropTypes.func.isRequired,
data: PropTypes.shape({
challengeNode: ChallengeNode
}),
description: PropTypes.string,
openCompletionModal: PropTypes.func.isRequired,
pageContext: PropTypes.shape({
challengeMeta: PropTypes.object
}),
updateChallengeMeta: PropTypes.func.isRequired,
updateProjectFormValues: PropTypes.func.isRequired
};
export class Project extends Component {
constructor(props) {
super(props);
this.state = {
subtitles: ''
};
}
componentDidMount() {
const {
challengeMounted,
data: {
challengeNode: { title, challengeType }
},
pageContext: { challengeMeta },
updateChallengeMeta
} = this.props;
updateChallengeMeta({ ...challengeMeta, title, challengeType });
challengeMounted(challengeMeta.id);
this._container.focus();
}
componentDidUpdate(prevProps) {
const {
data: {
challengeNode: { title: prevTitle }
}
} = prevProps;
const {
challengeMounted,
data: {
challengeNode: { title: currentTitle, challengeType }
},
pageContext: { challengeMeta },
updateChallengeMeta
} = this.props;
if (prevTitle !== currentTitle) {
updateChallengeMeta({
...challengeMeta,
title: currentTitle,
challengeType
});
challengeMounted(challengeMeta.id);
}
}
render() {
const {
data: {
challengeNode: {
fields: { blockName },
title,
description,
videoId,
question: { text, answers, solution }
}
},
openCompletionModal,
pageContext: {
challengeMeta: { introPath, nextChallengePath, prevChallengePath }
}
} = this.props;
const blockNameTitle = `${blockName} - ${title}`;
return (
<Hotkeys
innerRef={c => (this._container = c)}
introPath={introPath}
nextChallengePath={nextChallengePath}
prevChallengePath={prevChallengePath}
>
<LearnLayout>
<Helmet title={`${blockNameTitle} | Learn | freeCodeCamp.org`} />
<Grid>
<Row>
<Col md={8} mdOffset={2} sm={10} smOffset={1} xs={12}>
<Spacer />
<ChallengeTitle>{blockNameTitle}</ChallengeTitle>
<div style={{ textAlign: 'center' }}>
<YouTube
onEnd={openCompletionModal}
opts={{ rel: 0 }}
videoId={videoId}
/>
<i>
<a
href={
'https://www.youtube.com/timedtext_editor?action_mde_edit_form=1&v=' +
videoId +
'&lang=en&bl=watch&ui=hd&ref=wt&tab=captions'
}
rel='noopener noreferrer'
target='_blank'
>
Help improve or add subtitles
</a>
.
</i>
</div>
<Spacer />
<ChallengeDescription description={description} />
<Button
block={true}
bsSize='large'
bsStyle='primary'
onClick={openCompletionModal}
>
Complete
</Button>
<Spacer />
</Col>
<CompletionVideoModal
answers={answers}
blockName={blockName}
question={text}
solution={solution}
/>
<HelpModal />
</Row>
</Grid>
</LearnLayout>
</Hotkeys>
);
}
}
Project.displayName = 'Project';
Project.propTypes = propTypes;
export default connect(
mapStateToProps,
mapDispatchToProps
)(Project);
export const query = graphql`
query VideoChallenge($slug: String!) {
challengeNode(fields: { slug: { eq: $slug } }) {
videoId
title
description
challengeType
fields {
blockName
slug
}
question {
text
answers
solution
}
}
}
`;

View File

@ -14,13 +14,12 @@ const preFormattedBlockNames = {
'apis-and-microservices': 'APIs and Microservices', 'apis-and-microservices': 'APIs and Microservices',
'apis-and-microservices-projects': 'APIs and Microservices Projects', 'apis-and-microservices-projects': 'APIs and Microservices Projects',
'scientific-computing-with-python': 'Scientific Computing with Python', 'scientific-computing-with-python': 'Scientific Computing with Python',
'scientific-computing-with-python-projects': 'scientific-computing-with-python-projects': 'Certification Projects',
'Scientific Computing with Python Projects',
'data-analysis-with-python': 'Data Analysis with Python', 'data-analysis-with-python': 'Data Analysis with Python',
'data-analysis-with-python-projects': 'Data Analysis with Python Projects', 'data-analysis-with-python-projects': 'Certification Projects',
'machine-learning-with-python': 'Machine Learning with Python', 'machine-learning-with-python': 'Machine Learning with Python',
'machine-learning-with-python-projects': 'machine-learning-with-python-projects': 'Certification Projects',
'Machine Learning with Python Projects' 'information-security-projects': 'Certification Projects'
}; };
const noFormatting = ['and', 'for', 'of', 'the', 'up', 'with']; const noFormatting = ['and', 'for', 'of', 'the', 'up', 'with'];

View File

@ -10,6 +10,7 @@ const step = 7;
const quiz = 8; const quiz = 8;
const invalid = 9; const invalid = 9;
const pythonProject = 10; const pythonProject = 10;
const video = 11;
// individual exports // individual exports
exports.backend = backend; exports.backend = backend;
@ -29,7 +30,8 @@ exports.challengeTypes = {
modern, modern,
step, step,
quiz, quiz,
invalid invalid,
video
}; };
// turn challengeType to file ext // turn challengeType to file ext
@ -45,11 +47,12 @@ exports.viewTypes = {
[bonfire]: 'classic', [bonfire]: 'classic',
[frontEndProject]: 'frontend', [frontEndProject]: 'frontend',
[backEndProject]: 'backend', [backEndProject]: 'backend',
[pythonProject]: 'backend', [pythonProject]: 'frontend',
[modern]: 'modern', [modern]: 'modern',
[step]: 'step', [step]: 'step',
[quiz]: 'quiz', [quiz]: 'quiz',
[backend]: 'backend' [backend]: 'backend',
[video]: 'video'
}; };
// determine the type of submit function to use for the challenge on completion // determine the type of submit function to use for the challenge on completion
@ -68,7 +71,8 @@ exports.submitTypes = {
[step]: 'step', [step]: 'step',
[quiz]: 'quiz', [quiz]: 'quiz',
[backend]: 'backend', [backend]: 'backend',
[modern]: 'tests' [modern]: 'tests',
[video]: 'tests'
}; };
// determine which help forum questions should be posted to // determine which help forum questions should be posted to
@ -109,8 +113,8 @@ exports.helpCategory = {
'information-security-with-helmetjs': 'JavaScript', 'information-security-with-helmetjs': 'JavaScript',
'quality-assurance-and-testing-with-chai': 'JavaScript', 'quality-assurance-and-testing-with-chai': 'JavaScript',
'advanced-node-and-express': 'JavaScript', 'advanced-node-and-express': 'JavaScript',
'information-security-and-quality-assurance-projects': 'quality-assurance-projects': 'Certification Projects',
'Certification Projects', 'information-security-projects': 'Certification Projects',
algorithms: 'JavaScript', algorithms: 'JavaScript',
'data-structures': 'JavaScript', 'data-structures': 'JavaScript',
'take-home-projects': 'Certification Projects', 'take-home-projects': 'Certification Projects',

View File

@ -23,12 +23,17 @@ const superBlockIntro = path.resolve(
__dirname, __dirname,
'../../src/templates/Introduction/SuperBlockIntro.js' '../../src/templates/Introduction/SuperBlockIntro.js'
); );
const video = path.resolve(
__dirname,
'../../src/templates/Challenges/video/Show.js'
);
const views = { const views = {
backend, backend,
classic, classic,
modern: classic, modern: classic,
frontend frontend,
video
// quiz: Quiz // quiz: Quiz
}; };

View File

@ -1,11 +1,11 @@
{ {
"name": "Advanced Node and Express", "name": "Advanced Node and Express",
"dashedName": "advanced-node-and-express", "dashedName": "advanced-node-and-express",
"order": 3, "order": 2,
"time": "5 hours", "time": "5 hours",
"template": "", "template": "",
"required": [], "required": [],
"superBlock": "information-security-and-quality-assurance", "superBlock": "quality-assurance",
"superOrder": 6, "superOrder": 6,
"challengeOrder": [ "challengeOrder": [
[ [

View File

@ -6,7 +6,7 @@
"template": "", "template": "",
"required": [], "required": [],
"superBlock": "coding-interview-prep", "superBlock": "coding-interview-prep",
"superOrder": 10, "superOrder": 11,
"challengeOrder": [ "challengeOrder": [
[ [
"a3f503de51cf954ede28891d", "a3f503de51cf954ede28891d",

View File

@ -6,7 +6,7 @@
"template": "", "template": "",
"required": [], "required": [],
"superBlock": "certificates", "superBlock": "certificates",
"superOrder": 11, "superOrder": 12,
"challengeOrder": [ "challengeOrder": [
[ [
"561add10cb82ac38a17523bc", "561add10cb82ac38a17523bc",
@ -14,5 +14,5 @@
] ]
], ],
"isPrivate": true, "isPrivate": true,
"fileName": "11-certificates/apis-and-microservices-certificate.json" "fileName": "12-certificates/apis-and-microservices-certificate.json"
} }

View File

@ -6,7 +6,7 @@
"template": "", "template": "",
"required": [], "required": [],
"superBlock": "certificates", "superBlock": "certificates",
"superOrder": 11, "superOrder": 12,
"challengeOrder": [ "challengeOrder": [
[ [
"5e46fc95ac417301a38fb934", "5e46fc95ac417301a38fb934",
@ -14,5 +14,5 @@
] ]
], ],
"isPrivate": true, "isPrivate": true,
"fileName": "11-certificates/data-analysis-with-python-certificate.json" "fileName": "12-certificates/data-analysis-with-python-certificate.json"
} }

View File

@ -6,7 +6,7 @@
"template": "", "template": "",
"required": [], "required": [],
"superBlock": "coding-interview-prep", "superBlock": "coding-interview-prep",
"superOrder": 10, "superOrder": 11,
"challengeOrder": [ "challengeOrder": [
[ [
"587d8253367417b2b2512c6a", "587d8253367417b2b2512c6a",

View File

@ -6,7 +6,7 @@
"template": "", "template": "",
"required": [], "required": [],
"superBlock": "certificates", "superBlock": "certificates",
"superOrder": 10, "superOrder": 12,
"challengeOrder": [ "challengeOrder": [
[ [
"5a553ca864b52e1d8bceea14", "5a553ca864b52e1d8bceea14",
@ -14,5 +14,5 @@
] ]
], ],
"isPrivate": true, "isPrivate": true,
"fileName": "11-certificates/data-visualization-certificate.json" "fileName": "12-certificates/data-visualization-certificate.json"
} }

View File

@ -6,7 +6,7 @@
"template": "", "template": "",
"required": [], "required": [],
"superBlock": "certificates", "superBlock": "certificates",
"superOrder": 11, "superOrder": 12,
"challengeOrder": [ "challengeOrder": [
[ [
"561acd10cb82ac38a17513bc", "561acd10cb82ac38a17513bc",
@ -14,5 +14,5 @@
] ]
], ],
"isPrivate": true, "isPrivate": true,
"fileName": "11-certificates/front-end-libraries-certificate.json" "fileName": "12-certificates/front-end-libraries-certificate.json"
} }

View File

@ -1,12 +1,12 @@
{ {
"name": "Information Security and Quality Assurance Projects", "name": "Information Security and Quality Assurance Projects",
"dashedName": "information-security-and-quality-assurance-projects", "dashedName": "information-security-and-quality-assurance-projects",
"order": 4, "order": 0,
"time": "150 hours", "time": "150 hours",
"template": "", "template": "",
"required": [], "required": [],
"superBlock": "information-security-and-quality-assurance", "superBlock": "information-security-and-quality-assurance",
"superOrder": 6, "superOrder": 13,
"challengeOrder": [ "challengeOrder": [
[ [
"587d8249367417b2b2512c41", "587d8249367417b2b2512c41",
@ -27,16 +27,8 @@
[ [
"587d824a367417b2b2512c45", "587d824a367417b2b2512c45",
"Anonymous Message Board" "Anonymous Message Board"
],
[
"5e46f979ac417301a38fb932",
"Port Scanner"
],
[
"5e46f983ac417301a38fb933",
"SHA-1 Password Cracker"
] ]
], ],
"helpRoom": "HelpBackend", "helpRoom": "HelpBackend",
"fileName": "06-information-security-and-quality-assurance/quality-assurance-and-information-security-projects.json" "fileName": "12-information-security-and-quality-assurance/quality-assurance-and-information-security-projects.json"
} }

View File

@ -0,0 +1,18 @@
{
"name": "Information Security Certificate",
"dashedName": "information-security-certificate",
"order": 9,
"time": "",
"template": "",
"required": [],
"superBlock": "certificates",
"superOrder": 12,
"challengeOrder": [
[
"5e6021435ac9d0ecd8b94b00",
"Information Security Certificate"
]
],
"isPrivate": true,
"fileName": "12-certificates/information-security-certificate.json"
}

View File

@ -0,0 +1,34 @@
{
"name": "Information Security Projects",
"dashedName": "information-security-projects",
"order": 2,
"time": "150 hours",
"template": "",
"required": [],
"superBlock": "information-security",
"superOrder": 9,
"challengeOrder": [
[
"587d824a367417b2b2512c44",
"Stock Price Checker"
],
[
"587d824a367417b2b2512c45",
"Anonymous Message Board"
],
[
"5e601c775ac9d0ecd8b94aff",
"Real Time Multiplayer Game"
],
[
"5e46f979ac417301a38fb932",
"Port Scanner"
],
[
"5e46f983ac417301a38fb933",
"SHA-1 Password Cracker"
]
],
"helpRoom": "HelpBackend",
"fileName": "09-information-security/information-security-projects.json"
}

View File

@ -5,8 +5,8 @@
"time": "5 hours", "time": "5 hours",
"template": "", "template": "",
"required": [], "required": [],
"superBlock": "information-security-and-quality-assurance", "superBlock": "information-security",
"superOrder": 6, "superOrder": 9,
"challengeOrder": [ "challengeOrder": [
[ [
"587d8247367417b2b2512c36", "587d8247367417b2b2512c36",

View File

@ -6,7 +6,7 @@
"template": "", "template": "",
"required": [], "required": [],
"superBlock": "certificates", "superBlock": "certificates",
"superOrder": 11, "superOrder": 12,
"challengeOrder": [ "challengeOrder": [
[ [
"561add10cb82ac38a17213bc", "561add10cb82ac38a17213bc",
@ -14,5 +14,5 @@
] ]
], ],
"isPrivate": true, "isPrivate": true,
"fileName": "11-certificates/information-security-and-quality-assurance-certificate.json" "fileName": "12-certificates/information-security-and-quality-assurance-certificate.json"
} }

View File

@ -6,7 +6,7 @@
"template": "", "template": "",
"required": [], "required": [],
"superBlock": "certificates", "superBlock": "certificates",
"superOrder": 11, "superOrder": 12,
"challengeOrder": [ "challengeOrder": [
[ [
"561abd10cb81ac38a17513bc", "561abd10cb81ac38a17513bc",
@ -14,5 +14,5 @@
] ]
], ],
"isPrivate": true, "isPrivate": true,
"fileName": "11-certificates/javascript-algorithms-and-data-structures-certificate.json" "fileName": "12-certificates/javascript-algorithms-and-data-structures-certificate.json"
} }

View File

@ -0,0 +1,262 @@
{
"name": "Python for Everybody",
"dashedName": "lectures-python-for-everybody",
"order": 1,
"time": "15 hours",
"superBlock": "scientific-computing-with-python",
"superOrder": 7,
"challengeOrder": [
[
"5e6a54a558d3af90110a60a0",
"Introduction A"
],
[
"5e6a54af58d3af90110a60a1",
"Introduction B"
],
[
"5e6a54ba58d3af90110a60a2",
"Introduction C"
],
[
"5e6a54c358d3af90110a60a3",
"Introduction D"
],
[
"5e7b9f050b6c005b0e76f056",
"Expressions A"
],
[
"5e7b9f050b6c005b0e76f057",
"Expressions B"
],
[
"5e7b9f050b6c005b0e76f058",
"Conditional A"
],
[
"5e7b9f060b6c005b0e76f059",
"Conditional B"
],
[
"5e7b9f060b6c005b0e76f05a",
"Functions A"
],
[
"5e7b9f060b6c005b0e76f05b",
"Functions B"
],
[
"5e7b9f060b6c005b0e76f05c",
"Iterations A"
],
[
"5e7b9f070b6c005b0e76f05d",
"Iterations B"
],
[
"5e7b9f070b6c005b0e76f05e",
"Iterations C"
],
[
"5e7b9f070b6c005b0e76f05f",
"Iterations D"
],
[
"5e7b9f070b6c005b0e76f060",
"Strings A"
],
[
"5e7b9f070b6c005b0e76f061",
"Strings B"
],
[
"5e7b9f080b6c005b0e76f062",
"Files A"
],
[
"5e7b9f080b6c005b0e76f063",
"Files B"
],
[
"5e7b9f080b6c005b0e76f064",
"Lists A"
],
[
"5e7b9f090b6c005b0e76f065",
"Lists B"
],
[
"5e7b9f090b6c005b0e76f066",
"Lists C"
],
[
"5e7b9f090b6c005b0e76f067",
"Dictionaries A"
],
[
"5e7b9f090b6c005b0e76f068",
"Dictionaries B"
],
[
"5e7b9f0a0b6c005b0e76f069",
"Dictionaries C"
],
[
"5e7b9f0a0b6c005b0e76f06c",
"Tuples A"
],
[
"5e7b9f0b0b6c005b0e76f06d",
"Tuples B"
],
[
"5e7b9f0b0b6c005b0e76f06e",
"RegEx A"
],
[
"5e7b9f0b0b6c005b0e76f06f",
"RegEx B"
],
[
"5e7b9f0b0b6c005b0e76f070",
"RegEx C"
],
[
"5e7b9f0c0b6c005b0e76f071",
"HTTP A"
],
[
"5e7b9f0c0b6c005b0e76f072",
"HTTP B"
],
[
"5e7b9f0c0b6c005b0e76f073",
"HTTP C"
],
[
"5e7b9f0c0b6c005b0e76f074",
"HTTP D"
],
[
"5e7b9f0d0b6c005b0e76f075",
"HTTP E"
],
[
"5e7b9f0d0b6c005b0e76f076",
"HTTP F"
],
[
"5e7b9f0e0b6c005b0e76f07a",
"Web Services A"
],
[
"5e7b9f0e0b6c005b0e76f07b",
"Web Services B"
],
[
"5e7b9f0e0b6c005b0e76f07c",
"Web Services C"
],
[
"5e7b9f140b6c005b0e76f07d",
"Web Services D"
],
[
"5e7b9f140b6c005b0e76f07e",
"Web Services E"
],
[
"5e7b9f150b6c005b0e76f07f",
"Web Services F"
],
[
"5e7b9f150b6c005b0e76f080",
"Web Services G"
],
[
"5e7b9f160b6c005b0e76f085",
"Objects A"
],
[
"5e7b9f160b6c005b0e76f086",
"Objects B"
],
[
"5e7b9f170b6c005b0e76f087",
"Objects C"
],
[
"5e7b9f170b6c005b0e76f088",
"Objects D"
],
[
"5e7b9f170b6c005b0e76f08a",
"Databases A"
],
[
"5e7b9f170b6c005b0e76f08b",
"Databases B"
],
[
"5e7b9f180b6c005b0e76f08c",
"Databases C"
],
[
"5e7b9f180b6c005b0e76f08d",
"Databases D"
],
[
"5e7b9f180b6c005b0e76f08e",
"Databases E"
],
[
"5e7b9f180b6c005b0e76f08f",
"Databases F"
],
[
"5e7b9f190b6c005b0e76f090",
"Databases G"
],
[
"5e7b9f690b6c005b0e76f095",
"Viz A"
],
[
"5e7b9f6a0b6c005b0e76f096",
"Viz B"
],
[
"5e7b9f6a0b6c005b0e76f097",
"Viz C"
],
[
"5e7b9f6a0b6c005b0e76f098",
"Viz Geodata"
],
[
"5e7b9f6a0b6c005b0e76f099",
"Viz Gmane Model"
],
[
"5e7b9f6b0b6c005b0e76f09a",
"Viz Gmane Spider"
],
[
"5e7b9f6b0b6c005b0e76f09b",
"Viz Gmane Viz"
],
[
"5e7b9f6b0b6c005b0e76f09c",
"Viz Page Rank"
],
[
"5e7b9f6b0b6c005b0e76f09d",
"Viz Page Spider"
],
[
"5e7b9f6c0b6c005b0e76f09e",
"Viz Page Viz"
]
]
}

View File

@ -6,7 +6,7 @@
"template": "", "template": "",
"required": [], "required": [],
"superBlock": "certificates", "superBlock": "certificates",
"superOrder": 11, "superOrder": 12,
"challengeOrder": [ "challengeOrder": [
[ [
"660add10cb82ac38a17513be", "660add10cb82ac38a17513be",
@ -14,5 +14,5 @@
] ]
], ],
"isPrivate": true, "isPrivate": true,
"fileName": "11-certificates/legacy-back-end-certificate.json" "fileName": "12-certificates/legacy-back-end-certificate.json"
} }

View File

@ -6,7 +6,7 @@
"template": "", "template": "",
"required": [], "required": [],
"superBlock": "certificates", "superBlock": "certificates",
"superOrder": 11, "superOrder": 12,
"challengeOrder": [ "challengeOrder": [
[ [
"561add10cb82ac39a17513bc", "561add10cb82ac39a17513bc",
@ -14,5 +14,5 @@
] ]
], ],
"isPrivate": true, "isPrivate": true,
"fileName": "11-certificates/legacy-data-visualization-certificate.json" "fileName": "12-certificates/legacy-data-visualization-certificate.json"
} }

View File

@ -6,7 +6,7 @@
"template": "", "template": "",
"required": [], "required": [],
"superBlock": "certificates", "superBlock": "certificates",
"superOrder": 11, "superOrder": 12,
"challengeOrder": [ "challengeOrder": [
[ [
"561add10cb82ac38a17513be", "561add10cb82ac38a17513be",
@ -14,5 +14,5 @@
] ]
], ],
"isPrivate": true, "isPrivate": true,
"fileName": "11-certificates/legacy-front-end-certificate.json" "fileName": "12-certificates/legacy-front-end-certificate.json"
} }

View File

@ -1,12 +1,12 @@
{ {
"name": "Machine Learning with Python Certificate", "name": "Machine Learning with Python Certificate",
"dashedName": "machine-learning-with-python-certificate", "dashedName": "machine-learning-with-python-certificate",
"order": 9, "order": 10,
"time": "", "time": "",
"template": "", "template": "",
"required": [], "required": [],
"superBlock": "certificates", "superBlock": "certificates",
"superOrder": 11, "superOrder": 12,
"challengeOrder": [ "challengeOrder": [
[ [
"5e46fc95ac417301a38fb935", "5e46fc95ac417301a38fb935",
@ -14,5 +14,5 @@
] ]
], ],
"isPrivate": true, "isPrivate": true,
"fileName": "11-certificates/machine-learning-with-python-certificate.json" "fileName": "12-certificates/machine-learning-with-python-certificate.json"
} }

View File

@ -4,7 +4,7 @@
"order": 1, "order": 1,
"time": "150 hours", "time": "150 hours",
"superBlock": "machine-learning-with-python", "superBlock": "machine-learning-with-python",
"superOrder": 9, "superOrder": 10,
"challengeOrder": [ "challengeOrder": [
[ [
"5e46f8d6ac417301a38fb92d", "5e46f8d6ac417301a38fb92d",

View File

@ -6,7 +6,7 @@
"template": "", "template": "",
"required": [], "required": [],
"superBlock": "coding-interview-prep", "superBlock": "coding-interview-prep",
"superOrder": 10, "superOrder": 11,
"challengeOrder": [ "challengeOrder": [
[ [
"5900f36e1000cf542c50fe80", "5900f36e1000cf542c50fe80",

View File

@ -1,11 +1,11 @@
{ {
"name": "Quality Assurance and Testing with Chai", "name": "Quality Assurance and Testing with Chai",
"dashedName": "quality-assurance-and-testing-with-chai", "dashedName": "quality-assurance-and-testing-with-chai",
"order": 2, "order": 1,
"time": "5 hours", "time": "5 hours",
"template": "", "template": "",
"required": [], "required": [],
"superBlock": "information-security-and-quality-assurance", "superBlock": "quality-assurance",
"superOrder": 6, "superOrder": 6,
"challengeOrder": [ "challengeOrder": [
[ [
@ -106,5 +106,5 @@
] ]
], ],
"helpRoom": "Help", "helpRoom": "Help",
"fileName": "06-information-security-and-quality-assurance/testing-with-chai.json" "fileName": "06-quality-assurance/quality-assurance-and-testing-with-chai.json"
} }

View File

@ -0,0 +1,18 @@
{
"name": "Quality Assurance Certificate",
"dashedName": "quality-assurance-certificate",
"order": 6,
"time": "",
"template": "",
"required": [],
"superBlock": "certificates",
"superOrder": 12,
"challengeOrder": [
[
"5e611829481575a52dc59c0e",
"Quality Assurance Certificate"
]
],
"isPrivate": true,
"fileName": "12-certificates/quality-assurance-certificate.json"
}

View File

@ -0,0 +1,34 @@
{
"name": "Quality Assurance Projects",
"dashedName": "quality-assurance-projects",
"order": 3,
"time": "150 hours",
"template": "",
"required": [],
"superBlock": "quality-assurance",
"superOrder": 6,
"challengeOrder": [
[
"587d8249367417b2b2512c41",
"Metric-Imperial Converter"
],
[
"587d8249367417b2b2512c42",
"Issue Tracker"
],
[
"587d824a367417b2b2512c43",
"Personal Library"
],
[
"5e601bf95ac9d0ecd8b94afd",
"Sudoku Solver"
],
[
"5e601c0d5ac9d0ecd8b94afe",
"American British Translator"
]
],
"helpRoom": "HelpBackend",
"fileName": "06-quality-assurance/quality-assurance-projects.json"
}

View File

@ -6,7 +6,7 @@
"template": "", "template": "",
"required": [], "required": [],
"superBlock": "certificates", "superBlock": "certificates",
"superOrder": 11, "superOrder": 12,
"challengeOrder": [ "challengeOrder": [
[ [
"561add10cb82ac38a17513bc", "561add10cb82ac38a17513bc",
@ -14,5 +14,5 @@
] ]
], ],
"isPrivate": true, "isPrivate": true,
"fileName": "11-certificates/responsive-web-design-certificate.json" "fileName": "12-certificates/responsive-web-design-certificate.json"
} }

View File

@ -6,7 +6,7 @@
"template": "", "template": "",
"required": [], "required": [],
"superBlock": "coding-interview-prep", "superBlock": "coding-interview-prep",
"superOrder": 10, "superOrder": 11,
"challengeOrder": [ "challengeOrder": [
[ [
"594810f028c0303b75339acb", "594810f028c0303b75339acb",

View File

@ -6,7 +6,7 @@
"template": "", "template": "",
"required": [], "required": [],
"superBlock": "certificates", "superBlock": "certificates",
"superOrder": 11, "superOrder": 12,
"challengeOrder": [ "challengeOrder": [
[ [
"5e44431b903586ffb414c951", "5e44431b903586ffb414c951",
@ -14,5 +14,5 @@
] ]
], ],
"isPrivate": true, "isPrivate": true,
"fileName": "11-certificates/scientific-computing-with-python-certificate.json" "fileName": "12-certificates/scientific-computing-with-python-certificate.json"
} }

View File

@ -1,7 +1,7 @@
{ {
"name": "Scientific Computing with Python Projects", "name": "Scientific Computing with Python Projects",
"dashedName": "scientific-computing-with-python-projects", "dashedName": "scientific-computing-with-python-projects",
"order": 1, "order": 2,
"time": "150 hours", "time": "150 hours",
"superBlock": "scientific-computing-with-python", "superBlock": "scientific-computing-with-python",
"superOrder": 7, "superOrder": 7,

View File

@ -6,7 +6,7 @@
"template": "", "template": "",
"required": [], "required": [],
"superBlock": "coding-interview-prep", "superBlock": "coding-interview-prep",
"superOrder": 10, "superOrder": 11,
"challengeOrder": [ "challengeOrder": [
[ [
"bd7158d8c442eddfaeb5bd10", "bd7158d8c442eddfaeb5bd10",

Some files were not shown because too many files have changed in this diff Show More