[PYTHON] Let's turn the air gacha

Introduction

I learned a lot in the crap, so I shared it

Idea ancestors 30 consecutive gachas of air components

How far can you say the elements that make up air? Nitrogen, oxygen, carbon dioxide, argon ... I didn't know the rest.

You can spin the gacha at this site.

Air gacha emission rate

The components that make up air are [air-Wikipedia](https://ja.wikipedia.org/wiki/%E7%A9%BA%E6%B0%97#%E6%88%90%E5%88% According to 86)

component Chemical formula Volume ratio ratio (vol)%)
nitrogen N2 78.084
oxygen O2 20.9476
Argon Ar 0.934
carbon dioxide CO2 0.0390
neon Ne 0.001818
helium He 0.000524
methane CH4 0.000181
krypton Kr 0.000114
Sulfur dioxide SO2 0.0001
hydrogen H2 0.00005
Nitrous oxide N2O 0.000032
xenon Xe 0.0000087
ozone O3 0.000007
Nitrogen dioxide NO2 0.000002
Iodine I2 0.000001

The volume ratio of the components that make up the air is used as the gacha emission rate.

Source code

air_gacha.py


"""
https://ja.wikipedia.org/wiki/%E7%A9%BA%E6%B0%97#%E6%88%90%E5%88%86
table 1:Main composition of dry air (International Standard Atmosphere, 1975)
Component chemical formula Volume ratio ratio (vol)%) Ppm ppb Remarks
Nitrogen N2 78.084	780,840	-	[12]
Oxygen O2 20.9476	209,476	-	[12]
Argon Ar 0.934	9,340	-	[12]
Carbon dioxide CO2 0.0390	390	-	+*2011 value[13][12][Note 2]
Neon Ne 0.001818	18.18	-	[12]
Helium He 0.000524	5.24	-	[12]
Methane CH4 0.000181	1.81	1813±2	+2011 value[13][12][Note 3]
Krypton Kr 0.000114	1.14	-	[12]
Sulfur dioxide SO2 0.0001>	1>	-	*[12]
Hydrogen H2 0.00005	0.5	-	[12]
Nitrous Oxide N2O 0.000032	0.32	324.2±0.1	+*2011 value[13][12][Note 4]
Xenon Xe 0.0000087	0.087	87	[12]
Ozone O3 0.000007>	0.07>	70>	*[Note 5][12]
Nitrogen dioxide NO2 0.000002>	0.02>	20>	*[12]
Iodine I2 0.000001>	0.01>	10>	*[12]
"""
import random
import time
from decimal import Decimal
dic = {"Nitrogen N2":78.084, "Oxygen O2":20.9476, "Argon Ar":0.934, "Carbon dioxide CO2":0.0390, "Neon Ne":0.001818, "Helium He":0.000524, "Methane CH4":0.000181, "Krypton Kr":0.000114, "Sulfur dioxide SO2":0.0001, "Hydrogen H2":0.00005, "一酸化二Nitrogen N2O":0.000032, "Xenon Xe":0.0000087, "Ozone O3":0.000007, "Nitrogen dioxide NO2":0.000002, "Iodine I2":0.000001}
com = ["nitrogen", "oxygen", "Argon", "carbon dioxide", "neon", "helium", "methane", "krypton", "Sulfur dioxide", "hydrogen", "一酸化二nitrogen", "xenon", "ozone", "二酸化nitrogen", "Iodine"]
che = ["N2", "O2", "Ar", "CO2", "Ne", "He", "CH4", "Kr", "SO2", "H2", "N2O", "Xe", "O3", "NO2", "I2"]
keys = []
for i in dic.keys():
    keys.append(i)
su = 0
for i in dic.keys():
    su += int(Decimal(str(dic[i]))*(10**7))
    dic[i] = int(Decimal(str(dic[i]))*(10**7))
out = [0 for i in range(len(keys))]
que = 10**6
for q in range(que): #10**6 is 10 seconds, 10**7 takes 2 minutes
    t = time.perf_counter()
    random.seed(t)
    ra = random.randint(0, su)
    res = 0
    if 0 <= ra < dic[keys[0]]:
        out[0] += 1
    else:
        res += dic[keys[0]]
        for i in range(1, len(keys)):
            """
            if i >= 5:
                print("!!!!!!!!!!!!")
                print(out)
            """
            if res <= ra < res + dic[keys[i]]:
                out[i] += 1
                break
            res += dic[keys[i]]

#Half size,Full-width characters"Fluctuation"Function to format
import unicodedata
def left(digit, msg):
    for c in msg:
        if unicodedata.east_asian_width(c) in ('F', 'W', 'A'):
            digit -= 2
        else:
            digit -= 1
    return msg + ' '*digit

print("Air gacha" + "{:.0e}".format(que) + "(" + str(que) + ")" + "Communicating")
for i in range(len(keys)):
    print(left(12, com[i]), left(3, che[i]), "{:>7}".format(out[i]))

Execution result

When que = 10 ** 6

Air gacha 1e+06(1000000)Communicating
Nitrogen N2 780580
Oxygen O2 209579
Argon Ar 9406
Carbon dioxide CO2 391
Neon Ne 32
Helium He 5
Methane CH4 3
Krypton Kr 1
Sulfur dioxide SO2 2
Hydrogen H2 1
Nitrous Oxide N2O 0
Xenon Xe 0
Ozone O3 0
Nitrogen dioxide NO2 0
Iodine I2 0

When que = 10 ** 7

Air gacha 1e+07(10000000)Communicating
Nitrogen N2 7809540
Oxygen O2 2092942
Argon Ar 93396
Carbon dioxide CO2 3808
Neon Ne 214
Helium He 54
Methane CH4 12
Krypton Kr 11
Sulfur dioxide SO2 6
Hydrogen H2 10
Nitrous Oxide N2O 6
Xenon Xe 1
Ozone O3 0
Nitrogen dioxide NO2 0
Iodine I2 0

Attention point

Floating point error

Be careful when handling float types. In the world of binary numbers in computers, when dealing with decimal numbers, it is not possible to deal with accurate values.

print(0.1 + 0.2)
#Execution result: 0.30000000000000004

Where did 0.00000000000000004 !!!!!!!! So when dealing with decimals in Python, it's a good idea to use Decimal (). 15. Floating Point Arithmetic, Its Problems and Limitations — Python 3.8.3 Documentation

from decimal import Decimal
print(Decimal("0.1") + Decimal("0.2"))
#Execution result: 0.3

In the code

for i in dic.keys():
    su += int(Decimal(str(dic[i]))*(10**7))
    dic[i] = int(Decimal(str(dic[i]))*(10**7))

The part marked with corresponds to avoiding errors. When trying to handle the emission rate as an integer by multiplying by 10 ** 7, an error will occur if it is a floating point type because the calculation is being performed.

Random creation

[Is time.time () not very accurate? --Qiita] (https://qiita.com/takeopy/items/170d0e1ddbf02ef9fbb9) Since the for statement turns too quickly, time.time () will likely generate the same time and have the same seed value (which was the case in the Windows environment). Therefore, use the highly accurate time.perf_counter ().

t = time.perf_counter()
random.seed(t)
ra = random.randint(0, su)

Shape the "fluctuation" of characters by half-width and full-width

Displays full-width and half-width characters aligned using Python's unicodedata library --Qiita Try to make the output easy to see.

for i in range(len(keys)):
    print(left(12, com[i]), left(3, che[i]), "{:>7}".format(out[i]))

Impressions

The probability is biased.

Recommended Posts

Let's turn the air gacha
Let's search from the procession
Turn off the brew warning
Django-TodoList② ~ Let's display the details page ~
Let's touch on the Go language
Let's cut the face from the image
Let's display the map using Basemap
Let's decide the winner of bingo