Project structure for a reactor model built in Python
up vote
4
down vote
favorite
I use Python for various computational reactor modeling activities. While there are many components to the models I develop, the basic structure of the project folder tends to be similar to the following:
pyreactor/
├── gas_properties.py
├── geometry.py
├── main.py
├── parameters.py
├── results
│ ├── fig1.pdf
│ └── output.txt
└── velocity.py
The parameters.py
file contains dictionaries with various model parameters for different components of the model. Each parameter has an associated value and description.
# parameters.py
reactor = {
'd_inner': (0.2, 'Inner diameter [m]'),
'height': (1.5, 'Height of reactor [m]')
}
gas = {
'mu': ([300, 350, 400, 450, 500], 'Gas viscosities [uP]'),
'p': (115_000, 'Gas pressure [Pa]'),
'species': 'CO2',
'temp': (500, 'Temperature of gas [Celsius]'),
}
solid = {
'cd': (0.25, 'Drag coefficient [-]'),
'dp': (0.03, 'Particle diameter [m]'),
'phi': (0.86, 'Particle sphericity [-]'),
'rho': (2500, 'Density of sand particle [kg/m^3]')
}
The Python files labeled gas_properties.py
, geometry.py
, and velocity.py
represent different components of the reactor model. The gas_properties.py
file calculates various properties of the gas using parameters defined in parameters.py
. If the script is run as __main__
then it prints some results to the console and displays a plot figure:
# gas_properties.py
import matplotlib.pyplot as plt
import parameters as pm
def rhog(mw, p, tk):
mw = mw / 1000
r = 8.3145
rho = (p * mw) / (r * tk)
return rho
# Parameters
# ----------------------------------------------------------------------------
mu = pm.gas['mu'][0]
p = pm.gas['p'][0]
sp = pm.gas['species']
tk = pm.gas['temp'][0]
# Calculate density and plot viscosities
# ----------------------------------------------------------------------------
if sp is 'CO2':
mw = 44
elif sp is 'CO':
mw = 28
rho = rhog(mw, p, tk)
fig1, ax = plt.subplots()
ax.plot(mu)
ax.set_xlabel('Items [-]')
ax.set_ylabel('Gas viscosity [uP]')
if __name__ == "__main__":
print('--- Gas properties ---')
print(f'mw = {mw} g/mol')
print(f'rho = {rho:.2f} kg/m^3')
plt.show()
The geometry.py
file calculates dimensions of the reactor. It prints results to the console if run as __main__
:
# geometry.py
import numpy as np
import parameters as pm
# Parameters
# ----------------------------------------------------------------------------
d = pm.reactor['d_inner'][0]
h = pm.reactor['height'][0]
# Calculate cross section area and volume
# ----------------------------------------------------------------------------
a_cross = (np.pi / 4) * (d**2)
vol = a_cross * h
if __name__ == "__main__":
print('--- Geometry calculations ---')
print(f'a_cross = {a_cross:.4f} m^2')
print(f'volume = {vol:.4f} m^3')
The velocity.py
file estimates velocity of the particles in the system. It imports gas_properties
for the gas density that is used in the velocity function ut()
. If the script is run as __main__
then results are printed to the console:
# velocity.py
import parameters as pm
from gas_properties import rho as rhog
def ut(cd, dp, rhog, rhos):
g = 9.81
tm1 = 4 * dp * (rhos - rhog) * g
tm2 = 3 * rhog * cd
ut = (tm1 / tm2)**(1 / 2)
return ut
# Parameters
# ----------------------------------------------------------------------------
cd = pm.solid['cd'][0]
d = pm.solid['dp'][0]
rhos = pm.solid['rho'][0]
# Calculate terminal velocity
# ----------------------------------------------------------------------------
ut = ut(cd, d, rhog, rhos)
if __name__ == "__main__":
print('--- Velocity of particle ---')
print(f'ut = {ut:.2f} m/s')
Finally, the main.py
file imports all the components gas_properties.py
, geometry.py
, and velocity.py
of the reactor model. This file prints the parameters and results to a text file named output.txt
in the results/
folder. The main file also saves plot figures to the results/
folder:
# main.py
import datetime
import parameters as pm
import gas_properties as gp
import geometry as gm
import velocity as ve
# Parameters and results saved to text file in results/ folder
# ----------------------------------------------------------------------------
with open('results/output.txt', 'w') as txt_file:
date = datetime.datetime.now().strftime('%m/%d/%Y')
print(f'Generated on {date} by G.W.', file=txt_file)
print('n--- Reactor Parameters ---n', file=txt_file)
for key, value in pm.reactor.items():
print(f'{key:8} {value[0]:10} t {value[1]}', file=txt_file)
print('n--- Gas Parameters ---n', file=txt_file)
for key, value in pm.gas.items():
if type(value[0]) is list:
print(f'{key:8} {value[0]} t {value[1]}', file=txt_file)
elif key is 'species':
print(f'{key:27} {value}', file=txt_file)
else:
print(f'{key:20} {value[0]:10} t {value[1]}', file=txt_file)
print('n--- Solid Parameters ---n', file=txt_file)
for key, value in pm.solid.items():
print(f'{key:8} {value[0]:10} t {value[1]}', file=txt_file)
print('n--- Gas Properties Results ---n', file=txt_file)
print(f"{'rho':8} {gp.rho:10.2f} t Density of gas [kg/m^3]", file=txt_file)
print('n--- Geometry Results ---n', file=txt_file)
print(f"{'a_cross':10} {gm.a_cross:.4f} t Cross section area of reactor [m^2]", file=txt_file)
print(f"{'volume':10} {gm.vol:.4f} t Volume of reactor [m^3]", file=txt_file)
print('n--- Velocity Results ---n', file=txt_file)
print(f"{'ut':10} {ve.ut:.2f} t Terminal velocity [m/s]", file=txt_file)
# Plots saved to file in results/ folder
# ----------------------------------------------------------------------------
gp.fig1.savefig('results/fig1.pdf', bbox_inches='tight')
While this approach works fine, I feel like there may be a better way of organizing the code and folder structure. Some specific questions that come to mind are:
- Is using a parameters file that contains dictionaries a good practice? I find that having all model parameters in one file is more maintainable and makes it easy to find what parameters are used for the model.
- Each component of the reactor model is treated as an individual file (or module) which is imported into the main script. Is this an efficient way to handle model components or is there another feature of the Python programming language that I should consider?
- All results and figures are saved to the results folder. Is this a reasonable approach or should save results elsewhere on the computer?
Please let me know if there are ways to improve my code and project structure. Regarding the parameters file, I'm aware of YAML, JSON, and INI files but for this example I would like to use standard Python 3 features such as a dictionary, list, tuple, set, etc.
python python-3.x numpy matplotlib
add a comment |
up vote
4
down vote
favorite
I use Python for various computational reactor modeling activities. While there are many components to the models I develop, the basic structure of the project folder tends to be similar to the following:
pyreactor/
├── gas_properties.py
├── geometry.py
├── main.py
├── parameters.py
├── results
│ ├── fig1.pdf
│ └── output.txt
└── velocity.py
The parameters.py
file contains dictionaries with various model parameters for different components of the model. Each parameter has an associated value and description.
# parameters.py
reactor = {
'd_inner': (0.2, 'Inner diameter [m]'),
'height': (1.5, 'Height of reactor [m]')
}
gas = {
'mu': ([300, 350, 400, 450, 500], 'Gas viscosities [uP]'),
'p': (115_000, 'Gas pressure [Pa]'),
'species': 'CO2',
'temp': (500, 'Temperature of gas [Celsius]'),
}
solid = {
'cd': (0.25, 'Drag coefficient [-]'),
'dp': (0.03, 'Particle diameter [m]'),
'phi': (0.86, 'Particle sphericity [-]'),
'rho': (2500, 'Density of sand particle [kg/m^3]')
}
The Python files labeled gas_properties.py
, geometry.py
, and velocity.py
represent different components of the reactor model. The gas_properties.py
file calculates various properties of the gas using parameters defined in parameters.py
. If the script is run as __main__
then it prints some results to the console and displays a plot figure:
# gas_properties.py
import matplotlib.pyplot as plt
import parameters as pm
def rhog(mw, p, tk):
mw = mw / 1000
r = 8.3145
rho = (p * mw) / (r * tk)
return rho
# Parameters
# ----------------------------------------------------------------------------
mu = pm.gas['mu'][0]
p = pm.gas['p'][0]
sp = pm.gas['species']
tk = pm.gas['temp'][0]
# Calculate density and plot viscosities
# ----------------------------------------------------------------------------
if sp is 'CO2':
mw = 44
elif sp is 'CO':
mw = 28
rho = rhog(mw, p, tk)
fig1, ax = plt.subplots()
ax.plot(mu)
ax.set_xlabel('Items [-]')
ax.set_ylabel('Gas viscosity [uP]')
if __name__ == "__main__":
print('--- Gas properties ---')
print(f'mw = {mw} g/mol')
print(f'rho = {rho:.2f} kg/m^3')
plt.show()
The geometry.py
file calculates dimensions of the reactor. It prints results to the console if run as __main__
:
# geometry.py
import numpy as np
import parameters as pm
# Parameters
# ----------------------------------------------------------------------------
d = pm.reactor['d_inner'][0]
h = pm.reactor['height'][0]
# Calculate cross section area and volume
# ----------------------------------------------------------------------------
a_cross = (np.pi / 4) * (d**2)
vol = a_cross * h
if __name__ == "__main__":
print('--- Geometry calculations ---')
print(f'a_cross = {a_cross:.4f} m^2')
print(f'volume = {vol:.4f} m^3')
The velocity.py
file estimates velocity of the particles in the system. It imports gas_properties
for the gas density that is used in the velocity function ut()
. If the script is run as __main__
then results are printed to the console:
# velocity.py
import parameters as pm
from gas_properties import rho as rhog
def ut(cd, dp, rhog, rhos):
g = 9.81
tm1 = 4 * dp * (rhos - rhog) * g
tm2 = 3 * rhog * cd
ut = (tm1 / tm2)**(1 / 2)
return ut
# Parameters
# ----------------------------------------------------------------------------
cd = pm.solid['cd'][0]
d = pm.solid['dp'][0]
rhos = pm.solid['rho'][0]
# Calculate terminal velocity
# ----------------------------------------------------------------------------
ut = ut(cd, d, rhog, rhos)
if __name__ == "__main__":
print('--- Velocity of particle ---')
print(f'ut = {ut:.2f} m/s')
Finally, the main.py
file imports all the components gas_properties.py
, geometry.py
, and velocity.py
of the reactor model. This file prints the parameters and results to a text file named output.txt
in the results/
folder. The main file also saves plot figures to the results/
folder:
# main.py
import datetime
import parameters as pm
import gas_properties as gp
import geometry as gm
import velocity as ve
# Parameters and results saved to text file in results/ folder
# ----------------------------------------------------------------------------
with open('results/output.txt', 'w') as txt_file:
date = datetime.datetime.now().strftime('%m/%d/%Y')
print(f'Generated on {date} by G.W.', file=txt_file)
print('n--- Reactor Parameters ---n', file=txt_file)
for key, value in pm.reactor.items():
print(f'{key:8} {value[0]:10} t {value[1]}', file=txt_file)
print('n--- Gas Parameters ---n', file=txt_file)
for key, value in pm.gas.items():
if type(value[0]) is list:
print(f'{key:8} {value[0]} t {value[1]}', file=txt_file)
elif key is 'species':
print(f'{key:27} {value}', file=txt_file)
else:
print(f'{key:20} {value[0]:10} t {value[1]}', file=txt_file)
print('n--- Solid Parameters ---n', file=txt_file)
for key, value in pm.solid.items():
print(f'{key:8} {value[0]:10} t {value[1]}', file=txt_file)
print('n--- Gas Properties Results ---n', file=txt_file)
print(f"{'rho':8} {gp.rho:10.2f} t Density of gas [kg/m^3]", file=txt_file)
print('n--- Geometry Results ---n', file=txt_file)
print(f"{'a_cross':10} {gm.a_cross:.4f} t Cross section area of reactor [m^2]", file=txt_file)
print(f"{'volume':10} {gm.vol:.4f} t Volume of reactor [m^3]", file=txt_file)
print('n--- Velocity Results ---n', file=txt_file)
print(f"{'ut':10} {ve.ut:.2f} t Terminal velocity [m/s]", file=txt_file)
# Plots saved to file in results/ folder
# ----------------------------------------------------------------------------
gp.fig1.savefig('results/fig1.pdf', bbox_inches='tight')
While this approach works fine, I feel like there may be a better way of organizing the code and folder structure. Some specific questions that come to mind are:
- Is using a parameters file that contains dictionaries a good practice? I find that having all model parameters in one file is more maintainable and makes it easy to find what parameters are used for the model.
- Each component of the reactor model is treated as an individual file (or module) which is imported into the main script. Is this an efficient way to handle model components or is there another feature of the Python programming language that I should consider?
- All results and figures are saved to the results folder. Is this a reasonable approach or should save results elsewhere on the computer?
Please let me know if there are ways to improve my code and project structure. Regarding the parameters file, I'm aware of YAML, JSON, and INI files but for this example I would like to use standard Python 3 features such as a dictionary, list, tuple, set, etc.
python python-3.x numpy matplotlib
add a comment |
up vote
4
down vote
favorite
up vote
4
down vote
favorite
I use Python for various computational reactor modeling activities. While there are many components to the models I develop, the basic structure of the project folder tends to be similar to the following:
pyreactor/
├── gas_properties.py
├── geometry.py
├── main.py
├── parameters.py
├── results
│ ├── fig1.pdf
│ └── output.txt
└── velocity.py
The parameters.py
file contains dictionaries with various model parameters for different components of the model. Each parameter has an associated value and description.
# parameters.py
reactor = {
'd_inner': (0.2, 'Inner diameter [m]'),
'height': (1.5, 'Height of reactor [m]')
}
gas = {
'mu': ([300, 350, 400, 450, 500], 'Gas viscosities [uP]'),
'p': (115_000, 'Gas pressure [Pa]'),
'species': 'CO2',
'temp': (500, 'Temperature of gas [Celsius]'),
}
solid = {
'cd': (0.25, 'Drag coefficient [-]'),
'dp': (0.03, 'Particle diameter [m]'),
'phi': (0.86, 'Particle sphericity [-]'),
'rho': (2500, 'Density of sand particle [kg/m^3]')
}
The Python files labeled gas_properties.py
, geometry.py
, and velocity.py
represent different components of the reactor model. The gas_properties.py
file calculates various properties of the gas using parameters defined in parameters.py
. If the script is run as __main__
then it prints some results to the console and displays a plot figure:
# gas_properties.py
import matplotlib.pyplot as plt
import parameters as pm
def rhog(mw, p, tk):
mw = mw / 1000
r = 8.3145
rho = (p * mw) / (r * tk)
return rho
# Parameters
# ----------------------------------------------------------------------------
mu = pm.gas['mu'][0]
p = pm.gas['p'][0]
sp = pm.gas['species']
tk = pm.gas['temp'][0]
# Calculate density and plot viscosities
# ----------------------------------------------------------------------------
if sp is 'CO2':
mw = 44
elif sp is 'CO':
mw = 28
rho = rhog(mw, p, tk)
fig1, ax = plt.subplots()
ax.plot(mu)
ax.set_xlabel('Items [-]')
ax.set_ylabel('Gas viscosity [uP]')
if __name__ == "__main__":
print('--- Gas properties ---')
print(f'mw = {mw} g/mol')
print(f'rho = {rho:.2f} kg/m^3')
plt.show()
The geometry.py
file calculates dimensions of the reactor. It prints results to the console if run as __main__
:
# geometry.py
import numpy as np
import parameters as pm
# Parameters
# ----------------------------------------------------------------------------
d = pm.reactor['d_inner'][0]
h = pm.reactor['height'][0]
# Calculate cross section area and volume
# ----------------------------------------------------------------------------
a_cross = (np.pi / 4) * (d**2)
vol = a_cross * h
if __name__ == "__main__":
print('--- Geometry calculations ---')
print(f'a_cross = {a_cross:.4f} m^2')
print(f'volume = {vol:.4f} m^3')
The velocity.py
file estimates velocity of the particles in the system. It imports gas_properties
for the gas density that is used in the velocity function ut()
. If the script is run as __main__
then results are printed to the console:
# velocity.py
import parameters as pm
from gas_properties import rho as rhog
def ut(cd, dp, rhog, rhos):
g = 9.81
tm1 = 4 * dp * (rhos - rhog) * g
tm2 = 3 * rhog * cd
ut = (tm1 / tm2)**(1 / 2)
return ut
# Parameters
# ----------------------------------------------------------------------------
cd = pm.solid['cd'][0]
d = pm.solid['dp'][0]
rhos = pm.solid['rho'][0]
# Calculate terminal velocity
# ----------------------------------------------------------------------------
ut = ut(cd, d, rhog, rhos)
if __name__ == "__main__":
print('--- Velocity of particle ---')
print(f'ut = {ut:.2f} m/s')
Finally, the main.py
file imports all the components gas_properties.py
, geometry.py
, and velocity.py
of the reactor model. This file prints the parameters and results to a text file named output.txt
in the results/
folder. The main file also saves plot figures to the results/
folder:
# main.py
import datetime
import parameters as pm
import gas_properties as gp
import geometry as gm
import velocity as ve
# Parameters and results saved to text file in results/ folder
# ----------------------------------------------------------------------------
with open('results/output.txt', 'w') as txt_file:
date = datetime.datetime.now().strftime('%m/%d/%Y')
print(f'Generated on {date} by G.W.', file=txt_file)
print('n--- Reactor Parameters ---n', file=txt_file)
for key, value in pm.reactor.items():
print(f'{key:8} {value[0]:10} t {value[1]}', file=txt_file)
print('n--- Gas Parameters ---n', file=txt_file)
for key, value in pm.gas.items():
if type(value[0]) is list:
print(f'{key:8} {value[0]} t {value[1]}', file=txt_file)
elif key is 'species':
print(f'{key:27} {value}', file=txt_file)
else:
print(f'{key:20} {value[0]:10} t {value[1]}', file=txt_file)
print('n--- Solid Parameters ---n', file=txt_file)
for key, value in pm.solid.items():
print(f'{key:8} {value[0]:10} t {value[1]}', file=txt_file)
print('n--- Gas Properties Results ---n', file=txt_file)
print(f"{'rho':8} {gp.rho:10.2f} t Density of gas [kg/m^3]", file=txt_file)
print('n--- Geometry Results ---n', file=txt_file)
print(f"{'a_cross':10} {gm.a_cross:.4f} t Cross section area of reactor [m^2]", file=txt_file)
print(f"{'volume':10} {gm.vol:.4f} t Volume of reactor [m^3]", file=txt_file)
print('n--- Velocity Results ---n', file=txt_file)
print(f"{'ut':10} {ve.ut:.2f} t Terminal velocity [m/s]", file=txt_file)
# Plots saved to file in results/ folder
# ----------------------------------------------------------------------------
gp.fig1.savefig('results/fig1.pdf', bbox_inches='tight')
While this approach works fine, I feel like there may be a better way of organizing the code and folder structure. Some specific questions that come to mind are:
- Is using a parameters file that contains dictionaries a good practice? I find that having all model parameters in one file is more maintainable and makes it easy to find what parameters are used for the model.
- Each component of the reactor model is treated as an individual file (or module) which is imported into the main script. Is this an efficient way to handle model components or is there another feature of the Python programming language that I should consider?
- All results and figures are saved to the results folder. Is this a reasonable approach or should save results elsewhere on the computer?
Please let me know if there are ways to improve my code and project structure. Regarding the parameters file, I'm aware of YAML, JSON, and INI files but for this example I would like to use standard Python 3 features such as a dictionary, list, tuple, set, etc.
python python-3.x numpy matplotlib
I use Python for various computational reactor modeling activities. While there are many components to the models I develop, the basic structure of the project folder tends to be similar to the following:
pyreactor/
├── gas_properties.py
├── geometry.py
├── main.py
├── parameters.py
├── results
│ ├── fig1.pdf
│ └── output.txt
└── velocity.py
The parameters.py
file contains dictionaries with various model parameters for different components of the model. Each parameter has an associated value and description.
# parameters.py
reactor = {
'd_inner': (0.2, 'Inner diameter [m]'),
'height': (1.5, 'Height of reactor [m]')
}
gas = {
'mu': ([300, 350, 400, 450, 500], 'Gas viscosities [uP]'),
'p': (115_000, 'Gas pressure [Pa]'),
'species': 'CO2',
'temp': (500, 'Temperature of gas [Celsius]'),
}
solid = {
'cd': (0.25, 'Drag coefficient [-]'),
'dp': (0.03, 'Particle diameter [m]'),
'phi': (0.86, 'Particle sphericity [-]'),
'rho': (2500, 'Density of sand particle [kg/m^3]')
}
The Python files labeled gas_properties.py
, geometry.py
, and velocity.py
represent different components of the reactor model. The gas_properties.py
file calculates various properties of the gas using parameters defined in parameters.py
. If the script is run as __main__
then it prints some results to the console and displays a plot figure:
# gas_properties.py
import matplotlib.pyplot as plt
import parameters as pm
def rhog(mw, p, tk):
mw = mw / 1000
r = 8.3145
rho = (p * mw) / (r * tk)
return rho
# Parameters
# ----------------------------------------------------------------------------
mu = pm.gas['mu'][0]
p = pm.gas['p'][0]
sp = pm.gas['species']
tk = pm.gas['temp'][0]
# Calculate density and plot viscosities
# ----------------------------------------------------------------------------
if sp is 'CO2':
mw = 44
elif sp is 'CO':
mw = 28
rho = rhog(mw, p, tk)
fig1, ax = plt.subplots()
ax.plot(mu)
ax.set_xlabel('Items [-]')
ax.set_ylabel('Gas viscosity [uP]')
if __name__ == "__main__":
print('--- Gas properties ---')
print(f'mw = {mw} g/mol')
print(f'rho = {rho:.2f} kg/m^3')
plt.show()
The geometry.py
file calculates dimensions of the reactor. It prints results to the console if run as __main__
:
# geometry.py
import numpy as np
import parameters as pm
# Parameters
# ----------------------------------------------------------------------------
d = pm.reactor['d_inner'][0]
h = pm.reactor['height'][0]
# Calculate cross section area and volume
# ----------------------------------------------------------------------------
a_cross = (np.pi / 4) * (d**2)
vol = a_cross * h
if __name__ == "__main__":
print('--- Geometry calculations ---')
print(f'a_cross = {a_cross:.4f} m^2')
print(f'volume = {vol:.4f} m^3')
The velocity.py
file estimates velocity of the particles in the system. It imports gas_properties
for the gas density that is used in the velocity function ut()
. If the script is run as __main__
then results are printed to the console:
# velocity.py
import parameters as pm
from gas_properties import rho as rhog
def ut(cd, dp, rhog, rhos):
g = 9.81
tm1 = 4 * dp * (rhos - rhog) * g
tm2 = 3 * rhog * cd
ut = (tm1 / tm2)**(1 / 2)
return ut
# Parameters
# ----------------------------------------------------------------------------
cd = pm.solid['cd'][0]
d = pm.solid['dp'][0]
rhos = pm.solid['rho'][0]
# Calculate terminal velocity
# ----------------------------------------------------------------------------
ut = ut(cd, d, rhog, rhos)
if __name__ == "__main__":
print('--- Velocity of particle ---')
print(f'ut = {ut:.2f} m/s')
Finally, the main.py
file imports all the components gas_properties.py
, geometry.py
, and velocity.py
of the reactor model. This file prints the parameters and results to a text file named output.txt
in the results/
folder. The main file also saves plot figures to the results/
folder:
# main.py
import datetime
import parameters as pm
import gas_properties as gp
import geometry as gm
import velocity as ve
# Parameters and results saved to text file in results/ folder
# ----------------------------------------------------------------------------
with open('results/output.txt', 'w') as txt_file:
date = datetime.datetime.now().strftime('%m/%d/%Y')
print(f'Generated on {date} by G.W.', file=txt_file)
print('n--- Reactor Parameters ---n', file=txt_file)
for key, value in pm.reactor.items():
print(f'{key:8} {value[0]:10} t {value[1]}', file=txt_file)
print('n--- Gas Parameters ---n', file=txt_file)
for key, value in pm.gas.items():
if type(value[0]) is list:
print(f'{key:8} {value[0]} t {value[1]}', file=txt_file)
elif key is 'species':
print(f'{key:27} {value}', file=txt_file)
else:
print(f'{key:20} {value[0]:10} t {value[1]}', file=txt_file)
print('n--- Solid Parameters ---n', file=txt_file)
for key, value in pm.solid.items():
print(f'{key:8} {value[0]:10} t {value[1]}', file=txt_file)
print('n--- Gas Properties Results ---n', file=txt_file)
print(f"{'rho':8} {gp.rho:10.2f} t Density of gas [kg/m^3]", file=txt_file)
print('n--- Geometry Results ---n', file=txt_file)
print(f"{'a_cross':10} {gm.a_cross:.4f} t Cross section area of reactor [m^2]", file=txt_file)
print(f"{'volume':10} {gm.vol:.4f} t Volume of reactor [m^3]", file=txt_file)
print('n--- Velocity Results ---n', file=txt_file)
print(f"{'ut':10} {ve.ut:.2f} t Terminal velocity [m/s]", file=txt_file)
# Plots saved to file in results/ folder
# ----------------------------------------------------------------------------
gp.fig1.savefig('results/fig1.pdf', bbox_inches='tight')
While this approach works fine, I feel like there may be a better way of organizing the code and folder structure. Some specific questions that come to mind are:
- Is using a parameters file that contains dictionaries a good practice? I find that having all model parameters in one file is more maintainable and makes it easy to find what parameters are used for the model.
- Each component of the reactor model is treated as an individual file (or module) which is imported into the main script. Is this an efficient way to handle model components or is there another feature of the Python programming language that I should consider?
- All results and figures are saved to the results folder. Is this a reasonable approach or should save results elsewhere on the computer?
Please let me know if there are ways to improve my code and project structure. Regarding the parameters file, I'm aware of YAML, JSON, and INI files but for this example I would like to use standard Python 3 features such as a dictionary, list, tuple, set, etc.
python python-3.x numpy matplotlib
python python-3.x numpy matplotlib
edited Dec 5 at 20:13
asked Dec 4 at 19:40
wigging
13816
13816
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
up vote
0
down vote
Is using a parameters file that contains dictionaries a good practice?
No. It doesn't look like you're actually using the dictionaries for anything other than static lookup (and an iteration); as such, those parameters should simply be in a tuple, copied to locals
.
Also, I suggest that you make your parameters uniform (insofar as name, value and unit); something like
from collections import namedtuple
Param = namedtuple('Param', ('name', 'value', 'unit', 'desc'))
params = (
Param('d_inner', 0.2, 'm', 'Inner diameter'),
Param('height', 1.5, 'm', 'Height of reactor'),
# ...
)
locals().update({p.name: p for p in params})
# ...
print('--- Reactor Parameters ---')
print('{:8} {:6} {:4} {:20}'.format('Name', 'Value', 'Unit', 'Description'))
for p in params:
print('{:8} {:<6.2f} {:4} {:20}'.format(p.name, p.value, p.unit, p.desc))
What islocals
? Is it like a collection of global variables?
– wigging
Dec 4 at 20:22
It's a dictionary of all of the variables in the current scope.
– Reinderien
Dec 4 at 20:45
I’d even go further and recommend a config module. That’s usually where you want to store parameters.
– яүυк
Dec 4 at 21:26
Other than the parameters, do you have any comments on using a main script to run everything and where to put results?
– wigging
Dec 4 at 21:59
Not really, that's all fairly sane
– Reinderien
Dec 4 at 22:14
|
show 5 more comments
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
0
down vote
Is using a parameters file that contains dictionaries a good practice?
No. It doesn't look like you're actually using the dictionaries for anything other than static lookup (and an iteration); as such, those parameters should simply be in a tuple, copied to locals
.
Also, I suggest that you make your parameters uniform (insofar as name, value and unit); something like
from collections import namedtuple
Param = namedtuple('Param', ('name', 'value', 'unit', 'desc'))
params = (
Param('d_inner', 0.2, 'm', 'Inner diameter'),
Param('height', 1.5, 'm', 'Height of reactor'),
# ...
)
locals().update({p.name: p for p in params})
# ...
print('--- Reactor Parameters ---')
print('{:8} {:6} {:4} {:20}'.format('Name', 'Value', 'Unit', 'Description'))
for p in params:
print('{:8} {:<6.2f} {:4} {:20}'.format(p.name, p.value, p.unit, p.desc))
What islocals
? Is it like a collection of global variables?
– wigging
Dec 4 at 20:22
It's a dictionary of all of the variables in the current scope.
– Reinderien
Dec 4 at 20:45
I’d even go further and recommend a config module. That’s usually where you want to store parameters.
– яүυк
Dec 4 at 21:26
Other than the parameters, do you have any comments on using a main script to run everything and where to put results?
– wigging
Dec 4 at 21:59
Not really, that's all fairly sane
– Reinderien
Dec 4 at 22:14
|
show 5 more comments
up vote
0
down vote
Is using a parameters file that contains dictionaries a good practice?
No. It doesn't look like you're actually using the dictionaries for anything other than static lookup (and an iteration); as such, those parameters should simply be in a tuple, copied to locals
.
Also, I suggest that you make your parameters uniform (insofar as name, value and unit); something like
from collections import namedtuple
Param = namedtuple('Param', ('name', 'value', 'unit', 'desc'))
params = (
Param('d_inner', 0.2, 'm', 'Inner diameter'),
Param('height', 1.5, 'm', 'Height of reactor'),
# ...
)
locals().update({p.name: p for p in params})
# ...
print('--- Reactor Parameters ---')
print('{:8} {:6} {:4} {:20}'.format('Name', 'Value', 'Unit', 'Description'))
for p in params:
print('{:8} {:<6.2f} {:4} {:20}'.format(p.name, p.value, p.unit, p.desc))
What islocals
? Is it like a collection of global variables?
– wigging
Dec 4 at 20:22
It's a dictionary of all of the variables in the current scope.
– Reinderien
Dec 4 at 20:45
I’d even go further and recommend a config module. That’s usually where you want to store parameters.
– яүυк
Dec 4 at 21:26
Other than the parameters, do you have any comments on using a main script to run everything and where to put results?
– wigging
Dec 4 at 21:59
Not really, that's all fairly sane
– Reinderien
Dec 4 at 22:14
|
show 5 more comments
up vote
0
down vote
up vote
0
down vote
Is using a parameters file that contains dictionaries a good practice?
No. It doesn't look like you're actually using the dictionaries for anything other than static lookup (and an iteration); as such, those parameters should simply be in a tuple, copied to locals
.
Also, I suggest that you make your parameters uniform (insofar as name, value and unit); something like
from collections import namedtuple
Param = namedtuple('Param', ('name', 'value', 'unit', 'desc'))
params = (
Param('d_inner', 0.2, 'm', 'Inner diameter'),
Param('height', 1.5, 'm', 'Height of reactor'),
# ...
)
locals().update({p.name: p for p in params})
# ...
print('--- Reactor Parameters ---')
print('{:8} {:6} {:4} {:20}'.format('Name', 'Value', 'Unit', 'Description'))
for p in params:
print('{:8} {:<6.2f} {:4} {:20}'.format(p.name, p.value, p.unit, p.desc))
Is using a parameters file that contains dictionaries a good practice?
No. It doesn't look like you're actually using the dictionaries for anything other than static lookup (and an iteration); as such, those parameters should simply be in a tuple, copied to locals
.
Also, I suggest that you make your parameters uniform (insofar as name, value and unit); something like
from collections import namedtuple
Param = namedtuple('Param', ('name', 'value', 'unit', 'desc'))
params = (
Param('d_inner', 0.2, 'm', 'Inner diameter'),
Param('height', 1.5, 'm', 'Height of reactor'),
# ...
)
locals().update({p.name: p for p in params})
# ...
print('--- Reactor Parameters ---')
print('{:8} {:6} {:4} {:20}'.format('Name', 'Value', 'Unit', 'Description'))
for p in params:
print('{:8} {:<6.2f} {:4} {:20}'.format(p.name, p.value, p.unit, p.desc))
answered Dec 4 at 20:07
Reinderien
1,889616
1,889616
What islocals
? Is it like a collection of global variables?
– wigging
Dec 4 at 20:22
It's a dictionary of all of the variables in the current scope.
– Reinderien
Dec 4 at 20:45
I’d even go further and recommend a config module. That’s usually where you want to store parameters.
– яүυк
Dec 4 at 21:26
Other than the parameters, do you have any comments on using a main script to run everything and where to put results?
– wigging
Dec 4 at 21:59
Not really, that's all fairly sane
– Reinderien
Dec 4 at 22:14
|
show 5 more comments
What islocals
? Is it like a collection of global variables?
– wigging
Dec 4 at 20:22
It's a dictionary of all of the variables in the current scope.
– Reinderien
Dec 4 at 20:45
I’d even go further and recommend a config module. That’s usually where you want to store parameters.
– яүυк
Dec 4 at 21:26
Other than the parameters, do you have any comments on using a main script to run everything and where to put results?
– wigging
Dec 4 at 21:59
Not really, that's all fairly sane
– Reinderien
Dec 4 at 22:14
What is
locals
? Is it like a collection of global variables?– wigging
Dec 4 at 20:22
What is
locals
? Is it like a collection of global variables?– wigging
Dec 4 at 20:22
It's a dictionary of all of the variables in the current scope.
– Reinderien
Dec 4 at 20:45
It's a dictionary of all of the variables in the current scope.
– Reinderien
Dec 4 at 20:45
I’d even go further and recommend a config module. That’s usually where you want to store parameters.
– яүυк
Dec 4 at 21:26
I’d even go further and recommend a config module. That’s usually where you want to store parameters.
– яүυк
Dec 4 at 21:26
Other than the parameters, do you have any comments on using a main script to run everything and where to put results?
– wigging
Dec 4 at 21:59
Other than the parameters, do you have any comments on using a main script to run everything and where to put results?
– wigging
Dec 4 at 21:59
Not really, that's all fairly sane
– Reinderien
Dec 4 at 22:14
Not really, that's all fairly sane
– Reinderien
Dec 4 at 22:14
|
show 5 more comments
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f209022%2fproject-structure-for-a-reactor-model-built-in-python%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown