Уведомления

Группа в Telegram: @pythonsu

#1 Янв. 17, 2018 16:15:07

SomethingButNotNickName
Зарегистрирован: 2017-12-19
Сообщения: 75
Репутация: +  0  -
Профиль   Отправить e-mail  

Регулярные выражения

Добрый день.
Есть файл в котором строками прописаны сотрудники и их оклад. Причем между фамилией и именем может быть какая то еще информация. Какая именно неизвестно. Например строка выглядит так.

 line = 'Петров Герой труда Петр 100000'
Задача по имени вытащить оклад сотрудника.
Как вариант можно пробежать по файлу и проверить каждую строку на наличие в ней интересующей фамилии. Если возвращен список не нулевой длины, т.е. есть совпадение, пробежать повторно уже доставая оклад.

 surname = 'Петров'    # имена и фамилии также хранятся в соответствующих переменных.
import re
if len(re.findall(surname, line)) != 0:
    pay = re.findall(r'\d+', line)
print(pay)

Но в списке могут быть и однофамильцы. Следовательно нужно передать в качестве паттерна две переменных (имя и фамилию). Вот тут я уже теряюсь и прошу помощи.
Так же, насколько я понимаю, в питоне должны поддерживаться условия внутри регулярок. Но заставить их работать тоже не удалось. Можно пример?

Отредактировано SomethingButNotNickName (Янв. 17, 2018 16:23:59)

Офлайн

#2 Янв. 17, 2018 16:27:17

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9731
Репутация: +  843  -
Профиль   Отправить e-mail  

Регулярные выражения

Напиши функцию, которая принимает строку файла и возращает словарь, в котором данные из строки разделены по ключам. Потом просто каждую строку передаёшь в эту функцию и в полученном из неё словаре ищешь нужные данные.



Отредактировано py.user.next (Янв. 17, 2018 16:27:47)

Офлайн

#3 Янв. 17, 2018 16:54:29

SomethingButNotNickName
Зарегистрирован: 2017-12-19
Сообщения: 75
Репутация: +  0  -
Профиль   Отправить e-mail  

Регулярные выражения

py.user.next
Напиши функцию, которая принимает строку файла и возращает словарь, в котором данные из строки разделены по ключам. Потом просто каждую строку передаёшь в эту функцию и в полученном из неё словаре ищешь нужные данные.
Как вариант - да.

Ну а насчет регулярок? Такие операции невозможны в питоне?

Офлайн

#4 Янв. 17, 2018 17:02:05

SomethingButNotNickName
Зарегистрирован: 2017-12-19
Сообщения: 75
Репутация: +  0  -
Профиль   Отправить e-mail  

Регулярные выражения

Дело в том, что:
1) условие задачи целиком выглядит так
# Задание-1: Решите задачу (дублированную ниже):

# Дана ведомость расчета заработной платы (файл “data/workers”). Рассчитайте зарплату всех работников,
# зная что они получат полный оклад, если отработают норму часов. Если же они отработали меньше нормы,
# то их ЗП уменьшается пропорционально, а за заждый час переработки они получают удвоенную ЗП,
# пропорциональную норме.
# Кол-во часов, которые были отработаны, указаны в файле “data/hours_of”

# С использованием классов.
# Реализуйте классы сотрудников так, чтобы на вход функции-конструктора каждый работник получал строку из файла
т.е. то, что вы предлагаете засунуть в словарь уже находится внутри класса.
2) половина данных о сотруднике лежит в одном файле, а половина (включая и з/п) в другом.
И мне нужны данные из обоих файлов. А строки в них перемешаны до кучи.
Файлы тоже с датой вложил

Отредактировано SomethingButNotNickName (Янв. 17, 2018 17:03:53)

Прикреплённый файлы:
attachment workers.txt (921 байт)

Офлайн

#5 Янв. 17, 2018 17:02:50

SomethingButNotNickName
Зарегистрирован: 2017-12-19
Сообщения: 75
Репутация: +  0  -
Профиль   Отправить e-mail  

Регулярные выражения

второй файл

Прикреплённый файлы:
attachment hours_of.txt (307 байт)

Офлайн

#6 Янв. 17, 2018 17:06:10

SomethingButNotNickName
Зарегистрирован: 2017-12-19
Сообщения: 75
Репутация: +  0  -
Профиль   Отправить e-mail  

Регулярные выражения

Первая копия workers не верная.
Правильная тут

Прикреплённый файлы:
attachment workers.txt (922 байта)

Офлайн

#7 Янв. 17, 2018 17:39:23

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9731
Репутация: +  843  -
Профиль   Отправить e-mail  

Регулярные выражения

SomethingButNotNickName
т.е. то, что вы предлагаете засунуть в словарь уже находится внутри класса
Это тебе кажется так.

Надо для каждого файла сделать свою функцию обработки его строки. Функция такая: на вход принимается строка файла; на выходе возвращается словарь, в котором поля строки разделены по ключам.
Для каждого файла должна быть своя функция обработки строки этого файла.
Эти функции никакого отношения к твоему заданию не имеют. Они используются для того, чтобы точно работать с данными. Таким образом при чтении первого файла у тебя получаются словари из его строк, и в этих словарях можно легко искать любые поля (фамилию, имя, зарплату, часы), просто обращаясь к ним по именам. С сырой строкой ты этого не сделаешь, даже если сделаешь регулярку, потому что регулярка не будет тебе давать именованных полей.

SomethingButNotNickName
Ну а насчет регулярок?
Регулярки используются только внутри таких функций для разделения строк на поля. Больше нигде. Когда словарь для одной строки файла возвращён, поля в нём разделены точно и имеют удобные имена, поэтому никакие регулярки больше не требуются.

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

Например, ты получил словарь первой строки первого файла и словарь первой строки второго файла. Эти словари разные, но брать поля из них легко. Ты берёшь из них поля (допустим, фамилии) и сравниваешь между собой. Если фамилии одинаковые, значит эти словари относятся к одному работнику и ты можешь из этих словарей брать следующие данные и куда-то их копировать или совместные вычисления проводить. Можно и просто взять два словаря, относящиеся к одному работнику, и сделать из них третий словарь, более полный. Вот твой этот класс, которые требуется в задании, имеет примерно такую структуру - словари из разных файлов, слитые в один словарь, и так по каждому работнику. Только вместо словаря используется класс, у которого внутри хранятся эти данные одного работника. Отличие словаря от класса в том, что класс может меняться по своему устройству, а словарь остаётся неизменным. Но класс может иметь и поведение, тогда как словарь используется только для хорошо структурированного хранения данных.

Пример
Разделение строки
  
>>> import re
>>> 
>>> def split1(s):
...     parts = re.findall(r'^(\S+).*\s(\S+)\s+(\d+)$', s)[0]
...     out = {'surname': parts[0],
...            'firstname': parts[1],
...            'salary': int(parts[2])}
...     return out
... 
>>> 
>>> s = 'Петров Герой труда Петр 100000'
>>> 
>>> d = split1(s)
>>> d
{'surname': 'Петров', 'firstname': 'Петр', 'salary': 100000}
>>> d['salary'] * 2
200000
>>>

Несколько человек из файла
  
>>> import re
>>> 
>>> def split1(s):
...     parts = re.findall(r'^(\S+).*\s(\S+)\s+(\d+)$', s)[0]
...     out = {'surname': parts[0],
...            'firstname': parts[1],
...            'salary': int(parts[2])}
...     return out
... 
>>> 
>>> lst = ['Петров Герой труда Петр 100000',
...        'Иванов Саша 5100',
...        'Сидоров Старик Андрей 12345']
>>> 
>>> out = list(map(split1, lst))
>>> out
[{'surname': 'Петров', 'firstname': 'Петр', 'salary': 100000}, {'surname': 'Иванов', 'firstname': 'Саша', 'salary': 5100}, {'surname': 'Сидоров', 'firstname': 'Андрей', 'salary': 12345}]
>>>

Разделение по всем полям
  
>>> import re
>>> 
>>> def split1(s):
...     parts = re.findall(r'^(\S+)\s*(.*)\s+(\S+)\s+(\d+)$', s)[0]
...     out = {'surname': parts[0],
...            'firstname': parts[2],
...            'status': parts[1] or None,
...            'salary': int(parts[3])}
...     return out
... 
>>> 
>>> lst = ['Петров Герой труда Петр 100000',
...        'Иванов Саша 5100',
...        'Сидоров Старик Андрей 12345']
>>> 
>>> out = list(map(split1, lst))
>>> out
[{'surname': 'Петров', 'firstname': 'Петр', 'status': 'Герой труда', 'salary': 100000}, {'surname': 'Иванов', 'firstname': 'Саша', 'status': None, 'salary': 5100}, {'surname': 'Сидоров', 'firstname': 'Андрей', 'status': 'Старик', 'salary': 12345}]
>>>



Отредактировано py.user.next (Янв. 17, 2018 18:01:41)

Офлайн

#8 Янв. 17, 2018 19:33:22

SomethingButNotNickName
Зарегистрирован: 2017-12-19
Сообщения: 75
Репутация: +  0  -
Профиль   Отправить e-mail  

Регулярные выражения

насколько я понял предлагается такой алгоритм:
1) сортировка одного из файлов, чтобы конкретному человеку соответствовала строка под одинаковым номером в обоих файлах, т.е. мы перезаписываем один из файлов;
2) в цикле:
а) взять строку первого файла;
б) взять строку второго файла;
в) слепить из них класс, описать в этом классе метод подсчета заработка;
г) запустить метод подсчета заработка и вывести результат.
Таким образом, мы пробежим по обоим файлам и после прочтения строки будем выдавать результат.
И в памяти не будут лежать не нужные словари по сотрудникам, которые ожидают расчета или уже рассчитаны.

Все верно?

и еще вопрос по регулярке

 parts = re.findall(r'^(\S+).*\s(\S+)\s+(\d+)$', s)[0]
$ - указатель на конец строки, т.е. если после цифр будет что-то еще паттерн не должен сработать. А для чего эта проверка?


Офлайн

#9 Янв. 17, 2018 21:44:34

marvellik
Зарегистрирован: 2016-05-15
Сообщения: 639
Репутация: +  73  -
Профиль   Отправить e-mail  

Регулярные выражения

py.user.next а не проще создать словарь где ключ это имя фамилия ну а значение зарплата?
мне кажется меньше путаницы будет

Офлайн

#10 Янв. 18, 2018 04:07:17

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9731
Репутация: +  843  -
Профиль   Отправить e-mail  

Регулярные выражения

marvellik
py.user.next а не проще создать словарь где ключ это имя фамилия ну а значение зарплата?
К одному человеку относится куча всяких значений. Поэтому для одного человека делается один словарь и все данные в нём относятся только к этому человеку. А полей там может быть сотня.

marvellik
мне кажется меньше путаницы будет
Путаница тут возникает только оттого, что SomethingButNotNickName думает, что может сам что-то сделать. Ему говорят “делай словари”, а он такой “нет, мне вот словари не нужны, мне сказали классы какие-то там делать”. Ему опять говорят “делай словари”, а он опять повторяет то же самое. Вот это путаница.

SomethingButNotNickName
1) сортировка одного из файлов, чтобы конкретному человеку соответствовала строка под одинаковым номером в обоих файлах, т.е. мы перезаписываем один из файлов;
А если там будет разное количество людей?
А если там будет миллион людей ещё к тому же?
То есть ты будешь затратно сортировать, а смысла в этом не будет никакого. Ты не контролируешь содержимое этих файлов. Откуда оно приходит и кого туда могут добавить? - это всё от тебя не зависит.

SomethingButNotNickName
а) взять строку первого файла;
б) взять строку второго файла;
И первая строка - один человек, а другая строка - другой человек. (Это ты отсортировал файлы, в которых есть разные люди, но ты про это не знал.)
Как ты, вообще, прогарантировал то, что даже просто люди одни и те же в этих файлах? С чего ты взял, что эти файлы образуют биективное отображение? Может, в первом файле есть человек, которого нет во втором файле, а во втором файле есть человек, которого нет в первом файле? Да, они могут пересекаться, но пересечение ещё не гарантирует, что эти файлы отображаются один человек в один человек в обе стороны. В задании это нигде не написано.

И в реале обычно так и устроены базы данных: есть просто разные таблицы, где есть одинаковые элементы (люди, товары и прочее), в каждой таблице свои какие-то данные про эти элементы; но из того, что эти данные есть в обеих таблицах, не следует, что эти таблицы связаны друг с другом. Одну таблицу может одна хрень какая-нибудь заполнять, а другую таблицу может другая хрень заполнять. И первая хрень не будет смотреть во вторую таблицу, а вторая хрень не будет смотреть в первую таблицу. Они про них не знают, они только за свои таблицы отвечают.

SomethingButNotNickName
$ - указатель на конец строки, т.е. если после цифр будет что-то еще паттерн не должен сработать. А для чего эта проверка?
Оно может совпасть с чем-нибудь в середине. Ты никак не контролиуешь то, что в середине не может быть цифр. Например “фамилия ударник завода номер 123 имя зарплата”. Вот чтобы оно в середине ни с чем не совпало, ты говоришь ему “ищи в конце цифры и бери от них первое слово слева”.



Отредактировано py.user.next (Янв. 18, 2018 04:15:05)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version