Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15,199 changes: 0 additions & 15,199 deletions package-lock.json

This file was deleted.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -141,5 +141,8 @@
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/test/__mocks__/fileMock.js",
"\\.(css|less)$": "<rootDir>/test/__mocks__/styleMock.js"
}
},
"dependencies": {
"automatic-assessments": "^1.0.5"
}
}
Empty file.
Empty file.
21 changes: 21 additions & 0 deletions src/components/gui/gui.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ import VM from "scratch-vm";
import Renderer from "scratch-render";

import Blocks from "../../containers/blocks.jsx";

import CostumeTab from "../../containers/costume-tab.jsx";
import TargetPane from "../../containers/target-pane.jsx";
import SoundTab from "../../containers/sound-tab.jsx";
import SaveLoadTab from "../../containers/save-load-tab.jsx";
import AssessmentTab from "../../containers/assessment-tab.jsx";
import StageWrapper from "../../containers/stage-wrapper.jsx";
import Loader from "../loader/loader.jsx";
import Box from "../box/box.jsx";
Expand All @@ -43,11 +45,14 @@ import layout, { STAGE_SIZE_MODES } from "../../lib/layout-constants";
import { getStageDimensions, resolveStageSize } from "../../lib/screen-utils";

import styles from "./gui.css";

import addExtensionIcon from "./icon--extensions.svg";
import codeIcon from "./icon--code.svg";
import costumesIcon from "./icon--costumes.svg";
import soundsIcon from "./icon--sounds.svg";
import saveIcon from "./icon--save.svg";
import assessmentIcon from "./icon--assessment.svg";

import Controls from "../../containers/controls.jsx";
import StageHeader from "../../containers/editor-stagesize-header.jsx";
import MonitorList from "../../containers/monitor-list.jsx";
Expand Down Expand Up @@ -112,6 +117,7 @@ const GUIComponent = (props) => {
onToggleLoginOpen,
onActivateCostumesTab,
onActivateSaveLoadTab,
onActivateAssessmentTab,
onActivateSoundsTab,
onActivateTab,
onClickLogo,
Expand All @@ -126,6 +132,7 @@ const GUIComponent = (props) => {
onTelemetryModalOptIn,
onTelemetryModalOptOut,
saveLoadTabVisible,
assessmentTabVisible,
showComingSoon,
soundsTabVisible,
stageSizeForSensors,
Expand Down Expand Up @@ -302,6 +309,17 @@ const GUIComponent = (props) => {
id="gui.gui.toggleSpriteTab"
/>
</Tab>
<Tab
className={tabClassNames.tab}
onClick={onActivateAssessmentTab}
>
<img draggable={false} src={assessmentIcon} />
<FormattedMessage
defaultMessage="Assessment"
description="Automatic assessment of code"
id="gui.gui.toggleAssessmentTab"
/>
</Tab>
<LanguageStandalone
canChangeLanguage={canChangeLanguage}
/>
Expand Down Expand Up @@ -364,6 +382,9 @@ const GUIComponent = (props) => {
>
{saveLoadTabVisible ? <SaveLoadTab vm={vm} /> : null}
</TabPanel>
<TabPanel className={tabClassNames.tabPanel}>
{assessmentTabVisible ? <AssessmentTab vm={vm} /> : null}
</TabPanel>
</Tabs>
{/* {backpackVisible ? (
<Backpack host={backpackHost} />
Expand Down
88 changes: 88 additions & 0 deletions src/components/gui/icon--assessment.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 26 additions & 0 deletions src/components/marty-assessment/assessment.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
.outer-container {
display: grid;
width: 100%;
height: 100%;
grid-template-columns: 1.5fr 1fr;
grid-template-rows: 1fr;
grid-template-areas: "scores-card details-card";
}

.modal-container {
margin: 50px;
}

@media screen and (max-width: 800px) {
.outer-container {
grid-template-areas:
"details-card"
"scores-card";
grid-template-columns: 1fr;
row-gap: 40px;
margin: 50px;
padding: 40px;
overflow: scroll;
height: 90vh;
}
}
69 changes: 69 additions & 0 deletions src/components/marty-assessment/assessment.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import React from "react";
import PropTypes from "prop-types";
import VM from "scratch-vm";
import { assess } from "automatic-assessments/lib";
import ScoresCard from "./scores-card/scores-card.jsx";
import styles from "./assessment.css";
import Modal from "../../containers/modal.jsx";
import DetailsCard from "./details-card/details-card.jsx";

class Assessment extends React.Component {
constructor(props) {
super(props);
this.state = { scores: assess(vm.runtime.targets), showModal: false, modalData: {content: null, title: ""} };
this.closeModal = this.closeModal.bind(this);
this.openModal = this.openModal.bind(this);
this.totalScore = this.totalScore.bind(this);
}

closeModal() {
this.setState({ showModal: false });
}

openModal(modalData) {
this.setState({ showModal: true, modalData: modalData });
}

totalScore() {
let total = 0;
Object.keys(this.state.scores).forEach(categoryKey => {
total += this.state.scores[categoryKey];
})
return total;
}

render() {
return (
<div className={styles.outerContainer}>
{this.state.showModal && (
<Modal
id="assessment-modal"
className={styles.modalContent}
contentLabel={this.state.modalData.title}
onRequestClose={this.closeModal}
fullScreen={true}
>
<div className={styles.modalContainer}>{this.state.modalData.content}</div>
</Modal>
)}
<ScoresCard
onCategoryClick={this.openModal}
dataRepresentation={this.state.scores.DataRepresentation}
flowControl={this.state.scores.FlowControl}
interactivity={this.state.scores.Interactivity}
logic={this.state.scores.Logic}
abstraction={this.state.scores.Abstraction}
synchronisation={this.state.scores.Synchronisation}
parallelism={this.state.scores.Parallelism}
/>
<DetailsCard totalScore={this.totalScore()}/>
</div>
);
}
}

Assessment.propTypes = {
vm: PropTypes.instanceOf(VM).isRequired,
};

export default Assessment;
113 changes: 113 additions & 0 deletions src/components/marty-assessment/categories-info/abstraction-info.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import React from "react";
import abstractionImg1 from "../../../../static/abs1.png";
import abstractionImg2 from "../../../../static/abs2.png";
import abstractionImg3 from "../../../../static/abs3.png";
import abstractionImg4 from "../../../../static/abs4.png";
import abstractionImg5 from "../../../../static/abs5.png";
import abstractionImg6 from "../../../../static/abs6.png";

import mainStyles from "./categories-styles.css";

const AbstractionInfo = () => {
return (
<div className={mainStyles.outerContainer}>
<h2 className={mainStyles.title}>If you get 0 points...</h2>
<p className={mainStyles.paragraph}>
When you start programming with Scratch, sometimes it may seem that the
simplest solution is to program all the behavior of a character in a
single program. However, ideally is that character behavior is
controlled by different programs and each of these programs deal with a
particular issue. Here's an example:
</p>
<img
className={mainStyles.image}
src={abstractionImg1}
alt="scratch-img"
/>
<p className={mainStyles.paragraph}>
This project, which paints a picture on the screen, has been programmed
in a single program that draws the two lines that make up the drawing.
Although it is a valid option, a simpler option to program and maintain
the program is divided into two parts, so that we have two different
programs, one to paint the front and another to paint the second:
</p>
<img
className={mainStyles.image}
src={abstractionImg2}
alt="scratch-img"
/>
<p className={mainStyles.paragraph}>
Thus, if we make any changes eg in one of the lines drawn, it is much
easier to know which part of the program we need to go to carry out the
changes.
</p>
<h2 className={mainStyles.title}>If you get 1 points...</h2>
<p className={mainStyles.paragraph}>
Scratch allows new user-defined blocks that consist of a sequence of
instructions. These abstractions allow you to create simple programs to
read, program and maintain. Here's an example:
</p>
<img
className={mainStyles.image}
src={abstractionImg3}
alt="scratch-img"
/>
<p className={mainStyles.paragraph}>
This Scratch project draws two orange lines of different length on the
screen. Rather than repeat the code 2 times, as shown in the example,
you can define a 'DrawOrange' block consisting of blocks that paint an
orange line on the screen and that you can tell what is the length of
the line. For this you go to the category 'More Blocks' and press the
Create button a block:
</p>
<img
className={mainStyles.image}
src={abstractionImg4}
alt="scratch-img"
/>
<p className={mainStyles.paragraph}>
Having defined the block 'DrawOrange' it can be used in any program of
the project, as we see below:
</p>
<img
className={mainStyles.image}
src={abstractionImg5}
alt="scratch-img"
/>
<p className={mainStyles.paragraph}>
In this way, we avoid repeating code, which makes our projects easier to
program and maintain. As can be seen, the first time the block is used
DrawOrange prompted a length of 100 steps, whereas the second time
length is 200 steps.
</p>
<h2 className={mainStyles.title}>If you get 2 points...</h2>
<p className={mainStyles.paragraph}>
In some Scratch projects we have many identical characters that exactly
perform the same actions. The first idea that comes to mind to do this
is to create a character, schedule all his behavior and once you're
ready, make as many copies as you need. Therefore, if we want 20
Martians, create 20 identical objects. However, what if I want to change
the program? Would have to go object by object performing this
modification. For such situations it is preferable to use clones, a type
of abstraction that helps us to program a single object, and dynamically
create exact copies with the same behavior. Let's see how it works with
an example. Imagine you want to pretend that it is snowing on a project.
We can draw an object that is a snowflake, and once you start
implementing the project, constantly be creating clones appear at the
top of the screen and they will fall to the bottom:
</p>
<img
className={mainStyles.image}
src={abstractionImg6}
alt="scratch-img"
/>
<p className={mainStyles.paragraph}>
Thus, just by programming a character, we can have infinite clones which
are created at a particular time of project implementation and are
deleted when they are no longer needed.
</p>
</div>
);
};

export default AbstractionInfo;
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.outer-container {}

.title {}

.paragraph {}

.image {
width: 50%;
}
Loading