diff --git a/beat/web/statistics/admin.py b/beat/web/statistics/admin.py
index 56bab00a6114be258c8abfcd12c8f7c5d9dfde9a..dc2e0744719e999cb65502c5fed6276d04e3248e 100644
--- a/beat/web/statistics/admin.py
+++ b/beat/web/statistics/admin.py
@@ -25,28 +25,29 @@
 #                                                                             #
 ###############################################################################
 
-from .models import HourlyStatistics as HourlyStatisticsModel
 from django.contrib import admin
 
+from .models import HourlyStatistics as HourlyStatisticsModel
 
-#----------------------------------------------------------
+# ----------------------------------------------------------
 
 
 class HourlyStatistics(admin.ModelAdmin):
 
-    list_display        = (
-        'id',
-            'date',
-            'hour',
-            'cpu_time',
-            'max_memory',
-            'data_read_size',
-            'data_read_nb_blocks',
-            'data_read_time',
-            'data_written_size',
-            'data_written_nb_blocks',
-            'data_written_time',
+    list_display = (
+        "id",
+        "date",
+        "hour",
+        "cpu_time",
+        "max_memory",
+        "data_read_size",
+        "data_read_nb_blocks",
+        "data_read_time",
+        "data_written_size",
+        "data_written_nb_blocks",
+        "data_written_time",
     )
-    list_display_links  = ('id', )
+    list_display_links = ("id",)
+
 
 admin.site.register(HourlyStatisticsModel, HourlyStatistics)
diff --git a/beat/web/statistics/models.py b/beat/web/statistics/models.py
index 5c4dd1a0dbc775f51c4158a02819f5f257c85779..3c126c5e4dfb687a21de42cad4ea921670c3e47e 100644
--- a/beat/web/statistics/models.py
+++ b/beat/web/statistics/models.py
@@ -27,24 +27,28 @@
 
 from django.db import models
 
+# ----------------------------------------------------------
 
-#----------------------------------------------------------
 
 class HourlyStatistics(models.Model):
 
-    date                             = models.DateField()
-    hour                             = models.IntegerField()
-    cpu_time                         = models.FloatField(default=0)
-    max_memory                       = models.BigIntegerField(default=0)
-    data_read_size                   = models.BigIntegerField(default=0)
-    data_read_nb_blocks              = models.IntegerField(default=0)
-    data_read_time                   = models.FloatField(default=0)
-    data_written_size                = models.BigIntegerField(default=0)
-    data_written_nb_blocks           = models.IntegerField(default=0)
-    data_written_time                = models.FloatField(default=0)
+    date = models.DateField()
+    hour = models.IntegerField()
+    cpu_time = models.FloatField(default=0)
+    max_memory = models.BigIntegerField(default=0)
+    data_read_size = models.BigIntegerField(default=0)
+    data_read_nb_blocks = models.IntegerField(default=0)
+    data_read_time = models.FloatField(default=0)
+    data_written_size = models.BigIntegerField(default=0)
+    data_written_nb_blocks = models.IntegerField(default=0)
+    data_written_time = models.FloatField(default=0)
 
     def __str__(self):
-        return 'Hourly statistics #%d (%s, hour %s)' % (self.id, self.date.strftime('%b %d, %Y'), self.hour)
+        return "Hourly statistics #%d (%s, hour %s)" % (
+            self.id,
+            self.date.strftime("%b %d, %Y"),
+            self.hour,
+        )
 
     class Meta:
         verbose_name_plural = "Hourly statistics"
diff --git a/beat/web/statistics/tests.py b/beat/web/statistics/tests.py
index 73162879732c161793b727c996e71781d3098f8a..63e4d950403a61fe7e51e2321fee73e3b9f44394 100644
--- a/beat/web/statistics/tests.py
+++ b/beat/web/statistics/tests.py
@@ -25,51 +25,41 @@
 #                                                                             #
 ###############################################################################
 
-from django.test import TestCase
-from django.contrib.auth.models import User
-from django.urls import reverse
-
 from datetime import datetime
-from datetime import date
-from datetime import timedelta
-
-from .models import HourlyStatistics
-from .utils import updateStatistics
-
-from ..dataformats.models import DataFormat
 
-from ..common.testutils import BaseTestCase
+import nose.tools
+from django.test import TestCase
 
 import beat.core.stats
 
-import nose.tools
+from .models import HourlyStatistics
+from .utils import updateStatistics
 
 STATS_1 = {
-    'cpu': { 'user': 1, 'system': 1.5, },
-        'memory': { 'rss': 100, },
-        'data': {
-            'volume': { 'read': 1000, 'write': 2000, },
-            'blocks': { 'read': 100, 'write': 200, },
-            'time': { 'read': 10000, 'write': 20000, },
-            'generated_files': [],
-    }
+    "cpu": {"user": 1, "system": 1.5},
+    "memory": {"rss": 100},
+    "data": {
+        "volume": {"read": 1000, "write": 2000},
+        "blocks": {"read": 100, "write": 200},
+        "time": {"read": 10000, "write": 20000},
+        "generated_files": [],
+    },
 }
 
 
 STATS_2 = {
-    'cpu': { 'user': 2, 'system': 3, },
-        'memory': { 'rss': 200, },
-        'data': {
-            'volume': { 'read': 500, 'write': 600, },
-            'blocks': { 'read': 50, 'write': 60, },
-            'time': { 'read': 5000, 'write': 6000, },
-            'generated_files': [],
-    }
+    "cpu": {"user": 2, "system": 3},
+    "memory": {"rss": 200},
+    "data": {
+        "volume": {"read": 500, "write": 600},
+        "blocks": {"read": 50, "write": 60},
+        "time": {"read": 5000, "write": 6000},
+        "generated_files": [],
+    },
 }
 
 
 class UpdateStatisticsFunction(TestCase):
-
     def test_first_update(self):
         statistics = beat.core.stats.Statistics(STATS_1)
 
@@ -82,15 +72,14 @@ class UpdateStatisticsFunction(TestCase):
         nose.tools.eq_(hourly.date, date1.date())
         nose.tools.eq_(hourly.hour, 6)
 
-        nose.tools.eq_(hourly.cpu_time                    , 2.5)
-        nose.tools.eq_(hourly.max_memory                  , 100)
-        nose.tools.eq_(hourly.data_read_size              , 1000)
-        nose.tools.eq_(hourly.data_read_nb_blocks         , 100)
-        nose.tools.eq_(hourly.data_read_time              , 10000)
-        nose.tools.eq_(hourly.data_written_size           , 2000)
-        nose.tools.eq_(hourly.data_written_nb_blocks      , 200)
-        nose.tools.eq_(hourly.data_written_time           , 20000)
-
+        nose.tools.eq_(hourly.cpu_time, 2.5)
+        nose.tools.eq_(hourly.max_memory, 100)
+        nose.tools.eq_(hourly.data_read_size, 1000)
+        nose.tools.eq_(hourly.data_read_nb_blocks, 100)
+        nose.tools.eq_(hourly.data_read_time, 10000)
+        nose.tools.eq_(hourly.data_written_size, 2000)
+        nose.tools.eq_(hourly.data_written_nb_blocks, 200)
+        nose.tools.eq_(hourly.data_written_time, 20000)
 
     def test_two_updates_in_the_same_hour(self):
         statistics = beat.core.stats.Statistics(STATS_1)
@@ -103,22 +92,20 @@ class UpdateStatisticsFunction(TestCase):
         date2 = datetime(2013, 10, 5, 6, 45, 0)
         updateStatistics(statistics, date=date2)
 
-
         nose.tools.eq_(HourlyStatistics.objects.count(), 1)
 
         hourly = HourlyStatistics.objects.all()[0]
         nose.tools.eq_(hourly.date, date1.date())
         nose.tools.eq_(hourly.hour, 6)
 
-        nose.tools.eq_(hourly.cpu_time                    , 7.5)
-        nose.tools.eq_(hourly.max_memory                  , 300)
-        nose.tools.eq_(hourly.data_read_size              , 1500)
-        nose.tools.eq_(hourly.data_read_nb_blocks         , 150)
-        nose.tools.eq_(hourly.data_read_time              , 15000)
-        nose.tools.eq_(hourly.data_written_size           , 2600)
-        nose.tools.eq_(hourly.data_written_nb_blocks      , 260)
-        nose.tools.eq_(hourly.data_written_time           , 26000)
-
+        nose.tools.eq_(hourly.cpu_time, 7.5)
+        nose.tools.eq_(hourly.max_memory, 300)
+        nose.tools.eq_(hourly.data_read_size, 1500)
+        nose.tools.eq_(hourly.data_read_nb_blocks, 150)
+        nose.tools.eq_(hourly.data_read_time, 15000)
+        nose.tools.eq_(hourly.data_written_size, 2600)
+        nose.tools.eq_(hourly.data_written_nb_blocks, 260)
+        nose.tools.eq_(hourly.data_written_time, 26000)
 
     def test_two_updates_in_different_hours(self):
         statistics = beat.core.stats.Statistics(STATS_1)
@@ -131,36 +118,33 @@ class UpdateStatisticsFunction(TestCase):
         date2 = datetime(2013, 10, 5, 7, 45, 0)
         updateStatistics(statistics, date=date2)
 
-
         nose.tools.eq_(HourlyStatistics.objects.count(), 2)
 
         hourly = HourlyStatistics.objects.all()[0]
         nose.tools.eq_(hourly.date, date1.date())
         nose.tools.eq_(hourly.hour, 6)
 
-        nose.tools.eq_(hourly.cpu_time                    , 2.5)
-        nose.tools.eq_(hourly.max_memory                  , 100)
-        nose.tools.eq_(hourly.data_read_size              , 1000)
-        nose.tools.eq_(hourly.data_read_nb_blocks         , 100)
-        nose.tools.eq_(hourly.data_read_time              , 10000)
-        nose.tools.eq_(hourly.data_written_size           , 2000)
-        nose.tools.eq_(hourly.data_written_nb_blocks      , 200)
-        nose.tools.eq_(hourly.data_written_time           , 20000)
-
+        nose.tools.eq_(hourly.cpu_time, 2.5)
+        nose.tools.eq_(hourly.max_memory, 100)
+        nose.tools.eq_(hourly.data_read_size, 1000)
+        nose.tools.eq_(hourly.data_read_nb_blocks, 100)
+        nose.tools.eq_(hourly.data_read_time, 10000)
+        nose.tools.eq_(hourly.data_written_size, 2000)
+        nose.tools.eq_(hourly.data_written_nb_blocks, 200)
+        nose.tools.eq_(hourly.data_written_time, 20000)
 
         hourly = HourlyStatistics.objects.all()[1]
         nose.tools.eq_(hourly.date, date2.date())
         nose.tools.eq_(hourly.hour, 7)
 
-        nose.tools.eq_(hourly.cpu_time                    , 5.0)
-        nose.tools.eq_(hourly.max_memory                  , 200)
-        nose.tools.eq_(hourly.data_read_size              , 500)
-        nose.tools.eq_(hourly.data_read_nb_blocks         , 50)
-        nose.tools.eq_(hourly.data_read_time              , 5000)
-        nose.tools.eq_(hourly.data_written_size           , 600)
-        nose.tools.eq_(hourly.data_written_nb_blocks      , 60)
-        nose.tools.eq_(hourly.data_written_time           , 6000)
-
+        nose.tools.eq_(hourly.cpu_time, 5.0)
+        nose.tools.eq_(hourly.max_memory, 200)
+        nose.tools.eq_(hourly.data_read_size, 500)
+        nose.tools.eq_(hourly.data_read_nb_blocks, 50)
+        nose.tools.eq_(hourly.data_read_time, 5000)
+        nose.tools.eq_(hourly.data_written_size, 600)
+        nose.tools.eq_(hourly.data_written_nb_blocks, 60)
+        nose.tools.eq_(hourly.data_written_time, 6000)
 
     def test_two_updates_in_different_days(self):
         statistics = beat.core.stats.Statistics(STATS_1)
@@ -173,35 +157,33 @@ class UpdateStatisticsFunction(TestCase):
         date2 = datetime(2013, 10, 6, 7, 45, 0)
         updateStatistics(statistics, date=date2)
 
-
         nose.tools.eq_(HourlyStatistics.objects.count(), 2)
 
         hourly = HourlyStatistics.objects.all()[0]
         nose.tools.eq_(hourly.date, date1.date())
         nose.tools.eq_(hourly.hour, 6)
 
-        nose.tools.eq_(hourly.cpu_time                    , 2.5)
-        nose.tools.eq_(hourly.max_memory                  , 100)
-        nose.tools.eq_(hourly.data_read_size              , 1000)
-        nose.tools.eq_(hourly.data_read_nb_blocks         , 100)
-        nose.tools.eq_(hourly.data_read_time              , 10000)
-        nose.tools.eq_(hourly.data_written_size           , 2000)
-        nose.tools.eq_(hourly.data_written_nb_blocks      , 200)
-        nose.tools.eq_(hourly.data_written_time           , 20000)
+        nose.tools.eq_(hourly.cpu_time, 2.5)
+        nose.tools.eq_(hourly.max_memory, 100)
+        nose.tools.eq_(hourly.data_read_size, 1000)
+        nose.tools.eq_(hourly.data_read_nb_blocks, 100)
+        nose.tools.eq_(hourly.data_read_time, 10000)
+        nose.tools.eq_(hourly.data_written_size, 2000)
+        nose.tools.eq_(hourly.data_written_nb_blocks, 200)
+        nose.tools.eq_(hourly.data_written_time, 20000)
 
         hourly = HourlyStatistics.objects.all()[1]
         nose.tools.eq_(hourly.date, date2.date())
         nose.tools.eq_(hourly.hour, 7)
 
-        nose.tools.eq_(hourly.cpu_time                    , 5.0)
-        nose.tools.eq_(hourly.max_memory                  , 200)
-        nose.tools.eq_(hourly.data_read_size              , 500)
-        nose.tools.eq_(hourly.data_read_nb_blocks         , 50)
-        nose.tools.eq_(hourly.data_read_time              , 5000)
-        nose.tools.eq_(hourly.data_written_size           , 600)
-        nose.tools.eq_(hourly.data_written_nb_blocks      , 60)
-        nose.tools.eq_(hourly.data_written_time           , 6000)
-
+        nose.tools.eq_(hourly.cpu_time, 5.0)
+        nose.tools.eq_(hourly.max_memory, 200)
+        nose.tools.eq_(hourly.data_read_size, 500)
+        nose.tools.eq_(hourly.data_read_nb_blocks, 50)
+        nose.tools.eq_(hourly.data_read_time, 5000)
+        nose.tools.eq_(hourly.data_written_size, 600)
+        nose.tools.eq_(hourly.data_written_nb_blocks, 60)
+        nose.tools.eq_(hourly.data_written_time, 6000)
 
     def test_two_updates_in_different_weeks(self):
         statistics = beat.core.stats.Statistics(STATS_1)
@@ -214,31 +196,30 @@ class UpdateStatisticsFunction(TestCase):
         date2 = datetime(2013, 10, 7, 7, 45, 0)
         updateStatistics(statistics, date=date2)
 
-
         nose.tools.eq_(HourlyStatistics.objects.count(), 2)
 
         hourly = HourlyStatistics.objects.all()[0]
         nose.tools.eq_(hourly.date, date1.date())
         nose.tools.eq_(hourly.hour, 6)
 
-        nose.tools.eq_(hourly.cpu_time                    , 2.5)
-        nose.tools.eq_(hourly.max_memory                  , 100)
-        nose.tools.eq_(hourly.data_read_size              , 1000)
-        nose.tools.eq_(hourly.data_read_nb_blocks         , 100)
-        nose.tools.eq_(hourly.data_read_time              , 10000)
-        nose.tools.eq_(hourly.data_written_size           , 2000)
-        nose.tools.eq_(hourly.data_written_nb_blocks      , 200)
-        nose.tools.eq_(hourly.data_written_time           , 20000)
+        nose.tools.eq_(hourly.cpu_time, 2.5)
+        nose.tools.eq_(hourly.max_memory, 100)
+        nose.tools.eq_(hourly.data_read_size, 1000)
+        nose.tools.eq_(hourly.data_read_nb_blocks, 100)
+        nose.tools.eq_(hourly.data_read_time, 10000)
+        nose.tools.eq_(hourly.data_written_size, 2000)
+        nose.tools.eq_(hourly.data_written_nb_blocks, 200)
+        nose.tools.eq_(hourly.data_written_time, 20000)
 
         hourly = HourlyStatistics.objects.all()[1]
         nose.tools.eq_(hourly.date, date2.date())
         nose.tools.eq_(hourly.hour, 7)
 
-        nose.tools.eq_(hourly.cpu_time                    , 5.0)
-        nose.tools.eq_(hourly.max_memory                  , 200)
-        nose.tools.eq_(hourly.data_read_size              , 500)
-        nose.tools.eq_(hourly.data_read_nb_blocks         , 50)
-        nose.tools.eq_(hourly.data_read_time              , 5000)
-        nose.tools.eq_(hourly.data_written_size           , 600)
-        nose.tools.eq_(hourly.data_written_nb_blocks      , 60)
-        nose.tools.eq_(hourly.data_written_time           , 6000)
+        nose.tools.eq_(hourly.cpu_time, 5.0)
+        nose.tools.eq_(hourly.max_memory, 200)
+        nose.tools.eq_(hourly.data_read_size, 500)
+        nose.tools.eq_(hourly.data_read_nb_blocks, 50)
+        nose.tools.eq_(hourly.data_read_time, 5000)
+        nose.tools.eq_(hourly.data_written_size, 600)
+        nose.tools.eq_(hourly.data_written_nb_blocks, 60)
+        nose.tools.eq_(hourly.data_written_time, 6000)
diff --git a/beat/web/statistics/utils.py b/beat/web/statistics/utils.py
index 9a205a9bede1dcd2a9daddef0795c1ff7fefe81b..9c9a4ab68b3ec04388ea6a6a5f9665757dcc8ba8 100755
--- a/beat/web/statistics/utils.py
+++ b/beat/web/statistics/utils.py
@@ -25,9 +25,11 @@
 #                                                                             #
 ###############################################################################
 
-from .models import HourlyStatistics
 from datetime import datetime
 
+from .models import HourlyStatistics
+
+
 def updateStatistics(stats, date=None):
     """Update the hourly statistics
 
@@ -41,34 +43,22 @@ def updateStatistics(stats, date=None):
 
     date = date or datetime.now()
 
-    # Retrieve the current obj entry (if it exists)
-    try:
-        obj = HourlyStatistics.objects.order_by('-date', '-hour')[0]
-        if (obj.date != date.date()) or (obj.hour != date.hour):
-            obj = None
-    except:
-        obj = None
-
-    # Create an obj entry if necessary
-    if obj is None:
-        obj = HourlyStatistics()
-        obj.date = date.date()
-        obj.hour = date.hour
+    obj, _ = HourlyStatistics.objects.get_or_create(date=date.date(), hour=date.hour)
 
     # Modify the obj entry
-    obj.cpu_time               += stats.cpu['user'] + stats.cpu['system']
-    obj.max_memory             += stats.memory['rss']
+    obj.cpu_time += stats.cpu["user"] + stats.cpu["system"]
+    obj.max_memory += stats.memory["rss"]
 
-    if 'volume' in stats.data:
-      obj.data_read_size    += stats.data['volume'].get('read', 0)
-      obj.data_written_size += stats.data['volume'].get('write', 0)
+    if "volume" in stats.data:
+        obj.data_read_size += stats.data["volume"].get("read", 0)
+        obj.data_written_size += stats.data["volume"].get("write", 0)
 
-    if 'blocks' in stats.data:
-      obj.data_read_nb_blocks    += stats.data['blocks'].get('read', 0)
-      obj.data_written_nb_blocks += stats.data['blocks'].get('write', 0)
+    if "blocks" in stats.data:
+        obj.data_read_nb_blocks += stats.data["blocks"].get("read", 0)
+        obj.data_written_nb_blocks += stats.data["blocks"].get("write", 0)
 
-    if 'time' in stats.data:
-      obj.data_read_time    += stats.data['time'].get('read', 0)
-      obj.data_written_time += stats.data['time'].get('write', 0)
+    if "time" in stats.data:
+        obj.data_read_time += stats.data["time"].get("read", 0)
+        obj.data_written_time += stats.data["time"].get("write", 0)
 
     obj.save()
diff --git a/beat/web/statistics/views.py b/beat/web/statistics/views.py
index 572a34c3d9ac104e23d3c6d3060a1ec289bdf35d..bd2e25419ad51a0ae2f12ae207d2b47c24a32653 100644
--- a/beat/web/statistics/views.py
+++ b/beat/web/statistics/views.py
@@ -34,11 +34,10 @@ except ImportError:
     from itertools import zip_longest as izip_longest
 
 import simplejson
-
-from django.shortcuts import render
 from django.contrib.auth.decorators import login_required
-from django.http import HttpResponseForbidden
 from django.db.models import Sum
+from django.http import HttpResponseForbidden
+from django.shortcuts import render
 
 from .models import HourlyStatistics
 
@@ -47,20 +46,23 @@ def calculate_totals():
     """Caculates all totals required by the statistics display"""
 
     from django.contrib.auth.models import User
+
+    from ..accounts.models import Profile
+    from ..algorithms.models import Algorithm
+    from ..attestations.models import Attestation
+    from ..backend.models import Environment
+    from ..backend.models import Queue
+    from ..backend.models import Worker
     from ..databases.models import Database
-    from ..backend.models import Environment, Queue, Worker
+    from ..dataformats.models import DataFormat
     from ..experiments.models import Experiment
-    from ..toolchains.models import Toolchain
-    from ..algorithms.models import Algorithm
     from ..libraries.models import Library
-    from ..dataformats.models import DataFormat
-    from ..team.models import Team
-    from ..attestations.models import Attestation
-    from ..reports.models import Report
     from ..plotters.models import Plotter
     from ..plotters.models import PlotterParameter
+    from ..reports.models import Report
     from ..search.models import Search
-    from ..accounts.models import Profile
+    from ..team.models import Team
+    from ..toolchains.models import Toolchain
 
     # for calculating the total cpu time, we use the HourlyStatistics and
     # accumulate over the whole history
@@ -68,38 +70,44 @@ def calculate_totals():
     counter = objects.count()
 
     details = objects.aggregate(
-        cpu_time=Sum('cpu_time'),
-        max_memory=Sum('max_memory'),
-        data_read_size=Sum('data_read_size'),
-        data_read_time=Sum('data_read_time'),
-        data_written_size=Sum('data_written_size'),
-        data_written_time=Sum('data_written_time'),
+        cpu_time=Sum("cpu_time"),
+        max_memory=Sum("max_memory"),
+        data_read_size=Sum("data_read_size"),
+        data_read_time=Sum("data_read_time"),
+        data_written_size=Sum("data_written_size"),
+        data_written_time=Sum("data_written_time"),
     )
 
-    cpu_time = details['cpu_time']
-    memory = details['max_memory']
-    input_size = details['data_read_size']
-    input_time = details['data_read_time']
-    output_size = details['data_written_size']
-    output_time = details['data_written_time']
+    cpu_time = details["cpu_time"]
+    memory = details["max_memory"]
+    input_size = details["data_read_size"]
+    input_time = details["data_read_time"]
+    output_size = details["data_written_size"]
+    output_time = details["data_written_time"]
 
-    new_users = User.objects.filter(profile__status = Profile.NEWUSER)
-    waiting_validation_users = User.objects.filter(profile__status = Profile.WAITINGVALIDATION)
-    accepted_users = User.objects.filter(profile__status = Profile.ACCEPTED)
-    rejected_users = User.objects.filter(profile__status = Profile.REJECTED)
-    yearrevalidation_users = User.objects.filter(profile__status = Profile.YEARREVALIDATION)
-    blocked_users = User.objects.filter(profile__status = Profile.BLOCKED)
+    new_users = User.objects.filter(profile__status=Profile.NEWUSER)
+    waiting_validation_users = User.objects.filter(
+        profile__status=Profile.WAITINGVALIDATION
+    )
+    accepted_users = User.objects.filter(profile__status=Profile.ACCEPTED)
+    rejected_users = User.objects.filter(profile__status=Profile.REJECTED)
+    yearrevalidation_users = User.objects.filter(
+        profile__status=Profile.YEARREVALIDATION
+    )
+    blocked_users = User.objects.filter(profile__status=Profile.BLOCKED)
 
     return dict(
-
         counter=counter,
-        cpu_time_hours=int(cpu_time/float(60**2)) if cpu_time else 0,
-        memory_gb=int(memory/float(2**30)) if memory else 0,
-        input_gb = int(input_size/float(2**30)) if input_size else 0,
-        input_bw_mb_s = int((input_size/float(2**20))/input_time) if input_size else 0,
-        output_gb = int(output_size/float(2**30)) if output_size else 0,
-        output_bw_mb_s = int((output_size/float(2**20))/output_time) if output_size else 0,
-
+        cpu_time_hours=int(cpu_time / float(60 ** 2)) if cpu_time else 0,
+        memory_gb=int(memory / float(2 ** 30)) if memory else 0,
+        input_gb=int(input_size / float(2 ** 30)) if input_size else 0,
+        input_bw_mb_s=int((input_size / float(2 ** 20)) / input_time)
+        if input_size
+        else 0,
+        output_gb=int(output_size / float(2 ** 30)) if output_size else 0,
+        output_bw_mb_s=int((output_size / float(2 ** 20)) / output_time)
+        if output_size
+        else 0,
         users=User.objects.count(),
         newusers=new_users.count(),
         waitingvalidationusers=waiting_validation_users.count(),
@@ -111,20 +119,17 @@ def calculate_totals():
         environments=Environment.objects.count(),
         queues=Queue.objects.count(),
         workers=Worker.objects.count(),
-
         experiments=Experiment.objects.count(),
         toolchains=Toolchain.objects.count(),
         algorithms=Algorithm.objects.count(),
         libraries=Library.objects.count(),
         dataformats=DataFormat.objects.count(),
         teams=Team.objects.count(),
-
         attestations=Attestation.objects.count(),
         searches=Search.objects.count(),
         reports=Report.objects.count(),
         plotters=Plotter.objects.count(),
         plotterparameters=PlotterParameter.objects.count(),
-
     )
 
 
@@ -133,23 +138,29 @@ def convert_values(stats):
 
     # transform into plottable data
     def _seconds_to_hours(s, field):
-        if s is not None: return s[field]/float(60**2) #hours
-        return 0.
+        if s is not None:
+            return s[field] / float(60 ** 2)  # hours
+        return 0.0
 
     def _bytes_to_gb(s, field):
-        if s is not None: return s[field]/float(2**30) #gigabytes
-        return 0.
+        if s is not None:
+            return s[field] / float(2 ** 30)  # gigabytes
+        return 0.0
 
     def _bw_in_mbs(s, num, den):
-        if s is None: return 0.
-        if not s[den]: return 0. #avoid division by zero
-        return (s[num]/float(2**20))/s[den] #mb per sec
+        if s is None:
+            return 0.0
+        if not s[den]:
+            return 0.0  # avoid division by zero
+        return (s[num] / float(2 ** 20)) / s[den]  # mb per sec
 
     return dict(
-        cpu_time=[_seconds_to_hours(k, 'cpu_time') for k in stats],
-        memory=[_bytes_to_gb(k, 'max_memory') for k in stats],
-        input_bw=[_bw_in_mbs(k, 'data_read_size', 'data_read_time') for k in stats],
-        output_bw=[_bw_in_mbs(k, 'data_written_size', 'data_written_time') for k in stats],
+        cpu_time=[_seconds_to_hours(k, "cpu_time") for k in stats],
+        memory=[_bytes_to_gb(k, "max_memory") for k in stats],
+        input_bw=[_bw_in_mbs(k, "data_read_size", "data_read_time") for k in stats],
+        output_bw=[
+            _bw_in_mbs(k, "data_written_size", "data_written_time") for k in stats
+        ],
     )
 
 
@@ -165,25 +176,24 @@ def get_statistics(hours_to_go_back, cluster_by):
     # entries for X days, including today
     now = datetime.datetime.now()
     back = now - datetime.timedelta(hours=hours_to_go_back)
-    available = HourlyStatistics.objects.filter(date__gt=back).order_by('date',
-                                                                        'hour')
+    available = HourlyStatistics.objects.filter(date__gt=back).order_by("date", "hour")
 
     # this must be true!
-    assert available.count() <= hours_to_go_back
+    if available.count() > hours_to_go_back:
+        raise RuntimeError("Too much entries in the hourly statistics")
 
     # annotate real entries with the actual timestamp
-    onehour = datetime.timedelta(hours=1)
-    start = back + onehour
 
     def _hours_since_back(o):
         timestamp = datetime.datetime.combine(o.date, datetime.time(o.hour))
-        return int((timestamp - back).total_seconds()/(60**2))
+        return int((timestamp - back).total_seconds() / (60 ** 2))
 
     annotated = dict([(_hours_since_back(k), k) for k in available])
 
     # complete the holes as there must be X entries available
     stats = hours_to_go_back * [None]
-    for k in annotated: stats[k] = annotated[k]
+    for k in annotated:
+        stats[k] = annotated[k]
 
     # cluster using the amount of hours provided by ``cluster_by``
     groups = grouper(cluster_by, stats)
@@ -195,8 +205,14 @@ def get_statistics(hours_to_go_back, cluster_by):
             retval[f] = sum([getattr(k, f) for k in group if k is not None])
         return retval
 
-    fields = ('cpu_time', 'max_memory', 'data_read_size', 'data_read_time',
-              'data_written_size', 'data_written_time')
+    fields = (
+        "cpu_time",
+        "max_memory",
+        "data_read_size",
+        "data_read_time",
+        "data_written_size",
+        "data_written_time",
+    )
     summaries = [_totals(g, fields) for g in groups]
 
     # setup data so information is shown for every field accros groups
@@ -207,12 +223,12 @@ def hourly_charts():
     """Returns the data for hourly charts on various axes"""
 
     # a set of intuitive labels for all data points
-    labels = 24*['']
-    labels[-1] = 'now'
-    labels[17] = '-6h'
-    labels[11] = '-12h'
-    labels[5] = '-18h'
-    labels[0] = '-23h'
+    labels = 24 * [""]
+    labels[-1] = "now"
+    labels[17] = "-6h"
+    labels[11] = "-12h"
+    labels[5] = "-18h"
+    labels[0] = "-23h"
 
     retval = dict(labels=labels)
     retval.update(get_statistics(hours_to_go_back=24, cluster_by=1))
@@ -223,15 +239,15 @@ def daily_charts():
     """Returns the data for daily charts on various axes"""
 
     # a set of intuitive labels for all data points
-    labels = 30*['']
-    labels[-1] = 'today'
-    labels[22] = '-7d'
-    labels[14] = '-15d'
-    labels[7] = '-22d'
-    labels[0] = '-29d'
+    labels = 30 * [""]
+    labels[-1] = "today"
+    labels[22] = "-7d"
+    labels[14] = "-15d"
+    labels[7] = "-22d"
+    labels[0] = "-29d"
 
     retval = dict(labels=labels)
-    retval.update(get_statistics(hours_to_go_back=24*30, cluster_by=24))
+    retval.update(get_statistics(hours_to_go_back=24 * 30, cluster_by=24))
     return simplejson.dumps(retval)
 
 
@@ -239,16 +255,15 @@ def weekly_charts():
     """Returns the data for weekly charts on various axes"""
 
     # a set of intuitive labels for all data points
-    labels = 24*['']
-    labels[-1] = 'this week'
-    labels[17] = '-6w'
-    labels[11] = '-12w'
-    labels[5] = '-18w'
-    labels[0] = '-23w'
+    labels = 24 * [""]
+    labels[-1] = "this week"
+    labels[17] = "-6w"
+    labels[11] = "-12w"
+    labels[5] = "-18w"
+    labels[0] = "-23w"
 
     retval = dict(labels=labels)
-    retval.update(get_statistics(hours_to_go_back=24*7*24,
-                                 cluster_by=24*7))
+    retval.update(get_statistics(hours_to_go_back=24 * 7 * 24, cluster_by=24 * 7))
     return simplejson.dumps(retval)
 
 
@@ -271,13 +286,16 @@ def statistics(request):
 
     """
 
-    if not(request.user.is_superuser): return HttpResponseForbidden()
-
-    return render(request,
-                  'statistics/statistics.html',
-                  dict(
-                      totals=calculate_totals(),
-                      hourly_chart_data=hourly_charts(),
-                      daily_chart_data=daily_charts(),
-                      weekly_chart_data=weekly_charts(),
-                  ))
+    if not (request.user.is_superuser):
+        return HttpResponseForbidden()
+
+    return render(
+        request,
+        "statistics/statistics.html",
+        dict(
+            totals=calculate_totals(),
+            hourly_chart_data=hourly_charts(),
+            daily_chart_data=daily_charts(),
+            weekly_chart_data=weekly_charts(),
+        ),
+    )