Ενδεικτική λύση εργαστηριακής άσκησης 1 2023-2024
Εκφώνηση
Λύση
Τα ακόλουθα αρχεία: utils.py
, erotima1.py
και erotima2.py
όπως και το αρχείο points.txt πρέπει να βρίσκονται στον ίδιο φάκελο.
utils.py |
---|
| def distance(x1, y1, x2, y2):
return ((x1 - x2) ** 2 + (y1 - y2) ** 2) ** 0.5
def area(x1, y1, x2, y2, x3, y3):
a = distance(x1, y1, x2, y2)
b = distance(x2, y2, x3, y3)
c = distance(x3, y3, x1, y1)
s = (a + b + c) / 2
if s * (s - a) * (s - b) * (s - c) <= 0:
raise ValueError(
f"Invalid triangle with sides {a}, {b}, {c} and semiperimeter {s}, points {x1, y1}, {x2, y2}, {x3, y3}"
)
return (s * (s - a) * (s - b) * (s - c)) ** 0.5
def mean(values):
return sum(values) / len(values)
def median(values):
values.sort()
n = len(values)
if n % 2 == 0:
return (values[n // 2 - 1] + values[n // 2]) / 2
else:
return values[n // 2]
def stdev(values):
m = mean(values)
return (sum((x - m) ** 2 for x in values) / len(values)) ** 0.5
|
erotima1.py |
---|
| import itertools
import os
import random
import statistics as stats
from utils import area, mean, median, stdev
def generate_points(n, seed=None):
if seed:
random.seed(seed)
points = []
for _ in range(n):
x = random.randint(-100, 100)
y = random.randint(-100, 100)
points.append((x, y))
return points
def save_points(points, filename):
with open(os.path.join(os.path.dirname(__file__), filename), "w") as f:
for x, y in points:
f.write(f"{x} {y}\n")
# Λύση Α: με χρήση εμφωλευμένων for
# def get_areas(points):
# areas = []
# for i in range(len(points)):
# for j in range(i + 1, len(points)):
# for k in range(j + 1, len(points)):
# p1 = points[i]
# p2 = points[j]
# p3 = points[k]
# try:
# areas.append(area(*p1, *p2, *p3))
# except ValueError:
# pass
# return areas
# Λύση Β: με χρήση του itertools
def get_areas(points):
areas = []
for i, j, k in itertools.combinations(range(len(points)), 3):
p1 = points[i]
p2 = points[j]
p3 = points[k]
try:
areas.append(area(*p1, *p2, *p3))
except ValueError:
pass
return areas
if __name__ == "__main__":
points = generate_points(100, seed=12345)
# save_points(points, "points.txt")
areas = get_areas(points)
print(f"Valid triangles: {len(areas)}")
print(f"Mean = {mean(areas):.2f}")
print(f"Median = {median(areas):.2f}")
print(f"Stdev = {stdev(areas):.2f}")
print("Using statistics module")
print(f"Mean = {stats.mean(areas):.2f}")
print(f"Median = {stats.median(areas):.2f}")
print(f"Stdev = {stats.stdev(areas):.2f}")
|
$ python erotima1.py
Valid triangles: 161673
Mean = 3206.82
Median = 2392.50
Stdev = 2843.24
Using statistics module
Mean = 3206.82
Median = 2392.50
Stdev = 2843.25
erotima2.py |
---|
| import os
import unittest
from erotima1 import get_areas
from utils import mean, median, stdev
def load_points(filename):
points = []
with open(os.path.join(os.path.dirname(__file__), filename), "r") as f:
for line in f:
x, y = line.strip().split()
points.append((int(x), int(y)))
return points
class TestPoints(unittest.TestCase):
def test_100_points_from_file(self):
points = load_points("points.txt")
areas = get_areas(points)
self.assertEqual(len(areas), 161673)
self.assertAlmostEqual(mean(areas), 3206.82, places=2)
self.assertAlmostEqual(median(areas), 2392.50, places=2)
self.assertAlmostEqual(stdev(areas), 2843.24, places=2)
if __name__ == "__main__":
unittest.main()
|
$ python erotima2.py
.
----------------------------------------------------------------------
Ran 1 test in 0.419s
OK