test(backend): Testen voor DatabaseLearningObjectProvider.getLearningObjectHTML toegevoegd.
Hierbij optredende problemen ook opgelost.
This commit is contained in:
parent
a3b995393b
commit
91e3b5ad91
15 changed files with 103 additions and 60 deletions
|
@ -1,12 +1,13 @@
|
||||||
/**
|
/**
|
||||||
* Based on https://github.com/dwengovzw/Learning-Object-Repository/blob/main/app/processors/audio/audio_processor.js
|
* Based on https://github.com/dwengovzw/Learning-Object-Repository/blob/main/app/processors/audio/audio_processor.js
|
||||||
*/
|
*/
|
||||||
import Processor from "../processor.js";
|
|
||||||
import DOMPurify from 'isomorphic-dompurify';
|
import DOMPurify from 'isomorphic-dompurify';
|
||||||
import {type} from "node:os";
|
import {type} from "node:os";
|
||||||
import {DwengoContentType} from "../content-type";
|
import {DwengoContentType} from "../content-type";
|
||||||
|
import {StringProcessor} from "../string-processor";
|
||||||
|
|
||||||
class AudioProcessor extends Processor<string> {
|
class AudioProcessor extends StringProcessor {
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super(DwengoContentType.AUDIO_MPEG);
|
super(DwengoContentType.AUDIO_MPEG);
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
* Based on https://github.com/dwengovzw/Learning-Object-Repository/blob/main/app/processors/extern/extern_processor.js
|
* Based on https://github.com/dwengovzw/Learning-Object-Repository/blob/main/app/processors/extern/extern_processor.js
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Processor from "../processor.js";
|
|
||||||
import DOMPurify from 'isomorphic-dompurify';
|
import DOMPurify from 'isomorphic-dompurify';
|
||||||
import {ProcessingError} from "../processing-error";
|
import {ProcessingError} from "../processing-error";
|
||||||
import {isValidHttpUrl} from "../../../../util/links";
|
import {isValidHttpUrl} from "../../../../util/links";
|
||||||
import {DwengoContentType} from "../content-type";
|
import {DwengoContentType} from "../content-type";
|
||||||
|
import {StringProcessor} from "../string-processor";
|
||||||
|
|
||||||
class ExternProcessor extends Processor<string> {
|
class ExternProcessor extends StringProcessor {
|
||||||
constructor() {
|
constructor() {
|
||||||
super(DwengoContentType.EXTERN);
|
super(DwengoContentType.EXTERN);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
* Based on https://github.com/dwengovzw/Learning-Object-Repository/blob/main/app/processors/gift/gift_processor.js
|
* Based on https://github.com/dwengovzw/Learning-Object-Repository/blob/main/app/processors/gift/gift_processor.js
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Processor from "../processor.js";
|
|
||||||
import DOMPurify from 'isomorphic-dompurify';
|
import DOMPurify from 'isomorphic-dompurify';
|
||||||
import {GIFTQuestion, parse} from "gift-pegjs"
|
import {GIFTQuestion, parse} from "gift-pegjs"
|
||||||
import {DwengoContentType} from "../content-type";
|
import {DwengoContentType} from "../content-type";
|
||||||
|
@ -15,8 +14,9 @@ import {MatchingQuestionRenderer} from "./question-renderers/matching-question-r
|
||||||
import {NumericalQuestionRenderer} from "./question-renderers/numerical-question-renderer";
|
import {NumericalQuestionRenderer} from "./question-renderers/numerical-question-renderer";
|
||||||
import {ShortQuestionRenderer} from "./question-renderers/short-question-renderer";
|
import {ShortQuestionRenderer} from "./question-renderers/short-question-renderer";
|
||||||
import {TrueFalseQuestionRenderer} from "./question-renderers/true-false-question-renderer";
|
import {TrueFalseQuestionRenderer} from "./question-renderers/true-false-question-renderer";
|
||||||
|
import {StringProcessor} from "../string-processor";
|
||||||
|
|
||||||
class GiftProcessor extends Processor<string> {
|
class GiftProcessor extends StringProcessor {
|
||||||
|
|
||||||
private renderers: RendererMap = {
|
private renderers: RendererMap = {
|
||||||
Category: new CategoryQuestionRenderer(),
|
Category: new CategoryQuestionRenderer(),
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
* Based on https://github.com/dwengovzw/Learning-Object-Repository/blob/main/app/processors/image/inline_image_processor.js
|
* Based on https://github.com/dwengovzw/Learning-Object-Repository/blob/main/app/processors/image/inline_image_processor.js
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Processor from "../processor.js";
|
|
||||||
import DOMPurify from 'isomorphic-dompurify';
|
import DOMPurify from 'isomorphic-dompurify';
|
||||||
import {DwengoContentType} from "../content-type.js";
|
import {DwengoContentType} from "../content-type.js";
|
||||||
import {ProcessingError} from "../processing-error.js";
|
import {ProcessingError} from "../processing-error.js";
|
||||||
import {isValidHttpUrl} from "../../../../util/links";
|
import {isValidHttpUrl} from "../../../../util/links";
|
||||||
|
import {StringProcessor} from "../string-processor";
|
||||||
|
|
||||||
class InlineImageProcessor extends Processor<string> {
|
class InlineImageProcessor extends StringProcessor {
|
||||||
constructor(contentType: DwengoContentType = DwengoContentType.IMAGE_INLINE) {
|
constructor(contentType: DwengoContentType = DwengoContentType.IMAGE_INLINE) {
|
||||||
super(contentType);
|
super(contentType);
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,45 +42,43 @@ function extractLearningObjectIdFromHref(href: string): LearningObjectIdentifier
|
||||||
* - embeddings of other learning objects.
|
* - embeddings of other learning objects.
|
||||||
*/
|
*/
|
||||||
const dwengoMarkedRenderer: RendererObject = {
|
const dwengoMarkedRenderer: RendererObject = {
|
||||||
heading(heading: Heading) {
|
heading(heading: Heading): string {
|
||||||
const text = heading.text;
|
const text = heading.text;
|
||||||
const level = heading.depth;
|
const level = heading.depth;
|
||||||
const escapedText = text.toLowerCase().replace(/[^\w]+/g, '-');
|
const escapedText = text.toLowerCase().replace(/[^\w]+/g, '-');
|
||||||
|
|
||||||
return `
|
return `<h${level}>\n` +
|
||||||
<h${level}>
|
` <a name="${escapedText}" class="anchor" href="#${escapedText}">\n` +
|
||||||
<a name="${escapedText}" class="anchor" href="#${escapedText}">
|
` <span class="header-link"></span>\n` +
|
||||||
<span class="header-link"></span>
|
` </a>\n` +
|
||||||
</a>
|
` ${text}\n` +
|
||||||
${text}
|
`</h${level}>\n`
|
||||||
</h${level}>`;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// When the syntax for a link is used => [text](href "title")
|
// When the syntax for a link is used => [text](href "title")
|
||||||
// render a custom link when the prefix for a learning object is used.
|
// render a custom link when the prefix for a learning object is used.
|
||||||
link(link: Link) {
|
link(link: Link): string {
|
||||||
const href = link.href;
|
const href = link.href;
|
||||||
const title = link.title || "";
|
const title = link.title || "";
|
||||||
const text = link.text;
|
const text = marked.parseInline(link.text); // There could for example be an image in the link.
|
||||||
|
|
||||||
if (href.startsWith(prefixes.learningObject)) {
|
if (href.startsWith(prefixes.learningObject)) {
|
||||||
// link to learning-object
|
// link to learning-object
|
||||||
const learningObjectId = extractLearningObjectIdFromHref(href);
|
const learningObjectId = extractLearningObjectIdFromHref(href);
|
||||||
return `
|
return `<a href="${getUrlStringForLearningObjectHTML(learningObjectId)}" target="_blank" title="${title}">${text}</a>`;
|
||||||
<a href="${getUrlStringForLearningObjectHTML(learningObjectId)}]" target="_blank" title="${title}">${text}</a>
|
|
||||||
`;
|
|
||||||
} else {
|
} else {
|
||||||
// any other link
|
// any other link
|
||||||
if (!isValidHttpUrl(href)) {
|
if (!isValidHttpUrl(href)) {
|
||||||
throw new ProcessingError("Link is not a valid HTTP URL!");
|
throw new ProcessingError("Link is not a valid HTTP URL!");
|
||||||
}
|
}
|
||||||
|
//<a href="https://kiks.ilabt.imec.be/hub/tmplogin?id=0101" title="Notebooks Werking"><img src="Knop.png" alt="" title="Knop"></a>
|
||||||
return `<a href="${href}" target="_blank" title="${title}">${text}</a>`;
|
return `<a href="${href}" target="_blank" title="${title}">${text}</a>`;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// When the syntax for an image is used => 
|
// When the syntax for an image is used => 
|
||||||
// render a learning object, pdf, audio or video if a prefix is used.
|
// render a learning object, pdf, audio or video if a prefix is used.
|
||||||
image(img: Image) {
|
image(img: Image): string {
|
||||||
const href = img.href;
|
const href = img.href;
|
||||||
if (href.startsWith(prefixes.learningObject)) {
|
if (href.startsWith(prefixes.learningObject)) {
|
||||||
// embedded learning-object
|
// embedded learning-object
|
||||||
|
|
|
@ -2,14 +2,14 @@
|
||||||
* Based on https://github.com/dwengovzw/Learning-Object-Repository/blob/main/app/processors/markdown/markdown_processor.js
|
* Based on https://github.com/dwengovzw/Learning-Object-Repository/blob/main/app/processors/markdown/markdown_processor.js
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {marked} from 'marked'
|
import {marked} from 'marked';
|
||||||
import Processor from '../processor.js';
|
|
||||||
import InlineImageProcessor from '../image/inline-image-processor.js';
|
import InlineImageProcessor from '../image/inline-image-processor.js';
|
||||||
import {DwengoContentType} from "../content-type";
|
import {DwengoContentType} from "../content-type";
|
||||||
import {ProcessingError} from "../processing-error";
|
|
||||||
import dwengoMarkedRenderer from "./dwengo-marked-renderer";
|
import dwengoMarkedRenderer from "./dwengo-marked-renderer";
|
||||||
|
import {StringProcessor} from "../string-processor";
|
||||||
|
import {ProcessingError} from "../processing-error";
|
||||||
|
|
||||||
class MarkdownProcessor extends Processor<string> {
|
class MarkdownProcessor extends StringProcessor {
|
||||||
constructor() {
|
constructor() {
|
||||||
super(DwengoContentType.TEXT_MARKDOWN);
|
super(DwengoContentType.TEXT_MARKDOWN);
|
||||||
}
|
}
|
||||||
|
@ -17,9 +17,9 @@ class MarkdownProcessor extends Processor<string> {
|
||||||
override renderFn(mdText: string) {
|
override renderFn(mdText: string) {
|
||||||
let html = "";
|
let html = "";
|
||||||
try {
|
try {
|
||||||
mdText = this.replaceLinks(mdText); // Replace html image links with path based on metadata
|
|
||||||
marked.use({renderer: dwengoMarkedRenderer});
|
marked.use({renderer: dwengoMarkedRenderer});
|
||||||
html = marked(mdText, {async: false});
|
html = marked(mdText, {async: false});
|
||||||
|
html = this.replaceLinks(html); // Replace html image links path
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
throw new ProcessingError(e.message);
|
throw new ProcessingError(e.message);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
* Based on https://github.com/dwengovzw/Learning-Object-Repository/blob/main/app/processors/pdf/pdf_processor.js
|
* Based on https://github.com/dwengovzw/Learning-Object-Repository/blob/main/app/processors/pdf/pdf_processor.js
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Processor from "../processor.js";
|
|
||||||
import DOMPurify from 'isomorphic-dompurify';
|
import DOMPurify from 'isomorphic-dompurify';
|
||||||
import {DwengoContentType} from "../content-type.js";
|
import {DwengoContentType} from "../content-type.js";
|
||||||
import {isValidHttpUrl} from "../../../../util/links.js";
|
import {isValidHttpUrl} from "../../../../util/links.js";
|
||||||
import {ProcessingError} from "../processing-error.js";
|
import {ProcessingError} from "../processing-error.js";
|
||||||
|
import {StringProcessor} from "../string-processor";
|
||||||
|
|
||||||
class PdfProcessor extends Processor<string> {
|
class PdfProcessor extends StringProcessor {
|
||||||
constructor() {
|
constructor() {
|
||||||
super(DwengoContentType.APPLICATION_PDF);
|
super(DwengoContentType.APPLICATION_PDF);
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,6 @@ abstract class Processor<T> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function which actually executes the rendering of a learning object.
|
* Function which actually executes the rendering of a learning object.
|
||||||
* By default, this just means rendering the content in the content property of the learning object.
|
|
||||||
*
|
*
|
||||||
* When implementing this function, we may assume that we are responsible for the content type of the learning
|
* When implementing this function, we may assume that we are responsible for the content type of the learning
|
||||||
* object.
|
* object.
|
||||||
|
@ -56,9 +55,7 @@ abstract class Processor<T> {
|
||||||
* @param toRender Learning object to render
|
* @param toRender Learning object to render
|
||||||
* @protected
|
* @protected
|
||||||
*/
|
*/
|
||||||
protected renderLearningObjectFn(toRender: LearningObject): string {
|
protected abstract renderLearningObjectFn(toRender: LearningObject): string;
|
||||||
return this.render(toRender.content as T);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Processor;
|
export default Processor;
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
import Processor from "./processor";
|
||||||
|
import {LearningObject} from "../../../entities/content/learning-object.entity";
|
||||||
|
|
||||||
|
export abstract class StringProcessor extends Processor<string> {
|
||||||
|
/**
|
||||||
|
* Function which actually executes the rendering of a learning object.
|
||||||
|
* By default, this just means rendering the content in the content property of the learning object (interpreted
|
||||||
|
* as string)
|
||||||
|
*
|
||||||
|
* When implementing this function, we may assume that we are responsible for the content type of the learning
|
||||||
|
* object.
|
||||||
|
*
|
||||||
|
* @param toRender Learning object to render
|
||||||
|
* @protected
|
||||||
|
*/
|
||||||
|
protected renderLearningObjectFn(toRender: LearningObject): string {
|
||||||
|
return this.render(toRender.content.toString("ascii"));
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,11 +2,11 @@
|
||||||
* Based on https://github.com/dwengovzw/Learning-Object-Repository/blob/main/app/processors/text/text_processor.js
|
* Based on https://github.com/dwengovzw/Learning-Object-Repository/blob/main/app/processors/text/text_processor.js
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import DOMPurify from 'isomorphic-dompurify'
|
import DOMPurify from 'isomorphic-dompurify';
|
||||||
import Processor from "../processor.js"
|
|
||||||
import {DwengoContentType} from "../content-type.js";
|
import {DwengoContentType} from "../content-type.js";
|
||||||
|
import {StringProcessor} from "../string-processor";
|
||||||
|
|
||||||
class TextProcessor extends Processor<string> {
|
class TextProcessor extends StringProcessor {
|
||||||
constructor() {
|
constructor() {
|
||||||
super(DwengoContentType.TEXT_PLAIN);
|
super(DwengoContentType.TEXT_PLAIN);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ import {LearningObjectIdentifier} from "../interfaces/learning-content";
|
||||||
|
|
||||||
export function isValidHttpUrl(url: string): boolean {
|
export function isValidHttpUrl(url: string): boolean {
|
||||||
try {
|
try {
|
||||||
const parsedUrl = new URL(url);
|
const parsedUrl = new URL(url, "http://test.be");
|
||||||
return parsedUrl.protocol === "http:" || parsedUrl.protocol === "https:";
|
return parsedUrl.protocol === "http:" || parsedUrl.protocol === "https:";
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -25,28 +25,34 @@ describe("DatabaseLearningObjectProvider", () => {
|
||||||
await setupTestApp();
|
await setupTestApp();
|
||||||
exampleLearningObject = await initExampleData();
|
exampleLearningObject = await initExampleData();
|
||||||
});
|
});
|
||||||
|
describe("getLearningObjectById", () => {
|
||||||
it("should return the learning object when it is queried by its id", async () => {
|
it("should return the learning object when it is queried by its id", async () => {
|
||||||
const result: FilteredLearningObject | null = await databaseLearningObjectProvider.getLearningObjectById(exampleLearningObject);
|
const result: FilteredLearningObject | null = await databaseLearningObjectProvider.getLearningObjectById(exampleLearningObject);
|
||||||
expect(result).toBeTruthy();
|
expect(result).toBeTruthy();
|
||||||
expectToBeCorrectFilteredLearningObject(result!, exampleLearningObject);
|
expectToBeCorrectFilteredLearningObject(result!, exampleLearningObject);
|
||||||
});
|
|
||||||
|
|
||||||
it("should return the learning object when it is queried by only hruid and language (but not version)", async () => {
|
|
||||||
const result: FilteredLearningObject | null = await databaseLearningObjectProvider.getLearningObjectById({
|
|
||||||
hruid: exampleLearningObject.hruid,
|
|
||||||
language: exampleLearningObject.language
|
|
||||||
});
|
});
|
||||||
expect(result).toBeTruthy();
|
|
||||||
expectToBeCorrectFilteredLearningObject(result!, exampleLearningObject);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should return null when queried with an id that does not exist", async () => {
|
it("should return the learning object when it is queried by only hruid and language (but not version)", async () => {
|
||||||
const result: FilteredLearningObject | null = await databaseLearningObjectProvider.getLearningObjectById({
|
const result: FilteredLearningObject | null = await databaseLearningObjectProvider.getLearningObjectById({
|
||||||
hruid: "non_existing_hruid",
|
hruid: exampleLearningObject.hruid,
|
||||||
language: Language.Dutch
|
language: exampleLearningObject.language
|
||||||
|
});
|
||||||
|
expect(result).toBeTruthy();
|
||||||
|
expectToBeCorrectFilteredLearningObject(result!, exampleLearningObject);
|
||||||
});
|
});
|
||||||
expect(result).toBeNull();
|
|
||||||
});
|
|
||||||
|
|
||||||
|
it("should return null when queried with an id that does not exist", async () => {
|
||||||
|
const result: FilteredLearningObject | null = await databaseLearningObjectProvider.getLearningObjectById({
|
||||||
|
hruid: "non_existing_hruid",
|
||||||
|
language: Language.Dutch
|
||||||
|
});
|
||||||
|
expect(result).toBeNull();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
describe("getLearningObjectHTML", () => {
|
||||||
|
it("should return the correct rendering of the learning object", async () => {
|
||||||
|
const result = await databaseLearningObjectProvider.getLearningObjectHTML(exampleLearningObject);
|
||||||
|
expect(result).toEqual(example.getHTMLRendering());
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -3,5 +3,6 @@ import {Attachment} from "../../../src/entities/content/attachment.entity";
|
||||||
|
|
||||||
type LearningObjectExample = {
|
type LearningObjectExample = {
|
||||||
createLearningObject: () => LearningObject,
|
createLearningObject: () => LearningObject,
|
||||||
createAttachment: {[key: string]: (owner: LearningObject) => Attachment}
|
createAttachment: {[key: string]: (owner: LearningObject) => Attachment},
|
||||||
|
getHTMLRendering: () => string
|
||||||
};
|
};
|
||||||
|
|
|
@ -45,7 +45,7 @@ const example: LearningObjectExample = {
|
||||||
|
|
||||||
learningObject.returnValue = returnValue;
|
learningObject.returnValue = returnValue;
|
||||||
learningObject.available = true;
|
learningObject.available = true;
|
||||||
learningObject.content = loadTestAsset(`${ASSETS_PREFIX}/dwengo.png`);
|
learningObject.content = loadTestAsset(`${ASSETS_PREFIX}/content.md`);
|
||||||
|
|
||||||
return learningObject
|
return learningObject
|
||||||
},
|
},
|
||||||
|
@ -66,6 +66,7 @@ const example: LearningObjectExample = {
|
||||||
att.content = loadTestAsset(`${ASSETS_PREFIX}/Knop.png`)
|
att.content = loadTestAsset(`${ASSETS_PREFIX}/Knop.png`)
|
||||||
return att;
|
return att;
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
getHTMLRendering: () => loadTestAsset(`${ASSETS_PREFIX}/rendering.html`).toString()
|
||||||
}
|
}
|
||||||
export default example;
|
export default example;
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
<h1>
|
||||||
|
<a name="werken-met-notebooks" class="anchor" href="#werken-met-notebooks">
|
||||||
|
<span class="header-link"></span>
|
||||||
|
</a>
|
||||||
|
Werken met notebooks
|
||||||
|
</h1>
|
||||||
|
<p>Het lesmateriaal van 'Python in wiskunde en STEM' wordt aangeboden in de vorm van interactieve <strong><em>notebooks</em></strong>. Notebooks zijn <em>digitale documenten</em> die zowel uitvoerbare code bevatten als tekst, afbeeldingen, video, hyperlinks ...</p>
|
||||||
|
<p><em>Nieuwe begrippen</em> worden aangebracht via tekstuele uitleg, video en afbeeldingen.</p>
|
||||||
|
<p>Er zijn uitgewerkte <em>voorbeelden</em> met daarnaast ook kleine en grote <em>opdrachten</em>. In deze opdrachten zal je aangereikte code kunnen uitvoeren, maar ook zelf code opstellen.</p>
|
||||||
|
<p>De code die in de notebooks gebruikt wordt, is Python versie 3. We kozen voor Python omdat dit een heel toegankelijke programmeertaal is, die vaak ook intuC/tief is.
|
||||||
|
Python is bovendien bezig aan een opmars en wordt gebruikt door bedrijven, zoals Google, NASA, Netflix, Uber, AstraZeneca, Barco, Instagram en YouTube.</p>
|
||||||
|
<p>We kozen voor notebooks omdat daar enkele belangrijke voordelen aan verbonden zijn: leerkrachten moeten geen geavanceerde installaties doen om de notebooks te gebruiken, leerkrachten kunnen verschillende soorten van lesinhouden aanbieden via C)C)n platform, de notebooks zijn interactief, leerlingen bouwen de oplossing van een probleem stap voor stap op in de notebook waardoor dat proces zichtbaar is voor de leerkracht (<a href="https://libstore.ugent.be/fulltxt/RUG01/003/151/437/RUG01-003151437_2023_0001_AC.pdf" target="_blank" title="">Jeroen Van der Hooft, 2023</a>).</p>
|
||||||
|
<hr>
|
||||||
|
<p>Klik je op onderstaande knop 'Open notebooks', dan word je doorgestuurd naar een andere website waar jouw persoonlijke notebooks ingeladen worden. (Dit kan even duren.)</p>
|
||||||
|
<p>Links op het scherm vind je er twee bestanden met extensie <em>.ipynb</em>.
|
||||||
|
Dit zijn de twee notebooks waarin je resp. een overzicht krijgt van de opbouw en mogelijkheden en hoe je er mee aan de slag kan. Dubbelklik op de bestandsnaam om een notebook te openen.</p>
|
||||||
|
<p>Je ziet er ook een map <em>images</em> met de afbeeldingen die in de notebooks getoond worden.</p>
|
||||||
|
<p>In deze eerste twee notebooks leer je hoe de notebooks zijn opgevat en hoe je ermee aan de slag kan.
|
||||||
|
Na het doorlopen van beide notebooks heb je een goed idee van hoe onze Python notebooks zijn opgevat.</p>
|
||||||
|
<p><a href="https://kiks.ilabt.imec.be/hub/tmplogin?id=0101" target="_blank" title="Notebooks Werking"><img alt="" src="Knop.png"></a></p>
|
Loading…
Add table
Add a link
Reference in a new issue