Comments 13
Я правильно понимаю что эта задача сводится к
Дано n множеств N1, N2,… Nn: ∀1 ≤ k ≤ n |Nk| ≥ 1
Найти множества: |Nk ⋂ Nj| ≥ max(|Nk|, |Nj|) / 2: j ≠ k
?
Потому что в этом случае решение укладывается в 3 строки:
import itertools
# данные, каждая цифра соотвествует директору
data = (
{1, 2, 3, 4},
{1, 2, 3, 5},
{3, 4, 5, 6, 7}
)
# решение
for s0, s1 in itertools.combinations(data, 2):
if len(s0 & s1) > max(len(s0), len(s1)) / 2:
print(s0 & s1)
0
Общий смысл задачи: проверить, что любые 3 директора из 5 предложенных пользователем должны находиться в строке с директорами общества.
0
Спасибо! Но ведь тогда всё ещё проще:
# предложенные директора
managers_of_interest = {1, 2, 3}
data = (
{1, 2, 3, 4},
{1, 2, 3, 5},
{3, 4, 5, 6, 7}
)
for s in data:
if managers_of_interest & s:
print(s)
A в предыдущем примере так и вообще ничего вводить не надо — программа сама найдёт все организации в которых пересечение директоров больше 50%. И уже в этом результате имеет смысл искать конкретные имена.
0
По 1-му коду:
да, он выявил, что есть пересечение по 1,2,3, но в каких обществах не указал.
Кроме того, пользователь вводит 5-ть человек, а не троих. Из этих 5-х надо понять кто трое есть в строке с обществом в любой комбинации.
По 2-му коду.
Вывод:
{1, 2, 3, 4}
{1, 2, 3, 5}
{3, 4, 5, 6, 7}
Но в третьей строке нет пересечения! Там нет троицы «1,2,3».
да, он выявил, что есть пересечение по 1,2,3, но в каких обществах не указал.
Кроме того, пользователь вводит 5-ть человек, а не троих. Из этих 5-х надо понять кто трое есть в строке с обществом в любой комбинации.
По 2-му коду.
Вывод:
{1, 2, 3, 4}
{1, 2, 3, 5}
{3, 4, 5, 6, 7}
Но в третьей строке нет пересечения! Там нет троицы «1,2,3».
0
как то так
def myfun(x, y, z):
# получим множество кортежей с директорами
directors = set(tuple(x.value for x in sheet['C2':'L36'].rows))
# Получим список всех идентификаторов организаций
companies = tuple(x.value for x in sheet['А2':'A36'])
data_dict = dict(zip(companies, directors))
checked_directors = set(x, y, z)
for key, value in data_dict:
if checked_directors.issubset(value):
h.write(str(key) + '\n')
0
Думаю в таком виде будет более изящное решение, и чуть более наглядное чем в статье.
Плюс учитывается что при заполнении таблицы имеются дубликаты ФИО (как в файле, когда один человек встречается 2 раза) и в таком случае он не добавляется в СД.
Плюс учитывается что при заполнении таблицы имеются дубликаты ФИО (как в файле, когда один человек встречается 2 раза) и в таком случае он не добавляется в СД.
Код
def find_managers(inp_list, search_manages, min_find=3, skip_dupl=True):
main_dict = {}
for x in inp_list:
i = 0
for j in x:
if i == 0:
company_name = j
main_dict[company_name] = {}
main_dict[company_name]["managers"] = []
main_dict[company_name]["count"] = 0
main_dict[company_name]["searh_managers"] = []
main_dict[company_name]["searh_count"] = 0
main_dict[company_name]["searh_share"] = 0
i += 1
else:
if isinstance(j, str):
bAdd = True
if skip_dupl:
if j in main_dict[company_name]["managers"]:
print(f"Дубликат {j} в членах СД компании {company_name}")
bAdd = False
if bAdd:
main_dict[company_name]["managers"].append(j)
if j in search_manages:
main_dict[company_name]["searh_managers"].append(j)
main_dict[company_name]["searh_count"] += 1
main_dict[company_name]["count"] += 1
if min_find >= 0:
if main_dict[company_name]["searh_count"] < min_find:
main_dict.pop(company_name, None)
continue
if main_dict[company_name]["count"] == 0:
main_dict[company_name]["searh_share"] = 0
else:
main_dict[company_name]["searh_share"] = (main_dict[company_name]["searh_count"] / main_dict[company_name]["count"] * 100)
main_dict[company_name]["managers"] = sorted( main_dict[company_name]["managers"])
main_dict[company_name]["searh_managers"] = sorted(main_dict[company_name]["searh_managers"])
return main_dict
import pprint
import pandas as pd
fing_names = []
fing_names.append("ЖаровЖ.Ж.")
fing_names.append("ИволгинИ.И.")
fing_names.append("СидоровС.С.")
fing_names.append("ДятловД.Д.")
fing_names.append("КлюевК.К.")
df = pd.read_excel("sd3.xlsx", sheet_name="Лист1", header=None, skiprows=0)
info = find_managers(df.drop(0, axis="columns").iloc[:, 0:].values.tolist(), fing_names, 3, True)
pp = pprint.PrettyPrinter(width=1, compact=True)
pp.pprint(info)
+1
Да, это более удачная реализация.
Единственно поправил, чтобы пользователь мог сам вводить состав СД для проверки:
Единственно поправил, чтобы пользователь мог сам вводить состав СД для проверки:
fing_names.append(str(input("Директор-1: ")))
fing_names.append(str(input("Директор-2: ")))
fing_names.append(str(input("Директор-3: ")))
fing_names.append(str(input("Директор-4: ")))
fing_names.append(str(input("Директор-5: ")))
0
Все-таки при прогоне, предложенная в комменте программа выдает лишнее:
выводит совпадение при менее 50 %.
Немного переписал, используя множества python. Теперь учитываются составы CД, с 7-ю и 9-тью членами СД и выдает только общества при совпадении более 50%:
Код:
выводит совпадение при менее 50 %.
Немного переписал, используя множества python. Теперь учитываются составы CД, с 7-ю и 9-тью членами СД и выдает только общества при совпадении более 50%:
Код:
Код
import openpyxl
import pprint
wb = openpyxl.load_workbook('sd2.xlsx')
sheet=wb.get_active_sheet()
a=str(input("Директор-1: "))
b=str(input("Директор-2: "))
c=str(input("Директор-3: "))
e=str(input("Директор-4: "))
f=str(input("Директор-5: "))
test=[]
h = open('итог_по_СД.txt','w')
s2 = set()
s1 = {a,b,c,e,f}
itog=0
found=[]
for row in sheet['C3':'K38']:
#s2={row}
#print(s2)
for cellObj in row:
s2.add(cellObj.value)
if cellObj.value ==None:
#print(s2)
if len(s2)==6: # если в множестве 5 чел +None
itog=s2-s1
if 4>len(itog)>=0:
d = list(cellObj.coordinate)
d[0]='B'
dd=d[0]+d[1]
if len(d)>2:
dd=d[0]+d[1]+d[2]
i=sheet[str(dd)].value
if i not in found:
found.append(i)
elif len(s2)==8: # если в множестве 7 чел +None
itog=s2-s1
if 5>len(itog)>=3:
d = list(cellObj.coordinate)
d[0]='B'
dd=d[0]+d[1]
if len(d)>2:
dd=d[0]+d[1]+d[2]
i=sheet[str(dd)].value
if i not in found:
found.append(i)
elif len(s2)==10: # если в множестве 9 чел +None
itog=s2-s1 # вычитаем из 9 чел 5 чел, которые ввел пользователь
if len(itog)==5: #если осталось 4 чел (т.е.сопадают более 50%, то выводим имя общества)
d = list(cellObj.coordinate)
d[0]='B'
dd=d[0]+d[1]
if len(d)>2:
dd=d[0]+d[1]+d[2]
i=sheet[str(dd)].value
if i not in found:
found.append(i)
continue
s2 = set()
for i in found:
print (i)
h.write (i+'\n')
h.close()
0
Sign up to leave a comment.
Определяем взаимозависимых лиц по составам советов директоров с помощью python