Compare commits
5 Commits
691ee7696b
...
bcc5f767ba
Author | SHA1 | Date | |
---|---|---|---|
bcc5f767ba | |||
a0a1aa10f4 | |||
d5e5343193 | |||
da815a1fc3 | |||
ef08cec0fb |
@ -31,6 +31,7 @@ class PiLogManager(models.Manager):
|
|||||||
newest = PiLog.objects.create(simulation_x=x, simulation_y=y,
|
newest = PiLog.objects.create(simulation_x=x, simulation_y=y,
|
||||||
total_count_inside=inside, total_count=total)
|
total_count_inside=inside, total_count=total)
|
||||||
|
|
||||||
|
# TODO: remove the x, y return values, now that we track them in the object
|
||||||
return newest, x, y
|
return newest, x, y
|
||||||
|
|
||||||
|
|
||||||
@ -66,4 +67,4 @@ class PiLog(models.Model):
|
|||||||
@property
|
@property
|
||||||
def hit(self):
|
def hit(self):
|
||||||
"""Return if this log entry is inside the unit circle."""
|
"""Return if this log entry is inside the unit circle."""
|
||||||
return math.hypot(self.simulation_x, self.simulation.y) < 1
|
return math.hypot(self.simulation_x, self.simulation_y) < 1
|
||||||
|
14
pi/views.py
14
pi/views.py
@ -1,12 +1,22 @@
|
|||||||
"""Provide pi simulation results."""
|
"""Provide pi simulation results."""
|
||||||
from rest_framework import viewsets
|
from rest_framework.decorators import action
|
||||||
|
from rest_framework.permissions import IsAuthenticated
|
||||||
|
from rest_framework.response import Response
|
||||||
|
from rest_framework.viewsets import ReadOnlyModelViewSet
|
||||||
|
|
||||||
from pi.models import PiLog
|
from pi.models import PiLog
|
||||||
from pi.serializers import PiLogSerializer
|
from pi.serializers import PiLogSerializer
|
||||||
|
|
||||||
|
|
||||||
class PiLogViewSet(viewsets.ReadOnlyModelViewSet):
|
class PiLogViewSet(ReadOnlyModelViewSet):
|
||||||
"""Provide list and detail actions for pi simulation log entries."""
|
"""Provide list and detail actions for pi simulation log entries."""
|
||||||
|
|
||||||
queryset = PiLog.objects.all()
|
queryset = PiLog.objects.all()
|
||||||
serializer_class = PiLogSerializer
|
serializer_class = PiLogSerializer
|
||||||
|
permission_classes = [IsAuthenticated]
|
||||||
|
|
||||||
|
@action(detail=False, methods=['post'])
|
||||||
|
def simulate(self, request):
|
||||||
|
"""Run one simulation of the pi estimator."""
|
||||||
|
simulation, _, _ = PiLog.objects.simulate()
|
||||||
|
return Response(self.get_serializer(simulation).data, 201)
|
||||||
|
47
tests/test_pi_models.py
Normal file
47
tests/test_pi_models.py
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
"""Test the pi models."""
|
||||||
|
from unittest import mock
|
||||||
|
|
||||||
|
from django.test import TestCase
|
||||||
|
from django.utils.timezone import now
|
||||||
|
|
||||||
|
from pi.models import PiLog
|
||||||
|
|
||||||
|
|
||||||
|
class PiLogTest(TestCase):
|
||||||
|
"""Test pi models."""
|
||||||
|
|
||||||
|
def test_hit_calculation(self):
|
||||||
|
"""Test that x,y combinations are properly considered inside or outside the circle."""
|
||||||
|
hit_item = PiLog(simulation_x=0.0, simulation_y=0.0, total_count=0, total_count_inside=0)
|
||||||
|
miss_item = PiLog(simulation_x=1.0, simulation_y=1.0, total_count=0, total_count_inside=0)
|
||||||
|
|
||||||
|
self.assertTrue(hit_item.hit)
|
||||||
|
self.assertFalse(miss_item.hit)
|
||||||
|
|
||||||
|
def test_value_calculation(self):
|
||||||
|
"""Test that a simulation's value of pi can be calculated."""
|
||||||
|
item = PiLog(simulation_x=0.0, simulation_y=0.0, total_count=1000, total_count_inside=788)
|
||||||
|
zero_item = PiLog(simulation_x=0.0, simulation_y=0.0, total_count=0, total_count_inside=0)
|
||||||
|
|
||||||
|
self.assertEqual(item.value, 3.152)
|
||||||
|
self.assertEqual(zero_item.value, 0.0)
|
||||||
|
|
||||||
|
def test_string_repr(self):
|
||||||
|
"""Test the string repr of a simulation log entry."""
|
||||||
|
item = PiLog(simulation_x=0.0, simulation_y=0.0, total_count=1000, total_count_inside=788,
|
||||||
|
created=now())
|
||||||
|
|
||||||
|
self.assertIn("(788/1000) @ ", str(item))
|
||||||
|
|
||||||
|
def test_simulation_inside_determination(self):
|
||||||
|
"""Test that running a simulation passes the proper inside value."""
|
||||||
|
# get at least one simulation in the DB
|
||||||
|
original_item, _, _ = PiLog.objects.simulate()
|
||||||
|
|
||||||
|
with mock.patch('random.random', return_value=1.0):
|
||||||
|
miss_item, _, _ = PiLog.objects.simulate()
|
||||||
|
self.assertEqual(miss_item.total_count_inside, original_item.total_count_inside)
|
||||||
|
|
||||||
|
with mock.patch('random.random', return_value=0.0):
|
||||||
|
hit_item, _, _ = PiLog.objects.simulate()
|
||||||
|
self.assertGreater(hit_item.total_count_inside, original_item.total_count_inside)
|
25
tests/test_pi_views.py
Normal file
25
tests/test_pi_views.py
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
"""Test the pi package's views."""
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
from rest_framework.status import HTTP_201_CREATED
|
||||||
|
from rest_framework.test import APITestCase
|
||||||
|
|
||||||
|
from pi.models import PiLog
|
||||||
|
|
||||||
|
|
||||||
|
class PiAPITest(APITestCase):
|
||||||
|
"""Test pi DRF views."""
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
"""Do pre-test stuff."""
|
||||||
|
self.client = self.client_class()
|
||||||
|
self.user = User.objects.create(username='test')
|
||||||
|
self.client.force_authenticate(user=self.user)
|
||||||
|
|
||||||
|
def test_simulate_creates_simulation(self):
|
||||||
|
"""Test that the simulate action creates a log entry."""
|
||||||
|
self.assertEqual(PiLog.objects.count(), 0)
|
||||||
|
|
||||||
|
resp = self.client.post('/pi/api/simulations/simulate/')
|
||||||
|
|
||||||
|
self.assertEqual(resp.status_code, HTTP_201_CREATED)
|
||||||
|
self.assertEqual(PiLog.objects.count(), 2) # 2 because 0 entry and the real entry
|
Loading…
x
Reference in New Issue
Block a user