Distributed and decentralized pi calculation
1from math import factorial
2from decimal import Decimal, getcontext
3import time
4import threading
5import requests
6import sys
7import urllib.request
8
9print("Pistributed, an app to calculate Pi with distributed power.")
10print("Do not run on systems owned by another entity, entities, person, or people, without explicit permission from them.")
11print("""This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
12
13This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.""")
16print("By continuing, you agree to these terms, disclaimers, and acknowledge that there is NO WARRANTY.")
17input("I agree, and would like to continue. (to continue, press enter) ")
18print("Thanks for confirming! I just need one more thing.")
19print("Make sure you trust the server! I do not control any of them and am not responsible for anything on external websites and/or servers.")
20server = input("What is the server URL that you'd like to connect to? (ex: https://example.com, http://localhost:5000) ")
21print("Alright! Thanks. Let the calculating begin :D (to exit, run ctrl+c or close terminal)")
22print("-------------------")
23
24global pi_val
25pi_val = None
26
27for line in urllib.request.urlopen(server + "/api/getmultiplier"):
28 multiplier = int(line.decode('utf-8'))
29 print("Multiplier from server is " + str(multiplier))
30
31try:
32 def calc(n, prec):
33 getcontext().prec = prec
34 t = Decimal(0)
35 pi = Decimal(0)
36 deno = Decimal(0)
37 for k in range(n):
38 t = ((-1)**k) * (factorial(6*k)) * (13591409 + 545140134*k)
39 deno = factorial(3*k) * (factorial(k)**3) * (640320**(3*k))
40 pi += Decimal(t) / Decimal(deno)
41 pi = pi * Decimal(12) / Decimal(640320**Decimal(1.5))
42 pi = 1/pi * multiplier
43 return pi
44
45 def upload():
46 time.sleep(1)
47 while True:
48 print(">> checking and uploading latest calculation")
49 response = requests.get(server + "/api/getpi")
50 print(response.text)
51 replen = len(response.text)
52 pilen = len(str(pi_val))
53 if response.text == "No clients have connected yet. Become one of the first!":
54 print("server pi doesn't exist! uploading")
55 data = {'pi': str(pi_val)}
56 print(data)
57 response = requests.post(server + "/api/postpi", data=data)
58 print(response.text)
59 else:
60 if replen > pilen:
61 print("server pi length is greater than local pi length! not uploading")
62 elif pilen > replen:
63 print("local pi length longer than server pi length! uploading")
64 data = {'pi': str(pi_val)}
65 response = requests.post(server + "/api/postpi", data=data)
66 print(response.text)
67 time.sleep(60)
68
69 threading.Thread(target=upload, daemon=True).start()
70
71 calculation = 1
72 precision = 10
73
74 while True:
75 pi_val = calc(calculation, precision)
76 print(pi_val)
77 calculation += 1
78 precision += 5
79 time.sleep(5)
80except:
81 print("\n")
82 print("Saving your latest Pi to Pi.txt and exiting...")
83 with open("pi.txt", "w") as f:
84 f.write(str(pi_val))
85 sys.exit()