first commit rate v2; adding Quality, Functionality Rates class
This commit is contained in:
parent
15f705dd50
commit
ddb1877133
0
ereuse_devicehub/dummy/files/index.js
Normal file
0
ereuse_devicehub/dummy/files/index.js
Normal file
|
@ -119,6 +119,21 @@ class FunctionalityRange(Enum):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
|
||||||
|
FUNCTIONALITY_RANGE = -0.25, 0.5
|
||||||
|
|
||||||
|
|
||||||
|
@unique
|
||||||
|
class FunctionalityRangev2(Enum):
|
||||||
|
"""Grade the buttons and chassis that affect its usage, like screen defect or camera defects"""
|
||||||
|
A = 'A. All the buttons works perfectly, no screen/camera defects and chassis without issues'
|
||||||
|
B = 'B. There is a button difficult to press or unstable it, a screen/camera defect or chassis problem'
|
||||||
|
C = 'C. Multiple buttons don\'t work; broken or unusable it, some screen/camera defects and chassis problems'
|
||||||
|
D = 'D. All buttons. screen or chassis don\'t work; broken or unusable it, difficult to usage.'
|
||||||
|
NONE = 'NA. Grade doesn’t exists'
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
@unique
|
@unique
|
||||||
class Bios(Enum):
|
class Bios(Enum):
|
||||||
"""How difficult it has been to set the bios to boot from the network."""
|
"""How difficult it has been to set the bios to boot from the network."""
|
||||||
|
@ -132,6 +147,8 @@ class Bios(Enum):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
|
||||||
|
# TODO add all grade tables (chassis defects, camera defects, buttons test, connectivity, ..)
|
||||||
|
|
||||||
@unique
|
@unique
|
||||||
class Orientation(Enum):
|
class Orientation(Enum):
|
||||||
Vertical = 'vertical'
|
Vertical = 'vertical'
|
||||||
|
|
|
@ -31,7 +31,8 @@ from ereuse_devicehub.resources.device.models import Component, Computer, DataSt
|
||||||
from ereuse_devicehub.resources.enums import AppearanceRange, Bios, ErasureStandards, \
|
from ereuse_devicehub.resources.enums import AppearanceRange, Bios, ErasureStandards, \
|
||||||
FunctionalityRange, PhysicalErasureMethod, PriceSoftware, RATE_NEGATIVE, RATE_POSITIVE, \
|
FunctionalityRange, PhysicalErasureMethod, PriceSoftware, RATE_NEGATIVE, RATE_POSITIVE, \
|
||||||
RatingRange, RatingSoftware, ReceiverRole, Severity, SnapshotExpectedEvents, SnapshotSoftware, \
|
RatingRange, RatingSoftware, ReceiverRole, Severity, SnapshotExpectedEvents, SnapshotSoftware, \
|
||||||
TestDataStorageLength
|
TestDataStorageLength, FUNCTIONALITY_RANGE, FunctionalityRangev2
|
||||||
|
from ereuse_devicehub.resources.event.rate.workbench.v2_0 import QualityRate, FunctionalityRate
|
||||||
from ereuse_devicehub.resources.models import STR_SM_SIZE, Thing
|
from ereuse_devicehub.resources.models import STR_SM_SIZE, Thing
|
||||||
from ereuse_devicehub.resources.user.models import User
|
from ereuse_devicehub.resources.user.models import User
|
||||||
|
|
||||||
|
@ -650,7 +651,7 @@ class ManualRate(IndividualRate):
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
|
||||||
class WorkbenchRate(ManualRate):
|
class WorkbenchComputerRate(ManualRate):
|
||||||
id = Column(UUID(as_uuid=True), ForeignKey(ManualRate.id), primary_key=True)
|
id = Column(UUID(as_uuid=True), ForeignKey(ManualRate.id), primary_key=True)
|
||||||
processor = Column(Float(decimal_return_scale=2), check_range('processor', *RATE_POSITIVE))
|
processor = Column(Float(decimal_return_scale=2), check_range('processor', *RATE_POSITIVE))
|
||||||
ram = Column(Float(decimal_return_scale=2), check_range('ram', *RATE_POSITIVE))
|
ram = Column(Float(decimal_return_scale=2), check_range('ram', *RATE_POSITIVE))
|
||||||
|
@ -696,6 +697,172 @@ class WorkbenchRate(ManualRate):
|
||||||
return RatingRange.from_score(self.graphic_card)
|
return RatingRange.from_score(self.graphic_card)
|
||||||
|
|
||||||
|
|
||||||
|
""" QUALITY RATE CODE START HERE """
|
||||||
|
|
||||||
|
|
||||||
|
class QualityRate(Rate):
|
||||||
|
id = Column(UUID(as_uuid=True), ForeignKey(Rate.id), primary_key=True)
|
||||||
|
processor = Column(Float(decimal_return_scale=2), check_range('processor', *RATE_POSITIVE),
|
||||||
|
comment='Is a test explain cpu component.')
|
||||||
|
ram = Column(Float(decimal_return_scale=2), check_range('ram', *RATE_POSITIVE),
|
||||||
|
comment='RAM memory rate.')
|
||||||
|
data_storage = Column(Float(decimal_return_scale=2), check_range('data_storage', *RATE_POSITIVE),
|
||||||
|
comment='Data storage rate, like HHD, SSD.')
|
||||||
|
|
||||||
|
@property
|
||||||
|
def ram_range(self):
|
||||||
|
return self.workbench.ram_range
|
||||||
|
|
||||||
|
@property
|
||||||
|
def processor_range(self):
|
||||||
|
return self.workbench.processor_range
|
||||||
|
|
||||||
|
@property
|
||||||
|
def display_range(self):
|
||||||
|
return self.workbench.data_storage_range
|
||||||
|
|
||||||
|
@property
|
||||||
|
def data_storage_range(self):
|
||||||
|
return self.workbench.data_storage_range
|
||||||
|
|
||||||
|
@property
|
||||||
|
def battery_range(self):
|
||||||
|
return self.workbench.ram_range
|
||||||
|
|
||||||
|
@property
|
||||||
|
def camera_range(self):
|
||||||
|
return self.workbench_mobile.camera_range
|
||||||
|
|
||||||
|
@property
|
||||||
|
def graphic_card_range(self):
|
||||||
|
return self.workbench_mobil.graphic_card_range
|
||||||
|
|
||||||
|
|
||||||
|
class QualityRateComputer(QualityRate):
|
||||||
|
id = Column(UUID(as_uuid=True), ForeignKey(QualityRate.id), primary_key=True)
|
||||||
|
processor = Column(Float(decimal_return_scale=2), check_range('processor', *RATE_POSITIVE),
|
||||||
|
comment='Is a test explain cpu component.')
|
||||||
|
ram = Column(Float(decimal_return_scale=2), check_range('ram', *RATE_POSITIVE),
|
||||||
|
comment='RAM memory rate.')
|
||||||
|
data_storage = Column(Float(decimal_return_scale=2), check_range('data_storage', *RATE_POSITIVE),
|
||||||
|
comment='Data storage rate, like HHD, SSD.')
|
||||||
|
|
||||||
|
graphic_card = Column(Float(decimal_return_scale=2), check_range('graphic_card', *RATE_POSITIVE),
|
||||||
|
comment='Graphic card score in performance, amount of memory and benchmark result')
|
||||||
|
network_adapter = Column(Float(decimal_return_scale=2), check_range('network_adapter', *RATE_POSITIVE),
|
||||||
|
comment='Network adapter rate, take it speed limit')
|
||||||
|
|
||||||
|
bios = Column(Float(decimal_return_scale=2), check_range('bios', *RATE_POSITIVE))
|
||||||
|
bios_range = Column(DBEnum(Bios))
|
||||||
|
bios_range.comment = Bios.__doc__
|
||||||
|
|
||||||
|
# todo ensure for WorkbenchRate version and software are not None when inserting them
|
||||||
|
|
||||||
|
def ratings(self):
|
||||||
|
"""
|
||||||
|
#Computes all the possible rates taking this rating as a model.
|
||||||
|
|
||||||
|
#Returns a set of ratings, including this one, which is mutated,
|
||||||
|
#and the final :class:`.AggregateRate`.
|
||||||
|
"""
|
||||||
|
from ereuse_devicehub.resources.event.rate.main import main
|
||||||
|
return main(self, **app.config.get_namespace('WORKBENCH_RATE_'))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def graphic_card_range(self):
|
||||||
|
if self.graphic_card:
|
||||||
|
return RatingRange.from_score(self.graphic_card)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def network_adapter_range(self):
|
||||||
|
return self.workbench_mobil.network_adapter_range
|
||||||
|
|
||||||
|
@property
|
||||||
|
def bios_range(self):
|
||||||
|
return self.workbench_mobil.bios_range
|
||||||
|
|
||||||
|
|
||||||
|
class QualityRateMobile(QualityRate):
|
||||||
|
id = Column(UUID(as_uuid=True), ForeignKey(QualityRate.id), primary_key=True)
|
||||||
|
display = Column(Float(decimal_return_scale=2), check_range('display', *RATE_POSITIVE))
|
||||||
|
display.comment = 'Display rate, screen resolution and size to calculate PPI and convert in score'
|
||||||
|
battery = Column(Float(decimal_return_scale=2), check_range('battery', *RATE_POSITIVE),
|
||||||
|
comment='Battery rate is related with capacity and its health')
|
||||||
|
camera = Column(Float(decimal_return_scale=2), check_range('camera', *RATE_POSITIVE),
|
||||||
|
comment='Camera rate take into account resolution')
|
||||||
|
|
||||||
|
graphic_card = Column(Float(decimal_return_scale=2), check_range('graphic_card', *RATE_POSITIVE),
|
||||||
|
comment='Graphic card score in performance, amount of memory and benchmark result')
|
||||||
|
network_adapter = Column(Float(decimal_return_scale=2), check_range('network_adapter', *RATE_POSITIVE),
|
||||||
|
comment='Network adapter rate, take it speed limit')
|
||||||
|
|
||||||
|
bios = Column(Float(decimal_return_scale=2), check_range('bios', *RATE_POSITIVE))
|
||||||
|
bios_range = Column(DBEnum(Bios))
|
||||||
|
bios_range.comment = Bios.__doc__
|
||||||
|
|
||||||
|
# todo ensure for WorkbenchRate version and software are not None when inserting them
|
||||||
|
|
||||||
|
def ratings(self):
|
||||||
|
"""
|
||||||
|
#Computes all the possible rates taking this rating as a model.
|
||||||
|
"""
|
||||||
|
from ereuse_devicehub.resources.event.rate.main import main
|
||||||
|
return main(self, **app.config.get_namespace('WORKBENCH_RATE_'))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def display_range(self):
|
||||||
|
if self.data_storage:
|
||||||
|
return RatingRange.from_score(self.data_storage)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def battery_range(self):
|
||||||
|
if self.ram:
|
||||||
|
return RatingRange.from_score(self.ram)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def camera_range(self):
|
||||||
|
if self.processor:
|
||||||
|
return RatingRange.from_score(self.processor)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def graphic_card_range(self):
|
||||||
|
if self.graphic_card:
|
||||||
|
return RatingRange.from_score(self.graphic_card)
|
||||||
|
|
||||||
|
|
||||||
|
class FunctionalityRate(Rate):
|
||||||
|
id = Column(UUID(as_uuid=True), ForeignKey(Rate.id), primary_key=True)
|
||||||
|
functionality = Column(Float(decimal_return_scale=2), check_range('functionality', *FUNCTIONALITY_RANGE))
|
||||||
|
functionality.comment = 'Functionality rate of a device'
|
||||||
|
|
||||||
|
functionality_range = Column(DBEnum(FunctionalityRangev2))
|
||||||
|
functionality_range.comment = FunctionalityRangev2.__doc__
|
||||||
|
|
||||||
|
connectivity = Column(Float(decimal_return_scale=2),
|
||||||
|
comment='This punctuation covers a series of aspects related to connectivity.')
|
||||||
|
audio = Column(Float(decimal_return_scale=2), comment='Take into account loudspeaker and microphone')
|
||||||
|
|
||||||
|
@property
|
||||||
|
def connectivity_rate(self):
|
||||||
|
yield
|
||||||
|
|
||||||
|
@property
|
||||||
|
def audio_rate(self):
|
||||||
|
yield
|
||||||
|
|
||||||
|
@property
|
||||||
|
def test_buttonse(self):
|
||||||
|
yield
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def test_camera_defects(self):
|
||||||
|
yield
|
||||||
|
|
||||||
|
|
||||||
|
class FinalRate(Rate):
|
||||||
|
id = Column(UUID(as_uuid=True), ForeignKey(Rate.id), primary_key=True)
|
||||||
|
|
||||||
|
|
||||||
class AggregateRate(Rate):
|
class AggregateRate(Rate):
|
||||||
id = Column(UUID(as_uuid=True), ForeignKey(Rate.id), primary_key=True)
|
id = Column(UUID(as_uuid=True), ForeignKey(Rate.id), primary_key=True)
|
||||||
manual_id = Column(UUID(as_uuid=True), ForeignKey(ManualRate.id))
|
manual_id = Column(UUID(as_uuid=True), ForeignKey(ManualRate.id))
|
||||||
|
@ -711,16 +878,16 @@ class AggregateRate(Rate):
|
||||||
order_by=lambda: AggregateRate.created,
|
order_by=lambda: AggregateRate.created,
|
||||||
collection_class=OrderedSet),
|
collection_class=OrderedSet),
|
||||||
primaryjoin=manual_id == ManualRate.id)
|
primaryjoin=manual_id == ManualRate.id)
|
||||||
workbench_id = Column(UUID(as_uuid=True), ForeignKey(WorkbenchRate.id))
|
workbench_id = Column(UUID(as_uuid=True), ForeignKey(QualityRateComputer.id))
|
||||||
workbench_id.comment = """The WorkbenchRate used to generate
|
workbench_id.comment = """The WorkbenchRate used to generate
|
||||||
this aggregation, or None if none used.
|
this aggregation, or None if none used.
|
||||||
"""
|
"""
|
||||||
workbench = relationship(WorkbenchRate,
|
workbench = relationship(QualityRateComputer,
|
||||||
backref=backref('aggregate_rate_workbench',
|
backref=backref('aggregate_rate_workbench',
|
||||||
lazy=True,
|
lazy=True,
|
||||||
order_by=lambda: AggregateRate.created,
|
order_by=lambda: AggregateRate.created,
|
||||||
collection_class=OrderedSet),
|
collection_class=OrderedSet),
|
||||||
primaryjoin=workbench_id == WorkbenchRate.id)
|
primaryjoin=workbench_id == QualityRateComputer.id)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs) -> None:
|
def __init__(self, *args, **kwargs) -> None:
|
||||||
kwargs.setdefault('version', StrictVersion('1.0'))
|
kwargs.setdefault('version', StrictVersion('1.0'))
|
||||||
|
@ -781,7 +948,198 @@ class AggregateRate(Rate):
|
||||||
return self.workbench.labelling
|
return self.workbench.labelling
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_workbench_rate(cls, rate: WorkbenchRate):
|
def from_workbench_rate(cls, rate: QualityRateComputer):
|
||||||
|
aggregate = cls()
|
||||||
|
aggregate.rating = rate.rating
|
||||||
|
aggregate.software = rate.software
|
||||||
|
aggregate.appearance = rate.appearance
|
||||||
|
aggregate.functionality = rate.functionality
|
||||||
|
aggregate.device = rate.device
|
||||||
|
aggregate.workbench = rate
|
||||||
|
return aggregate
|
||||||
|
|
||||||
|
|
||||||
|
####################################################################################
|
||||||
|
|
||||||
|
|
||||||
|
class ResultRate(Rate):
|
||||||
|
"""The act of grading the appearance, quality (performance), and functionality
|
||||||
|
of a device.
|
||||||
|
|
||||||
|
There are five categories of ``Rate``:
|
||||||
|
1. ``Quality``. How good is the machine, in terms of performance.
|
||||||
|
2. ``Functionality``.
|
||||||
|
3. ``Appearance``.
|
||||||
|
4. ``Market value``.
|
||||||
|
5. ``Cost of repair``.
|
||||||
|
|
||||||
|
|
||||||
|
There are types of rating a device:
|
||||||
|
|
||||||
|
1. Rate Quality
|
||||||
|
2. Rate Functionality
|
||||||
|
3. Rate Final
|
||||||
|
|
||||||
|
|
||||||
|
List of source where can input information of rating a device:
|
||||||
|
|
||||||
|
1. When processing the device with Workbench Computer/Mobile.
|
||||||
|
2. Using the Android App (through Scan).
|
||||||
|
3.
|
||||||
|
4. Anytime after manually written in a form in the website.
|
||||||
|
"""
|
||||||
|
|
||||||
|
id = Column(UUID(as_uuid=True), ForeignKey(Rate.id), primary_key=True)
|
||||||
|
quality_id = Column(UUID(as_uuid=True), ForeignKey(ManualRate.id))
|
||||||
|
quality_id.comment = """The Quality Rate used to generate this
|
||||||
|
aggregation, or None if none used.
|
||||||
|
"""
|
||||||
|
|
||||||
|
func_id = Column(UUID(as_uuid=True), ForeignKey(ManualRate.id))
|
||||||
|
func_id.comment = """The Functionality Rate used to generate this
|
||||||
|
aggregation, or None if none used.
|
||||||
|
"""
|
||||||
|
|
||||||
|
final_id = Column(UUID(as_uuid=True), ForeignKey(ManualRate.id))
|
||||||
|
final_id.comment = """The Final Rate used to generate this
|
||||||
|
aggregation, or None if none used.
|
||||||
|
"""
|
||||||
|
|
||||||
|
""" MANUAL INPUT """
|
||||||
|
manual_id = Column(UUID(as_uuid=True), ForeignKey(ManualRate.id))
|
||||||
|
manual_id.comment = """The ManualEvent used to generate this
|
||||||
|
aggregation, or None if none used.
|
||||||
|
|
||||||
|
An example of ManualEvent is using the web or the Android app
|
||||||
|
to rate a device.
|
||||||
|
"""
|
||||||
|
manual = relationship(ManualRate,
|
||||||
|
backref=backref('aggregate_rate_manual',
|
||||||
|
lazy=True,
|
||||||
|
order_by=lambda: ResultRate.created,
|
||||||
|
collection_class=OrderedSet),
|
||||||
|
primaryjoin=manual_id == ManualRate.id)
|
||||||
|
|
||||||
|
""" WORKBENCH COMPUTER """
|
||||||
|
workbench_computer_id = Column(UUID(as_uuid=True), ForeignKey(QualityRateComputer.id))
|
||||||
|
workbench_computer_id.comment = """The WorkbenchRate used to generate
|
||||||
|
this aggregation, or None if none used.
|
||||||
|
"""
|
||||||
|
workbench_computer = relationship(QualityRateComputer,
|
||||||
|
backref=backref('aggregate_rate_workbench',
|
||||||
|
lazy=True,
|
||||||
|
order_by=lambda: ResultRate.created,
|
||||||
|
collection_class=OrderedSet),
|
||||||
|
primaryjoin=workbench_computer_id == QualityRateComputer.id)
|
||||||
|
|
||||||
|
""" WORKBENCH MOBILE """
|
||||||
|
|
||||||
|
workbench_mobile_id = Column(UUID(as_uuid=True), ForeignKey(QualityRateMobile.id))
|
||||||
|
workbench_mobile_id.comment = """The WorkbenchRate used to generate
|
||||||
|
this aggregation, or None if none used.
|
||||||
|
"""
|
||||||
|
workbench_mobile = relationship(QualityRateMobile,
|
||||||
|
backref=backref('aggregate_rate_workbench',
|
||||||
|
lazy=True,
|
||||||
|
order_by=lambda: ResultRate.created,
|
||||||
|
collection_class=OrderedSet),
|
||||||
|
primaryjoin=workbench_mobile_id == QualityRateMobile.id)
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs) -> None:
|
||||||
|
kwargs.setdefault('version', StrictVersion('1.0'))
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def quality_rate(cls, quality: QualityRate):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def functionality_rate(cls, func: FunctionalityRate):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def final_rate(cls, rate: Rate):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Categories
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def quality_category(cls, quality: QualityRate):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def functionality_category(cls, quality: QualityRate):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def appearance_category(cls, quality: QualityRate):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def maket_value_category(cls, quality: QualityRate):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def cost_of_repair_category(cls, quality: QualityRate):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# todo take value from LAST event (manual or workbench)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def processor(self):
|
||||||
|
return self.workbench.processor
|
||||||
|
|
||||||
|
@property
|
||||||
|
def ram(self):
|
||||||
|
return self.workbench.ram
|
||||||
|
|
||||||
|
@property
|
||||||
|
def data_storage(self):
|
||||||
|
return self.workbench.data_storage
|
||||||
|
|
||||||
|
@property
|
||||||
|
def graphic_card(self):
|
||||||
|
return self.workbench.graphic_card
|
||||||
|
|
||||||
|
@property
|
||||||
|
def data_storage_range(self):
|
||||||
|
return self.workbench.data_storage_range
|
||||||
|
|
||||||
|
@property
|
||||||
|
def ram_range(self):
|
||||||
|
return self.workbench.ram_range
|
||||||
|
|
||||||
|
@property
|
||||||
|
def processor_range(self):
|
||||||
|
return self.workbench.processor_range
|
||||||
|
|
||||||
|
@property
|
||||||
|
def graphic_card_range(self):
|
||||||
|
return self.workbench.graphic_card_range
|
||||||
|
|
||||||
|
@property
|
||||||
|
def bios(self):
|
||||||
|
return self.workbench.bios
|
||||||
|
|
||||||
|
@property
|
||||||
|
def functionality_range(self):
|
||||||
|
return self.workbench.functionality_range
|
||||||
|
|
||||||
|
@property
|
||||||
|
def appearance_range(self):
|
||||||
|
return self.workbench.appearance_range
|
||||||
|
|
||||||
|
@property
|
||||||
|
def bios_range(self):
|
||||||
|
return self.workbench.bios_range
|
||||||
|
|
||||||
|
@property
|
||||||
|
def labelling(self):
|
||||||
|
return self.workbench.labelling
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_workbench_rate(cls, rate: QualityRateComputer):
|
||||||
aggregate = cls()
|
aggregate = cls()
|
||||||
aggregate.rating = rate.rating
|
aggregate.rating = rate.rating
|
||||||
aggregate.software = rate.software
|
aggregate.software = rate.software
|
||||||
|
|
301
ereuse_devicehub/resources/event/rate/workbench/v2_0.py
Normal file
301
ereuse_devicehub/resources/event/rate/workbench/v2_0.py
Normal file
|
@ -0,0 +1,301 @@
|
||||||
|
from enum import Enum
|
||||||
|
from typing import Iterable
|
||||||
|
|
||||||
|
from ereuse_devicehub.resources.device.models import Computer, DataStorage, Desktop, Laptop, \
|
||||||
|
Processor, RamModule, Server, Device
|
||||||
|
from ereuse_devicehub.resources.event.models import BenchmarkDataStorage, BenchmarkProcessor, \
|
||||||
|
WorkbenchRate
|
||||||
|
from ereuse_devicehub.resources.event.rate.rate import BaseRate
|
||||||
|
|
||||||
|
|
||||||
|
class Rate(BaseRate):
|
||||||
|
"""
|
||||||
|
Rate all the categories of a device
|
||||||
|
RATE = Quality Rate + Functionality Rate + Appearance Rate
|
||||||
|
"""
|
||||||
|
|
||||||
|
class Range(Enum):
|
||||||
|
@classmethod
|
||||||
|
def from_devicehub(cls, r: Enum):
|
||||||
|
return getattr(cls, r.name) if r else cls.NONE
|
||||||
|
|
||||||
|
def compute(self, device: Device):
|
||||||
|
rate_quality = QualityRate.compute()
|
||||||
|
rate_functionality = FunctionalityRate.compute()
|
||||||
|
rate_appearance = self.Appearance.from_devicehub(rate.appearance_range).value
|
||||||
|
|
||||||
|
# Final result
|
||||||
|
return round(max(rate_quality + rate_functionality + rate_appearance, 0), 2)
|
||||||
|
|
||||||
|
|
||||||
|
class QualityRate(BaseRate):
|
||||||
|
"""
|
||||||
|
Rate Quality aspect
|
||||||
|
Display (screen)
|
||||||
|
Processor
|
||||||
|
RAM
|
||||||
|
Data Storage
|
||||||
|
Battery
|
||||||
|
Camera
|
||||||
|
"""
|
||||||
|
"""
|
||||||
|
List components wieghts
|
||||||
|
total_weights = 1
|
||||||
|
"""
|
||||||
|
DISPLAY_WEIGHT = 0.25
|
||||||
|
PROCESSOR_WEIGHT = 0.1
|
||||||
|
RAM_WEIGHT = 0.25
|
||||||
|
DATA_STORAGE_WEIGHT = 0.05
|
||||||
|
BATTERY_WEIGHT = 0.25
|
||||||
|
CAMERA_WEIGHT = 0.1
|
||||||
|
|
||||||
|
def __init__(self) -> None:
|
||||||
|
super().__init__()
|
||||||
|
# TODO Check if component exists before rate it.
|
||||||
|
self.RATES = {
|
||||||
|
# composition: type: (field, compute class)
|
||||||
|
Display.t: ('display', DisplayRate()),
|
||||||
|
Processor.t: ('processor', ProcessorRate()),
|
||||||
|
RamModule.t: ('ram', RamRate()),
|
||||||
|
DataStorage.t: ('data_storage', DataStorageRate()),
|
||||||
|
Battery.t: ('battery', BatteryRate()),
|
||||||
|
Camera.t: ('camera', CameraRate())
|
||||||
|
}
|
||||||
|
|
||||||
|
def compute(self, device: Device):
|
||||||
|
rate = self.RATES
|
||||||
|
# TODO Assign only the weight of existing components.
|
||||||
|
weights = (
|
||||||
|
self.DISPLAY_WEIGHT, self.PROCESSOR_WEIGHT, self.RAM_WEIGHT, self.DATA_STORAGE_WEIGHT, self.BATTERY_WEIGHT,
|
||||||
|
self.CAMERA_WEIGHT)
|
||||||
|
|
||||||
|
return self.harmonic_mean(weights, rate)
|
||||||
|
|
||||||
|
|
||||||
|
class FunctionalityRate(BaseRate):
|
||||||
|
"""
|
||||||
|
Rate Functionality aspects on mobile devices
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Functionality Range v2
|
||||||
|
A = 0, 5
|
||||||
|
B = 0
|
||||||
|
C = -0, 25
|
||||||
|
D = -0, 5
|
||||||
|
NONE = -0, 3
|
||||||
|
|
||||||
|
# SUM(weights) = 1
|
||||||
|
SIM_WEIGHT = 0.2
|
||||||
|
USB_WEIGHT = 0.25
|
||||||
|
WIFI_WEIGHT = 0.05
|
||||||
|
BLUETOOTH_WEIGHT = 0.05
|
||||||
|
FINGERPRINT_WEIGHT = 0.05
|
||||||
|
LOUDSPEAKER_WEIGHT = 0.15
|
||||||
|
MICROPHONE_WEIGHT = 0.15
|
||||||
|
|
||||||
|
def compute(self, FunctionalityDevice: FunctionalityRate):
|
||||||
|
"""
|
||||||
|
|
||||||
|
:param FunctionalityDevice: List[Boolean]
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
# TODO Check if funcionality aspect is != NULL
|
||||||
|
sim = FunctionalityDevice.sim * self.SIM_WEIGHT
|
||||||
|
usb = FunctionalityDevice.usb * self.USB_WEIGHT
|
||||||
|
wifi = FunctionalityDevice.wifi * self.WIFI_WEIGHT
|
||||||
|
bt = FunctionalityDevice.bt * self.BLUETOOTH_WEIGHT
|
||||||
|
fingerprint = FunctionalityDevice.fingerprint * self.FINGERPRINT_WEIGHT
|
||||||
|
loudspeaker = FunctionalityDevice.loudspeaker * self.LOUDSPEAKER_WEIGHT
|
||||||
|
microphone = FunctionalityDevice.microphone * self.MICROPHONE_WEIGHT
|
||||||
|
|
||||||
|
functionality_rate = (sim + usb + wifi + bt + fingerprint + loudspeaker + microphone)
|
||||||
|
# TODO Add functionality range (buttons, chassis, display defects, camera defects)
|
||||||
|
return functionality_rate
|
||||||
|
|
||||||
|
|
||||||
|
class Appearance(Range):
|
||||||
|
"""
|
||||||
|
APPEARANCE GRADE [0.5,-0.5]
|
||||||
|
"""
|
||||||
|
|
||||||
|
Z = 0.5
|
||||||
|
A = 0.4
|
||||||
|
B = 0.1
|
||||||
|
C = -0.1
|
||||||
|
D = -0.25
|
||||||
|
E = -0.5
|
||||||
|
NONE = -0.3
|
||||||
|
|
||||||
|
|
||||||
|
class DisplayRate(QualityRate):
|
||||||
|
"""
|
||||||
|
Calculate a DisplayRate
|
||||||
|
"""
|
||||||
|
SIZE_NORM = 3.5, 7.24
|
||||||
|
RESOLUTION_H_NORM = 440, 1080
|
||||||
|
RESOLUTION_W_NORM = 720, 2048
|
||||||
|
|
||||||
|
DISPLAY_WEIGHTS = 0.6, 0.2, 0.2
|
||||||
|
|
||||||
|
def compute(self, display: Display):
|
||||||
|
size = display.size or self.DEFAULT_SIZE
|
||||||
|
resolution_h = display.resolution_h or 0
|
||||||
|
resolution_w = display.resolution_w or 0
|
||||||
|
|
||||||
|
# STEP: Normalize values
|
||||||
|
size_norm = max(self.norm(size, *self.SIZE_NORM), 0)
|
||||||
|
resolution_h_norm = max(self.norm(resolution_h, *self.RESOLUTION_H_NORM), 0)
|
||||||
|
resolution_w_norm = max(self.norm(resolution_w, *self.RESOLUTION_W_NORM), 0)
|
||||||
|
|
||||||
|
# STEP: Fusion Characteristics
|
||||||
|
return self.harmonic_mean(self.DISPLAY_WEIGHTS, rates=(size_norm, resolution_h_norm, resolution_w_norm))
|
||||||
|
|
||||||
|
|
||||||
|
# COMPONENTS RATE V1 (PROCESSOR,RAM,HHD)
|
||||||
|
|
||||||
|
# TODO quality components rate qualityrate class??
|
||||||
|
|
||||||
|
|
||||||
|
class ProcessorRate(QualityRate):
|
||||||
|
"""
|
||||||
|
Calculate a ProcessorRate
|
||||||
|
"""
|
||||||
|
# processor.xMin, processor.xMax
|
||||||
|
PROCESSOR_NORM = 3196.17, 17503.81
|
||||||
|
CORES_NORM = 1, 6
|
||||||
|
|
||||||
|
DEFAULT_CORES = 1
|
||||||
|
DEFAULT_SPEED = 1.6
|
||||||
|
DEFAULT_SCORE = 4000
|
||||||
|
|
||||||
|
PROCESSOR_WEIGHTS = 0.5, 0.5
|
||||||
|
|
||||||
|
def compute(self, processor: Processor):
|
||||||
|
""" Compute processor rate
|
||||||
|
Obs: cores and speed are possible NULL value
|
||||||
|
:return: result is a rate (score) of Processor characteristics
|
||||||
|
"""
|
||||||
|
cores = processor.cores or self.DEFAULT_CORES
|
||||||
|
speed = processor.speed or self.DEFAULT_SPEED
|
||||||
|
|
||||||
|
# STEP: Normalize values
|
||||||
|
cores_norm = max(self.norm(cores, *self.PROCESSOR_NORM), 0)
|
||||||
|
cpu_speed_norm = max(self.norm(speed, *self.CORES_NORM), 0)
|
||||||
|
|
||||||
|
# STEP: Fusion Characteristics
|
||||||
|
return self.harmonic_mean(self.PROCESSOR_WEIGHTS, rates=(cores_norm, cpu_speed_norm))
|
||||||
|
|
||||||
|
|
||||||
|
class RamRate(QualityRate):
|
||||||
|
"""
|
||||||
|
Calculate a RamRate of all RamModule devices
|
||||||
|
"""
|
||||||
|
# ram.size.xMin; ram.size.xMax
|
||||||
|
SIZE_NORM = 256, 8192
|
||||||
|
RAM_SPEED_NORM = 133, 1333
|
||||||
|
# ram.speed.factor
|
||||||
|
RAM_SPEED_FACTOR = 3.7
|
||||||
|
# ram.size.weight; ram.speed.weight;
|
||||||
|
RAM_WEIGHTS = 0.7, 0.3
|
||||||
|
|
||||||
|
def compute(self, ram_devices: Iterable[RamModule]):
|
||||||
|
"""
|
||||||
|
Obs: RamModule.speed is possible NULL value & size != NULL or NOT??
|
||||||
|
:return: result is a rate (score) of all RamModule components
|
||||||
|
"""
|
||||||
|
size = 0.0
|
||||||
|
speed = 0.0
|
||||||
|
|
||||||
|
# STEP: Filtering, data cleaning and merging of component parts
|
||||||
|
for ram in ram_devices:
|
||||||
|
_size = ram.size or 0
|
||||||
|
size += _size
|
||||||
|
|
||||||
|
_speed = ram.speed or 0
|
||||||
|
speed += _speed
|
||||||
|
|
||||||
|
# STEP: Normalize values
|
||||||
|
size_norm = max(self.norm(size, *self.SIZE_NORM), 0)
|
||||||
|
ram_speed_norm = max(self.norm(speed, *self.RAM_SPEED_NORM), 0)
|
||||||
|
|
||||||
|
# STEP: Fusion Characteristics
|
||||||
|
return self.harmonic_mean(self.RAM_WEIGHTS, rates=(size_norm, ram_speed_norm))
|
||||||
|
|
||||||
|
|
||||||
|
class DataStorageRate(QualityRate):
|
||||||
|
"""
|
||||||
|
Calculate the rate of all DataStorage devices
|
||||||
|
"""
|
||||||
|
# drive.size.xMin; drive.size.xMax
|
||||||
|
SIZE_NORM = 4096, 265000
|
||||||
|
READ_SPEED_NORM = 2.7, 109.5
|
||||||
|
WRITE_SPEED_NORM = 2, 27.35
|
||||||
|
# drive.size.weight; drive.readingSpeed.weight; drive.writingSpeed.weight;
|
||||||
|
DATA_STORAGE_WEIGHTS = 0.5, 0.25, 0.25
|
||||||
|
|
||||||
|
def compute(self, data_storage_devices: Iterable[DataStorage], rate: WorkbenchRate):
|
||||||
|
"""
|
||||||
|
Obs: size != NULL and 0 value & read_speed and write_speed != NULL
|
||||||
|
:return: result is a rate (score) of all DataStorage devices
|
||||||
|
"""
|
||||||
|
size = 0
|
||||||
|
read_speed = 0
|
||||||
|
write_speed = 0
|
||||||
|
|
||||||
|
# STEP: Filtering, data cleaning and merging of component parts
|
||||||
|
for storage in data_storage_devices:
|
||||||
|
# todo fix StopIteration if don't exists BenchmarkDataStorage
|
||||||
|
benchmark = next(e for e in storage.events if isinstance(e, BenchmarkDataStorage))
|
||||||
|
# prevent NULL values
|
||||||
|
_size = storage.size or 0
|
||||||
|
size += _size
|
||||||
|
read_speed += benchmark.read_speed * _size
|
||||||
|
write_speed += benchmark.write_speed * _size
|
||||||
|
|
||||||
|
# STEP: Fusion components
|
||||||
|
# Check almost one storage have size, try catch exception 0/0
|
||||||
|
if size:
|
||||||
|
read_speed /= size
|
||||||
|
write_speed /= size
|
||||||
|
|
||||||
|
# STEP: Normalize values
|
||||||
|
size_norm = max(self.norm(size, *self.SIZE_NORM), 0)
|
||||||
|
read_speed_norm = max(self.norm(read_speed, *self.READ_SPEED_NORM), 0)
|
||||||
|
write_speed_norm = max(self.norm(write_speed, *self.WRITE_SPEED_NORM), 0)
|
||||||
|
|
||||||
|
# STEP: Fusion Characteristics
|
||||||
|
return self.harmonic_mean(self.DATA_STORAGE_WEIGHTS,
|
||||||
|
rates=(size_norm, read_speed_norm, write_speed_norm))
|
||||||
|
|
||||||
|
|
||||||
|
class BatteryRate(QualityRate):
|
||||||
|
"""
|
||||||
|
Rate Battery component if device Type = {Mobile Devices}
|
||||||
|
"""
|
||||||
|
CAPACITY_NORM = 2200, 6000
|
||||||
|
DEFAULT_CAPACITY = 3000
|
||||||
|
|
||||||
|
def compute(self, display: Display):
|
||||||
|
capacity = battery.capacity or self.DEFAULT_CAPACITY
|
||||||
|
|
||||||
|
# STEP: Normalize values
|
||||||
|
capacity_norm = max(self.norm(capacity, *self.CAPACITY_NORM), 0)
|
||||||
|
|
||||||
|
return capacity_norm
|
||||||
|
|
||||||
|
|
||||||
|
class CameraRate(QualityRate):
|
||||||
|
"""
|
||||||
|
Rate camera component if exist on device
|
||||||
|
"""
|
||||||
|
RESOLUTION_NORM = 2200, 6000
|
||||||
|
DEFAULT_RESOLUTION = 16
|
||||||
|
|
||||||
|
def compute(self, display: Display):
|
||||||
|
resolution = camera.resolution or self.DEFAULT_RESOLUTION
|
||||||
|
|
||||||
|
# STEP: Normalize values
|
||||||
|
resolution_norm = max(self.norm(resolution, *self.RESOLUTION_NORM), 0)
|
||||||
|
|
||||||
|
return resolution_norm
|
|
@ -14,7 +14,7 @@ from ereuse_devicehub.resources.agent import schemas as s_agent
|
||||||
from ereuse_devicehub.resources.device import schemas as s_device
|
from ereuse_devicehub.resources.device import schemas as s_device
|
||||||
from ereuse_devicehub.resources.enums import AppearanceRange, Bios, FunctionalityRange, \
|
from ereuse_devicehub.resources.enums import AppearanceRange, Bios, FunctionalityRange, \
|
||||||
PhysicalErasureMethod, PriceSoftware, RATE_POSITIVE, RatingRange, RatingSoftware, ReceiverRole, \
|
PhysicalErasureMethod, PriceSoftware, RATE_POSITIVE, RatingRange, RatingSoftware, ReceiverRole, \
|
||||||
Severity, SnapshotExpectedEvents, SnapshotSoftware, TestDataStorageLength
|
Severity, SnapshotExpectedEvents, SnapshotSoftware, TestDataStorageLength, FunctionalityRangev2
|
||||||
from ereuse_devicehub.resources.event import models as m
|
from ereuse_devicehub.resources.event import models as m
|
||||||
from ereuse_devicehub.resources.models import STR_BIG_SIZE, STR_SIZE
|
from ereuse_devicehub.resources.models import STR_BIG_SIZE, STR_SIZE
|
||||||
from ereuse_devicehub.resources.schemas import Thing
|
from ereuse_devicehub.resources.schemas import Thing
|
||||||
|
@ -109,6 +109,7 @@ class StepRandom(Step):
|
||||||
__doc__ = m.StepRandom.__doc__
|
__doc__ = m.StepRandom.__doc__
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Rate(EventWithOneDevice):
|
class Rate(EventWithOneDevice):
|
||||||
__doc__ = m.Rate.__doc__
|
__doc__ = m.Rate.__doc__
|
||||||
rating = Integer(validate=Range(*RATE_POSITIVE),
|
rating = Integer(validate=Range(*RATE_POSITIVE),
|
||||||
|
@ -157,6 +158,28 @@ class WorkbenchRate(ManualRate):
|
||||||
graphic_card_range = EnumField(RatingRange, dump_only=True, data_key='graphicCardRange')
|
graphic_card_range = EnumField(RatingRange, dump_only=True, data_key='graphicCardRange')
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
WORKBENCH RATE COMPUTER
|
||||||
|
Adaptation of old class WorkbenchRate
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class WorkbenchRateComputer(ManualRate):
|
||||||
|
__doc__ = m.WorkbenchRate.__doc__
|
||||||
|
processor = Float()
|
||||||
|
ram = Float()
|
||||||
|
data_storage = Float()
|
||||||
|
graphic_card = Float()
|
||||||
|
bios = Float()
|
||||||
|
bios_range = EnumField(Bios,
|
||||||
|
description=m.WorkbenchComputerRate.bios_range.comment,
|
||||||
|
data_key='biosRange')
|
||||||
|
data_storage_range = EnumField(RatingRange, dump_only=True, data_key='dataStorageRange')
|
||||||
|
ram_range = EnumField(RatingRange, dump_only=True, data_key='ramRange')
|
||||||
|
processor_range = EnumField(RatingRange, dump_only=True, data_key='processorRange')
|
||||||
|
graphic_card_range = EnumField(RatingRange, dump_only=True, data_key='graphicCardRange')
|
||||||
|
|
||||||
|
|
||||||
class AggregateRate(Rate):
|
class AggregateRate(Rate):
|
||||||
__doc__ = m.AggregateRate.__doc__
|
__doc__ = m.AggregateRate.__doc__
|
||||||
workbench = NestedOn(WorkbenchRate, dump_only=True,
|
workbench = NestedOn(WorkbenchRate, dump_only=True,
|
||||||
|
@ -187,6 +210,106 @@ class AggregateRate(Rate):
|
||||||
graphic_card_range = EnumField(RatingRange, dump_only=True, data_key='graphicCardRange')
|
graphic_card_range = EnumField(RatingRange, dump_only=True, data_key='graphicCardRange')
|
||||||
|
|
||||||
|
|
||||||
|
class QualityRate(Rate):
|
||||||
|
__doc__ = m.QualityRate.__doc__
|
||||||
|
|
||||||
|
ram = Float(dump_only=True, description=m.QualityRate.ram.comment)
|
||||||
|
processor = Float(dump_only=True, description=m.QualityRate.processor.comment)
|
||||||
|
data_storage = Float(dump_only=True, description=m.QualityRate.data_storage.comment)
|
||||||
|
|
||||||
|
|
||||||
|
""" New class for WorkbenchRate in Rate v2"""
|
||||||
|
|
||||||
|
|
||||||
|
class QualityRateComputer(Rate):
|
||||||
|
__doc__ = m.QualityRateComputer.__doc__
|
||||||
|
|
||||||
|
""" List of components appears in general quality rate a device
|
||||||
|
|
||||||
|
ram = Float(dump_only=True, description=m.QualityRateComputer.ram.comment)
|
||||||
|
processor = Float(dump_only=True, description=m.QualityRateComputer.processor.comment)
|
||||||
|
data_storage = Float(dump_only=True, description=m.QualityRateComputer.data_storage.comment)
|
||||||
|
"""
|
||||||
|
|
||||||
|
graphic_card = Float(dump_only=True, description=m.QualityRateComputer.processor.comment)
|
||||||
|
network_adapter = Float(dump_only=True, description=m.QualityRateComputer.network_adapter.comment)
|
||||||
|
|
||||||
|
|
||||||
|
class QualityRateMobile(Rate):
|
||||||
|
__doc__ = m.QualityRateMobile.__doc__
|
||||||
|
|
||||||
|
""" List of components appears in general quality rate a device
|
||||||
|
|
||||||
|
ram = Float(dump_only=True, description=m.QualityRateMobile.ram.comment)
|
||||||
|
processor = Float(dump_only=True, description=m.QualityRateMobile.processor.comment)
|
||||||
|
data_storage = Float(dump_only=True, description=m.QualityRateMobile.data_storage.comment)
|
||||||
|
"""
|
||||||
|
|
||||||
|
display = Float(dump_only=True, description=m.QualityRateMobile.display.comment)
|
||||||
|
battery = Float(dump_only=True, description=m.QualityRateMobile.batter.comment)
|
||||||
|
camera = Float(dump_only=True, description=m.QualityRateMobile.camera.comment)
|
||||||
|
|
||||||
|
|
||||||
|
class FunctionalityRate(Rate):
|
||||||
|
__doc__ = m.FunctionalityRate.__doc__
|
||||||
|
|
||||||
|
functionality = EnumField(dump_only=True, description=m.FunctionalityRate.functionality.comment)
|
||||||
|
functionality_range = EnumField(dump_only=True, description=m.FunctionalityRate.functionality_range.comment)
|
||||||
|
connectivity_rate = EnumField(dump_only=True, description=m.FunctionalityRate.connectivity_rate.comment)
|
||||||
|
audio_rate = EnumField(dump_only=True, description=m.FunctionalityRate.audio_rate.comment)
|
||||||
|
|
||||||
|
|
||||||
|
class FinalRate(Rate):
|
||||||
|
__doc__ = m.FinalRate.__doc__
|
||||||
|
workbench_computer = NestedOn(WorkbenchComputer, dump_only=True,
|
||||||
|
description=m.ResultRate.workbench_computer_id.comment)
|
||||||
|
workbench_mobile = NestedOn(WorkbenchMobile, dump_only=True,
|
||||||
|
description=m.ResultRate.workbench_mobile_id.comment)
|
||||||
|
bios = EnumField(Bios, dump_only=True)
|
||||||
|
bios_range = EnumField(Bios,
|
||||||
|
description=m.WorkbenchRate.bios_range.comment,
|
||||||
|
data_key='biosRange')
|
||||||
|
|
||||||
|
|
||||||
|
# TODO Finish input rates (internal and external sources) - Whats really interesting to save in BD?? Whichs aspects?
|
||||||
|
class ResultRate(Rate):
|
||||||
|
__doc__ = m.ResultRate.__doc__
|
||||||
|
# TODO ask for what to do NestedOn??
|
||||||
|
workbench_computer = NestedOn(WorkbenchRateComputer, dump_only=True,
|
||||||
|
description=m.ResultRate.workbench_computer_id.comment)
|
||||||
|
workbench_mobile = NestedOn(WorkbenchRateMobile, dump_only=True,
|
||||||
|
description=m.ResultRate.workbench_mobile_id.comment)
|
||||||
|
manual_computer = NestedOn(ManualRateComputer,
|
||||||
|
dump_only=True,
|
||||||
|
description=m.ResultRate.manual_computer_id.comment)
|
||||||
|
|
||||||
|
processor = Float(dump_only=True)
|
||||||
|
ram = Float(dump_only=True)
|
||||||
|
data_storage = Float(dump_only=True)
|
||||||
|
graphic_card = Float(dump_only=True)
|
||||||
|
bios = EnumField(Bios, dump_only=True)
|
||||||
|
bios_range = EnumField(Bios,
|
||||||
|
description=m.WorkbenchRate.bios_range.comment,
|
||||||
|
data_key='biosRange')
|
||||||
|
appearance_range = EnumField(AppearanceRange,
|
||||||
|
required=True,
|
||||||
|
data_key='appearanceRange',
|
||||||
|
description=m.ManualRate.appearance_range.comment)
|
||||||
|
functionality_range = EnumField(FunctionalityRange,
|
||||||
|
required=True,
|
||||||
|
data_key='functionalityRange',
|
||||||
|
description=m.ManualRate.functionality_range.comment)
|
||||||
|
labelling = Boolean(description=m.ManualRate.labelling.comment)
|
||||||
|
data_storage_range = EnumField(RatingRange, dump_only=True, data_key='dataStorageRange')
|
||||||
|
ram_range = EnumField(RatingRange, dump_only=True, data_key='ramRange')
|
||||||
|
processor_range = EnumField(RatingRange, dump_only=True, data_key='processorRange')
|
||||||
|
graphic_card_range = EnumField(RatingRange, dump_only=True, data_key='graphicCardRange')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Price(EventWithOneDevice):
|
class Price(EventWithOneDevice):
|
||||||
__doc__ = m.Price.__doc__
|
__doc__ = m.Price.__doc__
|
||||||
currency = EnumField(Currency, required=True, description=m.Price.currency.comment)
|
currency = EnumField(Currency, required=True, description=m.Price.currency.comment)
|
||||||
|
|
73
tests/test_rate_v2.py
Normal file
73
tests/test_rate_v2.py
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
import math
|
||||||
|
|
||||||
|
from ereuse_devicehub.resources.device.models import HardDrive, Processor, RamModule, Device
|
||||||
|
from ereuse_devicehub.resources.event.rate.workbench.v2_0 import Rate
|
||||||
|
|
||||||
|
|
||||||
|
def test_ratev2_general():
|
||||||
|
"""
|
||||||
|
Test to check if compute all aspects (quality, functionality and appearance) correctly
|
||||||
|
|
||||||
|
Quality rate aspects:
|
||||||
|
Display (screen)
|
||||||
|
Processor
|
||||||
|
RAM
|
||||||
|
Data Storage
|
||||||
|
Battery
|
||||||
|
Camera
|
||||||
|
|
||||||
|
Functionality rate aspects on mobile devices
|
||||||
|
SIM
|
||||||
|
USB/ Charger plug
|
||||||
|
Wi-Fi
|
||||||
|
Bluetooth
|
||||||
|
Fingerprint sensor
|
||||||
|
Loudspeaker
|
||||||
|
Microphone
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
device_test = Device()
|
||||||
|
device_test.components |= {
|
||||||
|
Processor(cores=2, speed=3.4), # CPU
|
||||||
|
HardDrive(size=476940), # HDD
|
||||||
|
RamModule(size=4096, speed=1600), # RAM
|
||||||
|
RamModule(size=2048, speed=1067), # RAM
|
||||||
|
Display(size=5.5, resolutionH=1080, resolutionW=1920), # Screen
|
||||||
|
Battery(capacity=3000), # Mobile devices
|
||||||
|
Camera(resolution=16)
|
||||||
|
}
|
||||||
|
|
||||||
|
rate_device = Rate().compute(device_test)
|
||||||
|
|
||||||
|
assert math.isclose(rate_device, 2.2, rel_tol=0.001)
|
||||||
|
|
||||||
|
|
||||||
|
def test_quality_rate():
|
||||||
|
""" Test to check all quality aspects
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def test_functionality_rate():
|
||||||
|
"""
|
||||||
|
Test to check all functionality aspects
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def test_component_rate_equal_to_zero():
|
||||||
|
"""
|
||||||
|
Test to check all functionality aspects
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def tes_component_rate_is_null():
|
||||||
|
"""
|
||||||
|
Test to check all functionality aspects
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
pass
|
Reference in a new issue