2021年7月16日 星期五

學測及指試題分句程式(備份)

 學測及指試題分句程式(備份)

var app=SpreadsheetApp;

var ss=app.getActiveSpreadsheet();

var shCode=ss.getSheetByName('考題編碼');

var shGSAT=ss.getSheetByName('學測');

var shASTS=ss.getSheetByName('指考');

var shGSentence=ss.getSheetByName('學測分句');

var shASentence=ss.getSheetByName('指考分句');

const YEAR_COLUMN=2;  // 年度, 110,109...

const CAT_COLUMN=3;   // 考試類別,學測或指考

const QN1_COLUMN=4;   // 試題編號1, 題組的開始題號

const QN2_COLUMN=5;   // 試題編號2, 題組的結束題號

const QTYPE_COLUMN=6; // 題型 V,C,M,R,T

const QUESTION_COLUMN=7;  // 試題

const ANSWER_COLUMN=8;    // 答案

var numRows=shGSAT.getDataRange().getLastRow()-1; // 學測的資料列總數,扣除標題列

var rowG=1;  // 學測輸入的列指標標

var rowGS=1; // 學測分句輸出的列指標


function onOpen() {

  // Get the Ui Object.

  var ui=SpreadsheetApp.getUi();


  // Create and add a named menue and its items to the menu bar.

  ui.createMenu('試題分句')

    .addItem('學測分句','extractSentenceGSAT')

    .addItem('指考分句','extractSentenceASTS')

    .addToUi();

}

function extractSentenceGSAT(){


  // 學測題分句

/**

  var rows=shGSentence.getLastRow();

  var cols=shGSentence.getLastColumn();

  shGSentence.getRange(2,1,rows-1,cols).clear(); 

 */


  rowGS=1; // 學測分句輸出的列指標,第一列是標題,輸出時從第二列開始

  

  // 對於「學測」所有的試題

  for (rowG=2;rowG<=26;rowG++) // 測試時使用定值;正式用 numRows

  {

    // 對於每一列的試題,取出題型


    var qType=shGSAT.getRange(rowG,QTYPE_COLUMN).getValue(); // 題型


    switch (qType) { // 根據不同題型的資料結構來演算

      case 'V':

        qTypeV_(rowG);

        break;

      case 'C':

        qTypeC_(rowG);

        break;

      case 'M':

        qTypeM_(rowG);

        break;

      case 'R':

        qTypeR_(rowG);

        break;

      case 'T':

        qTypeT_(rowG);

        break;                

      default:

        Logger.log("QType Error!");

        break;

    }

  }

}

function qTypeV_(rowG){

    var year=shGSAT.getRange(rowG,YEAR_COLUMN).getValue(); // 年度

    var cat=shGSAT.getRange(rowG,CAT_COLUMN).getValue(); // 考試類別

    var qn1=shGSAT.getRange(rowG,QN1_COLUMN).getValue(); // 試題編號1

  //  var qn2=shGSAT.getRange(rowG,QN2_COLUMN).getValue(); // 試題編號2

    var qType=shGSAT.getRange(rowG,QTYPE_COLUMN).getValue(); // 題型

    var strQuestion=shGSAT.getRange(rowG,QUESTION_COLUMN).getValue(); // 試題

    var strLen=strQuestion.length; // 字串的長度


    //+ 處理一列的句子群,

    var i=0; // 字串的指標

    var qn2=0; 

    // 分句寫出,直到遇到選項群

    while ((strQuestion[i]!="(")&&(i<=strLen-1)){ 

      var strSentence="";


      // 發現句子結束時,寫出句子

      while ((matchSentence_(strQuestion,i)==0)&&

        (strQuestion[i]!="(")&&(i<=strLen-1)){

        //* 處理一個句子

        strSentence+=strQuestion[i];

        i++;

      }

      if (matchSentence_(strQuestion,i)>0)

      {

        rowGS++;

        qn2++; // 每一筆學測題從1起算

        shGSentence.getRange(rowGS,YEAR_COLUMN).setValue(year);

        shGSentence.getRange(rowGS,CAT_COLUMN).setValue(cat);

        shGSentence.getRange(rowGS,QN1_COLUMN).setValue(qn1);

        shGSentence.getRange(rowGS,QN2_COLUMN).setValue(qn2);

        shGSentence.getRange(rowGS,QTYPE_COLUMN).setValue(qType);

        strSentence+=strQuestion[i];

        if (matchSentence_(strQuestion,i)==2){

          strSentence+=strQuestion[i+1];

          i+=2;

        } else {

          i++;

        }

      

        shGSentence.getRange(rowGS,QUESTION_COLUMN).setValue(strSentence);


        if (strQuestion[i]==" ") {

          i++; // bypass 空白

        }

      }

    }


    //+ 處理選項群


    strSentence=strQuestion[i];

    i++;  

    while (i<=strLen-1){

      strSentence+=strQuestion[i];

      i++;

    }

    rowGS++;

    qn2++;

    shGSentence.getRange(rowGS,YEAR_COLUMN).setValue(year);

    shGSentence.getRange(rowGS,CAT_COLUMN).setValue(cat);

    shGSentence.getRange(rowGS,QN1_COLUMN).setValue(qn1);

    shGSentence.getRange(rowGS,QN2_COLUMN).setValue(qn2);

    shGSentence.getRange(rowGS,QTYPE_COLUMN).setValue(qType);

    shGSentence.getRange(rowGS,QUESTION_COLUMN).setValue(strSentence);


}

function matchSentence_(strQuestion,i) {

  if (strQuestion.substr(i-1,4)=='i.e.') { // 特殊情況的 . 非句點

    return 0;

  }

  if (strQuestion.substr(i-3,4)=='i.e.') { // 特殊情況的 . 非句點

    return 0;

  }

  if (strQuestion.substr(i-1,4)=='B.C.') { // 特殊情況的 . 非句點

    return 0;

  }

  if (strQuestion.substr(i-3,4)=='B.C.') { // 特殊情況的 . 非句點

    return 0;

  }

  if ((strQuestion[i]==".")||(strQuestion[i]=="?")||(strQuestion[i]=="!")) {

    if ((strQuestion[i+1]=='"')||(strQuestion[i+1]=='”')) {

      return 2; // 句尾為兩個符號;即為 .", 或 ?", 或 !" 

    }else {

      return 1; // 句尾為單一符號;即為., 或 ?, 或 !

    }

  } else {

    return 0; // 以上皆非;即非句尾。

  }

}

function qTypeC_(rowG){

    var year=shGSAT.getRange(rowG,YEAR_COLUMN).getValue(); // 年度

    var cat=shGSAT.getRange(rowG,CAT_COLUMN).getValue(); // 考試類別

    var qn1=shGSAT.getRange(rowG,QN1_COLUMN).getValue(); // 試題編號1

    // var qn2=shGSAT.getRange(rowG,QN2_COLUMN).getValue(); // 試題編號2

    var qType=shGSAT.getRange(rowG,QTYPE_COLUMN).getValue(); // 題型

    var strQuestion=shGSAT.getRange(rowG,QUESTION_COLUMN).getValue(); // 試題

    var strLen=strQuestion.length; // 字串的長度


    //+ 處理一列的句子群,

    var i=0; // 字串的指標

    var qn2=0; 

    // 分句寫出,直到遇到選項群

    // matchCItem_ 遇到選項時,會傳回 8 或 7,否則會傳回 0

      while ((matchCItem_(strQuestion,i)==0)&&(i<=strLen-1)){ 

      var strSentence="";


      // 發現句子結束時,寫出句子

      // matchSentence_ 遇到句點、問號、或驚歎號時,會傳回 2 或 1,否則會傳回 0

      while ((matchSentence_(strQuestion,i)==0)&&

        (matchCItem_(strQuestion,i)==0)&&(i<=strLen-1)){

        //* 處理一個句子

        strSentence+=strQuestion[i];

        i++;

      }

      if (matchSentence_(strQuestion,i)>0) // 發現句子結束

      {

        rowGS++;

        qn2++;

        shGSentence.getRange(rowGS,YEAR_COLUMN).setValue(year);

        shGSentence.getRange(rowGS,CAT_COLUMN).setValue(cat);

        shGSentence.getRange(rowGS,QN1_COLUMN).setValue(qn1);

        shGSentence.getRange(rowGS,QN2_COLUMN).setValue(qn2);

        shGSentence.getRange(rowGS,QTYPE_COLUMN).setValue(qType);

        strSentence+=strQuestion[i];

        if (matchSentence_(strQuestion,i)==2){ // .", 或 ?", 或 !"

          strSentence+=strQuestion[i+1];

          i+=2;

        } else {

          i++;             

        }

      

        shGSentence.getRange(rowGS,QUESTION_COLUMN).setValue(strSentence);


        if (strQuestion[i]==" ") {

          i++; // bypass 空白

        }

      }

    }


    //+ 處理選項群    

    while (i<=strLen-1){

      // matchCItem_ 遇到選項時,會傳回 8 或 7,否則會傳回 0

      if (matchCItem_(strQuestion,i)>0){

        strSentence=strQuestion.substr(i,matchCItem_(strQuestion,i));

        i+=matchCItem_(strQuestion,i);

      }

      // 處理一個選項,連接後續字元,直到遇到下一個選項,或字串結束

      while ((matchCItem_(strQuestion,i)==0)&&(i<=strLen-1)){

        strSentence+=strQuestion[i];

        i++;

      }

      // 新增一筆到學測分句試算表的下一列

      rowGS++;

      qn2++;

      shGSentence.getRange(rowGS,YEAR_COLUMN).setValue(year);

      shGSentence.getRange(rowGS,CAT_COLUMN).setValue(cat);

      shGSentence.getRange(rowGS,QN1_COLUMN).setValue(qn1);

      shGSentence.getRange(rowGS,QN2_COLUMN).setValue(qn2);

      shGSentence.getRange(rowGS,QTYPE_COLUMN).setValue(qType);

      shGSentence.getRange(rowGS,QUESTION_COLUMN).setValue(strSentence);        

    }

}

function matchCItem_(strQuestion,i){

  if (i>(strQuestion.length-9)){

    return 0;

  }

  if ((strQuestion[i]>='0' && strQuestion[i]<='9') && 

      (strQuestion[i+1]>='0' && strQuestion[i+1]<='9') &&

      (strQuestion.substr(i+2,6)==". (A) ")){

    return 8; // 兩位數字加 ". (A) " 共八位

  }

  if ((strQuestion[i]>='0' && strQuestion[i]<='9') && 

      (strQuestion.substr(i+1,6)==". (A) ")){

    return 7; // 一位數字加 ". (A) " 共七位

  }

  return 0; 

}

function qTypeM_(rowG){

    var year=shGSAT.getRange(rowG,YEAR_COLUMN).getValue(); // 年度

    var cat=shGSAT.getRange(rowG,CAT_COLUMN).getValue(); // 考試類別

    var qn1=shGSAT.getRange(rowG,QN1_COLUMN).getValue(); // 試題編號1

    //  var qn2=shGSAT.getRange(rowG,QN2_COLUMN).getValue(); // 試題編號2

    var qType=shGSAT.getRange(rowG,QTYPE_COLUMN).getValue(); // 題型

    var strQuestion=shGSAT.getRange(rowG,QUESTION_COLUMN).getValue(); // 試題

    var strLen=strQuestion.length; // 字串的長度


    //+ 處理一列的句子群,

    var i=0; // 字串的指標

    var qn2=0; 

    // 分句寫出,直到遇到選項群

    while ((strQuestion.substr(i,3)!="(A)")&&(i<=strLen-1)){ 

      var strSentence="";


      // 發現句子結束時,寫出句子

      while ((matchSentence_(strQuestion,i)==0)&&

        (strQuestion[i]!="(")&&(i<=strLen-1)){

        //* 處理一個句子

        strSentence+=strQuestion[i];

        i++;

      }

      if (matchSentence_(strQuestion,i)>0)

      {

        rowGS++;

        qn2++; // 每一筆學測題從1起算

        shGSentence.getRange(rowGS,YEAR_COLUMN).setValue(year);

        shGSentence.getRange(rowGS,CAT_COLUMN).setValue(cat);

        shGSentence.getRange(rowGS,QN1_COLUMN).setValue(qn1);

        shGSentence.getRange(rowGS,QN2_COLUMN).setValue(qn2);

        shGSentence.getRange(rowGS,QTYPE_COLUMN).setValue(qType);

        strSentence+=strQuestion[i];

        if (matchSentence_(strQuestion,i)==2){

          strSentence+=strQuestion[i+1];

          i+=2;

        } else {

          i++;

        }

      

        shGSentence.getRange(rowGS,QUESTION_COLUMN).setValue(strSentence);


        if (strQuestion[i]==" ") {

          i++; // bypass 空白

        }

      }

    }


    //+ 處理選項群


    strSentence=strQuestion[i];

    i++;  

    while (i<=strLen-1){

      strSentence+=strQuestion[i];

      i++;

    }

    rowGS++;

    qn2++;

    shGSentence.getRange(rowGS,YEAR_COLUMN).setValue(year);

    shGSentence.getRange(rowGS,CAT_COLUMN).setValue(cat);

    shGSentence.getRange(rowGS,QN1_COLUMN).setValue(qn1);

    shGSentence.getRange(rowGS,QN2_COLUMN).setValue(qn2);

    shGSentence.getRange(rowGS,QTYPE_COLUMN).setValue(qType);

    shGSentence.getRange(rowGS,QUESTION_COLUMN).setValue(strSentence);

}

function qTypeR_(rowG){

    var year=shGSAT.getRange(rowG,YEAR_COLUMN).getValue(); // 年度

    var cat=shGSAT.getRange(rowG,CAT_COLUMN).getValue(); // 考試類別

    var qn1=shGSAT.getRange(rowG,QN1_COLUMN).getValue(); // 試題編號1

    // var qn2=shGSAT.getRange(rowG,QN2_COLUMN).getValue(); // 試題編號2

    var qType=shGSAT.getRange(rowG,QTYPE_COLUMN).getValue(); // 題型

    var strQuestion=shGSAT.getRange(rowG,QUESTION_COLUMN).getValue(); // 試題

    var strLen=strQuestion.length; // 字串的長度


    //+ 處理一列的句子群,

    var i=0; // 字串的指標

    var qn2=0; 

    // 分句寫出,直到遇到選項群

    // matchRItem_ 遇到選項時,會傳回 4 或 3,否則會傳回 0

      while ((matchRItem_(strQuestion,i)==0)&&(i<=strLen-1)){ 

      var strSentence="";


      // 發現句子結束時,寫出句子

      // matchSentence_ 遇到句點、問號、或驚歎號時,會傳回 2 或 1,否則會傳回 0

      while ((matchSentence_(strQuestion,i)==0)&&

        (matchRItem_(strQuestion,i)==0)&&(i<=strLen-1)){

        //* 處理一個句子

        strSentence+=strQuestion[i];

        i++;

      }

      if (matchSentence_(strQuestion,i)>0) // 發現句子結束

      {

        rowGS++;

        qn2++;

        shGSentence.getRange(rowGS,YEAR_COLUMN).setValue(year);

        shGSentence.getRange(rowGS,CAT_COLUMN).setValue(cat);

        shGSentence.getRange(rowGS,QN1_COLUMN).setValue(qn1);

        shGSentence.getRange(rowGS,QN2_COLUMN).setValue(qn2);

        shGSentence.getRange(rowGS,QTYPE_COLUMN).setValue(qType);

        strSentence+=strQuestion[i];

        if (matchSentence_(strQuestion,i)==2){ // .", 或 ?", 或 !"

          strSentence+=strQuestion[i+1];

          i+=2;

        } else {

          i++;             

        }

      

        shGSentence.getRange(rowGS,QUESTION_COLUMN).setValue(strSentence);


        if (strQuestion[i]==" ") {

          i++; // bypass 空白

        }

      }

    }


    //+ 處理選項群    

    while (i<=strLen-1){

      // matchCItem_ 遇到選項時,會傳回 4 或 3,否則會傳回 0

      if (matchRItem_(strQuestion,i)>0){

        strSentence=strQuestion.substr(i,matchRItem_(strQuestion,i));

        i+=matchRItem_(strQuestion,i);

      }

      // 處理一個選項,連接後續字元,直到遇到下一個選項,或字串結束

      while ((matchRItem_(strQuestion,i)==0)&&(i<=strLen-1)){

        strSentence+=strQuestion[i];

        i++;

      }

      // 新增一筆到學測分句試算表的下一列

      rowGS++;

      qn2++;

      shGSentence.getRange(rowGS,YEAR_COLUMN).setValue(year);

      shGSentence.getRange(rowGS,CAT_COLUMN).setValue(cat);

      shGSentence.getRange(rowGS,QN1_COLUMN).setValue(qn1);

      shGSentence.getRange(rowGS,QN2_COLUMN).setValue(qn2);

      shGSentence.getRange(rowGS,QTYPE_COLUMN).setValue(qType);

      shGSentence.getRange(rowGS,QUESTION_COLUMN).setValue(strSentence);        

    }  

}

function matchRItem_(strQuestion,i){

  // 確保第 i-1 字非連續數字,避免句尾的 2010. 被視為選項的開始

  if ((strQuestion[i-1]<'0' || strQuestion[i-1]>'9')&& 

      (strQuestion[i]>='0' && strQuestion[i]<='9') && 

      (strQuestion[i+1]>='0' && strQuestion[i+1]<='9') &&

      (strQuestion.substr(i+2,2)==". ")){

      return 4; // 兩位數字加 ". " 共四位

    

  }

  // 確保第 i-1 字非連續數字,避免句尾的 2010. 被視為選項的開始

  if ((strQuestion[i-1]<'0' || strQuestion[i-1]>'9')&&

      (strQuestion[i]>='0' && strQuestion[i]<='9') && 

      (strQuestion.substr(i+1,2)==". ")){

    return 3; // 一位數字加 ". " 共三位 

  }

  return 0; 

}

function qTypeT_(rowG){

  rowGS++;

  qn2=1;

  var inputRow=shGSAT.getRange(rowG,1,1,8).getValues();

  shGSentence.getRange(rowGS,1,1,8).setValues(inputRow);

  shGSentence.getRange(rowGS,QN2_COLUMN).setValue(qn2);

}

function extractSentenceASTS(){}





沒有留言:

張貼留言