Я попробовал решить несколько простых школьных задач по химии в Python с помощью библиотек mendeleev, chemlib и chempy.

Каждая из “химических” библиотек Python содержит в себе оцифрованную базу данных химических элементов из периодической таблицы Менделеева. Из нее можно получить основные свойства химических элементов, например, атомную массу, группу, электронную конфигурацию и т.п.

Имея под рукой быстрый доступ к свойствам химических элементов, физическим константам (например, число Авогадро, постоянная Планка, скорость света и др.) и ряду функций, я решил несколько задач, в том числе несколько заданий из ОГЭ и ЕГЭ.

Задача №1

Начнем с простого - определим относительную молекулярную массу вещества на примере серной кислоты. В тетрадке эта задача решается так:

расчет относительной молекулярной массы вещества (где 1, 32 и 16 - это атомные массы водорода, серы и кислорода соответственно из таблицы Менделеева)
расчет относительной молекулярной массы вещества (где 1, 32 и 16 - это атомные массы водорода, серы и кислорода соответственно из таблицы Менделеева)

В скрипте используем библиотеку chemlib и импортируем объект Compound для расчета:

import chemlib
from chemlib import Compound
sulphuric_acid = Compound("H2SO4")
print('%.0f' % sulphuric_acid.molar_mass())

>>>98

Задача №2

Во второй задаче рассчитаем массовую долю кислорода в серной кислоте:

расчет массовой доли элемента в веществе
расчет массовой доли элемента в веществе

Используем функцию percentage_by_mass из библиотеки chemlib для расчета в Python:

import chemlib
from chemlib import Compound
sulphuric_acid = Compound("H2SO4")
print('%.0f' % sulphuric_acid.percentage_by_mass('O'))

>>>65

Задача №3

Сколько граммов сульфата меди (II) нужно внести в реакционную смесь, если для проведения реакции необходимо 8 г меди (II)?

Для решения задачи сначала нужно рассчитать массовую долю меди в сульфате меди. После разделим необходимую массу меди на эту долю:

расчет необходимой массы вещества для реакции
расчет необходимой массы вещества для реакции

В скрипте это будет выглядеть так:

import chemlib
from chemlib import Compound
copper_sulfate = Compound("CuSO4")
copper_mass = 8
print('%.0f' % (copper_mass / (copper_sulfate.percentage_by_mass('Cu')/100)))

>>> 20

Задача №4

Рассчитаем массу и число молекул для метана взятого в количестве 0,5 Моль вещества.

где N а - постоянная Авогадро (6,02 *10^23)
где N а - постоянная Авогадро (6,02 *10^23)

В скрипте применим уже готовые функции для расчета:

import chemlib
from chemlib import Compound
methane = Compound("CH4")
print('%.0f' % methane.get_amounts(moles = 0.5)['grams'])
print(methane.get_amounts(moles = 0.5)['molecules'])

>>>8
>>>3.01e+23

Таблица Менделеева

Перейдем к другой библиотеке - mendeleev - в ней тоже есть готовые функции для решения первых четырех задач. В mendeleev можно визуализировать периодическую систему химических элементов:

import mendeleev
from mendeleev.vis import periodic_table
periodic_table()
mendeleev - визуализация периодической системы химических элементов в цветах по умолчанию
mendeleev - визуализация периодической системы химических элементов в цветах по умолчанию

Задача №5

Вспомним как записывается электронная формула химического элемента и где у него расположены валентные электроны. Например, для ванадия (V) и мышьяка (As) в школьной тетради это выглядит так:

здесь применяется "правило троллейбуса, автобуса или трамвая" (кого как учили)
здесь применяется "правило троллейбуса, автобуса или трамвая" (кого как учили)

Импортировать химический элемент из библиотеки mendeleev можно либо через функцию element(V), либо как показано ниже в коде. Выведем электронную формулу и валентные электроны для мышьяка и ванадия:

import mendeleev
from mendeleev import As, V
print(As.name, As.ec," // ", As.econf)
print(V.name, V.ec," // ", V.econf)

>>>Arsenic 1s2 2s2 2p6 3s2 3p6 3d10 4s2 4p3  //  [Ar] 3d10 4s2 4p3
>>>Vanadium 1s2 2s2 2p6 3s2 3p6 3d3 4s2  //  [Ar] 3d3 4s2

Задача №6

В этой задаче нужно определить два элемента из списка [Cs, C, O, Cr, N], атомы которых в основном состоянии имеют одинаковое число неспаренных электронов.

Задача решается так же как и предыдущая через вывод электронной формулы элементов.

Добавим нужную функцию unpaired_electrons() и выведем количество неспаренных электронов для всех элементов:

import mendeleev
from mendeleev import Cs, C, O, Cr, N
import pandas as pd
    
df = pd.DataFrame([x.name, x.ec.unpaired_electrons()] for x in [Cs, C, O, Cr, N])
columns = ['Название элемента','Количество неспаренных электронов']
df.columns = columns
df
промежуточный вывод к задаче №6
промежуточный вывод к задаче №6

Добавим шаг для получения итогового ответа:

pd.concat(x for _, x in df.groupby('Количество неспаренных электронов') if len(x) > 1)
итоговый ответ к задаче №6
итоговый ответ к задаче №6

Задача №7

В задаче нужно рассчитать какая масса серной кислоты может быть получена из пирита массой 40 тонн.

Промышленный способ получения серной кислоты из пирита состоит из нескольких этапов и стехиометрическая цепочка выглядит следующим образом:

FeS2 →SO2 →SO3 →H2SO4

Для расставления коэффициентов уравнений распишем каждый этап отдельно.

На первом этапе подбираем коэффициенты уравнения через количество отданных и принятых электронов для элементов, которые меняют валентность в процессе реакции:

Следующие два этапа уравниваются проще:

Итоговая цепочка выглядит так: 

4FeS2 →8SO2 →8SO3 →8H2SO4  или сокращенно так  FeS2→2H2SO4

Итоговый ответ получаем из решения пропорции:

Теперь решим эту же задачу в Python. Для решения задачи со стехиометрическими цепочками воспользуемся библиотекой chempy. Импортируем функцию balance_stoichiometry и выведем коэффициенты для первого уравнения:

import chempy
from chempy import balance_stoichiometry
reac1, prod1 = balance_stoichiometry({'FeS2', 'O2'}, {'Fe2O3', 'SO2'})
print(dict(reac1), dict(prod1))

>>> {'FeS2': 4, 'O2': 11} {'Fe2O3': 2, 'SO2': 8}

Аналогично для второго и третьего:

import chempy
from chempy import balance_stoichiometry
reac2, prod2 = balance_stoichiometry({'SO2', 'O2'}, {'SO3'})
print(dict(reac2), dict(prod2))

>>> {'O2': 1, 'SO2': 2} {'SO3': 2}

reac3, prod3 = balance_stoichiometry({'SO3', 'H2O'}, {'H2SO4'})
print(dict(reac3), dict(prod3))

>>> {'H2O': 1, 'SO3': 1} {'H2SO4': 1}

Воспользуемся функциями расчета молярных масс исходного (пирита) и конечного вещества (серной кислоты):

import chempy
from chempy import Substance
pyrite, sulfuric_acid = Substance.from_formula('FeS2'), Substance.from_formula('H2SO4')
print('Молярная масса пирита '+ '%.0f' % pyrite.mass + ' г/моль')
print('Молярная масса серной кислоты '+ '%.0f' % sulfuric_acid.mass + ' г/моль')

>>> Молярная масса пирита 120 г/моль
>>> Молярная масса серной кислоты 98 г/моль

Выведем итоговый ответ:

pyrite_weight = 40
print(round((pyrite_weight * 2 * sulfuric_acid.mass) / pyrite.mass, 1))

>>> 65.4

Задача №8

При сгорании 8,4 г этилена выделяется 423,3 кДж теплоты. Вычислите количество теплоты, которое выделится при сгорании 0,896 м3 (при н.у.) этилена. [C2H4 + 3O2 → 2CO2 + 2H2O + Q]

Эта задача решается в несколько действий:

  1. Определим количество этилена, которое участвует в первой реакции n(C2H4)1 через молярную массу.

  2. Определим количество этилена, которое участвует во второй реакции n(C2H4)2 через объем газа при нормальных условиях.

  3. Рассчитаем количество теплоты, которое выделится во второй реакции через пропорцию.

расчет по термохимическому уравнению
расчет по термохимическому уравнению

Сделаем аналогичный расчет в Python:

from chempy import Substance
ethylene_mass = 8.4
ethylene = Substance.from_formula('C2H4')
ethylene_n1 = round(ethylene_mass/ethylene.mass,1)
print('Количество этилена в первой реакции '+ str(ethylene_n1) + ' моль')

>>> Количество этилена в первой реакции 0.3 моль

ethylene_volume = 0.896*1000
ethylene_n2 = ethylene_volume/22.4
print('Количество этилена во второй реакции '+ str(ethylene_n2) + ' моль')

>>> Количество этилена во второй реакции 40.0 моль

Q1 = 423.3
Q2 = (ethylene_n2 * Q1)/ethylene_n1
print('Количество теплоты во второй реакции '+ str(Q2) + ' кДж')

>>> Количество теплоты во второй реакции 56440.0 кДж

На этом я решил остановиться. Собрал все примеры вместе в одном ноутбуке School Chemistry Assignments.ipynb

Есть и другие библиотеки химической тематики. Здесь хорошая подборка с кратким описанием - Awesome Python Chemistry.

По итогу можно сделать вывод, что существующих библиотек с оцифрованной версией таблицей Менделеева и дополнительными функциями достаточно для решения простых задач по химии. Это можно использовать как инструмент для проверки ответов, рассчитанных вручную.

На мой взгляд это интересный пример совмещения развития навыков программирования на Python с практическим решением задач по химии в школе.

Комментарии (11)


  1. ainoneko
    19.10.2023 14:46
    +6

    Не было у нас "транспортного" правила рассадки электронов.


    1. leongurman
      19.10.2023 14:46

      +1. Это называлось принцип Паули и правило Хунда.


      1. denis_afanasyev Автор
        19.10.2023 14:46

        в университете уже был принцип Паули и правило Хунда, но в школе учили по "правилу трамвая"


        1. leongurman
          19.10.2023 14:46

          видимо от года обучения зависит. я окончил школу в 1984.


  1. turbidit
    19.10.2023 14:46

    А зачем лишний импорт библиотек?


    1. denis_afanasyev Автор
      19.10.2023 14:46

      добавил для удобства, если рассматривать каждую задачу отдельно


  1. Matshishkapeu
    19.10.2023 14:46
    +1

    А если школьнику стало интересно, но времена игр с карбидом он не застал, то ацетилен с избытком воздуха можно подрывать не выходя из петона, используя Cantera. Но там чтобы составить условия с ЕГЭ по химии и физике все должно быть ОК на старте.


  1. ebt
    19.10.2023 14:46

    Ваш интерес в высшей степени похвален. Рекомендую продолжить с химической термодинамикой, например, с теорией фазовых диаграмм, и с теорией твёрдого тела, кристаллографией, либо с экспериментальным уклоном (порошковая дифракция), либо с теоретическим уклоном (классическое молекулярно-механическое моделирование). Питон и информатика в этих областях становятся особенно красивы : )


    1. denis_afanasyev Автор
      19.10.2023 14:46

      спасибо! увидел другие библиотеки для решения серьезных задач, но с ними придется повозиться чуть подольше. В любом случае это увлекательный процесс. Здесь хотел опровергнуть свою же гипотезу о том, что химические задачи по-прежнему решают на листочке.


      1. aamonster
        19.10.2023 14:46

        Ну, всё ещё видится, что школьные задачки на листочке решить проще и быстрей (не надо разбираться с библиотеками), но было интересно.


  1. ptr128
    19.10.2023 14:46
    +1

    Самого главного не увидел. Как зная реагенты (левую часть формулы), написать результат (правую часть формулы). Или указать, что реакция не пойдет.