首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >语言Bot:用于创建名词、词缀或动词接合表

语言Bot:用于创建名词、词缀或动词接合表
EN

Code Review用户
提问于 2022-08-07 17:46:12
回答 1查看 83关注 0票数 3

我是新生。

What我的程序解决了吗?

这实际上是一个编辑机器人,在那个网站上有语言学习字幕,有时当我们和人们讨论一些事情时,我们可能需要向他们显示解密或共轭表,而不是发送链接,这个机器人将帮助你自动评论它。

What我认为我的代码做什么?

它只适用于立陶宛语,有一个关于立陶宛语的解密或连接的网站,我的程序转到那个网站上,从它的html表格上刮掉,然后形成一个表格,然后在评论中回复。

Why我想要一个评论吗?

实际上,这应该是一个学习项目,我想知道我的代码中的弱点,我做错了的事情,或者我可以更好地编码它的部分。这确实有效,但我认为这不足以成为一个好的程序员。

我的代码够干净了吗?我的代码干不干?很慢吗?有什么坏的地方吗?有什么建议吗?我正确地分开文件夹了吗?您可以在github上找到所有源代码--这是评论的样子

我的目录是这样的:

代码语言:javascript
复制
>src
    >config
        >lietuvos-config.js
    >service
        >bot.js
    >util
        >extract-word.js
        >get-table.js
        >pretty-stringified.js
    >app.js
>package.lock
>readme.md
>package.json

提取-词

代码语言:javascript
复制
const extractor = function(query){
    const pattern = /<[a-zA-Z]+>/; //only works with latin letters for now, to be updated
    const stringToSplit = query; //make it case insensitive
    const extractedWord= stringToSplit.match(pattern)
    extractedWord[0] = extractedWord[0].replace("<","")
    extractedWord[0] = extractedWord[0].replace(">","")
    return extractedWord
}

module.exports={
    extractor: extractor
}

get-table.js

代码语言:javascript
复制
var scraper = require('table-scraper');
const {prettifier} = require('../util/pretty-stringified')

const tableOfContent = function(query){
        return scraper.get('https://morfologija.lietuviuzodynas.lt/zodzio-formos/'+query)
                .then(function(tableData){ 
                    console.log(tableData)
                    return prettifier(tableData).toString() //JSON.stringify(tableData)
                }) 
                .catch((error)=>{
                    return "error"
                }) 
}

module.exports = {
    tableOfContent: tableOfContent
}

漂亮的-strgified.js

代码语言:javascript
复制
const tablemark = require('tablemark')

const prettifier = function(query){
    const decider = nounOrVerb(query);
    if(decider == "noun"){
        return declineNouns(query)
    }else if(decider == "verb"){
        return conjugateVerbs(query)
    }else if(decider == "adjective"){
        return declineAdjectives(query)
    }
}
const convertArrays = function(array){
    var newArr = [];
    for(var i = 0; i < array.length; i++){
    newArr = newArr.concat(array[i]);
    }
    return newArr
}
const declineNouns = function (query){
    const newArr = convertArrays(query)
    var tidiedArr = []
    for (var i = 0; i < newArr.length; i++) {
        tidiedArr.push(newArr[i]["\Š\."])
        tidiedArr.push(newArr[i].Vienaskaita)
    }
    var redditTable = tablemark([
        {Form:"**V.**",Vienaskaita:tidiedArr[0],Daugiskaita:tidiedArr[1]},
        {Form:"**K.**",Vienaskaita:tidiedArr[2],Daugiskaita:tidiedArr[3]},
        {Form:"**K.**",Vienaskaita:tidiedArr[4],Daugiskaita:tidiedArr[5]},
        {Form:"**G.**",Vienaskaita:tidiedArr[6],Daugiskaita:tidiedArr[7]},
        {Form:"**Įn.**",Vienaskaita:tidiedArr[8],Daugiskaita:tidiedArr[9]},
        {Form:"**Vt.**",Vienaskaita:tidiedArr[10],Daugiskaita:tidiedArr[11]},
        {Form:"**Š.**",Vienaskaita:tidiedArr[12],Daugiskaita:tidiedArr[13]},
    ])
    return redditTable;
}
const conjugateVerbs = function(query){
    const newArr = convertArrays(query)
    var tidiedArr = []
    for (var i = 0; i < newArr.length; i++) {
        tidiedArr.push(newArr[i]["Jie/jos"])
        tidiedArr.push(newArr[i]["Esamasis laikas"])
        tidiedArr.push(newArr[i]["Būtasis kartinis laikas"])
        tidiedArr.push(newArr[i]["Būtasis dažninis"])
    }
    var redditTable = tablemark([
        {Įvardis:"**Aš**","**Esamasis laikas**":tidiedArr[0],"**Būtasis kartinis laikas**":tidiedArr[1],"**Būtasis dažninis**":tidiedArr[2],"**Būsimasis laikas**":tidiedArr[3]},
        {Įvardis:"**Tu**","**Esamasis laikas**":tidiedArr[4],"**Būtasis kartinis laikas**":tidiedArr[5],"**Būtasis dažninis**":tidiedArr[6],"**Būsimasis laikas**":tidiedArr[7]},
        {Įvardis:"**Jis/ji**","**Esamasis laikas**":tidiedArr[8],"**Būtasis kartinis laikas**":tidiedArr[9],"**Būtasis dažninis**":tidiedArr[10],"**Būsimasis laikas**":tidiedArr[11]},
        {Įvardis:"**Mes**","**Esamasis laikas**":tidiedArr[12],"**Būtasis kartinis laikas**":tidiedArr[13],"**Būtasis dažninis**":tidiedArr[14],"**Būsimasis laikas**":tidiedArr[15]},
        {Įvardis:"**Jūs**","**Esamasis laikas**":tidiedArr[16],"**Būtasis kartinis laikas**":tidiedArr[17],"**Būtasis dažninis**":tidiedArr[18],"**Būsimasis laikas**":tidiedArr[19]},
        {Įvardis:"**Jie/jos**","**Esamasis laikas**":tidiedArr[20],"**Būtasis kartinis laikas**":tidiedArr[21],"**Būtasis dažninis**":tidiedArr[22],"**Būsimasis laikas**":tidiedArr[23]},
    ])
    return redditTable;
}
const declineAdjectives = function(query){
    const newArr = convertArrays(query)
    var tidiedArr = []
    for (var i = 0; i < newArr.length; i++) {
        tidiedArr.push(newArr[i]["\Š\."])
        tidiedArr.push(newArr[i].Vienaskaita)
        tidiedArr.push(newArr[i].Daugiskaita)
        tidiedArr.push(newArr[i]["Vienaskaita_2"])
    }
    var redditTable = tablemark([
        {Form: "",name:"**Vienaskaita**",name2:"**Daugiskaita**",name3:"**Vienaskaita**",name4:"**Daugiskaita**"},
        {Form:"**V.**",name:tidiedArr[0],name2:tidiedArr[1],name3:tidiedArr[2],name4:tidiedArr[3]},
        {Form:"**K.**",name:tidiedArr[4],name2:tidiedArr[5],name3:tidiedArr[6],name4:tidiedArr[7]},
        {Form:"**K.**",name:tidiedArr[8],name2:tidiedArr[9],name3:tidiedArr[10],name4:tidiedArr[11]},
        {Form:"**G.**",name:tidiedArr[12],name2:tidiedArr[13],name3:tidiedArr[14],name4:tidiedArr[15]},
        {Form:"**Įn.**",name:tidiedArr[16],name2:tidiedArr[17],name3:tidiedArr[18],name4:tidiedArr[19]},
        {Form:"**Vt.**",name:tidiedArr[20],name2:tidiedArr[21],name3:tidiedArr[22],name4:tidiedArr[23]},
        {Form:"**Š.**",name:tidiedArr[24],name2:tidiedArr[25],name3:tidiedArr[26],name4:tidiedArr[27]},
    ],{
        columns:[
            "Form",
            {name: "Vyriškoji giminė"},
            {name:" "},
            {name: "Moteriškoji giminė"},
            {name:" "}
        ]
    })
    return redditTable;
}
const nounOrVerb = function(array){
    try{
        const listOfTable = Object.keys(array[0][0]);
        if(listOfTable[0] == "Jie/jos"){
                return "verb"
        }else if(listOfTable[3] =="Vienaskaita_2"){
                return "adjective"
        }else if(listOfTable[0] == "Š."){
                return "noun"
        }
    }catch{
        return "Error"
    }
   
   
}
module.exports = {
    prettifier:prettifier
}

bot.js

代码语言:javascript
复制
const {comments} = require('../config/lietuvos-config')
const {extractor} = require('../util/extract-word')
const {tableOfContent} = require('../util/get-table')
const BOT_START = Date.now() / 1000;

const canSummon = (msg) => {
    /*if(msg){
        msg.toLowerCase().includes('!inspect');
        //function
        return;
    }
    return*/
    return msg && msg.toLowerCase().includes('!inspect');
};

const commenting =  function(){
    comments.on('item',async (item) => {
        try{
            var replyString = "labas u/"+item.author.name+"! esu robotas ir pateikiu lentelę apie žodžius, veiksmažodžius, būdvardžius."+
                " jei prieš nieko, čia tavo žodžio lentelė. net galite sužinot daugiau čia ^[šaltinis](https://morfologija.lietuviuzodynas.lt/zodzio-formos/"+extractedWord+
                ") \n\n "
                var errorReply= "labas u/"+item.author.name+"! esu bandęs rasti žodį, kurį rašėi, atsiprašau ir dėja, bet negalėjau rasti. "+
                    "gal tas žodis neegzistuoja lietuvių kalboj, rašėi neteisingai - arba yra klaida mano kode.\n šiaip ar taip, galite bandyt rast savarankiškai čia ^[žodynas](https://morfologija.lietuviuzodynas.lt/"
                var replyStringEnder = " \n\n \*\*\* \n ^feel ^free ^to ^report ^bugs ^or ^errors\n ^\[[source-code]\](https://github.com/wulfharth7/lietuvos-robotas) ^| ^\[[buy-me-a-coffee☕]\](https://www.buymeacoffee.com/beriscen)"
            if(item.created_utc < BOT_START) return;
            if(!canSummon(item.body)) return;
            var extractedWord = extractor(item.body)
            tableOfContent(extractedWord).then(function(tableofLog){
                if(tableofLog !== "error"){
                    item.reply(replyString+ tableofLog+replyStringEnder)
                }else{
                    item.reply(errorReply+replyStringEnder)
                }
            })
        }catch(Error){  
            var errorReply= "labas u/"+item.author.name+"! esu bandęs rasti žodį, kurį rašėi, atsiprašau ir dėja, bet negalėjau rasti. "+
                    "gal tas žodis neegzistuoja lietuvių kalboj, rašėi neteisingai - arba yra klaida mano kode.\n\n šiaip ar taip, galite bandyt rast savarankiškai čia ^[žodynas](https://morfologija.lietuviuzodynas.lt/)"
                    item.reply(errorReply+replyStringEnder)
        }
    
});
} 

module.exports={
    commenting: commenting
}
EN

回答 1

Code Review用户

回答已采纳

发布于 2022-08-19 15:42:38

extract-word.js

很明显,你已经意识到它只适用于拉丁文字母是个问题,但我还是要指出。因为,你知道,它不包括在立陶宛使用的几个字母。

顺便说一句,正则表达式可以使用i标志不区分大小写,比如const pattern = /<[a-z]+>/i

stringToSplit有点多余-它包含与query完全相同的内容,所以我们可以直接在query上操作。

我们可以通过使用捕获组来清理提取。如果我们执行const pattern = /<([a-z]+)>/i,则父类定义一个组,并且可以以extractedWord[1]的形式访问该组。

总之,这个函数可以简化成一个像return query.match(/<([a-z]+)>/i)[1];这样的单行。或者return query.match(/<([a-ząčęėįšųūž]+)>/i)[1];来添加一些字母(我希望它们是正确的)。更明智的做法可能是将模式保持在一条单独的线上,例如:

代码语言:javascript
复制
const extractor = function(query){
    const pattern = /<([a-ząčęėįšųūž]+)>/i;
    return query.match(pattern)[1];
}

module.exports={
    extractor: extractor
}

get-table.js

我确实想知道在失败的情况下返回"error"是否是最有用的行为。会不会更方便.让失败仍然是一个失败,以使调用者更容易发现和清理?由于bot.js已经有一个提供错误消息的catch块,所以最好只.让它也从这里处理错误。

然后我们可以让这份文件更接近

代码语言:javascript
复制
var scraper = require('table-scraper');
const {prettifier} = require('../util/pretty-stringified')

const tableOfContent = function(query) {
    return scraper.get('https://morfologija.lietuviuzodynas.lt/zodzio-formos/' + query)
        .then(function(tableData) { 
            console.log(tableData);
            return prettifier(tableData).toString();
        });
}

module.exports = {
    tableOfContent: tableOfContent
}

pretty-stringified.js

首先,nounOrVerb的名字有点误导,因为它有三个可能的结果。就目前而言。也许有一天它还会有第四个?让我们给它取个名字,给它留出扩张的空间。比如const typeOfWord = getTypeOfWord(query);

或者,不让一个函数返回一个字符串,然后根据该字符串的内容进行分支.我们可以直接返回函数:

代码语言:javascript
复制
const prettify = function(query) {
    const prettifier = choosePrettifier(query);
    return prettifier(query);
}

const choosePrettifier = function(table) {
    try {
        const listOfTable = Object.keys(table[0][0]);
        if (listOfTable[0] == "Jie/jos") {
            return conjugateVerbs;
        } else if (listOfTable[3] == "Vienaskaita_2") {
            return declineAdjectives;
        } else if (listOfTable[0] == "Š.") {
            return declineNouns;
        }
    }
}

我们甚至可以在那里叫它但是..。我不知道,我觉得那看起来更糟了。这可能是一个迹象,表明有一个更好的解决方案,我现在正在错过。

接下来是共轭/递减函数,它们似乎遵循了一种有点奇怪的模式。它们使用包含某种结构化对象的数组,通过将其字段推入平面数组来移除该结构,然后通过处理单个数组索引重新添加结构。感觉有点迂回。例如,看看declineNouns,似乎这样的东西应该能工作:

代码语言:javascript
复制
const declineNouns = function(query) {
    const newArr = convertArrays(query);
    const forms = ["**V.**", "**K.**", "**K.**", "**G.**", "**Įn.**", "**Vt.**", "**Š.**"];

    const tidiedArr = [];
    // There's probably some even neater functional way to do this, but I don't remember it right now
    for (var i = 0; i < newArr.length; ++i) {
        tidiedArr.push({Form: forms[i], Vienaskaita: newArr[i]["\Š\."], Daugiskaita: newArr[i].Vienaskaita});
    }

    return tablemark(tidiedArr);
}

现在,我知道Daugiskaita: newArr[i].Vienaskaita部件在Vienaskaita键也存在时看起来有点可疑,但是旧代码有Daugiskaita: tidiedArr[1]tidiedArr[1]是由tidiedArr.push(newArr[i].Vienaskaita)设置的,所以我假设它是正确的

bot.js

应该删除canSummon中的注释代码。如果我们出于某种原因需要它回来,总是有版本控制的。

errorReply两次以完全相同的方式定义。我建议在函数开始时只做一次。由于它依赖于注释作者的用户名,所以我们可以在传递给comments.on的回调开始时定义它,或者我们可以有一个类型的“模板函数”,它只需要一个用户名并发出正确的错误消息。我有点喜欢后者,但这两种方法都很管用。

extractedWord似乎用于在实际设置replyString之前创建它。感谢JS的范围规则,如果它找到一个单词,我不会完全感到惊讶,但我希望它能找到一个更早的评论者所要求的单词。我们可能希望确保在获得所有内容之后创建答复,无论是稍后移动定义还是将其传递给将其插入字符串的函数。

最后只有一个item.reply调用,我们也可以节省一些重复。

如果我们还使用前面提到的“抛出一个异常而不是返回"error"”的想法,我可能会做一些离以下几步不远的事情:

代码语言:javascript
复制
const commenting =  function(){
    let replyString = function(username, extractedWord) {
        return `labas u/${username}! esu robotas ir pateikiu lentelę apie žodžius, veiksmažodžius, būdvardžius.` +
            ` jei prieš nieko, čia tavo žodžio lentelė. net galite sužinot daugiau čia ^[šaltinis](https://morfologija.lietuviuzodynas.lt/zodzio-formos/${extractedWord}")`;
    };

    let errorReply = function(username) {
        return `labas u/${item.author.name}! esu bandęs rasti žodį, kurį rašėi, atsiprašau ir dėja, bet negalėjau rasti. ` +
            "gal tas žodis neegzistuoja lietuvių kalboj, rašėi neteisingai - arba yra klaida mano kode.\n šiaip ar taip, galite bandyt rast savarankiškai čia ^[žodynas](https://morfologija.lietuviuzodynas.lt/";
    }

    let replyStringEnder = " \n\n \*\*\* \n ^feel ^free ^to ^report ^bugs ^or ^errors\n ^\[[source-code]\](https://github.com/wulfharth7/lietuvos-robotas) ^| ^\[[buy-me-a-coffee☕]\](https://www.buymeacoffee.com/beriscen)";
    
    comments.on('item',async (item) => {
        let message;
        try {            
            if(item.created_utc < BOT_START) return;
            if(!canSummon(item.body)) return;
            let extractedWord = extractor(item.body);
            table = await tableOfContent(extractedWord);
            message = replyString(item.author.name) + table;
        } catch(Error) {
            message = errorReply(item.author.name);
        }

        item.reply(message + replyStringEnder);
    });
} 
票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/278671

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档