<<<===############################################### line 49587
If you log out and immediately start this mode, everything works fine. But if you do something before that in the system, and then run it, then this error occurs, but not always.
Code: Select all
************************************************************************************************************************************
******** 4.1.9. Подготовка результатов распознавания в форме CSV-файлов в стандарте http://kaggle.com. 
******** Данный режим предполагает, что: 1) в модели 2 класса; 2) результаты распознавания во всех моделях уже получены в режиме 3.5
************************************************************************************************************************************
FUNCTION F4_1_9()
   Running(.T.)
   **********************************************************************
   ******* Провести проверки на:
   ******* - наличие приложения;
   ******* - 2 класса в модели;
   ******  - наличие результатов распознавания во всех моделях;
   ******  - числовой результат распознавания;
   ******* с выдачей соответствующих сообщение.
   ******* Если все нормально - переход на выполнение.
   ******* Спросить сколько знаков после запятой включать.
   ******* Сообщить о том, что возможно нужно поменять название 1-го поля
   **********************************************************************
   ***********************************************
   ******* Провести проверки на наличие приложения
   ***********************************************
   PUBLIC M_PathAppl := "", M_NameAppl := "", mFlagErr := .F., mFlagAppl :=.F.
   IF .NOT. FILE("Appls.dbf")
      mFlagErr = .T.                                // Выдать сообщение об ошибке и вернуться в главное меню
      aMess := {}
      AADD(aMess, L('Отсутствует текущее приложение !'))
      AADD(aMess, L('Надо создать его в режиме 2.3.2.2,'))
      AADD(aMess, L('1.3, 2.3.2.1 или в другом!'))
      LB_Warning(aMess, L('(C) System "Aidos-X++"' ))
      **************************************************************
      ***** БД, открытые перед запуском главного меню
      ***** Восстанавливать их после выхода из функций главного меню
      **************************************************************
      CLOSE ALL
      DIRCHANGE(Disk_dir)                          // Перейти в папку с исполнимым модулем системы
      USE PathGrAp EXCLUSIVE NEW
      USE Appls    EXCLUSIVE NEW
      USE Users    EXCLUSIVE NEW
      Running(.F.)
      RETURN NIL
   ELSE
      CLOSE ALL
      USE Appls EXCLUSIVE NEW
      SELECT Appls
      
      DBGOTOP()
      DO WHILE .NOT. EOF()
         IF LEN(ALLTRIM(By_default)) > 0
            REPLACE By_default WITH "W"
            M_PathAppl = UPPER(ALLTRIM(Path_Appl))  // Путь на текущее приложение
            M_NameAppl = ALLTRIM(Name_Appl)             
            mFlagAppl =.T.                          // Текущее приложение существует, его имя: M_NameAppl, путь на него: M_PathAppl
            EXIT
         ENDIF
         DBSKIP(1)
      ENDDO
   ENDIF
   IF mFlagAppl =.F.                                // Текущего приложения не существует
      mFlagErr = .T.                                // Выдать сообщение об ошибке и вернуться в главное меню
      aMess := {}
      AADD(aMess, L('Отсутствует текущее приложение !'))
      AADD(aMess, L('Надо создать его в режиме 2.3.2.2,'))
      AADD(aMess, L('1.3, 2.3.2.1 или в другом!'))
      LB_Warning(aMess, L('(C) System "Aidos-X++"' ))
      **************************************************************
      ***** БД, открытые перед запуском главного меню
      ***** Восстанавливать их после выхода из функций главного меню
      **************************************************************
      CLOSE ALL
      DIRCHANGE(Disk_dir)                          // Перейти в папку с исполнимым модулем системы
      USE PathGrAp EXCLUSIVE NEW
      USE Appls    EXCLUSIVE NEW
      USE Users    EXCLUSIVE NEW
      Running(.F.)
      RETURN NIL
   ENDIF
   
   **********************************************
   ******* Провести проверки на 2 класса в модели
   **********************************************
   DIRCHANGE(M_PathAppl)      // Путь на текущее приложение
   CLOSE ALL                                        // <<<===############################################### line 49587
   USE Classes EXCLUSIVE NEW;N_Cls = RECCOUNT()
   IF N_Cls <> 2
      mFlagErr = .T.                                // Выдать сообщение об ошибке и вернуться в главное меню
      aMess := {}
      AADD(aMess, L('В приложении:'))
      AADD(aMess, L(' '))
      AADD(aMess, L('Наименование:')+' '+M_NameAppl)
      AADD(aMess, L('Путь:')+' '+M_PathAppl)
      AADD(aMess, L(' '))
      AADD(aMess, ALLTRIM(STR(N_Cls))+' '+L('классов.'))
      AADD(aMess, L('А должно быть 2 (на Каггл бинарное распознавание)'))
      LB_Warning(aMess, L('(C) System "Aidos-X++"' ))
      **************************************************************
      ***** БД, открытые перед запуском главного меню
      ***** Восстанавливать их после выхода из функций главного меню
      **************************************************************
      CLOSE ALL
      DIRCHANGE(Disk_dir)                          // Перейти в папку с исполнимым модулем системы
      USE PathGrAp EXCLUSIVE NEW
      USE Appls    EXCLUSIVE NEW
      USE Users    EXCLUSIVE NEW
      Running(.F.)
      RETURN NIL
   ENDIF
   ******************************************************************************
   ******* Провести проверки на наличие результатов распознавания во всех моделях
   ******************************************************************************
   Ar_Model := {"Abs","Prc1","Prc2","Inf1","Inf2","Inf3","Inf4","Inf5","Inf6","Inf7" }
   
   aRsp2   := {}
   
   FOR mNumModel = 1 TO LEN(Ar_Model)
       mNameRsp2i = 'Rsp2i_'+Ar_Model[mNumModel]
       mNameRsp2k = 'Rsp2k_'+Ar_Model[mNumModel]    // #####################
       mFlagRsp2 = .F.
       USE (mNameRsp2i) EXCLUSIVE NEW;mReccount_i = RECCOUNT()
       USE (mNameRsp2k) EXCLUSIVE NEW;mReccount_k = RECCOUNT()
       IF (.NOT. FILE(mNameRsp2i+'.dbf') .OR. .NOT. FILE(mNameRsp2k+'.dbf') ) .OR. mReccount_i * mReccount_k = 0 
          mFlagErr = .T.                            // Выдать сообщение об ошибке и вернуться в главное меню
          aMess := {}
          AADD(aMess, L('В приложении:'))
          AADD(aMess, L(' '))
          AADD(aMess, L('Наименование:')+' '+M_NameAppl)
          AADD(aMess, L('Путь:')+' '+M_PathAppl)
          AADD(aMess, L(' '))
          AADD(aMess, L('нет результатов распознавания во всех моделях и со всеми инт.критериями.'))
          AADD(aMess, L(' '))
          AADD(aMess, L('Надо провести распознавание в режиме 3.5.'))
          LB_Warning(aMess, L('(C) System "Aidos-X++"' ))
          **************************************************************
          ***** БД, открытые перед запуском главного меню
          ***** Восстанавливать их после выхода из функций главного меню
          **************************************************************
          CLOSE ALL
          DIRCHANGE(Disk_dir)                          // Перейти в папку с исполнимым модулем системы
          USE PathGrAp EXCLUSIVE NEW
          USE Appls    EXCLUSIVE NEW
          USE Users    EXCLUSIVE NEW
          Running(.F.)
          RETURN NIL
       ENDIF
   NEXT
   ****************************************************************************
   ******* Провести проверки на то, что результат распознавания является числом
   ****************************************************************************
   CLOSE ALL
   USE Classes EXCLUSIVE NEW;N_Cls = RECCOUNT()
   SELECT Classes
   DBGOTOP()
   DO WHILE .NOT. EOF()
      IF AT('{', Name_cls) * AT('}', Name_cls) = 0
         mFlagErr = .T.                            // Выдать сообщение об ошибке и вернуться в главное меню
         aMess := {}
         AADD(aMess, L('В приложении:'))
         AADD(aMess, L(' '))
         AADD(aMess, L('Наименование:')+' '+M_NameAppl)
         AADD(aMess, L('Путь:')+' '+M_PathAppl)
         AADD(aMess, L(' '))
         AADD(aMess, L('классы должны быть интервальными числовыми значениями'))
         AADD(aMess, L('(классификационная шкала должна быть числовой!)'))
         LB_Warning(aMess, L('(C) System "Aidos-X++"' ))
         **************************************************************
         ***** БД, открытые перед запуском главного меню
         ***** Восстанавливать их после выхода из функций главного меню
         **************************************************************
         CLOSE ALL
         DIRCHANGE(Disk_dir)                          // Перейти в папку с исполнимым модулем системы
         USE PathGrAp EXCLUSIVE NEW
         USE Appls    EXCLUSIVE NEW
         USE Users    EXCLUSIVE NEW
         Running(.F.)
         RETURN NIL
      ENDIF
      DBSKIP(1)
   ENDDO
   
   ******************************************************
   ******* Спросить сколько знаков после запятой включать
   ******************************************************
   mDeci = 1
   @0,0 DCSAY L('Задайте число знаков после запятой: ') GET mDeci PICTURE "##" SAYSIZE 0
   DCREAD GUI FIT ADDBUTTONS TITLE L('4.1.9. Подготовка результатов для http://kaggle.com')
   mDeci = IF(mDeci<=15,mDeci,15)
   oScr := DC_WaitOn(L('4.1.9. Подготовка результатов распознавания в форме CSV-файлов в стандарте http://kaggle.com'))     
   CLOSE ALL
   USE Classes EXCLUSIVE NEW;N_Cls = RECCOUNT()
   IF N_Cls = 2
      SELECT Classes
      mNameCls1 = ALLTRIM(Name_cls)
      DBSKIP(1)
      mNameCls2 = ALLTRIM(Name_cls)
      ***** Структура создаваемой базы ***********
       
      CLOSE ALL
      
      Ar_Model := {"Abs","Prc1","Prc2","Inf1","Inf2","Inf3","Inf4","Inf5","Inf6","Inf7" }
      
      aRsp2   := {}
      aKaggle := {}
      
      FOR mNumModel = 1 TO LEN(Ar_Model)
          mNameRsp2i = 'Rsp2i_'+Ar_Model[mNumModel]
          mNameRsp2k = 'Rsp2k_'+Ar_Model[mNumModel]              // #####################
          IF FILE(mNameRsp2i+'.dbf') .AND.;
             FILE(mNameRsp2k+'.dbf')
      
             AADD(aRsp2  , mNameRsp2i)
             AADD(aRsp2  , mNameRsp2k)
             
             AADD(aKaggle, 'Kaggle_'+Ar_Model[mNumModel]+'i')
             AADD(aKaggle, 'Kaggle_'+Ar_Model[mNumModel]+'k')
      
          ENDIF
      NEXT
      IF LEN(aRsp2) > 0
         mMaxLen = -999
         
         FOR ik = 1 TO LEN(aRsp2)
         
             CLOSE ALL
             USE (aRsp2[ik]) EXCLUSIVE NEW
             SELECT (aRsp2[ik])
             DBGOTOP()
             DO WHILE .NOT. EOF()
                mMaxLen = MAX(mMaxLen, LEN(ALLTRIM(Name_obj)))
                DBSKIP(1)
             ENDDO
         
         NEXT
         aStructure := { { "id"       , "C",mMaxLen, 0},;    // 1 id фрагмента текста из тестовой выборки
                         { "Prob"     , "N",     15, 7},;    // 2 Итоговая релевантность текстового фрагмента с истинным классом для каггла (предполагается, что модель дает истинных решений больше, чем ложных)
                         { "Prob1"    , "N",     15, 7},;    // 3 Релевантность текстового фрагмента с классом 1 = mKorr1 - mKorr2
                         { "Prob2"    , "N",     15, 7},;    // 4 Релевантность текстового фрагмента с классом 2 = mKorr2 - mKorr1
                         { "UrSx_Cls1", "N",     15, 7},;    // 5 Ур.сходства с классом 1, который дает система Эйдос
                         { "UrSx_Cls2", "N",     15, 7} }    // 6 Ур.сходства с классом 2, который дает система Эйдос
         
         FOR mNumModel = 1 TO LEN(Ar_Model)
         
             mNameRsp2i = 'Rsp2i_'+Ar_Model[mNumModel]
             mNameRsp2k = 'Rsp2k_'+Ar_Model[mNumModel]       // ################
         
             IF FILE(mNameRsp2i+'.dbf') .AND.;
                FILE(mNameRsp2k+'.dbf')
                DbCreate( 'Kaggle_'+Ar_Model[mNumModel]+'i', aStructure )
                DbCreate( 'Kaggle_'+Ar_Model[mNumModel]+'k', aStructure )
         
             ENDIF
         
         NEXT
         
         FOR ik = 1 TO LEN(aRsp2)
         
             CLOSE ALL
             USE (aRsp2[ik]) EXCLUSIVE NEW
             INDEX ON STR(Kod_obj,15) TO (aRsp2[ik])
             
             CLOSE ALL
             USE (aRsp2[ik])   INDEX (aRsp2[ik]) EXCLUSIVE NEW
             USE (aKaggle[ik]) EXCLUSIVE NEW
             
             mKorr1Max = -9999                 // Max.знач.ур.сходства с классом 1
             mKorr1Min = +9999                 // Min.знач.ур.сходства с классом 1
         
             mKorr2Max = -9999                 // Max.знач.ур.сходства с классом 2
             mKorr2Min = +9999                 // Min.знач.ур.сходства с классом 2
         
             mClass1Sum = 0
             mClass2Sum = 0
             
             SELECT (aRsp2[ik])
             DBGOTOP()
             
             mIdErr = ''                       // Отсутствующие id
             mIdOld = VAL(Name_obj)
             
             DO WHILE .NOT. EOF()
             
                mID    = ALLTRIM(Name_obj)
         
                mKorr1 = Korr
                DBSKIP(1)
                mKorr2 = Korr
         
                mClass1Sum = mClass1Sum + mKorr1
                mClass2Sum = mClass2Sum + mKorr2
             
                // mKorr1 уровень сходства с классом: "есть описание суицида"
                // mKorr2 уровень сходства с классом: "нет  описания суицида"
             
                SELECT (aKaggle[ik])
                APPEND BLANK
         
                mProb1 = mKorr1 - mKorr2
                mProb2 = mKorr2 - mKorr1
         
                REPLACE id        WITH mID
                REPLACE prob1     WITH mProb1
                REPLACE prob2     WITH mProb2
         
                REPLACE UrSx_Cls1 WITH mKorr1
                REPLACE UrSx_Cls2 WITH mKorr2
         
                mKorr1Max =    MAX(mKorr1Max, mProb1)
                mKorr1Min =    MIN(mKorr1Min, mProb1)
             
                mKorr2Max =    MAX(mKorr2Max, mProb2)
                mKorr2Min =    MIN(mKorr2Min, mProb2)
                SELECT (aRsp2[ik])
                DBSKIP(1)
         
*               **** Сделать проверку на пропуски в id и вставлять пустые записи при пропусках ЭТО ДЕЛАТЬ НЕ НАДО #####
*               mNameObj = ALLTRIM(Name_obj)
*               mIdNew = VAL(mNameObj)               // ############## НЕ ЧИСЛО ###################
*               IF mIdNew - mIdOld > 1
*                  mIdErr = mIdErr + ALLTRIM(STR(mIdNew - 1, 15)) + ' '
*                  SELECT (aKaggle[ik])
*                  APPEND BLANK
*                  REPLACE id        WITH ALLTRIM(STR(mIdNew - 1,15))                // ###########
*                  REPLACE prob1     WITH 0
*                  REPLACE prob2     WITH 0
*                  REPLACE UrSx_Cls1 WITH 0
*                  REPLACE UrSx_Cls2 WITH 0
*                  SELECT (aRsp2[ik])
*               ENDIF
*               mIdOld = mIdNew
             
             ENDDO
             
             StrFile(mIdErr, 'Id_Error.txt')                                         // Запись текстового файла с пропущенными id
             
             ****** Сделать нормировку prob к 1-0
         
             SELECT (aKaggle[ik])
             DBGOTOP()
             DO WHILE .NOT. EOF()
                IF mClass1Sum > mClass2Sum                                           // Предполагаем, что классификатор дает истинных решений больше, чем ложных, т.е. "не с точностью наоборот"
                   REPLACE Prob WITH (Prob1 - mKorr1Min) / (mKorr1Max - mKorr1Min)
                ELSE
                   REPLACE Prob WITH (Prob2 - mKorr2Min) / (mKorr2Max - mKorr2Min)
                ENDIF
                DBSKIP(1)
             ENDDO
         NEXT
         
         CLOSE ALL
         IF .F.                  // ####################################
            DC_Impl(oScr)                                                   
            aMess := {}
            AADD(aMess, L('РЕЗУЛЬТАТЫ БИНАРНОЙ КЛАССИФИКАЦИИ В БАЗАХ:'))
            AADD(aMess, L(' '))
            AADD(aMess, L('Интегральный критерий: "Сумма знаний":'))
            FOR j=1 TO LEN(aKaggle) STEP 2
                AADD(aMess, ALLTRIM(aKaggle[j])+'.dbf')
            NEXT
            AADD(aMess, L(' '))
            AADD(aMess, L('Интегральный критерий: "Резонанс знаний":'))
            FOR j=2 TO LEN(aKaggle) STEP 2
                AADD(aMess, ALLTRIM(aKaggle[j])+'.dbf')
            NEXT
            AADD(aMess, L(' '))
            AADD(aMess, L('Все эти базы данных открываются в MS Excel.'))
            AADD(aMess, L(' '))
            AADD(aMess, L('Смысл полей баз данных: "Kaggle_#_###.dbf":'))
            AADD(aMess, L('- id: id фрагмента текста из тестовой выборки;'))
            AADD(aMess, L('- Prob: Итоговая релевантность текстового фрагмента с истинным классом для каггла;'))
            AADD(aMess, L('            где:'))
            AADD(aMess,   '            Prob = (Prob1 - Korr1Min) / (Korr1Max - Korr1Min);')
            AADD(aMess,   '            Prob = (Prob2 - Korr2Min) / (Korr2Max - Korr2Min);')
            AADD(aMess,   '            Korr1Max = MAX(Korr1Max, Prob1);')
            AADD(aMess,   '            Korr1Min = MIN(Korr1Min, Prob1);')
            AADD(aMess,   '            Korr2Max = MAX(Korr2Max, Prob2);')
            AADD(aMess,   '            Korr2Min = MIN(Korr2Min, Prob2);')
            AADD(aMess, L('- Prob1 = UrSx_Cls1 - UrSx_Cls2: Релевантность текстового фрагмента с классом 1;'))
            AADD(aMess, L('- Prob2 = UrSx_Cls2 - UrSx_Cls1: Релевантность текстового фрагмента с классом 2;'))
            AADD(aMess, L('- UrSx_Cls1: Уровень сходства с классом 1, который дает система Эйдос;'))
            AADD(aMess, L('- UrSx_Cls2: Уровень сходства с классом 2, который дает система Эйдос;'))
            AADD(aMess, L(' '))
            AADD(aMess, L('Если модель работает "не с точностью до наоборот", то по итогам классификации;'))
            AADD(aMess, L('можно предположить, что истинными являются решения о принадлежности к классу:;'))
            AADD(aMess, IF(mClass1Sum > mClass2Sum, '"'+mNameCls1+'"', '"'+mNameCls2+'".'))
            
            LB_Warning(aMess, L('(C) System "Aidos-X++"' ))
         ENDIF
      ENDIF
   ENDIF
   mCountF = ADIR("Kaggle_*.DBF")                            // Кол-во TXT-файлов
   IF mCountF > 0
      PRIVATE aFileName[mCountF], aFileSize[mCountF]            // Имена и размеры файлов
      
      ADIR("Kaggle_*.DBF", aFileName, aFileSize)
      
      FOR ff=1 TO mCountF
      
          mFileName = SUBSTR(aFileName[ff], 1, AT('.',aFileName[ff])-1)
      
          CLOSE ALL
          USE (mFileName) EXCLUSIVE NEW
          SELECT (mFileName)
      
          ********** Открыть процесс печати выходной формы
          set device to printer
          set printer on
          set printer to (mFileName+'.csv')
          set console off
      
          ??'SK_ID_CURR,TARGET'
      
          DBGOTOP()
          DO WHILE .NOT. EOF()
          
             ?ALLTRIM(ID)+','+ALLTRIM(STR(ROUND(PROB,mDeci)))
      
             DBSKIP(1)
          
          ENDDO
      
          ********** Закрыть процесс печати выходной формы
          Set device to screen
          Set printer off
          Set printer to
          Set console on
      
      NEXT
      DC_Impl(oScr)                                                   
      
      aMess := {}
      AADD(aMess,L('4.1.9. Подготовка результатов распознавания в форме CSV-файлов в стандарте http://kaggle.com завершена успешно!'))
      AADD(aMess,L(''))
      AADD(aMess,L('Результаты распознавания находятся в папке: "'+M_PathAppl+'" в файлах:'))
      AADD(aMess,L(''))
      AADD(aMess,L('Kaggle_Inf1i.csv'))
      AADD(aMess,L('Kaggle_Inf2i.csv'))
      AADD(aMess,L('Kaggle_Inf3i.csv'))
      AADD(aMess,L('Kaggle_Inf4i.csv'))
      AADD(aMess,L('Kaggle_Inf5i.csv'))
      AADD(aMess,L('Kaggle_Inf6i.csv'))
      AADD(aMess,L('Kaggle_Inf7i.csv'))
      AADD(aMess,L('Kaggle_Prc1i.csv'))
      AADD(aMess,L('Kaggle_Prc2i.csv'))
      AADD(aMess,L(''))
      AADD(aMess,L('Kaggle_Inf1k.csv'))
      AADD(aMess,L('Kaggle_Inf2k.csv'))
      AADD(aMess,L('Kaggle_Inf3k.csv'))
      AADD(aMess,L('Kaggle_Inf4k.csv'))
      AADD(aMess,L('Kaggle_Inf5k.csv'))
      AADD(aMess,L('Kaggle_Inf6k.csv'))
      AADD(aMess,L('Kaggle_Inf7k.csv'))
      AADD(aMess,L('Kaggle_Prc1k.csv'))
      AADD(aMess,L('Kaggle_Prc2k.csv'))
      AADD(aMess,L(''))
      AADD(aMess,L('Проверьте наименование полей в CSV-файлах'))
      LB_Warning(aMess)
   ENDIF
   DC_Impl(oScr)                                                   
   **************************************************************
   ***** БД, открытые перед запуском главного меню
   ***** Восстанавливать их после выхода из функций главного меню
   **************************************************************
   CLOSE ALL
   DIRCHANGE(Disk_dir)                          // Перейти в папку с исполнимым модулем системы
   USE PathGrAp EXCLUSIVE NEW
   USE Appls    EXCLUSIVE NEW
   USE Users    EXCLUSIVE NEW
   Running(.F.)
RETURN NIL


