From 4d94322c55a1aa684c70c8a49b9a527eb6da29b6 Mon Sep 17 00:00:00 2001 From: "Brian S. Stephan" Date: Sat, 24 Oct 2020 11:47:36 -0500 Subject: [PATCH] refactor PiLog to retain x,y values --- pi/ircplugin.py | 16 ++---- pi/migrations/0003_rename_count_fields.py | 23 +++++++++ pi/migrations/0004_simulation_x_y_logging.py | 25 ++++++++++ pi/models.py | 52 ++++++++++---------- 4 files changed, 78 insertions(+), 38 deletions(-) create mode 100644 pi/migrations/0003_rename_count_fields.py create mode 100644 pi/migrations/0004_simulation_x_y_logging.py diff --git a/pi/ircplugin.py b/pi/ircplugin.py index 375d7bd..87e1e15 100644 --- a/pi/ircplugin.py +++ b/pi/ircplugin.py @@ -1,21 +1,14 @@ # coding: utf-8 - -import logging - +"""Provide pi simulation results to IRC.""" from ircbot.lib import Plugin from pi.models import PiLog -log = logging.getLogger('pi.ircplugin') - - class Pi(Plugin): - """Use the Monte Carlo method to simulate pi.""" def start(self): """Set up the handlers.""" - self.connection.reactor.add_global_regex_handler(['pubmsg', 'privmsg'], r'^!pi$', self.handle_pi, -20) @@ -23,17 +16,16 @@ class Pi(Plugin): def stop(self): """Tear down handlers.""" - self.connection.reactor.remove_global_regex_handler(['pubmsg', 'privmsg'], self.handle_pi) super(Pi, self).stop() def handle_pi(self, connection, event, match): """Handle the pi command by generating another value and presenting it.""" - - newest, x, y, hit = PiLog.objects.simulate() + newest, x, y = PiLog.objects.simulate() msg = ("({0:.10f}, {1:.10f}) is {2}within the unit circle. π is {5:.10f}. (i:{3:d} p:{4:d})" - "".format(x, y, "" if hit else "not ", newest.count_inside, newest.count_total, newest.value())) + "".format(x, y, "" if newest.hit else "not ", newest.total_count_inside, + newest.total_count, newest.value)) return self.bot.reply(event, msg) diff --git a/pi/migrations/0003_rename_count_fields.py b/pi/migrations/0003_rename_count_fields.py new file mode 100644 index 0000000..e722df5 --- /dev/null +++ b/pi/migrations/0003_rename_count_fields.py @@ -0,0 +1,23 @@ +# Generated by Django 3.1.2 on 2020-10-24 16:27 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('pi', '0002_auto_20150521_2204'), + ] + + operations = [ + migrations.RenameField( + model_name='pilog', + old_name='count_total', + new_name='total_count', + ), + migrations.RenameField( + model_name='pilog', + old_name='count_inside', + new_name='total_count_inside', + ), + ] diff --git a/pi/migrations/0004_simulation_x_y_logging.py b/pi/migrations/0004_simulation_x_y_logging.py new file mode 100644 index 0000000..02db64a --- /dev/null +++ b/pi/migrations/0004_simulation_x_y_logging.py @@ -0,0 +1,25 @@ +# Generated by Django 3.1.2 on 2020-10-24 16:31 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('pi', '0003_rename_count_fields'), + ] + + operations = [ + migrations.AddField( + model_name='pilog', + name='simulation_x', + field=models.DecimalField(decimal_places=10, default=0.0, max_digits=11), + preserve_default=False, + ), + migrations.AddField( + model_name='pilog', + name='simulation_y', + field=models.DecimalField(decimal_places=10, default=0.0, max_digits=11), + preserve_default=False, + ), + ] diff --git a/pi/models.py b/pi/models.py index 10e9548..0490748 100644 --- a/pi/models.py +++ b/pi/models.py @@ -1,67 +1,67 @@ """Karma logging models.""" - -import logging import math -import pytz import random +import pytz from django.conf import settings from django.db import models -log = logging.getLogger('pi.models') - - class PiLogManager(models.Manager): - """Assemble some queries against PiLog.""" def simulate(self): """Add one more entry to the log, and return it.""" - try: latest = self.latest() except PiLog.DoesNotExist: - latest = PiLog(count_inside=0, count_total=0) + latest = PiLog.objects.create(simulation_x=0.0, simulation_y=0.0, + total_count_inside=0, total_count=0) latest.save() - inside = latest.count_inside - total = latest.count_total + inside = latest.total_count_inside + total = latest.total_count x = random.random() y = random.random() - hit = True if math.hypot(x,y) < 1 else False + total += 1 + if math.hypot(x, y) < 1: + inside += 1 - if hit: - newest = PiLog(count_inside=inside+1, count_total=total+1) - else: - newest = PiLog(count_inside=inside, count_total=total+1) - newest.save() + newest = PiLog.objects.create(simulation_x=x, simulation_y=y, + total_count_inside=inside, total_count=total) - return newest, x, y, hit + return newest, x, y class PiLog(models.Model): - """Track pi as it is estimated over time.""" - count_inside = models.PositiveIntegerField() - count_total = models.PositiveIntegerField() + simulation_x = models.DecimalField(max_digits=11, decimal_places=10) + simulation_y = models.DecimalField(max_digits=11, decimal_places=10) + total_count_inside = models.PositiveIntegerField() + total_count = models.PositiveIntegerField() created = models.DateTimeField(auto_now_add=True) objects = PiLogManager() class Meta: + """Options for the PiLog class.""" + get_latest_by = 'created' def __str__(self): - """String representation.""" - + """Provide string representation.""" tz = pytz.timezone(settings.TIME_ZONE) - return "({0:d}/{1:d}) @ {2:s}".format(self.count_inside, self.count_total, + return "({0:d}/{1:d}) @ {2:s}".format(self.total_count_inside, self.total_count, self.created.astimezone(tz).strftime('%Y-%m-%d %H:%M:%S %Z')) + @property def value(self): - """Return this log entry's value of pi.""" + """Return this log entry's estimated value of pi.""" + return 4.0 * int(self.total_count_inside) / int(self.total_count) - return 4.0 * int(self.count_inside) / int(self.count_total) + @property + def hit(self): + """Return if this log entry is inside the unit circle.""" + return math.hypot(self.simulation_x, self.simulation.y) < 1