【问题标题】:IRC BOT in Python, if in elif in while-loopPython中的IRC BOT,如果在while循环中的elif中
【发布时间】:2013-04-02 21:37:36
【问题描述】:

完整代码如下:

#client der mit irc-server kontakt aufnimmt
import time
import socket
from sys import argv

script, mitspieler1, mitspieler2 = argv
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

class funktion:

    def main(self):

            print "Socket(Client)"
            host = "irc.iz-smart.net"
            port = 6667 
            PASS = "7987fshd" 
            NICK = "Testikus" 
            USER = "Testikus localhost irc.iz-smart.net :Testikus" 
            self.login(PASS, NICK, USER, host, port)
            print "Verbindung aufgebaut zu {0}(IP:{1})".format(
            host, socket.gethostbyname(host)
            )
            self.haupt_schleife()

    def haupt_schleife(self):
        while True:
            antwort = sock.recv(4096)
            join = "JOIN #testblablub \r\n"
            print antwort
            if antwort[0:4] == "PING":
                self.pong(antwort, join)
            elif antwort.split()[3] == ":quiz.start":
                sock.sendall("PRIVMSG #testblablub Es spielen mit: "
                            +mitspieler1+" und "+mitspieler2+"\r\n"
                            )
                time.sleep(2)
                self.fragen(antwort)

    def pong(self, antwort, join):
        sock.sendall("PONG " + antwort.split()[1] + "\n")
        time.sleep(3)
        sock.sendall(join)
        sock.sendall("PRIVMSG #testblablub hi \r\n")

    def login(self, PASS, NICK, USER, host, port):
        sock.connect((host, port))
        sock.sendall("PASS "+PASS+"\n")
        sock.sendall("NICK "+NICK+"\n")
        sock.sendall("USER "+USER+"\n")

    def fragen(self, antwort):
            sock.sendall("PRIVMSG #testblablub Welche Farbe hat der Himmel ? \r\n")
            time.sleep(3)
            if antwort.split()[3] == ":blau":
                sock.sendall("PRIVMSG #testblablub RISCHTISCH \r\n")





ausfuehren = funktion()
ausfuehren.main()

(抱歉有些字符串是用德语写的,但我认为这并不重要)

所以我的主要问题是我希望函数 def fragen(self, antwort)def haupt_schleife(self) 函数中运行(或者为了 python 的方法)。所有重要的东西都在这个def haupt_schleife(self) 中。我希望其余的测验代码在def haupt_schleife(self) 的 elif 块中运行,这样它就完全独立了。愚蠢的是,如果我输入“quiz.start”,sock.sendall("PRIVMSG #testblablub Welche Farbe hat der Himmel ? \r\n") 运行没有问题,但它不会启动 if 语句。它只是在频道中不做任何其他事情(只是打印“Welche Farbe hat der Himmel ? out)。

我希望最后有人明白这一点:/ (如果要运行代码,则必须在命令行中输入两个名称,因为 argv)

【问题讨论】:

  • 对于将来的参考,输出并不重要,但如果变量名是用英文写的,那就更好了。我并不是说必须获得帮助,但很多人可能会变得挑剔并因此而忽略代码,以便通过用英语编写所有变量来增加您的几率:) Jedenfalls, viel Glück :)

标签: python chat bots irc


【解决方案1】:

IRC 语法

应该以这种方式发送消息:

PRIVMSG #testblablub Es spielen mit:

应该是:

PRIVMSG #testblablub :Es spielen mit ...

另外,USER 应该由 4 个部分组成:

<username> <hostname> <servername> :<full name/realname>

在 irc 中,重要\r\n结束每个字符串
我注意到你有时会发送\n,结果会很糟糕,总是以\r\n 结尾!

然后是sock.sendall(...),它应该用于你想在所有打开的套接字上广播消息的 UDP 套接字,在你的情况下,你正在向服务器发送和从服务器发送消息,没有别的......它是通过TCP,所以你应该使用sock.send(...)(如果我错了,请纠正我)

附注:
PING,它应该只回复PONG &lt;server-name (usually sent with PING)&gt;\r\n,而不是每次都用JOIN发送垃圾邮件,JOIN应该在收到MOTD后发送,但确定没问题真的..它只会惹恼系统管理员。 在你的情况下,它可能是PONG irc.iz-smart.net\r\n,没有别的,没有JOIN等等。


现在,问题来了

   def haupt_schleife(self):
        while True:
            antwort = sock.recv(4096)
            join = "JOIN #testblablub \r\n"
            print antwort
            if antwort[0:4] == "PING":
                self.pong(antwort, join)
            elif antwort.split()[3] == ":quiz.start":
                sock.sendall("PRIVMSG #testblablub Es spielen mit: "
                            +mitspieler1+" und "+mitspieler2+"\r\n"
                            )
                time.sleep(2)
                self.fragen(antwort)
            elif antwort.split()[3] == ":blau":
                sock.sendall("PRIVMSG #testblablub RISCHTISH!\r\n")

由于self.fragen(...) 用户写入quiz.start时被调用,所以ifdef fragen(...)内的检查将永远不会再次运行..(因为下次用户写东西时,它可能是“blau”,并且与“:quiz.start”不匹配,这是进入if检查fragen(...)内部的唯一方法。

    def fragen(self, antwort):
            sock.sendall("PRIVMSG #testblablub Welche Farbe hat der Himmel ? \r\n")
            time.sleep(3)

因此,我们删除了 if 块并将其改为 haupt_schleife 中的 elif

FIRST 运行/消息的解析方式如下:

下一次运行,fragen 中的消息将是绿色的,但它永远不会到达那里,因为到达那里的唯一方法是通过 elif antwort.split()[3] == ":quiz.start": :)

【讨论】:

  • 嘿,非常感谢您的付出和所有细节 :) 这对我帮助很大。但我认为要做一个非常好的测验,如果必须做很多更复杂的东西,我会看看未来会带来什么。如果我想实现一些其他的东西,我怎样才能避免这些 if/elif caskades?我讨厌那样。(可能只是一个简短的回答?)问候
  • if caskades 没有“短”版本,在进行测验(字符串比较)时,会有很多遗憾地说出来。一种动态的方法是通过self.questions = {'Welche farbe hat der Himmel?' : 'balu', 'Was is mein name?' : 'testikus', 'welcher tag ist es?' : 'freitag'} and so on. When "starting" a game, you could remember it in say self.game = '是我的名字吗? ` 对于用户给出的任何答案,您都可以做if antwort == self.questions[self.question]: 并动态比较它,如果所有问题和答案只有一个:) Python 字典很棒,谷歌它们:)
  • 如果(且仅当)您认为这解决了您最初的问题,并且如果您需要任何帮助,请随时打开更多信息,请不要忘记接受它作为解决方案:)
  • 谢谢 :) 但也许我会切换到其他一些项目(一段时间),看看我能在那里学到什么。 :) 问候
【解决方案2】:

当此条件为真时,您调用fragen 函数:

elif antwort.split()[3] == ":quiz.start":

然后,在fragen 函数中,当此条件为真时,您进入if 分支:

if antwort.split()[3] == ":blau":

由于函数被调用,我们知道antwort.split()[3] 将是":quiz.start",因此if 语句将永远不会被执行。

您应该重新检查应用程序背后的逻辑。

【讨论】:

  • 嗨,谢谢你的回复 :) 有什么办法可以避免这些 if/elif caskades 吗??
  • 不要粗鲁,但避免它们的唯一方法就是不要写它们。
  • 或创建一个包含与答案匹配的问题的字典,并将其保留在一个 if 语句中。越少越好,但是如果您不按照您建议的方式将其溢出,那么作为开发人员阅读起来很快就会变得复杂:) 但是在这种情况下还有其他方法可以绕过 if 语句。
  • 好的,我会记住这一点的 :) 感谢@Torexed 的大力帮助!
猜你喜欢
  • 2017-10-13
  • 2023-03-25
  • 2021-04-15
  • 2014-11-02
  • 1970-01-01
  • 2021-10-31
  • 2021-06-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多