adding comments about rate algorithm

This commit is contained in:
nad 2019-05-14 20:31:43 +02:00
parent 61f4c127d4
commit c19783954e
4 changed files with 191 additions and 23 deletions

View File

@ -1,5 +1,6 @@
""" """
This file contains all actions can apply to a device and is sorted according to a structure based on: This file contains all actions can apply to a device and is sorted according
to a structure based on:
* Generic Actions * Generic Actions
* Benchmarks * Benchmarks
@ -647,6 +648,12 @@ class Test(JoinedWithOneDeviceMixin, ActionWithOneDevice):
"""The act of testing the physical condition of a device and its """The act of testing the physical condition of a device and its
components. components.
Ref in R2 Provision 6 pag.19:
Records of test results are imperative to documenting
the functionality of each device.
Pass or fail results for each test in the process must be recorded
either manually or through software automation.
Testing errors and warnings are easily taken in Testing errors and warnings are easily taken in
:attr:`ereuse_devicehub.resources.device.models.Device.working`. :attr:`ereuse_devicehub.resources.device.models.Device.working`.
""" """
@ -674,10 +681,23 @@ class TestMixin:
class MeasureBattery(TestMixin, Test): class MeasureBattery(TestMixin, Test):
"""A sample of the status of the battery. """
A sample of the status of the battery.
Ref in R2 Provision 6 pag.22 Example:
Length of charge; Expected results: Minimum 40 minutes.
Operative Systems keep a record of several aspects of a battery. Operative Systems keep a record of several aspects of a battery.
This is a sample of those. This is a sample of those.
:class: 'Severtity'
Info/Pass(0):
Notice(1):
Warning(2):
Error/Fail(3):
""" """
size = db.Column(db.Integer, nullable=False) size = db.Column(db.Integer, nullable=False)
size.comment = """Maximum battery capacity, in mAh.""" size.comment = """Maximum battery capacity, in mAh."""
@ -704,6 +724,16 @@ class TestDataStorage(TestMixin, Test):
The test takes to other SMART values indicators of the overall health The test takes to other SMART values indicators of the overall health
of the data storage. of the data storage.
:class: 'Severtity'
Info/Pass(0):
Notice(1):
Warning(2):
Error/Fail(3):
""" """
length = Column(DBEnum(TestDataStorageLength), nullable=False) # todo from type length = Column(DBEnum(TestDataStorageLength), nullable=False) # todo from type
status = Column(Unicode(), check_lower('status'), nullable=False) status = Column(Unicode(), check_lower('status'), nullable=False)
@ -771,7 +801,18 @@ class StressTest(TestMixin, Test):
class TestAudio(TestMixin, Test): class TestAudio(TestMixin, Test):
""" """
Test to check all this aspects related with audio functions, Manual Tests?? Test to check audio device aspects, focus on speaker sounds correctly
and microphone record sounds good
:class: 'Severtity'
Info/Pass(0):
Notice(1):
Warning(2):
Error/Fail(3):
""" """
_speaker = Column('speaker', Boolean) _speaker = Column('speaker', Boolean)
_speaker.comment = """Whether the speaker works as expected.""" _speaker.comment = """Whether the speaker works as expected."""
@ -803,35 +844,87 @@ class TestAudio(TestMixin, Test):
class TestConnectivity(TestMixin, Test): class TestConnectivity(TestMixin, Test):
"""Tests that the device can connect both physically and """
wirelessly. Tests that the device can connect both physically and wirelessly.
A failing test means that at least one connection of the device A failing test means that at least one connection of the device
is not working well. A comment should get into more detail. is not working well. A comment should get into more detail.
:class: 'Severtity'
Info/Pass(0):
Notice(1):
Warning(2):
Error/Fail(3):
""" """
class TestCamera(TestMixin, Test): class TestCamera(TestMixin, Test):
"""Tests the working conditions of the camera of the device, """
Tests the working conditions of the camera of the device,
specially when taking pictures or recording video. specially when taking pictures or recording video.
Fail when camera can't take pictures.
""" """
class TestKeyboard(TestMixin, Test): class TestKeyboard(TestMixin, Test):
"""Whether the keyboard works correctly.""" """
Whether the keyboard works correctly.
Ref in R2 Provision 6 pag.22 example:
PASS when each key produces character on the screen
"""
class TestTrackpad(TestMixin, Test): class TestTrackpad(TestMixin, Test):
"""Whether the trackpad works correctly.""" """
Whether the trackpad works correctly.
Ref in R2 Provision 6 pag.22 example:
PASS when cursor moves on screen
"""
class TestScreenHinge(TestMixin, Test):
"""
Whether screen hinge works correctly.
Laptop Test Ref in R2 Provision 6 pag.22 example:
PASS when laptop screen stays open/closed at desired angles
"""
class TestPowerAdapter(TestMixin, Test):
"""
Whether power adapter charge battery device without problems.
Laptop Test Ref in R2 Provision 6 pag.22 example:
PASS when plug power adapter into laptop and charges the battery.
"""
class TestBios(TestMixin, Test): class TestBios(TestMixin, Test):
"""Tests the working condition and grades the usability of the BIOS.""" """
bios_power_on = Column(Boolean) Tests the working condition and grades the usability of the BIOS.
bios_power_on.comment = """Whether there are no beeps or error
:class: 'Severtity'
Info/Pass(0):
Notice(1):
Warning(2):
Error/Fail(3):
"""
beeps_power_on = Column(Boolean)
beeps_power_on.comment = """Whether there are no beeps or error
codes when booting up. codes when booting up.
Reference: R2 standard page 23. Reference: R2 provision 6 page 23.
""" """
access_range = Column(DBEnum(BiosAccessRange)) access_range = Column(DBEnum(BiosAccessRange))
access_range.comment = """Difficulty to modify the boot menu. access_range.comment = """Difficulty to modify the boot menu.
@ -842,8 +935,25 @@ class TestBios(TestMixin, Test):
class VisualTest(TestMixin, Test): class VisualTest(TestMixin, Test):
"""The act of visually inspecting the appearance and functionality """
The act of visually inspecting the appearance and functionality
of the device. of the device.
Reference R2 provision 6 Templates Ready for Resale Checklist (Desktop)
https://sustainableelectronics.org/sites/default/files/6.c.2%20Desktop%20R2-Ready%20for%20Resale%20Checklist.docx
Physical condition grade
:class: 'Severtity'
Info/Pass(0):
Notice(1):
Warning(2):
Error/Fail(3):
""" """
appearance_range = Column(DBEnum(AppearanceRange), nullable=False) appearance_range = Column(DBEnum(AppearanceRange), nullable=False)
appearance_range.comment = AppearanceRange.__doc__ appearance_range.comment = AppearanceRange.__doc__
@ -860,7 +970,14 @@ class VisualTest(TestMixin, Test):
class Rate(JoinedWithOneDeviceMixin, ActionWithOneDevice): class Rate(JoinedWithOneDeviceMixin, ActionWithOneDevice):
"""The act of computing a rate based on different categories""" """
The act of computing a rate based on different categories:
Functionality (F). Tests, the act of testing usage condition of a device
Appearance (A). Visual evaluation, surface deterioration.
Performance (Q). Components characteristics and components benchmarks.
"""
# todo jn: explain in each comment what the rate considers. # todo jn: explain in each comment what the rate considers.
N = 2 N = 2
"""The number of significant digits for rates. """The number of significant digits for rates.
@ -938,7 +1055,11 @@ class RateMixin:
class RateComputer(RateMixin, Rate): class RateComputer(RateMixin, Rate):
"""The act of rating a computer.""" """
The act of rating a computer type devices.
It's the starting point for calculating the rate.
Algorithm explained in v1.0 file
"""
_processor = Column('processor', _processor = Column('processor',
Float(decimal_return_scale=Rate.N), Float(decimal_return_scale=Rate.N),
check_range('processor', *R_POSITIVE)) check_range('processor', *R_POSITIVE))

View File

@ -12,6 +12,51 @@ from ereuse_devicehub.resources.device.models import Computer, DataStorage, Proc
class RateAlgorithm(BaseRate): class RateAlgorithm(BaseRate):
"""The algorithm that generates the Rate v1.0. """The algorithm that generates the Rate v1.0.
Rate v1.0 is mainly based on 3 components (Processor, RAM and Data Storage)
and 2 visual grades (one for appearance aspects and other for functionality aspects).
From components we take into account their main characteristics and
also some tests and benchmarks. In particular:
* Processor:
- Cores
- Speed
- Benchmark processor
* RAM:
- Size
- Speed
* Data Storage:
- Size
- Benchmark data storage (Read and write speed)
Step by step to compute Rate v1.0:
1. Normalization the components characteristics.
Normalized the characteristics of the components between 0 and 1.
with xMin and xMax and standardize the values applying
the following formula:
**Normalization characteristic value = (x xMin)/(xMax xMin)**
2. Merge the characteristics of every component in one score for component.
3. Merge the components individual rates into a single components rate.
We calculate this rate using the weighted harmonic mean.
We establish all the components weights, 50% for processor,
20% for data storage, 30% for RAM.
The result is a unique performance score (components rate).
4. Grouping all categories aspects sum all in unique final rate.
To get Functionality and Appearance Rates values, only directly
related a value for each grade.
**Final Rate = Components Rate + Functionality Rate + Appearance Rate**
Final Rate are ranged from 0 to 4.7.
Do not call directly this class, but use Do not call directly this class, but use
:meth:`ereuse_devicehub.resources.action.models.RateComputer.compute`, :meth:`ereuse_devicehub.resources.action.models.RateComputer.compute`,
which then calls this. which then calls this.
@ -74,7 +119,7 @@ class RateAlgorithm(BaseRate):
rate.functionality = self.Functionality[visual_test.functionality_range.name].value rate.functionality = self.Functionality[visual_test.functionality_range.name].value
rate.rating = rate_components + rate.functionality + rate.appearance rate.rating = rate_components + rate.functionality + rate.appearance
device.actions_one.add(rate) device.actions_one.add(rate)
assert 0 <= rate.rating <= 4.7, 'Rate ranges from 0 to 4.7' assert 0 <= rate.rating <= 4.7
return rate return rate
@ -88,12 +133,11 @@ class ProcessorRate(BaseRate):
DEFAULT_CORES = 1 DEFAULT_CORES = 1
DEFAULT_SPEED = 1.6 DEFAULT_SPEED = 1.6
# In case of i2, i3,.. result penalized.
# Intel(R) Core(TM) i3 CPU 530 @ 2.93GHz, score = 23406.92 but results inan score of 17503.
DEFAULT_SCORE = 4000 DEFAULT_SCORE = 4000
def compute(self, processor: Processor): def compute(self, processor: Processor):
""" Compute processor rate """ Compute processor rate
We assume always exists a Benchmark Processor
Obs: cores and speed are possible NULL value Obs: cores and speed are possible NULL value
:return: result is a rate (score) of Processor characteristics :return: result is a rate (score) of Processor characteristics
""" """
@ -106,7 +150,7 @@ class ProcessorRate(BaseRate):
benchmark_cpu = benchmark_cpu.rate or self.DEFAULT_SCORE benchmark_cpu = benchmark_cpu.rate or self.DEFAULT_SCORE
# STEP: Fusion components # STEP: Fusion components
processor_rate = (benchmark_cpu + speed * 2000 * cores) / 2 # todo magic number! processor_rate = (benchmark_cpu + speed * 2000 * cores) / 2
# STEP: Normalize values # STEP: Normalize values
processor_norm = max(self.norm(processor_rate, *self.PROCESSOR_NORM), 0) processor_norm = max(self.norm(processor_rate, *self.PROCESSOR_NORM), 0)
@ -136,7 +180,7 @@ class RamRate(BaseRate):
def compute(self, ram_devices: Iterable[RamModule]): def compute(self, ram_devices: Iterable[RamModule]):
""" """
Obs: RamModule.speed is possible NULL value & size != NULL or NOT?? If ram speed or ram size, we assume default values before declared
:return: result is a rate (score) of all RamModule components :return: result is a rate (score) of all RamModule components
""" """
size = 0.0 size = 0.0

View File

@ -8,7 +8,7 @@ from teal.marshmallow import ValidationError
from teal.resource import View from teal.resource import View
from ereuse_devicehub.db import db from ereuse_devicehub.db import db
from ereuse_devicehub.resources.action.models import Action, RateComputer, Snapshot from ereuse_devicehub.resources.action.models import Action, RateComputer, Snapshot, VisualTest
from ereuse_devicehub.resources.action.rate.workbench.v1_0 import CannotRate from ereuse_devicehub.resources.action.rate.workbench.v1_0 import CannotRate
from ereuse_devicehub.resources.device.models import Component, Computer from ereuse_devicehub.resources.device.models import Component, Computer
from ereuse_devicehub.resources.enums import SnapshotSoftware from ereuse_devicehub.resources.enums import SnapshotSoftware
@ -28,6 +28,9 @@ class ActionView(View):
a = resource_def.schema.load(json) a = resource_def.schema.load(json)
if json['type'] == Snapshot.t: if json['type'] == Snapshot.t:
return self.snapshot(a, resource_def) return self.snapshot(a, resource_def)
if json['type'] == VisualTest.t:
pass
# TODO JN add compute rate with new visual test and old components device
Model = db.Model._decl_class_registry.data[json['type']]() Model = db.Model._decl_class_registry.data[json['type']]()
action = Model(**a) action = Model(**a)
db.session.add(action) db.session.add(action)

View File

@ -273,13 +273,13 @@ class Severity(IntEnum):
"""A flag evaluating the action execution. Ex. failed actions """A flag evaluating the action execution. Ex. failed actions
have the value `Severity.Error`. Devicehub uses 4 severity levels: have the value `Severity.Error`. Devicehub uses 4 severity levels:
* Info: default neutral severity. The action succeeded. * Info (Pass): default neutral severity. The action succeeded.
* Notice: The action succeeded but it is raising awareness. * Notice: The action succeeded but it is raising awareness.
Notices are not usually that important but something Notices are not usually that important but something
(good or bad) worth checking. (good or bad) worth checking.
* Warning: The action succeeded but there is something important * Warning: The action succeeded but there is something important
to check negatively affecting the action. to check negatively affecting the action.
* Error: the action failed. * Error (Fail): the action failed.
Devicehub specially raises user awareness when an action Devicehub specially raises user awareness when an action
has a Severity of ``Warning`` or greater. has a Severity of ``Warning`` or greater.