refactor PiLog to retain x,y values
This commit is contained in:
parent
10d73f570a
commit
4d94322c55
@ -1,21 +1,14 @@
|
|||||||
# coding: utf-8
|
# coding: utf-8
|
||||||
|
"""Provide pi simulation results to IRC."""
|
||||||
import logging
|
|
||||||
|
|
||||||
from ircbot.lib import Plugin
|
from ircbot.lib import Plugin
|
||||||
from pi.models import PiLog
|
from pi.models import PiLog
|
||||||
|
|
||||||
|
|
||||||
log = logging.getLogger('pi.ircplugin')
|
|
||||||
|
|
||||||
|
|
||||||
class Pi(Plugin):
|
class Pi(Plugin):
|
||||||
|
|
||||||
"""Use the Monte Carlo method to simulate pi."""
|
"""Use the Monte Carlo method to simulate pi."""
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
"""Set up the handlers."""
|
"""Set up the handlers."""
|
||||||
|
|
||||||
self.connection.reactor.add_global_regex_handler(['pubmsg', 'privmsg'], r'^!pi$',
|
self.connection.reactor.add_global_regex_handler(['pubmsg', 'privmsg'], r'^!pi$',
|
||||||
self.handle_pi, -20)
|
self.handle_pi, -20)
|
||||||
|
|
||||||
@ -23,17 +16,16 @@ class Pi(Plugin):
|
|||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
"""Tear down handlers."""
|
"""Tear down handlers."""
|
||||||
|
|
||||||
self.connection.reactor.remove_global_regex_handler(['pubmsg', 'privmsg'], self.handle_pi)
|
self.connection.reactor.remove_global_regex_handler(['pubmsg', 'privmsg'], self.handle_pi)
|
||||||
|
|
||||||
super(Pi, self).stop()
|
super(Pi, self).stop()
|
||||||
|
|
||||||
def handle_pi(self, connection, event, match):
|
def handle_pi(self, connection, event, match):
|
||||||
"""Handle the pi command by generating another value and presenting it."""
|
"""Handle the pi command by generating another value and presenting it."""
|
||||||
|
newest, x, y = PiLog.objects.simulate()
|
||||||
newest, x, y, hit = PiLog.objects.simulate()
|
|
||||||
msg = ("({0:.10f}, {1:.10f}) is {2}within the unit circle. π is {5:.10f}. (i:{3:d} p:{4:d})"
|
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)
|
return self.bot.reply(event, msg)
|
||||||
|
|
||||||
|
23
pi/migrations/0003_rename_count_fields.py
Normal file
23
pi/migrations/0003_rename_count_fields.py
Normal file
@ -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',
|
||||||
|
),
|
||||||
|
]
|
25
pi/migrations/0004_simulation_x_y_logging.py
Normal file
25
pi/migrations/0004_simulation_x_y_logging.py
Normal file
@ -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,
|
||||||
|
),
|
||||||
|
]
|
52
pi/models.py
52
pi/models.py
@ -1,67 +1,67 @@
|
|||||||
"""Karma logging models."""
|
"""Karma logging models."""
|
||||||
|
|
||||||
import logging
|
|
||||||
import math
|
import math
|
||||||
import pytz
|
|
||||||
import random
|
import random
|
||||||
|
|
||||||
|
import pytz
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
|
|
||||||
log = logging.getLogger('pi.models')
|
|
||||||
|
|
||||||
|
|
||||||
class PiLogManager(models.Manager):
|
class PiLogManager(models.Manager):
|
||||||
|
|
||||||
"""Assemble some queries against PiLog."""
|
"""Assemble some queries against PiLog."""
|
||||||
|
|
||||||
def simulate(self):
|
def simulate(self):
|
||||||
"""Add one more entry to the log, and return it."""
|
"""Add one more entry to the log, and return it."""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
latest = self.latest()
|
latest = self.latest()
|
||||||
except PiLog.DoesNotExist:
|
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()
|
latest.save()
|
||||||
|
|
||||||
inside = latest.count_inside
|
inside = latest.total_count_inside
|
||||||
total = latest.count_total
|
total = latest.total_count
|
||||||
|
|
||||||
x = random.random()
|
x = random.random()
|
||||||
y = 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.objects.create(simulation_x=x, simulation_y=y,
|
||||||
newest = PiLog(count_inside=inside+1, count_total=total+1)
|
total_count_inside=inside, total_count=total)
|
||||||
else:
|
|
||||||
newest = PiLog(count_inside=inside, count_total=total+1)
|
|
||||||
newest.save()
|
|
||||||
|
|
||||||
return newest, x, y, hit
|
return newest, x, y
|
||||||
|
|
||||||
|
|
||||||
class PiLog(models.Model):
|
class PiLog(models.Model):
|
||||||
|
|
||||||
"""Track pi as it is estimated over time."""
|
"""Track pi as it is estimated over time."""
|
||||||
|
|
||||||
count_inside = models.PositiveIntegerField()
|
simulation_x = models.DecimalField(max_digits=11, decimal_places=10)
|
||||||
count_total = models.PositiveIntegerField()
|
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)
|
created = models.DateTimeField(auto_now_add=True)
|
||||||
|
|
||||||
objects = PiLogManager()
|
objects = PiLogManager()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
"""Options for the PiLog class."""
|
||||||
|
|
||||||
get_latest_by = 'created'
|
get_latest_by = 'created'
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
"""String representation."""
|
"""Provide string representation."""
|
||||||
|
|
||||||
tz = pytz.timezone(settings.TIME_ZONE)
|
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'))
|
self.created.astimezone(tz).strftime('%Y-%m-%d %H:%M:%S %Z'))
|
||||||
|
|
||||||
|
@property
|
||||||
def value(self):
|
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
|
||||||
|
Loading…
Reference in New Issue
Block a user