Skip to content

Commit

Permalink
Merge pull request #298 from PremierLangage/components
Browse files Browse the repository at this point in the history
Components
  • Loading branch information
Pavell94000 authored Jul 17, 2019
2 parents f415ac3 + a2b79f0 commit fc0e294
Show file tree
Hide file tree
Showing 29 changed files with 1,755 additions and 296 deletions.
4 changes: 1 addition & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# Project
home/**
!home/lib

!/home/lib/
tmp/


Expand Down Expand Up @@ -37,7 +36,6 @@ dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
Expand Down
335 changes: 335 additions & 0 deletions apps/components/components.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,335 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# source.py
#
# Copyright 2019 Cisse Mamadou [[email protected]]

import importlib
import inspect
import json
import random
import sys
import uuid



def components_source():
"""
Used by playexo to retrieve the place this file
on the sandbox before a build
"""

mod = sys.modules[__name__]
return inspect.getsource(mod)


# MAP OF CURRENTS COMPONENTS WHERE KEY
# IS THE NAME OF THE COMPONENT AND VALUE
# THE SELECTOR OF THE COMPONENT
SELECTORS = {
"AutomatonDrawer": "c-automaton-drawer",
"AutomatonEditor": "c-automaton-editor",
"CheckboxGroup": "c-checkbox-group",
"CodeEditor": "c-code-editor",
"DragDrop": "c-drag-drop",
"GraphDrawer": "c-graph-drawer",
"Input": "c-input",
"MatchList": "c-match-list",
"MathDrawer": "c-math-drawer",
"MathInput": "c-math-input",
"MathMatrix": "c-math-matrix",
"RadioGroup": "c-radio-group",
"SortList": "c-sort-list",
"Text": "c-text",
"TransfertList": "c-transfert-list"
}



class Component:
"""
Base class of the components.
"""


def __init__(self, **kwargs):
for k, v in kwargs.items():
setattr(self, k, v)

if getattr(self, 'cid', '') == '':
self.cid = str(uuid.uuid4())


def __str__(self):
return str(vars(self))


@staticmethod
def deserialize(target, data):
"""
Transforms `target` into the instance of a class extending `Component`
and initializes its fields with the given dict `data`.
- If `target` is already an instance of `Component` values of
`data` will be copied into it. (always true if deserialized during grade)
- if 'target' is a dict (always true during build) and `decorator` key is in it,
target will be instancied as an instance of decorator retrieved from the sandbox.
- If none of the case above are not respected, the method will creates
and instance of the type depending of `selector` key of `data`.
"""
if isinstance(target, Component):
for k, v in data.items():
setattr(target, k, v)
return target

decorator = None

if isinstance(target, dict):
decorator = data.get('decorator')

if decorator:
module = importlib.import_module(decorator.lower())
return getattr(module, decorator)(**data)

selector = data.get('selector')
if not selector:
msg = 'selector property is required for components'
raise Exception(msg)
for k in SELECTORS:
if SELECTORS[k] == selector:
cls = globals().get(k)
if not cls:
break
return cls(**data)

return Component(**data)


@staticmethod
def sync_context(context):
context['Component'] = Component
for k in SELECTORS:
context[k] = globals()[k]

# tranform dict with cid properties to a component
for k, v in context.items():
if isinstance(v, dict) and 'cid' in v:
context[k] = Component.deserialize(v, v)

# sync answers with context in grader
answers = None
for arg in sys.argv:
if arg == 'answers.json':
with open(arg, "r") as f:
answers = json.load(f)
break

copy = dict(context)
if answers:
for k, v in answers.items():
if isinstance(v, dict) and "cid" in v:
for k2, v2 in copy.items():
if isinstance(v2, Component) and v2.cid == v["cid"]:
context[k2] = Component.deserialize(v2, v)


@staticmethod
def from_context(context):
components = {}
for k, v in context.items():
if isinstance(v, dict) and 'cid' in v:
components[k] = {
e: v[e] for e in v if not e.startswith('_')
}
return components



class SortList(Component):
"""
Custom class for SortList component.
"""


def __init__(self, **kwargs):
self._answer = []
super().__init__(**kwargs)
self.selector = 'c-sort-list'


def remind(self):
"""
Saves the current ordering of the items
to provides auto correction when self.auto_grade()
will be called.
The method stores the id properties of the items
in a list and compares it with the list retrieved
during evaluation.
Then it will randomize the items
"""

# since self._answer starts with '_'
# it will be hidden to the student

self._answer = []
for e in self.items:
self._answer.append(e['id'])

random.shuffle(self.items)


def parse_string(self, separator="\n"):
"""
Assumes that current type of self.items is str
and initializes items to the JSON format required
by the component in JS.
The method will split the items by using the argument separator.
"""
items = self.items.split(separator)
self.items = []
for e in items:
if e.strip():
self.items.append({
"id": str(uuid.uuid4()),
"content": e,
})


def auto_grade(self):
"""
Provides an grade according to the answer of a student using the list
saved during the last call to self.remind()
"""

score = 0
if len(self._answer) != len(self.items):
for e in self.items:
e["css"] = "error-state anim-fade"
return 0

for i, e in enumerate(self._answer):
self.items[i]['css'] = 'success-state anim-fade'
score += 1
if self.items[i]['id'] != e:
self.items[i]['css'] = 'error-state anim-fade'
score -= 1

return score / len(self._answer)



class AutomatonEditor(Component):

def __init__(self, **kwargs):
super().__init__(**kwargs)
self.selector = 'c-automaton-editor'



class AutomatonDrawer(Component):

def __init__(self, **kwargs):
super().__init__(**kwargs)
self.selector = 'c-automaton-drawer'



class CheckboxGroup(Component):

def __init__(self, **kwargs):
super().__init__(**kwargs)
self.selector = 'c-checkbox-group'



class CodeEditor(Component):

def __init__(self, **kwargs):
super().__init__(**kwargs)
self.selector = 'c-code-editor'



class DragDrop(Component):

def __init__(self, **kwargs):
super().__init__(**kwargs)
self.selector = 'c-drag-drop'



class GraphDrawer(Component):

def __init__(self, **kwargs):
super().__init__(**kwargs)
self.selector = 'c-graph-drawer'



class Input(Component):

def __init__(self, **kwargs):
super().__init__(**kwargs)
self.selector = 'c-input'



class MatchList(Component):

def __init__(self, **kwargs):
super().__init__(**kwargs)
self.selector = 'c-match-list'



class MathDrawer(Component):

def __init__(self, **kwargs):
super().__init__(**kwargs)
self.selector = 'c-math-drawer'



class MathInput(Component):

def __init__(self, **kwargs):
super().__init__(**kwargs)
self.selector = 'c-math-input'



class MathMatrix(Component):

def __init__(self, **kwargs):
super().__init__(**kwargs)
self.selector = 'c-math-matrix'



class RadioGroup(Component):

def __init__(self, **kwargs):
super().__init__(**kwargs)
self.selector = 'c-radio-group'



class Text(Component):

def __init__(self, **kwargs):
super().__init__(**kwargs)
self.selector = 'c-text'



class TransfertList(Component):

def __init__(self, **kwargs):
super().__init__(**kwargs)
self.selector = 'c-transfert-list'
12 changes: 7 additions & 5 deletions apps/components/static/components/3rdpartylicenses.txt
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,9 @@ The above copyright notice and this permission notice shall be included in all c
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


d3-path
d3-dispatch
BSD-3-Clause
Copyright 2015-2016 Mike Bostock
Copyright 2010-2016 Mike Bostock
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
Expand Down Expand Up @@ -466,7 +466,7 @@ MIT

@angular/material/icon

@angular/material/progress-bar
@angular/material/progress-spinner

@angular/material/tabs

Expand All @@ -489,6 +489,8 @@ MIT

@angular/material/sidenav

@angular/material/toolbar

@angular/material/radio

@angular/material/checkbox
Expand Down Expand Up @@ -823,9 +825,9 @@ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


d3-dispatch
d3-path
BSD-3-Clause
Copyright 2010-2016 Mike Bostock
Copyright 2015-2016 Mike Bostock
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
Expand Down
Loading

0 comments on commit fc0e294

Please sign in to comment.