Initial commit: Pi calculation benchmark with 34 languages
- Added implementations for: bash, brainfuck, c, cpp, crystal, csharp, d, dart, elixir, erlang, fortran, go, haskell, java, javascript, julia, kotlin, objective-c, scala, typescript, lua, nim, odin, perl, php, python, r, ruby, rust, swift, zig, assembly, vimscript, wolfram - All implementations use Machin's formula: π/4 = 4*arctan(1/5) - arctan(1/239) - Build system with ./build.sh, test system with ./test.sh - Performance testing with ./run_all.sh - Comprehensive README.md explaining performance differences - Test framework verifies correctness against known π values
This commit is contained in:
Executable
+21
@@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Python Build Script - Python är interpreterat, ingen kompilering behövs
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
cd "$SCRIPT_DIR"
|
||||
|
||||
echo "=== Python Build ==="
|
||||
echo "Python är ett interpreterat språk, ingen kompilering behövs."
|
||||
echo "Script: src/print_hej.py"
|
||||
echo ""
|
||||
echo "Skapar wrapper script i bin/"
|
||||
mkdir -p bin
|
||||
cat > bin/print_hej << 'EOF'
|
||||
#!/bin/bash
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
cd "$SCRIPT_DIR"
|
||||
python3 src/print_hej.py "$@"
|
||||
EOF
|
||||
chmod +x bin/print_hej
|
||||
echo "✓ Klart!"
|
||||
Executable
+88
@@ -0,0 +1,88 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Beräknar pi med angivet antal decimaler
|
||||
Användning: python3 print_hej.py <antal_decimaler>
|
||||
"""
|
||||
|
||||
import sys
|
||||
from decimal import Decimal, getcontext
|
||||
|
||||
def arctan(x, precision):
|
||||
"""
|
||||
Beräknar arctan(1/x) med Taylor-serien
|
||||
arctan(1/x) = 1/x - 1/(3*x^3) + 1/(5*x^5) - ...
|
||||
"""
|
||||
result = Decimal(0)
|
||||
x = Decimal(x)
|
||||
x_squared = x * x
|
||||
|
||||
term = Decimal(1) / x
|
||||
sign = 1
|
||||
|
||||
for n in range(1000000):
|
||||
divisor = Decimal(2 * n + 1)
|
||||
contrib = term / divisor
|
||||
|
||||
if sign > 0:
|
||||
result += contrib
|
||||
else:
|
||||
result -= contrib
|
||||
|
||||
term = term / x_squared
|
||||
sign = -sign
|
||||
|
||||
# Avbryt om termen är tillräckligt liten
|
||||
if term < Decimal(10) ** (-precision - 10):
|
||||
break
|
||||
|
||||
return result
|
||||
|
||||
def calculate_pi(decimals):
|
||||
"""
|
||||
Beräknar pi med Machins formel: pi/4 = 4*arctan(1/5) - arctan(1/239)
|
||||
"""
|
||||
# Sätt precision
|
||||
getcontext().prec = decimals + 20
|
||||
|
||||
atan1_5 = arctan(5, decimals)
|
||||
atan1_239 = arctan(239, decimals)
|
||||
|
||||
# pi = 4 * (4*arctan(1/5) - arctan(1/239))
|
||||
pi = Decimal(4) * atan1_5
|
||||
pi = pi - atan1_239
|
||||
pi = pi * Decimal(4)
|
||||
|
||||
return pi
|
||||
|
||||
def main():
|
||||
# Hämta antal decimaler från argument
|
||||
if len(sys.argv) > 1:
|
||||
try:
|
||||
decimals = int(sys.argv[1])
|
||||
if decimals < 1:
|
||||
decimals = 100
|
||||
except ValueError:
|
||||
decimals = 100
|
||||
else:
|
||||
decimals = 100
|
||||
|
||||
# Beräkna pi
|
||||
pi = calculate_pi(decimals)
|
||||
|
||||
# Skriv ut resultatet med rätt antal decimaler
|
||||
pi_str = str(pi)
|
||||
|
||||
# Hitta decimalpunkten
|
||||
if '.' in pi_str:
|
||||
int_part, dec_part = pi_str.split('.')
|
||||
# Ta exakt decimals decimaler
|
||||
if len(dec_part) > decimals:
|
||||
dec_part = dec_part[:decimals]
|
||||
else:
|
||||
dec_part = dec_part.ljust(decimals, '0')
|
||||
print(f"{int_part}.{dec_part}")
|
||||
else:
|
||||
print(pi_str)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,66 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Unit tests for Python pi calculation using pytest
|
||||
"""
|
||||
|
||||
import subprocess
|
||||
import pytest
|
||||
|
||||
SCRIPT_PATH = "/Users/einand/Code/test/python/print_hej.py"
|
||||
|
||||
def run_script(decimals=None):
|
||||
"""Run the Python script with optional decimals argument"""
|
||||
cmd = ["python3", SCRIPT_PATH]
|
||||
if decimals is not None:
|
||||
cmd.append(str(decimals))
|
||||
result = subprocess.run(cmd, capture_output=True, text=True)
|
||||
return result.stdout.strip()
|
||||
|
||||
class TestPiCalculation:
|
||||
"""Test cases for pi calculation"""
|
||||
|
||||
def test_10_decimals(self):
|
||||
"""Test with 10 decimal places"""
|
||||
result = run_script(10)
|
||||
expected = "3.1415926535"
|
||||
assert result == expected, f"Expected {expected}, got {result}"
|
||||
|
||||
def test_5_decimals(self):
|
||||
"""Test with 5 decimal places"""
|
||||
result = run_script(5)
|
||||
expected = "3.14159"
|
||||
assert result == expected, f"Expected {expected}, got {result}"
|
||||
|
||||
def test_1_decimal(self):
|
||||
"""Test with 1 decimal place"""
|
||||
result = run_script(1)
|
||||
expected = "3.1"
|
||||
assert result == expected, f"Expected {expected}, got {result}"
|
||||
|
||||
def test_100_decimals(self):
|
||||
"""Test with 100 decimal places"""
|
||||
result = run_script(100)
|
||||
expected = "3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679"
|
||||
assert result == expected, f"Expected {expected}, got {result}"
|
||||
|
||||
def test_default_100_decimals(self):
|
||||
"""Test default (100 decimal places)"""
|
||||
result = run_script()
|
||||
expected = "3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679"
|
||||
assert result == expected, f"Expected {expected}, got {result}"
|
||||
|
||||
def test_invalid_input(self):
|
||||
"""Test with invalid input (should use default 100)"""
|
||||
result = run_script("invalid")
|
||||
expected = "3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679"
|
||||
assert result == expected, f"Expected {expected}, got {result}"
|
||||
|
||||
def test_10000_decimals(self):
|
||||
"""Test with 10000 decimal places"""
|
||||
result = run_script(10000)
|
||||
# Check length: "3." + 10000 digits = 10002 characters
|
||||
assert len(result) == 10002, f"Expected 10002 characters, got {len(result)}"
|
||||
assert result.startswith("3.14159"), f"Result should start with 3.14159, got {result[:10]}"
|
||||
|
||||
if __name__ == "__main__":
|
||||
pytest.main([__file__, "-v"])
|
||||
Executable
+123
@@ -0,0 +1,123 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Unit tests for Python pi calculation
|
||||
"""
|
||||
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
SCRIPT_DIR = "/Users/einand/Code/test/python"
|
||||
SCRIPT = f"{SCRIPT_DIR}/print_hej.py"
|
||||
|
||||
def run_test(decimals, expected_prefix):
|
||||
"""Run the program and check output"""
|
||||
result = subprocess.run(
|
||||
["python3", SCRIPT, str(decimals)],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=30
|
||||
)
|
||||
|
||||
output = result.stdout.strip()
|
||||
|
||||
if output.startswith(expected_prefix):
|
||||
print(f"✓ PASS: {decimals} decimaler - {output[:50]}...")
|
||||
return True
|
||||
else:
|
||||
print(f"✗ FAIL: {decimals} decimaler")
|
||||
print(f" Förväntade: {expected_prefix}...")
|
||||
print(f" Fick: {output[:100]}")
|
||||
return False
|
||||
|
||||
def main():
|
||||
print("=== Python Pi-beräkning Unit Tester ===")
|
||||
print()
|
||||
|
||||
tests_passed = 0
|
||||
tests_failed = 0
|
||||
|
||||
# Test 1: 10 decimaler
|
||||
print("Test 1: 10 decimaler")
|
||||
if run_test(10, "3.1415926535"):
|
||||
tests_passed += 1
|
||||
else:
|
||||
tests_failed += 1
|
||||
print()
|
||||
|
||||
# Test 2: 5 decimaler
|
||||
print("Test 2: 5 decimaler")
|
||||
if run_test(5, "3.14159"):
|
||||
tests_passed += 1
|
||||
else:
|
||||
tests_failed += 1
|
||||
print()
|
||||
|
||||
# Test 3: 1 decimal
|
||||
print("Test 3: 1 decimal")
|
||||
if run_test(1, "3.1"):
|
||||
tests_passed += 1
|
||||
else:
|
||||
tests_failed += 1
|
||||
print()
|
||||
|
||||
# Test 4: 100 decimaler
|
||||
print("Test 4: 100 decimaler")
|
||||
expected_100 = "3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067"
|
||||
if run_test(100, expected_100):
|
||||
tests_passed += 1
|
||||
else:
|
||||
tests_failed += 1
|
||||
print()
|
||||
|
||||
# Test 5: Default (100 decimaler)
|
||||
print("Test 5: Default (100 decimaler)")
|
||||
result = subprocess.run(
|
||||
["python3", SCRIPT],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=30
|
||||
)
|
||||
output = result.stdout.strip()
|
||||
if output.startswith(expected_100):
|
||||
print(f"✓ PASS: Default - {output[:50]}...")
|
||||
tests_passed += 1
|
||||
else:
|
||||
print(f"✗ FAIL: Default")
|
||||
print(f" Förväntade: {expected_100}...")
|
||||
print(f" Fick: {output[:100]}")
|
||||
tests_failed += 1
|
||||
print()
|
||||
|
||||
# Test 6: Ogiltig input
|
||||
print("Test 6: Ogiltig input (ska använda default 100)")
|
||||
result = subprocess.run(
|
||||
["python3", SCRIPT, "invalid"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=30
|
||||
)
|
||||
output = result.stdout.strip()
|
||||
if output.startswith(expected_100):
|
||||
print(f"✓ PASS: Ogiltig input hanterad korrekt")
|
||||
tests_passed += 1
|
||||
else:
|
||||
print(f"✗ FAIL: Ogiltig input")
|
||||
print(f" Förväntade: {expected_100}...")
|
||||
print(f" Fick: {output[:100]}")
|
||||
tests_failed += 1
|
||||
print()
|
||||
|
||||
# Summary
|
||||
print("=== Sammanfattning ===")
|
||||
print(f"Passerade: {tests_passed}")
|
||||
print(f"Misslyckade: {tests_failed}")
|
||||
|
||||
if tests_failed == 0:
|
||||
print("✓ Alla tester passerade!")
|
||||
sys.exit(0)
|
||||
else:
|
||||
print("✗ Några tester misslyckades")
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user