Skip to content

Commit 84b6852

Browse files
authored
Graham's Law (TheAlgorithms#8162)
* grahams law * doctest and type hints * doctest formatting * peer review updates
1 parent a213cea commit 84b6852

File tree

1 file changed

+208
-0
lines changed

1 file changed

+208
-0
lines changed

physics/grahams_law.py

+208
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
"""
2+
Title: Graham's Law of Effusion
3+
4+
Description: Graham's law of effusion states that the rate of effusion of a gas is
5+
inversely proportional to the square root of the molar mass of its particles:
6+
7+
r1/r2 = sqrt(m2/m1)
8+
9+
r1 = Rate of effusion for the first gas.
10+
r2 = Rate of effusion for the second gas.
11+
m1 = Molar mass of the first gas.
12+
m2 = Molar mass of the second gas.
13+
14+
(Description adapted from https://en.wikipedia.org/wiki/Graham%27s_law)
15+
"""
16+
17+
from math import pow, sqrt
18+
19+
20+
def validate(*values: float) -> bool:
21+
"""
22+
Input Parameters:
23+
-----------------
24+
effusion_rate_1: Effustion rate of first gas (m^2/s, mm^2/s, etc.)
25+
effusion_rate_2: Effustion rate of second gas (m^2/s, mm^2/s, etc.)
26+
molar_mass_1: Molar mass of the first gas (g/mol, kg/kmol, etc.)
27+
molar_mass_2: Molar mass of the second gas (g/mol, kg/kmol, etc.)
28+
29+
Returns:
30+
--------
31+
>>> validate(2.016, 4.002)
32+
True
33+
>>> validate(-2.016, 4.002)
34+
False
35+
>>> validate()
36+
False
37+
"""
38+
result = len(values) > 0 and all(value > 0.0 for value in values)
39+
return result
40+
41+
42+
def effusion_ratio(molar_mass_1: float, molar_mass_2: float) -> float | ValueError:
43+
"""
44+
Input Parameters:
45+
-----------------
46+
molar_mass_1: Molar mass of the first gas (g/mol, kg/kmol, etc.)
47+
molar_mass_2: Molar mass of the second gas (g/mol, kg/kmol, etc.)
48+
49+
Returns:
50+
--------
51+
>>> effusion_ratio(2.016, 4.002)
52+
1.408943
53+
>>> effusion_ratio(-2.016, 4.002)
54+
ValueError('Input Error: Molar mass values must greater than 0.')
55+
>>> effusion_ratio(2.016)
56+
Traceback (most recent call last):
57+
...
58+
TypeError: effusion_ratio() missing 1 required positional argument: 'molar_mass_2'
59+
"""
60+
return (
61+
round(sqrt(molar_mass_2 / molar_mass_1), 6)
62+
if validate(molar_mass_1, molar_mass_2)
63+
else ValueError("Input Error: Molar mass values must greater than 0.")
64+
)
65+
66+
67+
def first_effusion_rate(
68+
effusion_rate: float, molar_mass_1: float, molar_mass_2: float
69+
) -> float | ValueError:
70+
"""
71+
Input Parameters:
72+
-----------------
73+
effusion_rate: Effustion rate of second gas (m^2/s, mm^2/s, etc.)
74+
molar_mass_1: Molar mass of the first gas (g/mol, kg/kmol, etc.)
75+
molar_mass_2: Molar mass of the second gas (g/mol, kg/kmol, etc.)
76+
77+
Returns:
78+
--------
79+
>>> first_effusion_rate(1, 2.016, 4.002)
80+
1.408943
81+
>>> first_effusion_rate(-1, 2.016, 4.002)
82+
ValueError('Input Error: Molar mass and effusion rate values must greater than 0.')
83+
>>> first_effusion_rate(1)
84+
Traceback (most recent call last):
85+
...
86+
TypeError: first_effusion_rate() missing 2 required positional arguments: \
87+
'molar_mass_1' and 'molar_mass_2'
88+
>>> first_effusion_rate(1, 2.016)
89+
Traceback (most recent call last):
90+
...
91+
TypeError: first_effusion_rate() missing 1 required positional argument: \
92+
'molar_mass_2'
93+
"""
94+
return (
95+
round(effusion_rate * sqrt(molar_mass_2 / molar_mass_1), 6)
96+
if validate(effusion_rate, molar_mass_1, molar_mass_2)
97+
else ValueError(
98+
"Input Error: Molar mass and effusion rate values must greater than 0."
99+
)
100+
)
101+
102+
103+
def second_effusion_rate(
104+
effusion_rate: float, molar_mass_1: float, molar_mass_2: float
105+
) -> float | ValueError:
106+
"""
107+
Input Parameters:
108+
-----------------
109+
effusion_rate: Effustion rate of second gas (m^2/s, mm^2/s, etc.)
110+
molar_mass_1: Molar mass of the first gas (g/mol, kg/kmol, etc.)
111+
molar_mass_2: Molar mass of the second gas (g/mol, kg/kmol, etc.)
112+
113+
Returns:
114+
--------
115+
>>> second_effusion_rate(1, 2.016, 4.002)
116+
0.709752
117+
>>> second_effusion_rate(-1, 2.016, 4.002)
118+
ValueError('Input Error: Molar mass and effusion rate values must greater than 0.')
119+
>>> second_effusion_rate(1)
120+
Traceback (most recent call last):
121+
...
122+
TypeError: second_effusion_rate() missing 2 required positional arguments: \
123+
'molar_mass_1' and 'molar_mass_2'
124+
>>> second_effusion_rate(1, 2.016)
125+
Traceback (most recent call last):
126+
...
127+
TypeError: second_effusion_rate() missing 1 required positional argument: \
128+
'molar_mass_2'
129+
"""
130+
return (
131+
round(effusion_rate / sqrt(molar_mass_2 / molar_mass_1), 6)
132+
if validate(effusion_rate, molar_mass_1, molar_mass_2)
133+
else ValueError(
134+
"Input Error: Molar mass and effusion rate values must greater than 0."
135+
)
136+
)
137+
138+
139+
def first_molar_mass(
140+
molar_mass: float, effusion_rate_1: float, effusion_rate_2: float
141+
) -> float | ValueError:
142+
"""
143+
Input Parameters:
144+
-----------------
145+
molar_mass: Molar mass of the first gas (g/mol, kg/kmol, etc.)
146+
effusion_rate_1: Effustion rate of first gas (m^2/s, mm^2/s, etc.)
147+
effusion_rate_2: Effustion rate of second gas (m^2/s, mm^2/s, etc.)
148+
149+
Returns:
150+
--------
151+
>>> first_molar_mass(2, 1.408943, 0.709752)
152+
0.507524
153+
>>> first_molar_mass(-1, 2.016, 4.002)
154+
ValueError('Input Error: Molar mass and effusion rate values must greater than 0.')
155+
>>> first_molar_mass(1)
156+
Traceback (most recent call last):
157+
...
158+
TypeError: first_molar_mass() missing 2 required positional arguments: \
159+
'effusion_rate_1' and 'effusion_rate_2'
160+
>>> first_molar_mass(1, 2.016)
161+
Traceback (most recent call last):
162+
...
163+
TypeError: first_molar_mass() missing 1 required positional argument: \
164+
'effusion_rate_2'
165+
"""
166+
return (
167+
round(molar_mass / pow(effusion_rate_1 / effusion_rate_2, 2), 6)
168+
if validate(molar_mass, effusion_rate_1, effusion_rate_2)
169+
else ValueError(
170+
"Input Error: Molar mass and effusion rate values must greater than 0."
171+
)
172+
)
173+
174+
175+
def second_molar_mass(
176+
molar_mass: float, effusion_rate_1: float, effusion_rate_2: float
177+
) -> float | ValueError:
178+
"""
179+
Input Parameters:
180+
-----------------
181+
molar_mass: Molar mass of the first gas (g/mol, kg/kmol, etc.)
182+
effusion_rate_1: Effustion rate of first gas (m^2/s, mm^2/s, etc.)
183+
effusion_rate_2: Effustion rate of second gas (m^2/s, mm^2/s, etc.)
184+
185+
Returns:
186+
--------
187+
>>> second_molar_mass(2, 1.408943, 0.709752)
188+
1.970351
189+
>>> second_molar_mass(-2, 1.408943, 0.709752)
190+
ValueError('Input Error: Molar mass and effusion rate values must greater than 0.')
191+
>>> second_molar_mass(1)
192+
Traceback (most recent call last):
193+
...
194+
TypeError: second_molar_mass() missing 2 required positional arguments: \
195+
'effusion_rate_1' and 'effusion_rate_2'
196+
>>> second_molar_mass(1, 2.016)
197+
Traceback (most recent call last):
198+
...
199+
TypeError: second_molar_mass() missing 1 required positional argument: \
200+
'effusion_rate_2'
201+
"""
202+
return (
203+
round(pow(effusion_rate_1 / effusion_rate_2, 2) / molar_mass, 6)
204+
if validate(molar_mass, effusion_rate_1, effusion_rate_2)
205+
else ValueError(
206+
"Input Error: Molar mass and effusion rate values must greater than 0."
207+
)
208+
)

0 commit comments

Comments
 (0)