Привет, Хабр! Аргентум на связи, сегодня мы будем решать химические задачи, проводить исследования по химии с нуля на языке программирования Python. Это первая, моя дебютная статья из серии "Змеиная наука", где мы будем создавать программное обеспечение для научных вычислений.
Почему именно Python? В рейтинге GitHub'а он занял 2-е место, уступив место JavaScript, а количество курсов "Стань программистом за 2 месяца и получай $300к в наносекунду" просто зашкаливает. Из-за этого, кстати, на одну ваканзию Junior Python разработчика может прилететь до 1000, а может и больше, заявок. Но он, довольно легко изучается, по сравнению с многими другими языками.
Химия, как наука, всегда требовала точности, глубокого анализа и системного подхода. С развитием вычислительных технологий открылись новые перспективы для химиков: возможность использовать программирование для моделирования, анализа данных и ускорения процессов исследований. В этой статье мы погрузимся в мир химии, представленный через призму Python - мощного языка программирования, который стал надежным инструментом для химиков в их исследованиях. Мы рассмотрим ключевые библиотеки (а может даже обойдемся без них), инструменты и подходы, позволяющие применять Python для анализа химических данных, создания моделей молекулярной структуры и многого другого. Давайте вместе исследуем, как Python становится неотъемлемой частью химических исследований, расширяя горизонты возможностей в этой захватывающей научной области.
Краткое введение
Для работы, нам желательно создать рабочее окружение. Вы можете использовать GitHub и Git, но здесь я приведу примеры без системы контроля версий.
Ниже я привел код для создания и активации виртуального окружения Python. Почему мы не устанавливаем библиотеку в систему, и не создавать эти ваши окружения? Потому что это плохая практика, и сам pip не даст вам этого (PEP 668). Ну, как не даст, даст, но с флагом --break-system-packages
# Способ для Linux-систем
python3 -m venv venv # создаем виртуальное окружение
source venv/bin/activate # активируем его
pip3 install --upgrade pip # обновляем pip
Теория
Вспомним школьную программу. А вы помните её?
1. Что такое относительная атомная масса и молекулярная масса:
Относительная атомная масса (также известная как атомная массовая единица, amu) - это масса атома в единицах массы атома углерода-12. Она используется для измерения массы атомов и молекул.
Относительная молекулярная масса - это сумма относительных атомных масс атомов в молекуле. Она позволяет определить массу молекулы в отношении массы атома углерода-12.
2. Число Авогадро:
Число Авогадро равно приближенно 6.02214076 x 10^23 и представляет собой количество атомов или молекул в одном моле вещества. Это основная константа, используемая для связи массы атомов и молекул с массой вещества в молях.
3. Моли:
Моль - это единица измерения количества вещества. Один моль вещества содержит число Авогадро частиц (около 6.022 x 10^23) атомов, молекул или других элементарных частиц.
4. Металлы и неметаллы:
Металлы - это элементы, обладающие характерными свойствами, такими как отличная теплопроводность, проводимость электричества, металлический блеск и гибкость. Примеры металлов включают железо, медь и алюминий.
Неметаллы - это элементы, обладающие характеристиками, противоположными металлам. Неметаллы обычно плохо проводят тепло и электричество и могут быть хрупкими. Примеры неметаллов включают кислород, азот и серу.
5. Электроны, нейтроны и протоны:
Электроны - это элементарные частицы, обладающие отрицательным электрическим зарядом. Они находятся в орбиталях вокруг ядра атома.
Протоны - это элементарные частицы, обладающие положительным электрическим зарядом, и они находятся в ядре атома.
Нейтроны - это элементарные частицы, не имеющие электрического заряда, и они также находятся в ядре атома.
6. Заряд ядра и энергетические уровни:
Заряд ядра - это сумма зарядов протонов в атомном ядре, который определяет химические свойства элемента.
Энергетические уровни - это уровни энергии, на которых находятся электроны в атоме. Электроны находятся на определенных энергетических уровнях и могут переходить между ними, поглощая или испуская энергию в форме света (спектральных линий).
Практика
Весь код будет в моем репозитории на GitHub. Там будет модифицированный код, здесь я приведу базовые функции
Относительная молекулярная масса элемента
Исходный код нашего калькулятора:
import re
from collections import Counter
class Element:
def __init__(self, short_name: str, electronic_conf_of_outer_layer: str,
name: str, atomic_number: int, relative_atomic_mass: float,
group: str, period: int, row: int, group_num: int,
side_group: bool, is_metal: bool):
self.short_name = short_name
self.electronic_conf_of_outer_layer = electronic_conf_of_outer_layer
self.name = name
self.atomic_number = atomic_number
self.relative_atomic_mass = relative_atomic_mass
self.group = group
self.side_group = side_group
self.is_metal = is_metal
self.period = period
self.row = row
self.group_num = group_num
ELEMENTS = {
# Символ ЭлКонф Название АтомноеЧисло ОтносАтомМасса группа период ряд
# номерГруппы ЭтопобочнаяГруппа ЭтоМетал
'H': Element('H', '1s^1', 'Водород', 1, 1.00794, 'A', 1, 1, 1, False, False),
'He': Element('He', '1s^2', 'Гелий', 2, 4.002602, 'A', 8, 1, 1, False, False),
'Li': Element('Li', '2s^1', 'Литий', 3, 6.941, 'A', 1, 2, 2, False, True),
'Be': Element('Be', '2s^2', 'Бериллий', 4, 9.01218, 'A', 2, 2, 2, False, True),
'B': Element('B', '2s^2 2p^1', 'Бор', 5, 10.811, 'A', 3, 2, 2, False, False),
'C': Element('C', '2s^2 2p^2', 'Углерод', 6, 12.011, 'A', 4, 2, 2, False, False),
'N': Element('N', '2s^2 2p^3', 'Азот', 7, 14.0067, 'A', 5, 2, 2, False, False),
'O': Element('O', '2s^2 2p^4', 'Кислород', 8, 15.9994, 'A', 6, 2, 2, False, False),
'F': Element('F', '2s^2 2p^5', 'Фтор', 9, 18.998403, 'A', 7, 2, 2, False, False),
'Ne': Element('Ne', '2s^2 2p^6', 'Неон', 10, 20.179, 'A', 8, 2, 2, False, False),
'Na': Element('Na', '3s^1', 'Натрий', 11, 22.98977, 'A', 1, 3, 3, False, True),
# добавляйте другие элементы по надобности
}
def repl(m):
return m[1] * int(m[2] if m[2] else 1)
def parse_molecule(formula: str) -> dict:
while '(' in formula:
formula = re.sub(r'\((\w*)\)(\d*)', repl, formula)
while '[' in formula:
formula = re.sub(r'\[(\w*)\](\d*)', repl, formula)
formula = re.sub(r'([A-Z][a-z]?)(\d*)', repl, formula)
formula_dict = Counter(re.findall('[A-Z][a-z]*', formula))
return formula_dict
def get_element_mass(element):
return ELEMENTS[element].relative_atomic_mass
def calculate_relative_molecular_mass(formula):
result = parse_molecule(formula)
mass = 0
for i in result.items():
print(f'{i[1]} {ELEMENTS[i[0]].name} = {ELEMENTS[i[0]].relative_atomic_mass * i[1]}')
mass += get_element_mass(i[0]) * i[1]
return mass
def main():
formula = input('Введите формулу: ')
mass = calculate_relative_molecular_mass(formula)
if mass is not None:
print(f'Относительная молекулярная масса формулы {formula} = ~{mass}')
else:
print(f'Ошибка парсинга формулы {formula}')
if __name__ == "__main__":
main()
В следующей статье мы затронем вычисления молярной массы, количества молекул, и количество вещества.
Всем удачи, всем пока, с вами был Доктор Аргентум