Hey OP !
Here is the French translation :
#!/usr/bin/env python3
##########################################
# 2023/Jan/28 by citb0in #
# https://github.com/citb0in #
# #
# This project is licensed under the #
# terms of the GPLv3 license. #
##########################################
import requests
import re
####################
# Some global vars #
####################
# Uncomment following line(s) for manually seting the difficulty/netrate to a value of your choice
#diff = 210453655497.094
#netrate = 1510000000000000000
# Number of chars to print as horizontal line separator, on a widescreen you could try 200
sep = 150
###########################
# Definitions (functions) #
###########################
def get_diff_and_netrate(diff_from_api=False,netrate_from_api=False):
"""Function for getting the current Bitcoin difficulty and network hashrate from API"""
global diff
global netrate
if 'diff' not in globals() or 'netrate' not in globals():
response = requests.get("https://mempool.space/api/v1/mining/hashrate/3d")
print("Execution de la requête API pour recevoir les informations du réseau Bitcoin...\n")
if response.status_code != 200:
raise Exception("Èchec, impossible de recevoir les données depuis API")
if 'diff' not in globals():
diff = response.json()["currentDifficulty"]
diff_from_api = True
if 'netrate' not in globals():
netrate = response.json()["currentHashrate"]
netrate_from_api = True
return diff, netrate, diff_from_api, netrate_from_api
def get_probability_single_hash():
"""Function to calculate the probability of a single hash solving a block"""
# the target represents the number of valid hashes
# ratio of all hashes over valid hashes => 2**256 / (0xffff*2**208 / D)
ratio = diff * 2**48 / 0xffff
prob = 1/ratio
return ratio, prob
def get_proportion_of_netrate(hashrate):
"""Function to set the hashrate of the solominer in relation to the total network rate"""
proportion = hashrate_raw / netrate * 100
if "e-" in str(proportion):
precision = 1
netrate_prec = int(str(proportion).split("e-")[1]) + precision
else:
netrate_prec = re.search(r"[1-9]", str(proportion)).start()
return proportion, netrate_prec
def format_input(hashrate_raw):
"""Function for formatting the input hashrate"""
hashrate_match = re.match(r'^\s*([0-9]+(?:\.[0-9]+)?)\s*([KMGTPEZY]?)\s*(H)?\s*(\/)?\s*(s|sec)?\s*$', hashrate_raw, flags=re.IGNORECASE)
if hashrate_match:
hashrate_nounit = float(hashrate_match.group(1))
hashrate_unit = hashrate_match.group(2).upper()
conversions = {'K': 1e3, 'M': 1e6, 'G': 1e9, 'T': 1e12, 'P': 1e15, 'E': 1e18, 'Z': 1e21, 'Y': 1e24}
if hashrate_unit in conversions:
hashrate_raw = hashrate_nounit*conversions[hashrate_unit]
else:
hashrate_raw = hashrate_nounit
else:
return None
return hashrate_nounit, hashrate_unit, hashrate_raw
def scale_unit(value):
"""Function for scaling to highest possible unit"""
units = ['', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']
value = str(value)
prefix = ''
if ' ' in value:
value, prefix = value.split()
exponent = 0
while float(value) >= 1000:
value = str(float(value) / 1000)
exponent += 1
return f"{float(value):.2f} {units[exponent]}{prefix}"
def calculate_probability(hashrate):
"""Function for calculating the probability per block avg. time of 10min for use as a base"""
expected_blockhit_time = diff * 2**48 / 0xffff / hashrate_raw / 3600
expected_blockhit_rel_net = netrate / hashrate_raw * 600
prob_per_10min = hashrate_raw / (diff * 2**48 / 0xffff) * 600
prob_per_block = prob_per_10min
if "e-" in str(prob_per_10min):
# Number of desired additional decimal places
# beginning from first occurring decimal place not equal to zero
precision = 2
prob_prec = int(str(prob_per_10min).split("e-")[1]) + precision
else:
prob_prec = 3
# Define some additional time units
prob_per_hour = prob_per_block * 6
prob_per_day = prob_per_hour * 24
prob_per_week = prob_per_day * 7
prob_per_month = prob_per_day * 30
prob_per_halfyear = prob_per_day * 182.5
prob_per_year = prob_per_day * 365
return expected_blockhit_time, expected_blockhit_rel_net, prob_per_block, prob_per_hour, prob_per_day, prob_per_week, prob_per_month, prob_per_halfyear, prob_per_year, prob_prec, netrate_prec
def probability_phrase(probability):
if probability <= 0.00001:
return "plus de chances d'être frappé par un éclair"
elif probability <= 0.0001:
return "plus de chances de gagner au Lotto"
elif probability <= 0.45:
return "les chances sont contre vous en théorie"
elif probability <= 0.55:
return "aussi probable que de tirer à pile ou face et d'obtenir face."
elif probability <= 0.00001:
return "plus probable que de trouver une aiguille dans une botte de foin."
elif probability <= 0.001:
return "aussi probable que de faire un trou en un au golf."
elif probability <= 0.000001:
return "probabilité similaire à celle de trouver un grain de sable spécifique sur une plage"
elif probability <= 0.001:
return "aussi probable que d'obtenir un score parfait à un jeu de fléchettes."
elif probability <= 0.5:
return "improbable"
else:
return "plus probable que non"
def describe_probability(prob):
if prob >1:
return "une garantie, une chose sûre à 100% - vous pouvez parier votre dernier dollar là-dessus. Ça va arriver bientôt ! YEAH ! !!"
if prob >= 0.99 and prob <= 1:
return "pratiquement certain, presque une garantie - c'est similaire à la probabilité que le soleil se lève demain."
elif prob >= 0.98 and prob < 0.99:
return "extrêmement probable, presque une certitude - c'est similaire à la probabilité qu'une équipe de football gagne un match lorsqu'elle mène de 14 points à 2 minutes de la fin."
elif prob >= 0.95 and prob < 0.98:
return "très probable, hautement probable - c'est similaire à la probabilité qu'un lanceur de baseball lance un strike avec un compte de 3-2."
elif prob >= 0.9 and prob < 0.95:
return "C'est un peu comme la probabilité qu'un golfeur fasse un putt d'un mètre cinquante."
elif prob >= 0.8 and prob < 0.9:
return "plus probable que non - c'est similaire à la probabilité qu'une équipe de basket-ball réussisse un lancer franc."
elif prob >= 0.7 and prob < 0.8:
return "C'est un peu comme la probabilité qu'une équipe de football marque un touchdown dans une zone rouge."
elif prob >= 0.6 and prob < 0.7:
return "C'est un peu comme la probabilité qu'une prévision météorologique annonce de la pluie et qu'il pleuve réellement."
elif prob >= 0.5 and prob < 0.6:
return "C'est un peu comme la probabilité de tirer à pile ou face et d'obtenir pile du premier coup."
elif prob >= 0.4 and prob < 0.5:
return "assez probable - elle est similaire à la probabilité de tirer une carte rouge d'un jeu de cartes à jouer standard"
elif prob >= 0.3 and prob < 0.4:
return "moins probable que non - c'est similaire à la probabilité qu'une équipe de baseball remporte un match alors qu'elle est menée par quatre points dans le bas de la neuvième manche."
elif prob >= 0.2 and prob < 0.3:
return "improbable, tout à fait improbable - c'est un peu comme la probabilité de deviner la bonne combinaison d'une serrure à trois chiffres du premier coup."
elif prob >= 0.1 and prob < 0.2:
return "très improbable, hautement improbable - c'est comme la probabilité d'obtenir un nombre spécifique en lançant un dé juste."
elif prob >= 0.01 and prob < 0.1:
return "Extrêmement improbable - c'est comme tirer à pile ou face et obtenir pile 10 fois de suite."
elif prob >= 0.001 and prob < 0.01:
return "pratiquement impossible - c'est comme lancer une pièce de monnaie et obtenir pile 100 fois de suite."
elif prob >= 0.0001 and prob < 0.001:
return "pratiquement impossible - il est plus probable d'être frappé par la foudre deux fois au même endroit ou de recevoir une quinte royale au poker dès la première main."
elif prob >= 0.00005 and prob < 0.0001:
return "pratiquement impossible - il est plus probable d'être frappé par la foudre dans une vie."
elif prob >= 0.00001 and prob < 0.00005:
return "pratiquement impossible - c'est comme si un individu donné était frappé par la foudre plusieurs fois dans sa vie."
elif prob >= 0.000001 and prob < 0.00001:
return "pratiquement impossible - c'est comme la probabilité de gagner un prix dans une loterie avec 1 chance sur 10 millions."
elif prob >= 0.0000005 and prob < 0.000001:
return "pratiquement impossible - c'est comme la probabilité d'obtenir une combinaison spécifique de cinq numéros sur une machine à sous."
elif prob >= 0.00000005 and prob < 0.0000005:
return "pratiquement impossible - il est plus probable de gagner le jackpot de la loterie Powerball ou Mega Millions."
elif prob < 0.00000005:
return "infiniment petit - c'est similaire à la probabilité de trouver un atome spécifique parmi tous les atomes de l'univers."
else:
return "discutable ? !"
#######################################
# Program flow / variable assignments #
#######################################
# User input hash rate
hashrate_input = input("Entrer le hashrate/sec de votre équipement solo : ")
# Call the functions and fill the variables
diff, netrate, diff_from_api, netrate_from_api = get_diff_and_netrate()
diff_formatted, netrate_formatted = scale_unit(diff), scale_unit(netrate)+"H/s"
hashrate_nounit, hashrate_unit, hashrate_raw = format_input(hashrate_input)
proportion, netrate_prec = get_proportion_of_netrate(hashrate_raw)
expected_blockhit_time, expected_blockhit_rel_net, prob_per_block, prob_per_hour, prob_per_day, prob_per_week, prob_per_month, prob_per_halfyear, prob_per_year, prob_prec, netrate_prec = calculate_probability(hashrate_raw)
single_ratio, single_prob = get_probability_single_hash()
##########
# Output #
##########
print(f"{'Choisir la difficulté manuellement:' if not diff_from_api else 'La difficulté actuelle de Bitcoin est :'} {diff:,.3f} ({diff_formatted})\n{'Hashrate total du réseau Bitcoin:' if not netrate_from_api else 'Le hashrate total de tout le réseau Bitcoin:'} {netrate:,.2f} ({netrate_formatted})\n")
print('\nLe ratio de tous les hash par rapport aux shares valides est de:\n1 hash sur {:,.0f}'.format(single_ratio),'donnera un block potentiellement valide.\nOu chaque hash a une chance de miner un block de {:,.30f} %'.format(single_prob))
print('=' * sep)
print(f'\nLe hashrate entré de {hashrate_nounit} {hashrate_unit}H/sec équivaut à: {hashrate_raw:,.2f} hash/sec\n Le ratio de votre hashrate par rapport au réseau BTC est de: {proportion:,.{netrate_prec}f} %\n')
print('=' * sep)
# Display probability as decimal value, percentage, "1 in x" format and as description / analogy text
print(f'Chances par 10 min: {prob_per_block:,.{prob_prec}f} ({prob_per_block*100:,.{prob_prec}f} %) ou 1 sur {1/prob_per_block:,.0f}')
print(f'\nLa chance de miner un block avec le hashrate donné dans un délai de 1 an est similaire à la probabilité de choisir une boule rouge gagnante dans un bocal contenant {str(describe_probability(prob_per_block))}')
print('=' * sep)
print(f'Chances par heures: {prob_per_hour:,.{prob_prec}f} ({prob_per_hour*100:,.2f} %) ou 1 sur {1/prob_per_hour:,.0f}')
print(f'\nLa chance de miner un block avec le hashrate donné dans un délai de 1 an est similaire à la probabilité de choisir une boule rouge gagnante dans un bocal contenant {int(round(1/prob_per_hour,0)):,} boules blanches. Ou alors, la probabilité que cela se produise est de {str(describe_probability(prob_per_hour))}')
print('=' * sep)
print(f'Chances par jours: {prob_per_day:,.{prob_prec}f} ({prob_per_day*100:,.2f} %) ou 1 sur {1/prob_per_day:,.0f}')
print(f'\nLa chance de miner un block avec le hashrate donné dans un délai de 1 an est similaire à la probabilité de choisir une boule rouge gagnante dans un bocal contenant {int(round(1/prob_per_day,0)):,} boules blanches. Ou alors, la probabilité que cela se produise est de {str(describe_probability(prob_per_day))}')
print('=' * sep)
print(f'Chances par semaines: {prob_per_week:,.{prob_prec}f} ({prob_per_week*100:,.2f} %) ou 1 sur {1/prob_per_week:,.0f}')
print(f'\nLa chance de miner un block avec le hashrate donné dans un délai de 1 an est similaire à la probabilité de choisir une boule rouge gagnante dans un bocal contenant {int(round(1/prob_per_week,0)):,} boules blanches. Ou alors, la probabilité que cela se produise est de {str(describe_probability(prob_per_week))}')
print('=' * sep)
print(f'Chances par mois: {prob_per_month:,.{prob_prec}f} ({prob_per_month*100:,.2f} %) ou 1 sur {1/prob_per_month:,.0f}')
print(f'\nLa chance de miner un block avec le hashrate donné dans un délai de 1 an est similaire à la probabilité de choisir une boule rouge gagnante dans un bocal contenant {int(round(1/prob_per_month,0)):,} boules blanches. Ou alors, la probabilité que cela se produise est de {str(describe_probability(prob_per_month))}')
print('=' * sep)
print(f'Chances par demi-années: {prob_per_halfyear:,.{prob_prec}f} ({prob_per_halfyear*100:,.2f} %) ou 1 sur {1/prob_per_halfyear:,.0f}')
print(f'\nLa chance de miner un block avec le hashrate donné dans un délai de 1 an est similaire à la probabilité de choisir une boule rouge gagnante dans un bocal contenant {int(round(1/prob_per_halfyear,0)):,} boules blanches. Ou alors, la probabilité que cela se produise est de {str(describe_probability(prob_per_halfyear))}')
print('=' * sep)
print(f'Chances par années: {prob_per_year:,.{prob_prec}f} ({prob_per_year*100:,.2f} %) ou 1 sur {1/prob_per_year:,.0f}')
print(f'\nLa chance de miner un block avec le hashrate donné dans un délai de 1 an est similaire à la probabilité de choisir une boule rouge gagnante dans un bocal contenant {int(round(1/prob_per_year,0)):,} boules blanches. Ou alors, la probabilité que cela se produise est de {str(describe_probability(prob_per_year))}')
print('=' * sep)
print(f'Temps attendu moyen pour miner un block :\n{expected_blockhit_time*3600:,.1f} sec = {expected_blockhit_time*60:,.1f} min = {expected_blockhit_time:,.1f} h = {expected_blockhit_time/24:,.1f} jours = {expected_blockhit_time/24/7:,.1f} semaines = {expected_blockhit_time/24/7/4.34:,.1f} mois = {expected_blockhit_time/24/7/4.34/12:,.1f} années\n')
print(f'Temps attendu moyen (en fonction de tout le réseau):\n{expected_blockhit_rel_net:,.1f} sec = {expected_blockhit_rel_net/60:,.1f} min = {expected_blockhit_rel_net/60/60:,.1f} h = {expected_blockhit_rel_net/60/60/24:,.1f} jours = {expected_blockhit_rel_net/60/60/24/7:,.1f} semaines = {expected_blockhit_rel_net/60/60/24/7/4.34:,.1f} mois = {expected_blockhit_rel_net/60/60/24/7/4.34/12:,.1f} années')
print('=' * sep)