first iteration models ratev2

This commit is contained in:
nad 2019-03-07 17:07:59 +01:00
parent ddb1877133
commit 0f508a1d59
2 changed files with 552 additions and 264 deletions

View File

@ -651,7 +651,7 @@ class ManualRate(IndividualRate):
raise NotImplementedError() raise NotImplementedError()
class WorkbenchComputerRate(ManualRate): class ComputerRate(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))
@ -697,172 +697,6 @@ class WorkbenchComputerRate(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))
@ -959,7 +793,186 @@ class AggregateRate(Rate):
return aggregate return aggregate
#################################################################################### class EreusePrice(Price):
"""The act of setting a price by guessing it using the eReuse.org
algorithm.
This algorithm states that the price is the use value of the device
(represented by its last :class:`.Rate`) multiplied by a constants
value agreed by a circuit or platform.
"""
MULTIPLIER = {
Desktop: 20,
Laptop: 30
}
class Type:
def __init__(self, percentage: float, price: Decimal) -> None:
# see https://stackoverflow.com/a/29651462 for the - 0.005
self.amount = EreusePrice.to_price(price * Decimal(percentage))
self.percentage = EreusePrice.to_price(price * Decimal(percentage))
self.percentage = round(percentage - 0.005, 2)
class Service:
REFURBISHER, PLATFORM, RETAILER = 0, 1, 2
STANDARD, WARRANTY2 = 'STD', 'WR2'
SCHEMA = {
Desktop: {
RatingRange.HIGH: {
STANDARD: (0.35125, 0.204375, 0.444375),
WARRANTY2: (0.47425, 0.275875, 0.599875)
},
RatingRange.MEDIUM: {
STANDARD: (0.385, 0.2558333333, 0.3591666667),
WARRANTY2: (0.539, 0.3581666667, 0.5028333333)
},
RatingRange.LOW: {
STANDARD: (0.5025, 0.30875, 0.18875),
},
},
Laptop: {
RatingRange.HIGH: {
STANDARD: (0.3469230769, 0.195, 0.4580769231),
WARRANTY2: (0.4522307692, 0.2632307692, 0.6345384615)
},
RatingRange.MEDIUM: {
STANDARD: (0.382, 0.1735, 0.4445),
WARRANTY2: (0.5108, 0.2429, 0.6463)
},
RatingRange.LOW: {
STANDARD: (0.4528571429, 0.2264285714, 0.3207142857),
}
}
}
SCHEMA[Server] = SCHEMA[Desktop]
def __init__(self, device, rating_range, role, price: Decimal) -> None:
cls = device.__class__ if device.__class__ != Server else Desktop
rate = self.SCHEMA[cls][rating_range]
self.standard = EreusePrice.Type(rate[self.STANDARD][role], price)
if self.WARRANTY2 in rate:
self.warranty2 = EreusePrice.Type(rate[self.WARRANTY2][role], price)
def __init__(self, rating: AggregateRate, **kwargs) -> None:
if rating.rating_range == RatingRange.VERY_LOW:
raise ValueError('Cannot compute price for Range.VERY_LOW')
# We pass ROUND_UP strategy so price is always greater than what refurbisher... amounts
price = self.to_price(rating.rating * self.MULTIPLIER[rating.device.__class__], ROUND_UP)
super().__init__(rating=rating,
device=rating.device,
price=price,
software=kwargs.pop('software', app.config['PRICE_SOFTWARE']),
version=kwargs.pop('version', app.config['PRICE_VERSION']),
**kwargs)
self._compute()
@orm.reconstructor
def _compute(self):
"""
Calculates eReuse.org prices when initializing the
instance from the price and other properties.
"""
self.refurbisher = self._service(self.Service.REFURBISHER)
self.retailer = self._service(self.Service.RETAILER)
self.platform = self._service(self.Service.PLATFORM)
if hasattr(self.refurbisher, 'warranty2'):
self.warranty2 = round(self.refurbisher.warranty2.amount
+ self.retailer.warranty2.amount
+ self.platform.warranty2.amount, 2)
def _service(self, role):
return self.Service(self.device, self.rating.rating_range, role, self.price)
class EreusePrice(Price):
"""The act of setting a price by guessing it using the eReuse.org
algorithm.
This algorithm states that the price is the use value of the device
(represented by its last :class:`.Rate`) multiplied by a constants
value agreed by a circuit or platform.
"""
MULTIPLIER = {
Desktop: 20,
Laptop: 30
}
class Type:
def __init__(self, percentage: float, price: Decimal) -> None:
# see https://stackoverflow.com/a/29651462 for the - 0.005
self.amount = EreusePrice.to_price(price * Decimal(percentage))
self.percentage = EreusePrice.to_price(price * Decimal(percentage))
self.percentage = round(percentage - 0.005, 2)
class Service:
REFURBISHER, PLATFORM, RETAILER = 0, 1, 2
STANDARD, WARRANTY2 = 'STD', 'WR2'
SCHEMA = {
Desktop: {
RatingRange.HIGH: {
STANDARD: (0.35125, 0.204375, 0.444375),
WARRANTY2: (0.47425, 0.275875, 0.599875)
},
RatingRange.MEDIUM: {
STANDARD: (0.385, 0.2558333333, 0.3591666667),
WARRANTY2: (0.539, 0.3581666667, 0.5028333333)
},
RatingRange.LOW: {
STANDARD: (0.5025, 0.30875, 0.18875),
},
},
Laptop: {
RatingRange.HIGH: {
STANDARD: (0.3469230769, 0.195, 0.4580769231),
WARRANTY2: (0.4522307692, 0.2632307692, 0.6345384615)
},
RatingRange.MEDIUM: {
STANDARD: (0.382, 0.1735, 0.4445),
WARRANTY2: (0.5108, 0.2429, 0.6463)
},
RatingRange.LOW: {
STANDARD: (0.4528571429, 0.2264285714, 0.3207142857),
}
}
}
SCHEMA[Server] = SCHEMA[Desktop]
def __init__(self, device, rating_range, role, price: Decimal) -> None:
cls = device.__class__ if device.__class__ != Server else Desktop
rate = self.SCHEMA[cls][rating_range]
self.standard = EreusePrice.Type(rate[self.STANDARD][role], price)
if self.WARRANTY2 in rate:
self.warranty2 = EreusePrice.Type(rate[self.WARRANTY2][role], price)
def __init__(self, rating: AggregateRate, **kwargs) -> None:
if rating.rating_range == RatingRange.VERY_LOW:
raise ValueError('Cannot compute price for Range.VERY_LOW')
# We pass ROUND_UP strategy so price is always greater than what refurbisher... amounts
price = self.to_price(rating.rating * self.MULTIPLIER[rating.device.__class__], ROUND_UP)
super().__init__(rating=rating,
device=rating.device,
price=price,
software=kwargs.pop('software', app.config['PRICE_SOFTWARE']),
version=kwargs.pop('version', app.config['PRICE_VERSION']),
**kwargs)
self._compute()
@orm.reconstructor
def _compute(self):
"""
Calculates eReuse.org prices when initializing the
instance from the price and other properties.
"""
self.refurbisher = self._service(self.Service.REFURBISHER)
self.retailer = self._service(self.Service.RETAILER)
self.platform = self._service(self.Service.PLATFORM)
if hasattr(self.refurbisher, 'warranty2'):
self.warranty2 = round(self.refurbisher.warranty2.amount
+ self.retailer.warranty2.amount
+ self.platform.warranty2.amount, 2)
def _service(self, role):
return self.Service(self.device, self.rating.rating_range, role, self.price)
class ResultRate(Rate): class ResultRate(Rate):
@ -1150,6 +1163,92 @@ class ResultRate(Rate):
return aggregate return aggregate
class BenchmarkRate:
"""
Common class to group by benchmark rate classes
"""
class BenchmarkQuality(BenchmarkRate):
"""
Computes quality benchmarks results to aggregate in result rate
"""
cpu_sysbench = Column(Float(decimal_return_scale=2))
cpu_sysbench.comment = 'Benchmark processor component with sysbench tool'
ram_sysbench = Column(Float(decimal_return_scale=2))
ram_sysbench.comment = 'Benchmark RAM component'
# gpu_sysbench = Column(Float(decimal_return_scale=2)) todo how to do?
data_storage_sysbench = Column(Float(decimal_return_scale=2))
data_storage_sysbench.comment = 'Benchmark data storage component with sysbench tool'
data_storage_smart = Column(Float(decimal_return_scale=2))
data_storage_smart.comment = 'Benchmark data storage component with SMART tool'
class FunctionalityTest(Test):
"""
Class where are generic devices functionality aspects
"""
class TestAudio(FunctionalityTest):
"""
Test to check all this aspects related with audio fucntions
"""
loudspeaker = Column(BDEnum(LoudspeakerRange))
loudspeaker.comment = 'Range to determine if the speaker is working properly and what sound quality it has.'
microphone = Column(Boolean)
microphone.comment = 'This evaluate if microphone works correctly'
class TestConnectivity(FunctionalityTest):
"""
Test to check all this aspects related with functionality connections in devices
"""
SIM = Column(Boolean)
SIM.comment = 'Evaluate if SIM works'
wifi = Column(Boolean)
wifi.comment = 'Evaluate if wifi connection works correctly'
bluetooth = Column(Boolean)
bluetooth.comment = 'Evaluate if bluetooth works'
usb = Column(DBEnum())
usb.comment = 'Evaluate if usb port was detected and charger plug works'
class TestBattery(FunctionalityTest):
"""
Test of length of charge. Source R2: Minimum X minutes discharging the device
"""
battery_duration = Column(Boolean())
battery_duration.comment = ''
class TestBios(FunctionalityTest):
"""
Test that determinate if is difficult to access BIOS, like need password, are protected..
"""
bios_range = Column(DBEnum())
bios_range.comment = 'Range of difficult to acces BIOS'
class TestApperance():
"""
Class with appearance characteristics
"""
chassis_defects_range = Column(BDEnum(ChassisRange))
chassis_defects_range.comment = 'Range to determinate cosmetic defects on chassis like scratches'
class TestVisual(TestAppearance):
"""
Check aesthetics or cosmetic aspects. Like defects on chassis, display, ..
"""
camera_defects_range = Column(BDEnum(CameraRange))
camera_defects_range = 'Range to determinate cosmetic defects on camera'
display_defects_range = Column(BDEnum(DisplayRange))
display_defects_range = 'Range to determinate cosmetic defects on display'
class Price(JoinedWithOneDeviceMixin, EventWithOneDevice): class Price(JoinedWithOneDeviceMixin, EventWithOneDevice):
"""The act of setting a trading price for the device. """The act of setting a trading price for the device.
@ -1217,97 +1316,6 @@ class Price(JoinedWithOneDeviceMixin, EventWithOneDevice):
return '{0:0.2f} {1}'.format(self.price, self.currency) return '{0:0.2f} {1}'.format(self.price, self.currency)
class EreusePrice(Price):
"""The act of setting a price by guessing it using the eReuse.org
algorithm.
This algorithm states that the price is the use value of the device
(represented by its last :class:`.Rate`) multiplied by a constants
value agreed by a circuit or platform.
"""
MULTIPLIER = {
Desktop: 20,
Laptop: 30
}
class Type:
def __init__(self, percentage: float, price: Decimal) -> None:
# see https://stackoverflow.com/a/29651462 for the - 0.005
self.amount = EreusePrice.to_price(price * Decimal(percentage))
self.percentage = EreusePrice.to_price(price * Decimal(percentage))
self.percentage = round(percentage - 0.005, 2)
class Service:
REFURBISHER, PLATFORM, RETAILER = 0, 1, 2
STANDARD, WARRANTY2 = 'STD', 'WR2'
SCHEMA = {
Desktop: {
RatingRange.HIGH: {
STANDARD: (0.35125, 0.204375, 0.444375),
WARRANTY2: (0.47425, 0.275875, 0.599875)
},
RatingRange.MEDIUM: {
STANDARD: (0.385, 0.2558333333, 0.3591666667),
WARRANTY2: (0.539, 0.3581666667, 0.5028333333)
},
RatingRange.LOW: {
STANDARD: (0.5025, 0.30875, 0.18875),
},
},
Laptop: {
RatingRange.HIGH: {
STANDARD: (0.3469230769, 0.195, 0.4580769231),
WARRANTY2: (0.4522307692, 0.2632307692, 0.6345384615)
},
RatingRange.MEDIUM: {
STANDARD: (0.382, 0.1735, 0.4445),
WARRANTY2: (0.5108, 0.2429, 0.6463)
},
RatingRange.LOW: {
STANDARD: (0.4528571429, 0.2264285714, 0.3207142857),
}
}
}
SCHEMA[Server] = SCHEMA[Desktop]
def __init__(self, device, rating_range, role, price: Decimal) -> None:
cls = device.__class__ if device.__class__ != Server else Desktop
rate = self.SCHEMA[cls][rating_range]
self.standard = EreusePrice.Type(rate[self.STANDARD][role], price)
if self.WARRANTY2 in rate:
self.warranty2 = EreusePrice.Type(rate[self.WARRANTY2][role], price)
def __init__(self, rating: AggregateRate, **kwargs) -> None:
if rating.rating_range == RatingRange.VERY_LOW:
raise ValueError('Cannot compute price for Range.VERY_LOW')
# We pass ROUND_UP strategy so price is always greater than what refurbisher... amounts
price = self.to_price(rating.rating * self.MULTIPLIER[rating.device.__class__], ROUND_UP)
super().__init__(rating=rating,
device=rating.device,
price=price,
software=kwargs.pop('software', app.config['PRICE_SOFTWARE']),
version=kwargs.pop('version', app.config['PRICE_VERSION']),
**kwargs)
self._compute()
@orm.reconstructor
def _compute(self):
"""
Calculates eReuse.org prices when initializing the
instance from the price and other properties.
"""
self.refurbisher = self._service(self.Service.REFURBISHER)
self.retailer = self._service(self.Service.RETAILER)
self.platform = self._service(self.Service.PLATFORM)
if hasattr(self.refurbisher, 'warranty2'):
self.warranty2 = round(self.refurbisher.warranty2.amount
+ self.retailer.warranty2.amount
+ self.platform.warranty2.amount, 2)
def _service(self, role):
return self.Service(self.device, self.rating.rating_range, role, self.price)
class Test(JoinedWithOneDeviceMixin, EventWithOneDevice): class Test(JoinedWithOneDeviceMixin, EventWithOneDevice):
"""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.

View File

@ -1,10 +1,9 @@
from enum import Enum from enum import Enum
from typing import Iterable from typing import Iterable
from ereuse_devicehub.resources.device.models import Computer, DataStorage, Desktop, Laptop, \ from ereuse_devicehub.resources.device.models import DataStorage, Processor, RamModule, Device
Processor, RamModule, Server, Device from ereuse_devicehub.resources.enums import RatingRange
from ereuse_devicehub.resources.event.models import BenchmarkDataStorage, BenchmarkProcessor, \ from ereuse_devicehub.resources.event.models import BenchmarkDataStorage, WorkbenchRate
WorkbenchRate
from ereuse_devicehub.resources.event.rate.rate import BaseRate from ereuse_devicehub.resources.event.rate.rate import BaseRate
@ -128,6 +127,288 @@ class Appearance(Range):
NONE = -0.3 NONE = -0.3
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 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
class DisplayRate(QualityRate): class DisplayRate(QualityRate):
""" """
Calculate a DisplayRate Calculate a DisplayRate
@ -156,7 +437,6 @@ class DisplayRate(QualityRate):
# TODO quality components rate qualityrate class?? # TODO quality components rate qualityrate class??
class ProcessorRate(QualityRate): class ProcessorRate(QualityRate):
""" """
Calculate a ProcessorRate Calculate a ProcessorRate