adding comments about rate algorithm
This commit is contained in:
parent
61f4c127d4
commit
c19783954e
|
@ -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
|
||||
* Benchmarks
|
||||
|
@ -647,6 +648,12 @@ class Test(JoinedWithOneDeviceMixin, ActionWithOneDevice):
|
|||
"""The act of testing the physical condition of a device and its
|
||||
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
|
||||
:attr:`ereuse_devicehub.resources.device.models.Device.working`.
|
||||
"""
|
||||
|
@ -674,10 +681,23 @@ class TestMixin:
|
|||
|
||||
|
||||
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.
|
||||
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.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
|
||||
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
|
||||
status = Column(Unicode(), check_lower('status'), nullable=False)
|
||||
|
@ -771,7 +801,18 @@ class StressTest(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.comment = """Whether the speaker works as expected."""
|
||||
|
@ -803,35 +844,87 @@ class TestAudio(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
|
||||
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):
|
||||
"""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.
|
||||
Fail when camera can't take pictures.
|
||||
"""
|
||||
|
||||
|
||||
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):
|
||||
"""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):
|
||||
"""Tests the working condition and grades the usability of the BIOS."""
|
||||
bios_power_on = Column(Boolean)
|
||||
bios_power_on.comment = """Whether there are no beeps or error
|
||||
"""
|
||||
Tests the working condition and grades the usability of the BIOS.
|
||||
|
||||
: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.
|
||||
|
||||
Reference: R2 standard page 23.
|
||||
Reference: R2 provision 6 page 23.
|
||||
"""
|
||||
access_range = Column(DBEnum(BiosAccessRange))
|
||||
access_range.comment = """Difficulty to modify the boot menu.
|
||||
|
@ -842,8 +935,25 @@ class TestBios(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.
|
||||
|
||||
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.comment = AppearanceRange.__doc__
|
||||
|
@ -860,7 +970,14 @@ class VisualTest(TestMixin, Test):
|
|||
|
||||
|
||||
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.
|
||||
N = 2
|
||||
"""The number of significant digits for rates.
|
||||
|
@ -938,7 +1055,11 @@ class RateMixin:
|
|||
|
||||
|
||||
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',
|
||||
Float(decimal_return_scale=Rate.N),
|
||||
check_range('processor', *R_POSITIVE))
|
||||
|
|
|
@ -12,6 +12,51 @@ from ereuse_devicehub.resources.device.models import Computer, DataStorage, Proc
|
|||
class RateAlgorithm(BaseRate):
|
||||
"""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
|
||||
:meth:`ereuse_devicehub.resources.action.models.RateComputer.compute`,
|
||||
which then calls this.
|
||||
|
@ -74,7 +119,7 @@ class RateAlgorithm(BaseRate):
|
|||
rate.functionality = self.Functionality[visual_test.functionality_range.name].value
|
||||
rate.rating = rate_components + rate.functionality + rate.appearance
|
||||
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
|
||||
|
||||
|
||||
|
@ -88,12 +133,11 @@ class ProcessorRate(BaseRate):
|
|||
DEFAULT_CORES = 1
|
||||
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
|
||||
|
||||
def compute(self, processor: Processor):
|
||||
""" Compute processor rate
|
||||
We assume always exists a Benchmark Processor
|
||||
Obs: cores and speed are possible NULL value
|
||||
: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
|
||||
|
||||
# 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
|
||||
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]):
|
||||
"""
|
||||
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
|
||||
"""
|
||||
size = 0.0
|
||||
|
|
|
@ -8,7 +8,7 @@ from teal.marshmallow import ValidationError
|
|||
from teal.resource import View
|
||||
|
||||
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.device.models import Component, Computer
|
||||
from ereuse_devicehub.resources.enums import SnapshotSoftware
|
||||
|
@ -28,6 +28,9 @@ class ActionView(View):
|
|||
a = resource_def.schema.load(json)
|
||||
if json['type'] == Snapshot.t:
|
||||
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']]()
|
||||
action = Model(**a)
|
||||
db.session.add(action)
|
||||
|
|
|
@ -273,13 +273,13 @@ class Severity(IntEnum):
|
|||
"""A flag evaluating the action execution. Ex. failed actions
|
||||
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.
|
||||
Notices are not usually that important but something
|
||||
(good or bad) worth checking.
|
||||
* Warning: The action succeeded but there is something important
|
||||
to check negatively affecting the action.
|
||||
* Error: the action failed.
|
||||
* Error (Fail): the action failed.
|
||||
|
||||
Devicehub specially raises user awareness when an action
|
||||
has a Severity of ``Warning`` or greater.
|
||||
|
|
Reference in New Issue