Найти - Пользователи
Полная версия: Вам дан список молекул и их атомная масса Посчитайте молярную массу молекул, используя методы функционального программирования. Выведите значения в порядке возрастания молярной массы.
Начало » Python для новичков » Вам дан список молекул и их атомная масса Посчитайте молярную массу молекул, используя методы функционального программирования. Выведите значения в порядке возрастания молярной массы.
1 2
ant976
Здравствуйте!

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

Вам дан список молекул и их атомная масса:

H (водород) — 1.008
O (кислород) — 15.999;
S (сера) — 32.066;
Na (натрий) — 22.990;
Cl (хлор) — 35.453;
K (калий) — 39.098.
Посчитайте молярную массу молекул, используя методы функционального программирования. Выведите значения в порядке возрастания молярной массы.

Входные данные



Вывод программы

H2-O 18.015
H-CL 36.461
NA-CL 58.443
K-CL 74.551
H2-S-O4 98.078
py.user.next
Что на вход подаётся?
ant976
Входные данные



ant976
список формул молекул:
'H2-S-O4', ‘H2-O’, ‘NA-CL’, ‘H-CL’, ‘K-CL’
py.user.next
ant976
По идее долно быть просто, но пока какие-то очень устрашающие алгоритмы в голову приходят.



список формул молекул:
['H2-S-O4', 'H2-O', 'NA-CL', 'H-CL', 'K-CL']

Нужно сделать функцию для самых крупных структур на данном уровне.
Самая крупная структура - это весь список молекул. Значит, нужно сделать функцию для списка молекул.
  
def count_mols(lst):
    pass

Дальше разрабатываем тело функци
  
def count_mols(lst):
    out = [count_mol(i) for i in lst]
    return out

Нужно сделать функцию для самых крупных структур на данном уровне.
Самая крупная структура - это одна молекула. Значит, нужно сделать функцию для одной молекулы.
  
def count_mols(lst):
    out = [count_mol(i) for i in lst]
    return out
 
def count_mol(mol):
    pass

Дальше разрабатываем тело функции
  
def count_mols(lst):
    out = [count_mol(i) for i in lst]
    return out
 
def count_mol(mol):
    atom_lst = mol.split('-')
    out = sum([count_atom(i) for i in atom_lst])
    return out

Нужно сделать функцию для самых крупных структур на данном уровне.
Самая крупная структура - это один атом. Значит, нужно сделать функцию для одного атома.
  
def count_mols(lst):
    out = [count_mol(i) for i in lst]
    return out
 
def count_mol(mol):
    atom_lst = mol.split('-')
    out = sum([count_atom(i) for i in atom_lst])
    return out
 
def count_atom(atom):
    pass

Дальше разрабатываем тело функции
  
def count_mols(lst):
    out = [count_mol(i) for i in lst]
    return out
 
def count_mol(mol):
    atom_lst = mol.split('-')
    out = sum([count_atom(i) for i in atom_lst])
    return out
 
def count_atom(atom):
    element = ''
    number = ''
    for c in atom:
        if c.isalpha():
            element += c
        elif c.isdigit():
            number += c
    num = 1
    if number:
        num = int(number)
    out = count_mass(element, num)
    return out

Нужно сделать функцию для самых крупных структур на данном уровне.
Самая крупная структура - это один элемент в количестве. Значит, нужно сделать функцию для одного элемента в количестве.
  
def count_mols(lst):
    out = [count_mol(i) for i in lst]
    return out
 
def count_mol(mol):
    atom_lst = mol.split('-')
    out = sum([count_atom(i) for i in atom_lst])
    return out
 
def count_atom(atom):
    element = ''
    number = ''
    for c in atom:
        if c.isalpha():
            element += c
        elif c.isdigit():
            number += c
    num = 1
    if number:
        num = int(number)
    out = count_mass(element, num)
    return out
 
def count_mass(element, number):
    pass

Дальше разрабатываем тело функции
  
def count_mols(lst):
    out = [count_mol(i) for i in lst]
    return out
 
def count_mol(mol):
    atom_lst = mol.split('-')
    out = sum([count_atom(i) for i in atom_lst])
    return out
 
def count_atom(atom):
    element = ''
    number = ''
    for c in atom:
        if c.isalpha():
            element += c
        elif c.isdigit():
            number += c
    num = 1
    if number:
        num = int(number)
    out = count_mass(element, num)
    return out
 
def count_mass(element, number):
    dct = {
        'H': 1.008
        ...
    }
    out = dct[element] * number
    return out

Проверяем
  
>>> def count_mols(lst):
...     out = [count_mol(i) for i in lst]
...     return out
...
>>> def count_mol(mol):
...     atom_lst = mol.split('-')
...     out = sum([count_atom(i) for i in atom_lst])
...     return out
...
>>> def count_atom(atom):
...     element = ''
...     number = ''
...     for c in atom:
...         if c.isalpha():
...             element += c
...         elif c.isdigit():
...             number += c
...     num = 1
...     if number:
...         num = int(number)
...     out = count_mass(element, num)
...     return out
...
>>> def count_mass(element, number):
...     dct = {
...         'H': 1.008
...     }
...     out = dct[element] * number
...     return out
...
>>> count_mols(['H', 'H2', 'H2-H3'])
[1.008, 2.016, 5.04]
>>>
vic57
py.user.next
зачем так сложно?
 d ={}
d['H'] = '1.008'
d['O'] = '15.999'
d['S'] = '32.066'
d['NA'] = '22.990'
d['CL'] = '35.453'
d['K'] = '39.098'
arr = ['H2-S-O4','H-CL','NA-CL','K-CL','H2-O']
out = []
for i in arr:
    t = i
    for k in d:
        if k in t: 
            t = t.replace(k,d[k]+'*')
    t = t.replace('-','+')
    t = t.replace('*+','+')
    if t.endswith('*'):
        t = t[:-1]
    out.append([i,round(eval(t),3)])
out.sort(key=lambda x: x[1])
for i in out: print('{0:10}{1}'.format(*i))
py.user.next
vic57
зачем так сложно?
Вот я добавил в твой код углерод и соляную кислоту
  
>>> d = {}
>>> d['H'] = '1.008'
>>> d['O'] = '15.999'
>>> d['S'] = '32.066'
>>> d['C'] = '12.011'
>>> d['NA'] = '22.990'
>>> d['CL'] = '35.453'
>>> d['K'] = '39.098'
>>> arr = ['H-CL', 'H2-S-O4','H-CL','NA-CL','K-CL','H2-O']
>>> out = []
>>> for i in arr:
...     t = i
...     for k in d:
...         if k in t:
...             t = t.replace(k,d[k]+'*')
...     t = t.replace('-','+')
...     t = t.replace('*+','+')
...     if t.endswith('*'):
...         t = t[:-1]
...     out.append([i,round(eval(t),3)])
...
Traceback (most recent call last):
  File "<stdin>", line 10, in <module>
  File "<string>", line 1, in <module>
NameError: name 'L' is not defined
>>> out.sort(key=lambda x: x[1])
>>> for i in out: print('{0:10}{1}'.format(*i))
...
>>>
Как видишь, ничего не выводится, так как твой код пытается найти элемент L в таблице Менделеева.

А вот я добавил в свой код углерод, хлор, соляную кислоту и метан
  
>>> def count_mols(lst):
...     out = [count_mol(i) for i in lst]
...     return out
...
>>> def count_mol(mol):
...     atom_lst = mol.split('-')
...     out = sum([count_atom(i) for i in atom_lst])
...     return out
...
>>> def count_atom(atom):
...     element = ''
...     number = ''
...     for c in atom:
...         if c.isalpha():
...             element += c
...         elif c.isdigit():
...             number += c
...     num = 1
...     if number:
...         num = int(number)
...     out = count_mass(element, num)
...     return out
...
>>> def count_mass(element, number):
...     dct = {
...         'H': 1.008,
...         'C': 12.011,
...         'CL': 35.453
...     }
...     out = dct[element] * number
...     return out
...
>>> count_mols(['H', 'H2', 'H2-H3', 'H-CL', 'C-H4'])
[1.008, 2.016, 5.04, 36.461000000000006, 16.043]
>>>
Как видишь, у меня это не вызвало вообще никаких проблем.

Это потому, что структурная парадигма программирования придаёт коду много скрытой прочности. Мы можем один раз написать код и не париться по поводу того, как его быстро поменять под какие-либо изменившиеся условия.

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

Например, язык Pascal сдох, когда сдох DOS, потому что Pascal был привязан к DOS'у. И теперь паскаля фактически нет. А вот язык C до сих пор живёт и здравствует, потому что он пережил несколько разных эпох, так как он не был привязан ни к чему.
xam1816

vic57
зачем так сложно?)))

 import re; molar_mass = lambda f: sum(int(n or 1) * {"H": 1.008, "O": 15.999, "S": 32.066, "Na": 22.990, "Cl": 35.453, "K": 39.098}[e] for e, n in re.findall(r"([A-Z][a-z]*)(\d*)", f))
print(molar_mass("H2-SO4"))

На самом деле, py.user.next на примере этой задачи, показал подход к решению многих задач, потому что для некоторых тут сложность скорее психологическая, как и описал ТС.
ant976
Завис. По идее долно быть просто, но пока какие-то очень устрашающие алгоритмы в голову приходят.


Думаю он начинает представлять много разных алгоритмов, из которых не может найти оптимальный. И что делать в таком случае?

Знающие скажут:"поможет декомпозиция, разбиение
", так даже этому нужно учиться, чтобы понять, что тут большое, а что маленькое.
py.user.next
xam1816
  
import re; molar_mass = lambda f: sum(int(n or 1) * {"H": 1.008, "O": 15.999, "S": 32.066, "Na": 22.990, "Cl": 35.453, "K": 39.098}[e] for e, n in re.findall(r"([A-Z][a-z]*)(\d*)", f))
print(molar_mass("H2-SO4"))
Я добавил соляную кислоту в код xam1816
  
>>> import re; molar_mass = lambda f: sum(int(n or 1) * {"H": 1.008, "O": 15.999, "S": 32.066, "Na": 22.990, "Cl": 35.453, "K": 39.098}[e] for e, n in re.findall(r"([A-Z][a-z]*)(\d*)", f))
>>> print(molar_mass("H-CL"))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in <lambda>
  File "<stdin>", line 1, in <genexpr>
KeyError: 'C'
>>> 
И код не смог её распознать.

Это потому, что структурная парадигма программирования придаёт коду много скрытой прочности. Один из элементов этой прочности - это ясность кода. Мы очень быстро замечаем ошибки и неточности в больших массивах кода благодаря его ясности и простоте. Если же мы игнорируем теорию и пишем какой-то запутанный однострочник, то мы очень легко потом в упор не замечаем какие-то элементарные ошибки и пропускаем их. Когда мы их обнаруживаем потом, нам сначала надо понять запутанный однострочник и потом поменять его так, чтобы из-за этого изменения в нём не сломалось то, что работало в нём раньше. В итоге это приведёт к выкидыванию кода и написанию нового запутанного однострочника с нуля.
vic57
py.user.next
недосмотрел, согласен
ИМХО тут все что надо - преобразовать выражение H2-S-O4 к виду H*2+O+S*4
 import re
d ={}
d['H'] = 1.008
d['O'] = 15.999
d['S'] = 32.066
d['NA'] = 22.990
d['CL'] = 35.453
d['K'] = 39.098
d['C'] = 10 #
d['L'] = 5 #для примера
arr = ['H2-S-O4','H-CL','NA-CL','K-CL','H2-O','C-O2']
out = []
for i in arr:
    t = i.split('-')
    for j in range(len(t)):
        match = re.search('\d',t[j])
        if match: 
            idx = match.start()
            m,n = t[j][:idx],int(t[j][idx:])
        else: m,n = t[j],1
        if m in d: 
            t[j] = d[m]*n
    out.append([i,round(sum(t),3)])
out.sort(key=lambda x: x[1])
for i in out: print('{0:10}{1}'.format(*i))
 H2-O      18.015
H-CL      36.461
C-O2      41.998
NA-CL     58.443
K-CL      74.551
H2-S-O4   98.078
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB