fruitpicker01 commited on
Commit
33a02ce
1 Parent(s): 9f4be58

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +381 -1
app.py CHANGED
@@ -268,6 +268,369 @@ def generate_all_messages(desc, benefits, key_message, gender, generation, psych
268
  # Небольшая пауза между выводом каждого сообщения
269
  time.sleep(1)
270
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
271
 
272
  # Интерфейс Gradio
273
  with gr.Blocks() as demo:
@@ -398,6 +761,23 @@ with gr.Blocks() as demo:
398
  success_forecast_3 = gr.Plot(label="Прогноз успешности сообщения 3")
399
  gr.HTML("</div>")
400
 
401
- btn_check.click(fn=generate_random_gauges, inputs=[], outputs=[success_forecast_1, success_forecast_2, success_forecast_3])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
402
 
403
  demo.launch()
 
268
  # Небольшая пауза между выводом каждого сообщения
269
  time.sleep(1)
270
 
271
+ # ФУНКЦИИ ПРОВЕРОК (НАЧАЛО)
272
+
273
+ # 1. Запрещенные слова
274
+
275
+ def check_forbidden_words(message):
276
+ morph = pymorphy2.MorphAnalyzer()
277
+
278
+ # Перечень запрещённых слов и фраз
279
+ forbidden_patterns = [
280
+ r'№\s?1\b', r'номер\sодин\b', r'номер\s1\b',
281
+ r'вкусный', r'дешёвый', r'продукт',
282
+ r'спам', r'доступный', r'банкротство', r'долг[и]?', r'займ',
283
+ r'срочный', r'сейчас', r'главный',
284
+ r'гарантия', r'успех', r'лидер'
285
+ ]
286
+
287
+ # Удаляем знаки препинания для корректного анализа
288
+ message_without_punctuation = message.translate(str.maketrans('', '', string.punctuation))
289
+
290
+ # Проверка на наличие подстроки "лучш" (без учета регистра)
291
+ if re.search(r'лучш', message_without_punctuation, re.IGNORECASE):
292
+ return False
293
+
294
+ # Лемматизация слов сообщения
295
+ words = message_without_punctuation.split()
296
+ lemmas = [morph.parse(word)[0].normal_form for word in words]
297
+ normalized_message = ' '.join(lemmas)
298
+
299
+ # Проверка на запрещённые фразы и леммы
300
+ for pattern in forbidden_patterns:
301
+ if re.search(pattern, normalized_message, re.IGNORECASE):
302
+ return False
303
+
304
+ return True
305
+
306
+
307
+ # 2 и #3. Обращение к клиенту и приветствие клиента
308
+
309
+ def check_no_greeting(message):
310
+ morph = pymorphy2.MorphAnalyzer()
311
+ # Список типичных обращений и приветствий
312
+ greeting_patterns = [
313
+ r"привет\b", r"здравствуй", r"добрый\s(день|вечер|утро)",
314
+ r"дорогой\b", r"уважаемый\b", r"дорогая\b", r"уважаемая\b",
315
+ r"господин\b", r"госпожа\b", r"друг\b", r"коллега\b",
316
+ r"товарищ\b", r"приятель\b", r"друг\b", r"подруга\b"
317
+ ]
318
+
319
+ # Компилируем все шаблоны в один регулярное выражение
320
+ greeting_regex = re.compile('|'.join(greeting_patterns), re.IGNORECASE)
321
+
322
+ # Проверяем, начинается ли сообщение с шаблона приветствия или обращения
323
+ if greeting_regex.search(message.strip()):
324
+ return False
325
+ return True
326
+
327
+ # 4. Обещания и гарантии
328
+
329
+ def check_no_promises(message):
330
+ morph = pymorphy2.MorphAnalyzer()
331
+ promise_patterns = [
332
+ "обещать", "гарантировать", "обязаться"
333
+ ]
334
+
335
+ words = message.split()
336
+ lemmas = [morph.parse(word)[0].normal_form for word in words]
337
+
338
+ for pattern in promise_patterns:
339
+ if pattern in lemmas:
340
+ return False
341
+ return True
342
+
343
+ # 5. Составные конструкции из двух глаголов
344
+
345
+ def check_no_double_verbs(message):
346
+ morph = pymorphy2.MorphAnalyzer()
347
+ # Разделяем текст по пробелам и знакам препинания
348
+ words = re.split(r'\s+|[.!?]', message)
349
+ morphs = [morph.parse(word)[0] for word in words]
350
+
351
+ for i in range(len(morphs) - 1):
352
+ # Проверяем, что оба слова являются глаголами (в любой форме, включая инфинитивы)
353
+ if (morphs[i].tag.POS in {'VERB', 'INFN'}) and (morphs[i+1].tag.POS in {'VERB', 'INFN'}):
354
+ return False
355
+ return True
356
+
357
+ # 6. Причастия и причастные обороты
358
+
359
+ def check_no_participles(message):
360
+ morph = pymorphy2.MorphAnalyzer()
361
+ words = message.split()
362
+ morphs = [morph.parse(word)[0] for word in words]
363
+
364
+ for morph in morphs:
365
+ if 'PRTF' in morph.tag:
366
+ return False
367
+ return True
368
+
369
+ # 7. Деепричастия и деепричастные обороты
370
+
371
+ def check_no_adverbial_participles(message):
372
+ morph = pymorphy2.MorphAnalyzer()
373
+ words = message.split()
374
+ morphs = [morph.parse(word)[0] for word in words]
375
+
376
+ for morph in morphs:
377
+ if 'GRND' in morph.tag:
378
+ return False
379
+ return True
380
+
381
+ # 8. Превосходная степень прилагательных
382
+
383
+ def check_no_superlative_adjectives(message):
384
+ morph = pymorphy2.MorphAnalyzer()
385
+ words = message.split()
386
+ morphs = [morph.parse(word)[0] for word in words]
387
+
388
+ for morph in morphs:
389
+ if 'COMP' in morph.tag or 'Supr' in morph.tag:
390
+ return False
391
+ return True
392
+
393
+ # 9. Страдательный залог
394
+
395
+ def check_no_passive_voice(message):
396
+ morph = pymorphy2.MorphAnalyzer()
397
+ words = message.split()
398
+ morphs = [morph.parse(word)[0] for word in words]
399
+
400
+ for morph in morphs:
401
+ if 'PRTF' in morph.tag and ('passive' in morph.tag or 'в' in morph.tag):
402
+ return False
403
+ return True
404
+
405
+ # 10. Порядковые числительные от 10 прописью
406
+
407
+ def check_no_written_out_ordinals(message):
408
+ morph = pymorphy2.MorphAnalyzer()
409
+ ordinal_words = [
410
+ "десятый", "одиннадцатый", "двенадцатый", "тринадцатый", "четырнадцатый", "пятнадцатый",
411
+ "шестнадцатый", "семнадцатый", "восемнадцатый", "девятнадцатый", "двадцатый"
412
+ ]
413
+
414
+ words = message.split()
415
+ lemmas = [morph.parse(word)[0].normal_form for word in words]
416
+
417
+ for word in ordinal_words:
418
+ if word in lemmas:
419
+ return False
420
+ return True
421
+
422
+ # 11. Цепочки с придаточными предложениями
423
+
424
+ def check_no_subordinate_clauses_chain(message):
425
+ # Регулярное выражение, которое ищет последовательности придаточных предложений
426
+ subordinate_clause_patterns = [
427
+ r'\b(который|которая|которое|которые)\b',
428
+ r'\b(если|потому что|так как|что|когда)\b',
429
+ r'\b(хотя|несмотря на то что)\b'
430
+ ]
431
+
432
+ count = 0
433
+ for pattern in subordinate_clause_patterns:
434
+ if re.search(pattern, message):
435
+ count += 1
436
+
437
+ # Если в предложении найдено более одного придаточного предложения подряд, возвращаем False
438
+ return count < 2
439
+
440
+ # 12. Разделительные повторяющиеся союзы
441
+
442
+ def check_no_repeating_conjunctions(message):
443
+ # Регулярное выражение для поиска разделительных повторяющихся союзов с запятой перед вторым союзом
444
+ repeating_conjunctions_patterns = r'\b(и|ни|то|не то|или|либо)\b\s*(.*?)\s*,\s*\b\1\b'
445
+
446
+ # Разделяем сообщение на предложения по точке, вопросительному и восклицательному знакам
447
+ sentences = re.split(r'[.!?]\s*', message)
448
+
449
+ # Проверяем каждое предложение отдельно
450
+ for sentence in sentences:
451
+ if re.search(repeating_conjunctions_patterns, sentence, re.IGNORECASE):
452
+ return False
453
+ return True
454
+
455
+ # 13. Вводные конструкции
456
+
457
+ def check_no_introductory_phrases(message):
458
+ introductory_phrases = [
459
+ r'\b(во-первых|во-вторых|с одной стороны|по сути|по правде говоря)\b',
460
+ r'\b(может быть|кстати|конечно|естественно|безусловно|возможно)\b'
461
+ ]
462
+
463
+ for pattern in introductory_phrases:
464
+ if re.search(pattern, message, re.IGNORECASE):
465
+ return False
466
+ return True
467
+
468
+ # 14. Усилители
469
+
470
+ def check_no_amplifiers(message):
471
+ amplifiers = [
472
+ r'\b(очень|крайне|чрезвычайно|совсем|абсолютно|полностью|чисто)\b'
473
+ ]
474
+
475
+ for pattern in amplifiers:
476
+ if re.search(pattern, message, re.IGNORECASE):
477
+ return False
478
+ return True
479
+
480
+ # 15. Паразиты времени
481
+
482
+ def check_no_time_parasites(message):
483
+ time_parasites = [
484
+ r'\b(сейчас|немедленно|срочно|в данный момент|теперь)\b'
485
+ ]
486
+
487
+ for pattern in time_parasites:
488
+ if re.search(pattern, message, re.IGNORECASE):
489
+ return False
490
+ return True
491
+
492
+ # 16. Несколько существительных подряд
493
+
494
+ def check_no_multiple_nouns(message):
495
+ noun_count = 0
496
+ words = re.split(r'\s+|[.!?]', message) # Разбиваем по пробелам и знакам препинания
497
+ morph = pymorphy2.MorphAnalyzer()
498
+
499
+ for word in words:
500
+ parsed_word = morph.parse(word)[0]
501
+
502
+ # Если слово — существительное
503
+ if 'NOUN' in parsed_word.tag:
504
+ noun_count += 1
505
+ # Если встречен конец предложения (точка, вопросительный знак, восклицательный знак)
506
+ elif re.match(r'[.!?]', word):
507
+ noun_count = 0
508
+ else:
509
+ noun_count = 0
510
+
511
+ if noun_count > 2:
512
+ return False
513
+ return True
514
+
515
+ # 17. Производные предлоги
516
+
517
+ def check_no_derived_prepositions(message):
518
+ derived_prepositions = [
519
+ r'\b(в течение|в ходе|вследствие|в связи с|по м��ре|при помощи|согласно|вопреки|на основании|на случай|в продолжение|по причине|вблизи|вдалеке|вокруг|внутри|вдоль|посередине|вне|снаружи|благодаря|невзирая на|исходя из)\b'
520
+ ]
521
+
522
+ for pattern in derived_prepositions:
523
+ if re.search(pattern, message, re.IGNORECASE):
524
+ return False
525
+ return True
526
+
527
+ # 19. Сложноподчиненные предложения
528
+
529
+ def check_no_compound_sentences(message):
530
+ subordinating_conjunctions = [
531
+ r'\bкогда\b', r'\bкак только\b', r'\bпока\b', r'\bпосле того как\b',
532
+ r'\bпотому что\b', r'\bтак как\b', r'\bоттого что\b', r'\bблагодаря тому что\b',
533
+ r'\bчтобы\b', r'\bдля того чтобы\b', r'\bесли\b', r'\bкогда бы\b', r'\bесли бы\b',
534
+ r'\bхотя\b', r'\bнесмотря на то что\b', r'\bкак\b', r'\bбудто\b', r'\bсловно\b', r'\bкак будто\b',
535
+ r'\bчто\b'
536
+ ]
537
+
538
+ # Убедимся, что слово "как" используется не в вопросе
539
+ for pattern in subordinating_conjunctions:
540
+ if re.search(pattern, message) and not re.search(r'\?', message):
541
+ return False
542
+ return True
543
+
544
+ # 20. Даты прописью
545
+
546
+ def check_no_dates_written_out(message):
547
+ # Ищем упоминания месяцев или слов, связанных с датами
548
+ months = [
549
+ "января", "февраля", "марта", "апреля", "мая", "июня",
550
+ "июля", "августа", "сентября", "октября", "ноября", "декабря"
551
+ ]
552
+
553
+ # Слова для проверки чисел прописью
554
+ date_written_out_patterns = [
555
+ r'\b(первого|второго|третьего|четвертого|пятого|шестого|седьмого|восьмого|девятого|десятого|одиннадцатого|двенадцатого|тринадцатого|четырнадцатого|пятнадцатого|шестнадцатого|семнадцатого|восемнадцатого|девятнадцатого|двадцатого|двадцать первого|двадцать второго|двадцать третьего|двадцать четвертого|двадцать пятого|двадцать шестого|двадцать седьмого|двадцать восьмого|двадцать девятого|тридцатого|тридцать первого)\b'
556
+ ]
557
+
558
+ for month in months:
559
+ for pattern in date_written_out_patterns:
560
+ if re.search(f'{pattern}\\s{month}', message, re.IGNORECASE):
561
+ return False
562
+
563
+ return True
564
+
565
+ # ФУНКЦИИ ПРОВЕРОК (КОНЕЦ)
566
+
567
+ def perform_checks(message):
568
+ checks = {
569
+ "forbidden_words": check_forbidden_words(message),
570
+ "client_addressing": check_no_greeting(message),
571
+ "promises": check_no_promises(message),
572
+ "double_verbs": check_no_double_verbs(message),
573
+ "participles": check_no_participles(message),
574
+ "adverbial_participles": check_no_adverbial_participles(message),
575
+ "superlative_adjectives": check_no_superlative_adjectives(message),
576
+ "passive_voice": check_no_passive_voice(message),
577
+ "written_out_ordinals": check_no_written_out_ordinals(message),
578
+ "subordinate_clauses_chain": check_no_subordinate_clauses_chain(message),
579
+ "repeating_conjunctions": check_no_repeating_conjunctions(message),
580
+ "introductory_phrases": check_no_introductory_phrases(message),
581
+ "amplifiers": check_no_amplifiers(message),
582
+ "time_parasites": check_no_time_parasites(message),
583
+ "multiple_nouns": check_no_multiple_nouns(message),
584
+ "derived_prepositions": check_no_derived_prepositions(message),
585
+ "compound_sentences": check_no_compound_sentences(message),
586
+ "dates_written_out": check_no_dates_written_out(message)
587
+ }
588
+ return checks
589
+
590
+
591
+ def format_checks(checks):
592
+ translation = {
593
+ "forbidden_words": "Запрещенные слова",
594
+ "client_addressing": "Обращение к клиенту",
595
+ "promises": "Обещания и гарантии",
596
+ "double_verbs": "Два глагола подряд",
597
+ "participles": "Причастия",
598
+ "adverbial_participles": "Деепричастия",
599
+ "superlative_adjectives": "Превосходная степень",
600
+ "passive_voice": "Страдательный залог",
601
+ "written_out_ordinals": "Порядковые числительные",
602
+ "subordinate_clauses_chain": "Цепочки с придаточными предложениями",
603
+ "repeating_conjunctions": "Разделительные повторяющиеся союзы",
604
+ "introductory_phrases": "Вводные конструкции",
605
+ "amplifiers": "Усилители",
606
+ "time_parasites": "Паразиты времени",
607
+ "multiple_nouns": "Несколько существительных подряд",
608
+ "derived_prepositions": "Производные предлоги",
609
+ "compound_sentences": "Сложноподчиненные предложения",
610
+ "dates_written_out": "Даты прописью"
611
+ }
612
+ return " \n".join([f"{translation[rule]}: {'✔️' if result else '❌'}" for rule, result in checks.items()])
613
+
614
+
615
+ # Функция для обработки нажатия кнопки "Проверить"
616
+ def perform_all_checks_and_show_results(personalized_message_1, personalized_message_2, personalized_message_3):
617
+ # Выполняем проверки для каждого сообщения
618
+ checks_1 = perform_checks(personalized_message_1)
619
+ checks_2 = perform_checks(personalized_message_2)
620
+ checks_3 = perform_checks(personalized_message_3)
621
+
622
+ # Форматируем результаты для отображения
623
+ formatted_checks_1 = format_checks(checks_1)
624
+ formatted_checks_2 = format_checks(checks_2)
625
+ formatted_checks_3 = format_checks(checks_3)
626
+
627
+ # Возвращаем результаты проверок для каждого сообщения
628
+ return (
629
+ personalized_message_1, formatted_checks_1, # Первое персонализированное сообщение и его проверка
630
+ personalized_message_2, formatted_checks_2, # Второе персонализированное сообщение и его проверка
631
+ personalized_message_3, formatted_checks_3 # Третье персонализированное сообщение и его проверка
632
+ )
633
+
634
 
635
  # Интерфейс Gradio
636
  with gr.Blocks() as demo:
 
761
  success_forecast_3 = gr.Plot(label="Прогноз успешности сообщения 3")
762
  gr.HTML("</div>")
763
 
764
+ # Модифицируем нажатие кнопки "Проверить"
765
+ btn_check.click(
766
+ fn=change_tab,
767
+ inputs=[gr.Number(value=3, visible=False)], # Переключение на вкладку "Проверка"
768
+ outputs=tabs # Обновляем вкладку
769
+ ).then(
770
+ fn=perform_all_checks_and_show_results,
771
+ inputs=[personalized_1, personalized_2, personalized_3], # Входные персонализированные сообщения
772
+ outputs=[
773
+ personalized_message_1, check_message_1, # Результаты проверок для первого сообщения
774
+ personalized_message_2, check_message_2, # Результаты проверок для второго сообщения
775
+ personalized_message_3, check_message_3 # Результаты проверок для третьего сообщения
776
+ ]
777
+ ).then(
778
+ fn=generate_random_gauges,
779
+ inputs=[], # Нет входных данных для спидометров
780
+ outputs=[success_forecast_1, success_forecast_2, success_forecast_3] # Вывод значений спидометров
781
+ )
782
 
783
  demo.launch()