From 3b864447dc5923a837d71a8cb52ebbe9876d6894 Mon Sep 17 00:00:00 2001 From: Blake Reimer Date: Mon, 27 Feb 2023 22:11:29 +0000 Subject: [PATCH 1/4] grahams law --- physics/grahams_law.py | 191 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100644 physics/grahams_law.py diff --git a/physics/grahams_law.py b/physics/grahams_law.py new file mode 100644 index 000000000000..5b6e0bc2444b --- /dev/null +++ b/physics/grahams_law.py @@ -0,0 +1,191 @@ +""" +Title: Graham's Law of Effusion + +Description: Graham's law of effusion states that the rate of effusion of a gas is +inversely proportional to the square root of the molar mass of its particles: + +r1/r2 = sqrt(m2/m1) + +r1 = Rate of effusion for the first gas. +r2 = Rate of effusion for the second gas. +m1 = Molar mass of the first gas. +m2 = Molar mass of the second gas. + +(Description adapted from https://en.wikipedia.org/wiki/Graham%27s_law) +""" + +from math import pow, sqrt + + +def validate(*values) -> bool: + for value in values: + if value >= 0.0: + return True + else: + raise ValueError( + """Invalid inputs. Effusion rates and molar masses must be a positive + value.""" + ) + + return False + + +def effusion_ratio(molar_mass_1: float, molar_mass_2: float) -> float: + """ + Input Parameters: + ----------------- + molar_mass_1: Molar mass of the first gas (g/mol, kg/kmol, etc.) + molar_mass_2: Molar mass of the second gas (g/mol, kg/kmol, etc.) + + Returns: + -------- + >>> effusion_ratio(2.016, 4.002) + 1.408943 + >>> effusion_ratio(-2.016, 4.002) + Traceback (most recent call last): + ... + ValueError: Invalid inputs. Effusion rates and molar masses must be a positive + value. + >>> effusion_ratio(2.016) + Traceback (most recent call last): + ... + TypeError: effusion_ratio() missing 1 required positional argument: 'molar_mass_2' + """ + validate(molar_mass_1, molar_mass_2) + return round(sqrt(molar_mass_2 / molar_mass_1), 6) + + +def first_effusion_rate( + effusion_rate: float, molar_mass_1: float, molar_mass_2: float +) -> float: + """ + Input Parameters: + ----------------- + effusion_rate: Effustion rate of second gas (m^2/s, mm^2/s, etc.) + molar_mass_1: Molar mass of the first gas (g/mol, kg/kmol, etc.) + molar_mass_2: Molar mass of the second gas (g/mol, kg/kmol, etc.) + + Returns: + -------- + >>> first_effusion_rate(1, 2.016, 4.002) + 1.408943 + >>> first_effusion_rate(-1, 2.016, 4.002) + Traceback (most recent call last): + ... + ValueError: Invalid inputs. Effusion rates and molar masses must be a positive + value. + >>> first_effusion_rate(1) + Traceback (most recent call last): + ... + TypeError: first_effusion_rate() missing 2 required positional arguments: + 'molar_mass_1' and 'molar_mass_2' + >>> first_effusion_rate(1, 2.016) + Traceback (most recent call last): + ... + TypeError: first_effusion_rate() missing 1 required positional argument: + 'molar_mass_2' + """ + validate(effusion_rate, molar_mass_1, molar_mass_2) + return round(effusion_rate * sqrt(molar_mass_2 / molar_mass_1), 6) + + +def second_effusion_rate( + effusion_rate: float, molar_mass_1: float, molar_mass_2: float +) -> float: + """ + Input Parameters: + ----------------- + effusion_rate: Effustion rate of second gas (m^2/s, mm^2/s, etc.) + molar_mass_1: Molar mass of the first gas (g/mol, kg/kmol, etc.) + molar_mass_2: Molar mass of the second gas (g/mol, kg/kmol, etc.) + + Returns: + -------- + >>> second_effusion_rate(1, 2.016, 4.002) + 0.709752 + >>> second_effusion_rate(-1, 2.016, 4.002) + Traceback (most recent call last): + ... + ValueError: Invalid inputs. Effusion rates and molar masses must be a positive + value. + >>> second_effusion_rate(1) + Traceback (most recent call last): + ... + TypeError: second_effusion_rate() missing 2 required positional arguments: + 'molar_mass_1' and 'molar_mass_2' + >>> second_effusion_rate(1, 2.016) + Traceback (most recent call last): + ... + TypeError: second_effusion_rate() missing 1 required positional argument: + 'molar_mass_2' + """ + validate(effusion_rate, molar_mass_1, molar_mass_2) + return round(effusion_rate / sqrt(molar_mass_2 / molar_mass_1), 6) + + +def first_molar_mass( + molar_mass: float, effusion_rate_1: float, effusion_rate_2: float +) -> float: + """ + Input Parameters: + ----------------- + molar_mass: Molar mass of the first gas (g/mol, kg/kmol, etc.) + effusion_rate_1: Effustion rate of first gas (m^2/s, mm^2/s, etc.) + effusion_rate_2: Effustion rate of second gas (m^2/s, mm^2/s, etc.) + + Returns: + -------- + >>> first_molar_mass(2, 1.408943, 0.709752) + 0.507524 + >>> first_molar_mass(-1, 2.016, 4.002) + Traceback (most recent call last): + ... + ValueError: Invalid inputs. Effusion rates and molar masses must be a positive + value. + >>> first_molar_mass(1) + Traceback (most recent call last): + ... + TypeError: first_molar_mass() missing 2 required positional arguments: + 'effusion_rate_1' and 'effusion_rate_2' + >>> first_molar_mass(1, 2.016) + Traceback (most recent call last): + ... + TypeError: first_molar_mass() missing 1 required positional argument: + 'effusion_rate_2' + """ + validate(molar_mass, effusion_rate_1, effusion_rate_2) + return round(molar_mass / pow(effusion_rate_1 / effusion_rate_2, 2), 6) + + +def second_molar_mass( + molar_mass: float, effusion_rate_1: float, effusion_rate_2: float +) -> float: + """ + Input Parameters: + ----------------- + molar_mass: Molar mass of the first gas (g/mol, kg/kmol, etc.) + effusion_rate_1: Effustion rate of first gas (m^2/s, mm^2/s, etc.) + effusion_rate_2: Effustion rate of second gas (m^2/s, mm^2/s, etc.) + + Returns: + -------- + >>> second_molar_mass(2, 1.408943, 0.709752) + 1.970351 + >>> second_molar_mass(-2, 1.408943, 0.709752) + Traceback (most recent call last): + ... + ValueError: Invalid inputs. Effusion rates and molar masses must be a positive + value. + >>> second_molar_mass(1) + Traceback (most recent call last): + ... + TypeError: second_molar_mass() missing 2 required positional arguments: + 'effusion_rate_1' and 'effusion_rate_2' + >>> second_molar_mass(1, 2.016) + Traceback (most recent call last): + ... + TypeError: second_molar_mass() missing 1 required positional argument: + 'effusion_rate_2' + """ + validate(molar_mass, effusion_rate_1, effusion_rate_2) + return round(pow(effusion_rate_1 / effusion_rate_2, 2) / molar_mass, 6) From fc0cbefbe3eb5598cd8865acea64c14c7c66f2d1 Mon Sep 17 00:00:00 2001 From: Blake Reimer Date: Mon, 27 Feb 2023 22:23:18 +0000 Subject: [PATCH 2/4] doctest and type hints --- physics/grahams_law.py | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/physics/grahams_law.py b/physics/grahams_law.py index 5b6e0bc2444b..e13facbe703a 100644 --- a/physics/grahams_law.py +++ b/physics/grahams_law.py @@ -17,7 +17,27 @@ from math import pow, sqrt -def validate(*values) -> bool: +def validate(*values: float) -> bool: + """ + Input Parameters: + ----------------- + effusion_rate_1: Effustion rate of first gas (m^2/s, mm^2/s, etc.) + effusion_rate_2: Effustion rate of second gas (m^2/s, mm^2/s, etc.) + molar_mass_1: Molar mass of the first gas (g/mol, kg/kmol, etc.) + molar_mass_2: Molar mass of the second gas (g/mol, kg/kmol, etc.) + + Returns: + -------- + >>> validate(2.016, 4.002) + True + >>> validate(-2.016, 4.002) + Traceback (most recent call last): + ... + ValueError: Invalid inputs. Effusion rates and molar masses must be a positive + value. + >>> validate() + False + """ for value in values: if value >= 0.0: return True From df3ef08ac6ea5212d1d105b20dbc963646e1f815 Mon Sep 17 00:00:00 2001 From: Blake Reimer Date: Mon, 27 Feb 2023 23:03:16 +0000 Subject: [PATCH 3/4] doctest formatting --- physics/grahams_law.py | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/physics/grahams_law.py b/physics/grahams_law.py index e13facbe703a..df318a349372 100644 --- a/physics/grahams_law.py +++ b/physics/grahams_law.py @@ -97,13 +97,13 @@ def first_effusion_rate( >>> first_effusion_rate(1) Traceback (most recent call last): ... - TypeError: first_effusion_rate() missing 2 required positional arguments: - 'molar_mass_1' and 'molar_mass_2' + TypeError: first_effusion_rate() missing 2 required positional arguments: \ +'molar_mass_1' and 'molar_mass_2' >>> first_effusion_rate(1, 2.016) Traceback (most recent call last): ... - TypeError: first_effusion_rate() missing 1 required positional argument: - 'molar_mass_2' + TypeError: first_effusion_rate() missing 1 required positional argument: \ +'molar_mass_2' """ validate(effusion_rate, molar_mass_1, molar_mass_2) return round(effusion_rate * sqrt(molar_mass_2 / molar_mass_1), 6) @@ -131,13 +131,13 @@ def second_effusion_rate( >>> second_effusion_rate(1) Traceback (most recent call last): ... - TypeError: second_effusion_rate() missing 2 required positional arguments: - 'molar_mass_1' and 'molar_mass_2' + TypeError: second_effusion_rate() missing 2 required positional arguments: \ +'molar_mass_1' and 'molar_mass_2' >>> second_effusion_rate(1, 2.016) Traceback (most recent call last): ... - TypeError: second_effusion_rate() missing 1 required positional argument: - 'molar_mass_2' + TypeError: second_effusion_rate() missing 1 required positional argument: \ +'molar_mass_2' """ validate(effusion_rate, molar_mass_1, molar_mass_2) return round(effusion_rate / sqrt(molar_mass_2 / molar_mass_1), 6) @@ -165,13 +165,13 @@ def first_molar_mass( >>> first_molar_mass(1) Traceback (most recent call last): ... - TypeError: first_molar_mass() missing 2 required positional arguments: - 'effusion_rate_1' and 'effusion_rate_2' + TypeError: first_molar_mass() missing 2 required positional arguments: \ +'effusion_rate_1' and 'effusion_rate_2' >>> first_molar_mass(1, 2.016) Traceback (most recent call last): ... - TypeError: first_molar_mass() missing 1 required positional argument: - 'effusion_rate_2' + TypeError: first_molar_mass() missing 1 required positional argument: \ +'effusion_rate_2' """ validate(molar_mass, effusion_rate_1, effusion_rate_2) return round(molar_mass / pow(effusion_rate_1 / effusion_rate_2, 2), 6) @@ -199,13 +199,13 @@ def second_molar_mass( >>> second_molar_mass(1) Traceback (most recent call last): ... - TypeError: second_molar_mass() missing 2 required positional arguments: - 'effusion_rate_1' and 'effusion_rate_2' + TypeError: second_molar_mass() missing 2 required positional arguments: \ +'effusion_rate_1' and 'effusion_rate_2' >>> second_molar_mass(1, 2.016) Traceback (most recent call last): ... - TypeError: second_molar_mass() missing 1 required positional argument: - 'effusion_rate_2' + TypeError: second_molar_mass() missing 1 required positional argument: \ +'effusion_rate_2' """ validate(molar_mass, effusion_rate_1, effusion_rate_2) return round(pow(effusion_rate_1 / effusion_rate_2, 2) / molar_mass, 6) From 4059256881cc5ff408d32e31b1018a909bc90678 Mon Sep 17 00:00:00 2001 From: Blake Reimer Date: Wed, 1 Mar 2023 03:32:29 +0000 Subject: [PATCH 4/4] peer review updates --- physics/grahams_law.py | 95 ++++++++++++++++++++---------------------- 1 file changed, 46 insertions(+), 49 deletions(-) diff --git a/physics/grahams_law.py b/physics/grahams_law.py index df318a349372..6e5d75127e83 100644 --- a/physics/grahams_law.py +++ b/physics/grahams_law.py @@ -31,26 +31,15 @@ def validate(*values: float) -> bool: >>> validate(2.016, 4.002) True >>> validate(-2.016, 4.002) - Traceback (most recent call last): - ... - ValueError: Invalid inputs. Effusion rates and molar masses must be a positive - value. + False >>> validate() False """ - for value in values: - if value >= 0.0: - return True - else: - raise ValueError( - """Invalid inputs. Effusion rates and molar masses must be a positive - value.""" - ) + result = len(values) > 0 and all(value > 0.0 for value in values) + return result - return False - -def effusion_ratio(molar_mass_1: float, molar_mass_2: float) -> float: +def effusion_ratio(molar_mass_1: float, molar_mass_2: float) -> float | ValueError: """ Input Parameters: ----------------- @@ -62,22 +51,22 @@ def effusion_ratio(molar_mass_1: float, molar_mass_2: float) -> float: >>> effusion_ratio(2.016, 4.002) 1.408943 >>> effusion_ratio(-2.016, 4.002) - Traceback (most recent call last): - ... - ValueError: Invalid inputs. Effusion rates and molar masses must be a positive - value. + ValueError('Input Error: Molar mass values must greater than 0.') >>> effusion_ratio(2.016) Traceback (most recent call last): ... TypeError: effusion_ratio() missing 1 required positional argument: 'molar_mass_2' """ - validate(molar_mass_1, molar_mass_2) - return round(sqrt(molar_mass_2 / molar_mass_1), 6) + return ( + round(sqrt(molar_mass_2 / molar_mass_1), 6) + if validate(molar_mass_1, molar_mass_2) + else ValueError("Input Error: Molar mass values must greater than 0.") + ) def first_effusion_rate( effusion_rate: float, molar_mass_1: float, molar_mass_2: float -) -> float: +) -> float | ValueError: """ Input Parameters: ----------------- @@ -90,10 +79,7 @@ def first_effusion_rate( >>> first_effusion_rate(1, 2.016, 4.002) 1.408943 >>> first_effusion_rate(-1, 2.016, 4.002) - Traceback (most recent call last): - ... - ValueError: Invalid inputs. Effusion rates and molar masses must be a positive - value. + ValueError('Input Error: Molar mass and effusion rate values must greater than 0.') >>> first_effusion_rate(1) Traceback (most recent call last): ... @@ -105,13 +91,18 @@ def first_effusion_rate( TypeError: first_effusion_rate() missing 1 required positional argument: \ 'molar_mass_2' """ - validate(effusion_rate, molar_mass_1, molar_mass_2) - return round(effusion_rate * sqrt(molar_mass_2 / molar_mass_1), 6) + return ( + round(effusion_rate * sqrt(molar_mass_2 / molar_mass_1), 6) + if validate(effusion_rate, molar_mass_1, molar_mass_2) + else ValueError( + "Input Error: Molar mass and effusion rate values must greater than 0." + ) + ) def second_effusion_rate( effusion_rate: float, molar_mass_1: float, molar_mass_2: float -) -> float: +) -> float | ValueError: """ Input Parameters: ----------------- @@ -124,10 +115,7 @@ def second_effusion_rate( >>> second_effusion_rate(1, 2.016, 4.002) 0.709752 >>> second_effusion_rate(-1, 2.016, 4.002) - Traceback (most recent call last): - ... - ValueError: Invalid inputs. Effusion rates and molar masses must be a positive - value. + ValueError('Input Error: Molar mass and effusion rate values must greater than 0.') >>> second_effusion_rate(1) Traceback (most recent call last): ... @@ -139,13 +127,18 @@ def second_effusion_rate( TypeError: second_effusion_rate() missing 1 required positional argument: \ 'molar_mass_2' """ - validate(effusion_rate, molar_mass_1, molar_mass_2) - return round(effusion_rate / sqrt(molar_mass_2 / molar_mass_1), 6) + return ( + round(effusion_rate / sqrt(molar_mass_2 / molar_mass_1), 6) + if validate(effusion_rate, molar_mass_1, molar_mass_2) + else ValueError( + "Input Error: Molar mass and effusion rate values must greater than 0." + ) + ) def first_molar_mass( molar_mass: float, effusion_rate_1: float, effusion_rate_2: float -) -> float: +) -> float | ValueError: """ Input Parameters: ----------------- @@ -158,10 +151,7 @@ def first_molar_mass( >>> first_molar_mass(2, 1.408943, 0.709752) 0.507524 >>> first_molar_mass(-1, 2.016, 4.002) - Traceback (most recent call last): - ... - ValueError: Invalid inputs. Effusion rates and molar masses must be a positive - value. + ValueError('Input Error: Molar mass and effusion rate values must greater than 0.') >>> first_molar_mass(1) Traceback (most recent call last): ... @@ -173,13 +163,18 @@ def first_molar_mass( TypeError: first_molar_mass() missing 1 required positional argument: \ 'effusion_rate_2' """ - validate(molar_mass, effusion_rate_1, effusion_rate_2) - return round(molar_mass / pow(effusion_rate_1 / effusion_rate_2, 2), 6) + return ( + round(molar_mass / pow(effusion_rate_1 / effusion_rate_2, 2), 6) + if validate(molar_mass, effusion_rate_1, effusion_rate_2) + else ValueError( + "Input Error: Molar mass and effusion rate values must greater than 0." + ) + ) def second_molar_mass( molar_mass: float, effusion_rate_1: float, effusion_rate_2: float -) -> float: +) -> float | ValueError: """ Input Parameters: ----------------- @@ -192,10 +187,7 @@ def second_molar_mass( >>> second_molar_mass(2, 1.408943, 0.709752) 1.970351 >>> second_molar_mass(-2, 1.408943, 0.709752) - Traceback (most recent call last): - ... - ValueError: Invalid inputs. Effusion rates and molar masses must be a positive - value. + ValueError('Input Error: Molar mass and effusion rate values must greater than 0.') >>> second_molar_mass(1) Traceback (most recent call last): ... @@ -207,5 +199,10 @@ def second_molar_mass( TypeError: second_molar_mass() missing 1 required positional argument: \ 'effusion_rate_2' """ - validate(molar_mass, effusion_rate_1, effusion_rate_2) - return round(pow(effusion_rate_1 / effusion_rate_2, 2) / molar_mass, 6) + return ( + round(pow(effusion_rate_1 / effusion_rate_2, 2) / molar_mass, 6) + if validate(molar_mass, effusion_rate_1, effusion_rate_2) + else ValueError( + "Input Error: Molar mass and effusion rate values must greater than 0." + ) + )