Browse Source

Merge pull request #393 from CatalystCode/enhancement/refactor-to-colour-library

Enhancement/Replace Color class with colour library
pull/423/head
Hiroki Nakayama 5 years ago
committed by GitHub
parent
commit
6f217bd7cb
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 15 additions and 74 deletions
  1. 36
      app/api/tests/test_utils.py
  2. 52
      app/api/utils.py
  3. 1
      requirements.txt

36
app/api/tests/test_utils.py

@ -6,26 +6,7 @@ from seqeval.metrics.sequence_labeling import get_entities
from ..models import Label, Document
from ..utils import BaseStorage, ClassificationStorage, SequenceLabelingStorage, Seq2seqStorage, CoNLLParser
from ..utils import Color, iterable_to_io
class TestColor(TestCase):
def test_random_color(self):
color = Color.random()
self.assertTrue(0 <= color.red <= 255)
self.assertTrue(0 <= color.green <= 255)
self.assertTrue(0 <= color.blue <= 255)
def test_hex(self):
color = Color(red=255, green=192, blue=203)
self.assertEqual(color.hex, '#ffc0cb')
def test_contrast_color(self):
color = Color(red=255, green=192, blue=203)
self.assertEqual(color.contrast_color.hex, '#000000')
color = Color(red=199, green=21, blue=133)
self.assertEqual(color.contrast_color.hex, '#ffffff')
from ..utils import iterable_to_io
class TestBaseStorage(TestCase):
@ -48,15 +29,14 @@ class TestBaseStorage(TestCase):
labels = ['positive']
created = {}
actual = BaseStorage.to_serializer_format(labels, created, random_seed=123)
actual = BaseStorage.to_serializer_format(labels, created)
self.assertEqual(actual, [{
'text': 'positive',
'prefix_key': None,
'suffix_key': 'p',
'background_color': '#0d1668',
'text_color': '#ffffff',
}])
self.assertEqual(len(actual), 1)
self.assertEqual(actual[0]['text'], 'positive')
self.assertIsNone(actual[0]['prefix_key'])
self.assertEqual(actual[0]['suffix_key'], 'p')
self.assertIsNotNone(actual[0]['background_color'])
self.assertIsNotNone(actual[0]['text_color'])
def test_get_shortkey_without_existing_shortkey(self):
label = 'positive'

52
app/api/utils.py

@ -4,12 +4,12 @@ import itertools
import json
import re
from collections import defaultdict
from random import Random
import conllu
from chardet import UniversalDetector
from django.db import transaction
from django.conf import settings
from colour import Color
import pyexcel
from rest_framework.renderers import JSONRenderer
from seqeval.metrics.sequence_labeling import get_entities
@ -66,7 +66,7 @@ class BaseStorage(object):
return [label for label in labels if label not in created]
@classmethod
def to_serializer_format(cls, labels, created, random_seed=None):
def to_serializer_format(cls, labels, created):
existing_shortkeys = {(label.suffix_key, label.prefix_key)
for label in created.values()}
@ -81,9 +81,10 @@ class BaseStorage(object):
serializer_label['prefix_key'] = shortkey[1]
existing_shortkeys.add(shortkey)
color = Color.random(seed=random_seed)
serializer_label['background_color'] = color.hex
serializer_label['text_color'] = color.contrast_color.hex
background_color = Color(pick_for=label)
text_color = Color('white') if background_color.get_luminance() < 0.5 else Color('black')
serializer_label['background_color'] = background_color.hex
serializer_label['text_color'] = text_color.hex
serializer_labels.append(serializer_label)
@ -450,47 +451,6 @@ class CSVPainter(JSONPainter):
return res
class Color:
def __init__(self, red, green, blue):
self.red = red
self.green = green
self.blue = blue
@property
def contrast_color(self):
"""Generate black or white color.
Ensure that text and background color combinations provide
sufficient contrast when viewed by someone having color deficits or
when viewed on a black and white screen.
Algorithm from w3c:
* https://www.w3.org/TR/AERT/#color-contrast
"""
return Color.white() if self.brightness < 128 else Color.black()
@property
def brightness(self):
return ((self.red * 299) + (self.green * 587) + (self.blue * 114)) / 1000
@property
def hex(self):
return '#{:02x}{:02x}{:02x}'.format(self.red, self.green, self.blue)
@classmethod
def white(cls):
return cls(red=255, green=255, blue=255)
@classmethod
def black(cls):
return cls(red=0, green=0, blue=0)
@classmethod
def random(cls, seed=None):
rgb = Random(seed).choices(range(256), k=3)
return cls(*rgb)
def iterable_to_io(iterable, buffer_size=io.DEFAULT_BUFFER_SIZE):
"""See https://stackoverflow.com/a/20260030/3817588."""
class IterStream(io.RawIOBase):

1
requirements.txt

@ -1,5 +1,6 @@
apache-libcloud==2.4.0
applicationinsights==0.11.7
colour==0.1.5
chardet==3.0.4
coverage==4.5.3
dj-database-url==0.5.0

Loading…
Cancel
Save