【Dison夏令营 Day 07】用 Python 和 Rich 制作 Wordle克隆(下篇)

news2025/1/12 1:47:21

在大流行期间,Wordle 在 Twitter 上还算比较流行的一款基于网络的益智游戏,要求玩家每天在六次或更短时间内猜出一个新的五个字母的单词,每个人得到的单词都是一样的。

在本教程中,你将在终端上创建自己的 Wordle 克隆。自 2021 年 10 月 Josh Wardle 推出 Wordle 以来,已有数百万人玩过这款游戏。虽然您可以在网络上玩原版游戏,但您将以命令行应用程序的形式创建自己的版本,然后使用 Rich 库使其看起来更漂亮。

在这里插入图片描述
书接上回

第 5 步:添加验证和用户反馈

在上一步中,您添加了 Rich 并重写了您的游戏,使用颜色来更好地展示游戏。接下来,您将在此基础上,在用户做错事情时显示一些警告:

在这里插入图片描述
请注意,如果您的猜测不是五个字母,或者您重复了之前的猜测,就会收到警告。

在这一步中,您将添加一些功能,以便在用户做出意外举动时为他们提供指导,从而使您的游戏更加人性化。
确保单词表不是空的

理论上,您可以使用任何文本文件作为单词表。如果单词表不包含任何五个字母的单词,那么 get_random_word() 将会失败。但您的用户会看到哪条消息呢?

打开您的 REPL,尝试从一个空单词表中获取一个随机单词:

>>> import wyrdl
>>> wyrdl.get_random_word([])
Traceback (most recent call last):
  ...
IndexError: Cannot choose from an empty sequence

您看到的是回溯和 IndexError。如果没有其他上下文,用户可能不会意识到问题出在单词表上。

单词列表中没有任何有效单词是很难恢复的,但你至少可以提供一个更明确和可操作的错误信息。更新 get_random_word(),检查有效单词列表是否为空:

# wyrdl.py

# ...

def get_random_word(word_list):
    if words := [
        word.upper()
        for word in word_list
        if len(word) == 5 and all(letter in ascii_letters for letter in word)
    ]:
        return random.choice(words)
    else:
        console.print("No words of length 5 in the word list", style="warning")
        raise SystemExit()

# ...

您可以使用 walrus 运算符 (:=) 创建有效单词列表,并检查其中是否至少包含一个单词。使用 walrus 运算符时,您要编写一个赋值表达式,作为表达式的一部分进行赋值。

在这种情况下,您会像以前一样将单词列表赋值给单词。但是,现在您会立即在 if 测试中使用该列表来检查它是否为空。如果列表为空,则在 else 子句中打印警告,明确说明问题所在:

>>> import wyrdl
>>> wyrdl.get_random_word(["one", "four", "eleven"])
No words of length 5 in the word list

这样,用户就不会看到回溯。取而代之的是提供可操作的反馈,用户可以利用这些反馈来解决问题。

注意,你在调用 console.print() 时添加了 style=“warning”。这使用的是您之前在自定义主题中初始化控制台时定义的警告样式。

由于你的游戏需要一个密语,你将通过引发 SystemExit 来结束程序。接下来,您将考虑可以恢复的问题。例如,用户猜到的单词不是五个字母。不过首先要考虑哪些单词可以作为有效猜测。

考虑接受哪些词语

原始 Wordle 游戏的挑战之一是,您的猜测必须是字典中的实际单词。目前,您还没有在您的 Wordle 克隆中实施同样的限制。任何字母组合都是有效的猜测。

您可以要求猜测的单词也在您现有的单词列表中。但是,如果你使用的单词列表有限,这可能会让用户感到沮丧,因为他们最终需要先弄清楚单词列表中到底有哪些单词。

更好的办法可能是在检查猜测是否有效时使用第二个全面的单词表。重要的是,任何合理的单词都应被视为有效。在没有广泛字典的情况下,允许五个字母的任意组合可能是更好的用户体验。

在本教程中,您将不会处理为验证猜测而添加第二个单词表的问题。不过,你可以尝试一下。这是一个很好的尝试练习!

验证用户猜测的单词

虽然您不会根据单词表检查用户的猜测,但您应该进行一些验证,并在用户做错事情时提醒他们。在本节中,您将改进在用户猜词时提供的用户反馈。

目前,您在以下代码行中处理用户输入:

guesses[idx] = input("\nGuess word: ").upper()

要改进对猜测的处理,首先要将其重构为一个单独的函数。首先,在文件中添加 guess_word():

# wyrdl.py

# ...

def guess_word(previous_guesses):
    guess = console.input("\nGuess word: ").upper()
    return guess

# ...

Rich Console 包含一个 .input() 方法,该方法与输入()函数类似,但允许您为输入提示添加丰富的格式。虽然我们没有利用这一功能,但为了保持一致性,在这里使用 console 也是不错的。

您还将 previous_guesses 作为一个参数,因为您很快就会用它来检查用户是否重复猜测。不过在执行任何检查之前,请更新 main() 以调用新函数:

# wyrdl.py

# ...

def main():
    # Pre-process
    words_path = pathlib.Path(__file__).parent / "wordlist.txt"
    word = get_random_word(words_path.read_text(encoding="utf-8").split("\n"))
    guesses = ["_" * 5] * 6

    # Process (main loop)
    for idx in range(6):
        refresh_page(headline=f"Guess {idx + 1}")
        show_guesses(guesses, word)

        guesses[idx] = guess_word(previous_guesses=guesses[:idx])
        if guesses[idx] == word:
            break

    # Post-process
    game_over(guesses, word, guessed_correctly=guesses[idx] == word)

# ...

您可以创建一个先前猜测的列表,只包含猜测中已经填入的元素。然后将此列表传递给 guess_word()。

现在,使用 previous_guesses 检查用户是否两次做出相同的猜测。如果出现这种情况,就会向用户发出警告,并让他们再次猜测。您可以通过下面的 if 测试来实现:

# wyrdl.py

# ...

def guess_word(previous_guesses):
    guess = console.input("\nGuess word: ").upper()

    if guess in previous_guesses:
        console.print(f"You've already guessed {guess}.", style="warning")
        return guess_word(previous_guesses)

    return guess

# ...

使用之前定义的警告样式,您将向用户打印一条信息,告知他们已经猜出了单词。为了让用户进行新的猜测,您将再次调用 guess_word(),并返回该猜测。

注意:正如您在本教程前面学到的,递归调用通常不是在 Python 中创建循环的最佳方式。然而,在本例中,它却非常优雅。典型的缺点并不重要。例如,与用户输入猜测的时间相比,调用函数所花费的时间可以忽略不计。

既然所有的单词都是五个字母,那么您也应该检查所有的猜测是否都是五个字母。为此,您可以添加第二个条件:

# wyrdl.py

# ...

def guess_word(previous_guesses):
    guess = console.input("\nGuess word: ").upper()

    if guess in previous_guesses:
        console.print(f"You've already guessed {guess}.", style="warning")
        return guess_word(previous_guesses)

    if len(guess) != 5:
        console.print("Your guess must be 5 letters.", style="warning")
        return guess_word(previous_guesses)

    return guess

# ...

本测试的结构与上一测试相同。您要检查猜测中是否有五个字母。如果没有,则打印警告并让用户进行第二次猜测。

最后,您可以引导用户只使用英文字母。在这种情况下,if 测试要复杂一些,因为您需要检查用户猜测中的每个字母:

# wyrdl.py

# ...

def guess_word(previous_guesses):
    guess = console.input("\nGuess word: ").upper()

    if guess in previous_guesses:
        console.print(f"You've already guessed {guess}.", style="warning")
        return guess_word(previous_guesses)

    if len(guess) != 5:
        console.print("Your guess must be 5 letters.", style="warning")
        return guess_word(previous_guesses)

    if any((invalid := letter) not in ascii_letters for letter in guess):
        console.print(
            f"Invalid letter: '{invalid}'. Please use English letters.",
            style="warning",
        )
        return guess_word(previous_guesses)

    return guess

# ...

any()表达式检查猜测中是否有字母不在 ascii_letters 中,ascii_letters 是一个内置的小写和大写字母列表,从 A 到 Z。

注意:如果您添加了自己的单词列表,其中包含使用不同字母的单词,则需要更新此检查以允许用户使用所有字母。

您可以在 any() 中使用 walrus 运算符来收集无效字符的示例。如果用户的猜测中出现了无效字母,那么就像往常一样用 console.print() 报告,并给用户一次新的尝试。

注意:在 any() 中使用 := 功能强大,但其作用可能并不明显。您可以关于此结构的内容,了解详情。

运行您的游戏,并尝试通过不同类型的用户错误来刺激您的代码。当您猜测四个字母的单词或在猜测中包含数字时,您会得到有用的反馈吗?

虽然游戏的核心内容和以前一样,但您的程序现在更加稳固,并会在用户出错时为他们提供指导。如前所述,您可以通过扩展以下部分查看完整的源代码:

# wyrdl.py

import pathlib
import random
from string import ascii_letters

from rich.console import Console
from rich.theme import Theme

console = Console(width=40, theme=Theme({"warning": "red on yellow"}))

def main():
    # Pre-process
    words_path = pathlib.Path(__file__).parent / "wordlist.txt"
    word = get_random_word(words_path.read_text(encoding="utf-8").split("\n"))
    guesses = ["_" * 5] * 6

    # Process (main loop)
    for idx in range(6):
        refresh_page(headline=f"Guess {idx + 1}")
        show_guesses(guesses, word)

        guesses[idx] = guess_word(previous_guesses=guesses[:idx])
        if guesses[idx] == word:
            break

    # Post-process
    game_over(guesses, word, guessed_correctly=guesses[idx] == word)

def refresh_page(headline):
    console.clear()
    console.rule(f"[bold blue]:leafy_green: {headline} :leafy_green:[/]\n")

def get_random_word(word_list):
    if words := [
        word.upper()
        for word in word_list
        if len(word) == 5 and all(letter in ascii_letters for letter in word)
    ]:
        return random.choice(words)
    else:
        console.print("No words of length 5 in the word list", style="warning")
        raise SystemExit()

def show_guesses(guesses, word):
    for guess in guesses:
        styled_guess = []
        for letter, correct in zip(guess, word):
            if letter == correct:
                style = "bold white on green"
            elif letter in word:
                style = "bold white on yellow"
            elif letter in ascii_letters:
                style = "white on #666666"
            else:
                style = "dim"
            styled_guess.append(f"[{style}]{letter}[/]")

        console.print("".join(styled_guess), justify="center")

def guess_word(previous_guesses):
    guess = console.input("\nGuess word: ").upper()

    if guess in previous_guesses:
        console.print(f"You've already guessed {guess}.", style="warning")
        return guess_word(previous_guesses)

    if len(guess) != 5:
        console.print("Your guess must be 5 letters.", style="warning")
        return guess_word(previous_guesses)

    if any((invalid := letter) not in ascii_letters for letter in guess):
        console.print(
            f"Invalid letter: '{invalid}'. Please use English letters.",
            style="warning",
        )
        return guess_word(previous_guesses)

    return guess

def game_over(guesses, word, guessed_correctly):
    refresh_page(headline="Game Over")
    show_guesses(guesses, word)

    if guessed_correctly:
        console.print(f"\n[bold white on green]Correct, the word is {word}[/]")
    else:
        console.print(f"\n[bold white on red]Sorry, the word was {word}[/]")

if __name__ == "__main__":
    main()

您已经很好地实现了 Wordle 克隆。在结束本教程之前,您将在这里和那里调整您的代码,磨平一些尖锐的边缘。

第 6 步:清理游戏和代码

在第 5 步中,您通过添加一些信息来改善用户体验,这些信息可以在用户做错任何事情时提供帮助。在最后一步中,您将添加一个可以帮助用户的功能,即所有字母及其状态的列表:

猜测表下方的字母列表显示了每个字母的当前状态。与往常一样,绿色的字母是正确的,黄色的字母是错误的,灰色的字母是错误的。

好了,最后的调整时间到了。
使用常量为概念命名

魔法值通常会降低代码的可读性。魔力值是一个值,通常是一个数字,在程序中出现时没有任何上下文。例如,请看下面这行代码:

guesses = ["_" * 5] * 6

这里的 "5 "和 "6 "是什么意思?由于您目前正沉浸在游戏中,您可能会立即指出 5 表示单词中的字母数,而 6 指的是允许猜测的次数。不过,如果你几天不碰代码,这一点可能就不再那么明显了。

魔法值的另一个问题是难以更改。假如你想改变一下游戏规则,改猜七个字母的单词。这既麻烦又容易出错。

一个好的做法是用正确命名的常量来替换神奇值。例如,可以定义 NUM_LETTERS = 5,然后用 NUM_LETTERS 替换所有 5 的出现。

注意:Python 对常量没有任何特殊支持。从技术上讲,常量只是一个不改变其值的变量。然而,约定俗成的做法是使用大写字母来表示常量变量的名称。

在代码文件顶部添加几个描述性常量:

# wyrdl.py

import pathlib
import random
from string import ascii_letters

from rich.console import Console
from rich.theme import Theme

console = Console(width=40, theme=Theme({"warning": "red on yellow"}))

NUM_LETTERS = 5
NUM_GUESSES = 6
WORDS_PATH = pathlib.Path(__file__).parent / "wordlist.txt"

# ...

有了这些常量,你就可以开始用这些常量替换你的神奇值了。例如,你现在可以将猜测的初始化写成这样:

guesses = ["_" * NUM_LETTERS] * NUM_GUESSES

常量可以帮助您理解代码的作用。继续在代码中添加常量。您可以展开以下部分,查看您可以做出的所有更改:

# wyrdl.py

import pathlib
import random
from string import ascii_letters

from rich.console import Console
from rich.theme import Theme

console = Console(width=40, theme=Theme({"warning": "red on yellow"}))

NUM_LETTERS = 5
NUM_GUESSES = 6
WORDS_PATH = pathlib.Path(__file__).parent / "wordlist.txt"

def main():
    # Pre-process
    word = get_random_word(WORDS_PATH.read_text(encoding="utf-8").split("\n"))
    guesses = ["_" * NUM_LETTERS] * NUM_GUESSES

    # Process (main loop)
    for idx in range(NUM_GUESSES):
        refresh_page(headline=f"Guess {idx + 1}")
        show_guesses(guesses, word)

        guesses[idx] = guess_word(previous_guesses=guesses[:idx])
        if guesses[idx] == word:
            break

    # Post-process
    game_over(guesses, word, guessed_correctly=guesses[idx] == word)

def refresh_page(headline):
    console.clear()
    console.rule(f"[bold blue]:leafy_green: {headline} :leafy_green:[/]\n")

def get_random_word(word_list):
    if words := [
        word.upper()
        for word in word_list
        if len(word) == NUM_LETTERS
        and all(letter in ascii_letters for letter in word)
    ]:
        return random.choice(words)
    else:
        console.print(
            f"No words of length {NUM_LETTERS} in the word list",
            style="warning",
        )
        raise SystemExit()

def show_guesses(guesses, word):
    for guess in guesses:
        styled_guess = []
        for letter, correct in zip(guess, word):
            if letter == correct:
                style = "bold white on green"
            elif letter in word:
                style = "bold white on yellow"
            elif letter in ascii_letters:
                style = "white on #666666"
            else:
                style = "dim"
            styled_guess.append(f"[{style}]{letter}[/]")

        console.print("".join(styled_guess), justify="center")

def guess_word(previous_guesses):
    guess = console.input("\nGuess word: ").upper()

    if guess in previous_guesses:
        console.print(f"You've already guessed {guess}.", style="warning")
        return guess_word(previous_guesses)

    if len(guess) != NUM_LETTERS:
        console.print(
            f"Your guess must be {NUM_LETTERS} letters.", style="warning"
        )
        return guess_word(previous_guesses)

    if any((invalid := letter) not in ascii_letters for letter in guess):
        console.print(
            f"Invalid letter: '{invalid}'. Please use English letters.",
            style="warning",
        )
        return guess_word(previous_guesses)

    return guess

def game_over(guesses, word, guessed_correctly):
    refresh_page(headline="Game Over")
    show_guesses(guesses, word)

    if guessed_correctly:
        console.print(f"\n[bold white on green]Correct, the word is {word}[/]")
    else:
        console.print(f"\n[bold white on red]Sorry, the word was {word}[/]")

if __name__ == "__main__":
    main()

检查是否替换了所有 5 的方法之一是更改 NUM_LETTERS 的值。如果你猜了 8 次才猜出一个 6 个字母的单词,你的程序还能运行吗?如果没有,那就是漏掉了一个字母。

添加已用字母概览

Rich 提供的颜色为用户提供了很好的线索,让他们知道自己猜对了哪些字母。但是,要一眼看出用户已经猜出了哪些字母并不容易。为了帮助用户,您可以添加一行,显示字母表中每个字母的状态:

您已经在 show_guesses() 中获得了必要的信息,因此您将扩展该函数以显示单个字母的状态:

# wyrdl.py

import pathlib
import random
from string import ascii_letters, ascii_uppercase

# ...

def show_guesses(guesses, word):
    letter_status = {letter: letter for letter in ascii_uppercase}
    for guess in guesses:
        styled_guess = []
        for letter, correct in zip(guess, word):
            if letter == correct:
                style = "bold white on green"
            elif letter in word:
                style = "bold white on yellow"
            elif letter in ascii_letters:
                style = "white on #666666"
            else:
                style = "dim"
            styled_guess.append(f"[{style}]{letter}[/]")
            if letter != "_":
                letter_status[letter] = f"[{style}]{letter}[/]"

        console.print("".join(styled_guess), justify="center")
    console.print("\n" + "".join(letter_status.values()), justify="center")

# ...

您可以使用 dictionary letter_status 来跟踪每个字母的状态。首先,用所有大写字母初始化字典。然后,在处理每个猜测的每个字母时,用正确样式的字母更新 letter_status。处理完毕后,将所有字母连接起来,并以各自的样式打印出来。

将这些信息呈现在用户面前,会让游戏玩起来更轻松愉快。

干净利落地退出游戏

早些时候,您确保用户不会在单词列表为空的情况下看到难以理解的回溯。随着游戏的不断改进,用户接触到 Python 错误信息的可能性越来越小。

但仍然存在的一种可能性是,他们可以按 Ctrl+C 来提前结束游戏。您不想让他们失去退出游戏的能力。不过,在这种情况下,您可以让游戏干净利落地退出。

当用户键入 Ctrl+C 时,Python 会引发一个 KeyboardInterupt 异常。这是一个异常,您可以用 try … except 块捕获它。但在这种情况下,您不需要对异常进行任何特殊处理。因此,您可以使用 contextlib.suppress()。

通过在主循环外添加上下文管理器,可以确保 Ctrl+C 跳出主循环,运行后处理代码:

# wyrdl.py

import contextlib
import pathlib
import random
from string import ascii_letters, ascii_uppercase

# ...

def main():
    # Pre-process
    word = get_random_word(WORDS_PATH.read_text(encoding="utf-8").split("\n"))
    guesses = ["_" * NUM_LETTERS] * NUM_GUESSES

    # Process (main loop)
    with contextlib.suppress(KeyboardInterrupt):
        for idx in range(NUM_GUESSES):
            refresh_page(headline=f"Guess {idx + 1}")
            show_guesses(guesses, word)

            guesses[idx] = guess_word(previous_guesses=guesses[:idx])
            if guesses[idx] == word:
                break

    # Post-process
    game_over(guesses, word, guessed_correctly=guesses[idx] == word)

# ...

请注意,你要在 suppress() 上下文管理器内缩进整个主循环。如果在循环内发生 KeyboardInterrupt(键盘中断),控制权将立即传出循环,并调用 game_over()。

这样做的效果是,游戏将在向用户显示密语后结束。

这就是本教程的最后一项调整。如果你想查看完整的源代码,请查看下面:

# wyrdl.py

import contextlib
import pathlib
import random
from string import ascii_letters, ascii_uppercase

from rich.console import Console
from rich.theme import Theme

console = Console(width=40, theme=Theme({"warning": "red on yellow"}))

NUM_LETTERS = 5
NUM_GUESSES = 6
WORDS_PATH = pathlib.Path(__file__).parent / "wordlist.txt"

def main():
    # Pre-process
    word = get_random_word(WORDS_PATH.read_text(encoding="utf-8").split("\n"))
    guesses = ["_" * NUM_LETTERS] * NUM_GUESSES

    # Process (main loop)
    with contextlib.suppress(KeyboardInterrupt):
        for idx in range(NUM_GUESSES):
            refresh_page(headline=f"Guess {idx + 1}")
            show_guesses(guesses, word)

            guesses[idx] = guess_word(previous_guesses=guesses[:idx])
            if guesses[idx] == word:
                break

    # Post-process
    game_over(guesses, word, guessed_correctly=guesses[idx] == word)

def refresh_page(headline):
    console.clear()
    console.rule(f"[bold blue]:leafy_green: {headline} :leafy_green:[/]\n")

def get_random_word(word_list):
    if words := [
        word.upper()
        for word in word_list
        if len(word) == NUM_LETTERS
        and all(letter in ascii_letters for letter in word)
    ]:
        return random.choice(words)
    else:
        console.print(
            f"No words of length {NUM_LETTERS} in the word list",
            style="warning",
        )
        raise SystemExit()

def show_guesses(guesses, word):
    letter_status = {letter: letter for letter in ascii_uppercase}
    for guess in guesses:
        styled_guess = []
        for letter, correct in zip(guess, word):
            if letter == correct:
                style = "bold white on green"
            elif letter in word:
                style = "bold white on yellow"
            elif letter in ascii_letters:
                style = "white on #666666"
            else:
                style = "dim"
            styled_guess.append(f"[{style}]{letter}[/]")
            if letter != "_":
                letter_status[letter] = f"[{style}]{letter}[/]"

        console.print("".join(styled_guess), justify="center")
    console.print("\n" + "".join(letter_status.values()), justify="center")

def guess_word(previous_guesses):
    guess = console.input("\nGuess word: ").upper()

    if guess in previous_guesses:
        console.print(f"You've already guessed {guess}.", style="warning")
        return guess_word(previous_guesses)

    if len(guess) != NUM_LETTERS:
        console.print(
            f"Your guess must be {NUM_LETTERS} letters.", style="warning"
        )
        return guess_word(previous_guesses)

    if any((invalid := letter) not in ascii_letters for letter in guess):
        console.print(
            f"Invalid letter: '{invalid}'. Please use English letters.",
            style="warning",
        )
        return guess_word(previous_guesses)

    return guess

def game_over(guesses, word, guessed_correctly):
    refresh_page(headline="Game Over")
    show_guesses(guesses, word)

    if guessed_correctly:
        console.print(f"\n[bold white on green]Correct, the word is {word}[/]")
    else:
        console.print(f"\n[bold white on red]Sorry, the word was {word}[/]")

if __name__ == "__main__":
    main()

你已经写了不少代码。通过一步步构建 Wordle 克隆,你看到了每个部分是如何融入整体的。像这样以迭代的方式实现代码,是保持对程序所有操作的了解的好方法。

结束语

恭喜你 您已经创建了一个功能丰富的 Wordle 克隆,您可以自己玩,也可以与您所有的朋友–至少是那些知道如何在终端运行 Python 程序的朋友–分享。

一路走来,你已经熟悉了 Rich,并学会了如何使用该库为终端应用程序添加色彩和风格。

在这个循序渐进的项目中,你将学会:

  • 拥有迭代创建命令行应用程序的良好策略
  • 使用 Rich 的控制台在终端创建美观的用户界面
  • 读取并验证用户输入
  • 处理以字符串、列表和字典表示的数据
  • 处理存储在文本文件中的数据

接下来,挑战一下自己的 Wordle 克隆能力吧!您还可以寻找继续开发游戏的方法。请在下面的讨论区分享您的经验。

下一步

虽然您的 Wordle 克隆已经具备了最重要的功能,但您仍有许多方法可以更改或改进项目。您已经在教程中注意到了其中一些:

  • 只允许从有效单词列表中猜词: 这将使游戏更具挑战性,因为你不能随便把一些字母扔到一起,检查它们是否出现在密语中。要实现这一点,你需要一个全面的单词列表。

  • 创建主题 Wordle 克隆: 本教程中下载的单词表是基于教程本身的单词。根据您感兴趣的主题创建一个单词表可能会更有趣。也许你可以创建一个编程术语、人名或莎士比亚戏剧的列表。

  • 添加闪屏: 闪屏或介绍屏幕是让用户做好准备的好方法。为了让您的应用程序更容易使用,您还可以添加一些游戏内说明–例如,解释游戏的目的和不同颜色代表的含义。

尽情探索你自己的 Wordle 变体吧。另外,请记住,在创建其他命令行应用程序时,您可以使用本教程中学到的大部分原理。那么,你下一步要做什么呢?

感谢大家花时间阅读我的文章,你们的支持是我不断前进的动力。期望未来能为大家带来更多有价值的内容,请多多关注我的动态!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1889008.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

java基于ssm+vue 病人跟踪治疗信息管理系统

1病人功能模块 病人登录进入病人跟踪治疗信息管理系统可以查看首页、个人中心、病例采集管理、预约管理、医生管理、上传核酸检测报告管理、上传行动轨迹管理、病人治疗状况管理等内容。 病例采集管理,在病例采集管理页面可以查看账号、姓名、住院号、入院时间、病…

华三多台交换机堆叠配置(环形组网)

组网架构 配置步骤 SW1的配置: irf member 1 priority 32 设置master的优先级为32 interfacec range Ten-GigabitEthernet1/0/49 to Ten-GigabitEthernet1/0/50 shutdown 关闭上述接口(将其加入到堆叠口之前需要关闭,否则无法加入&a…

SpringBoot 项目整合 MyBatis 框架,附带测试示例

文章目录 一、创建 SpringBoot 项目二、添加 MyBatis 依赖三、项目结构和数据库表结构四、项目代码1、application.yml2、TestController3、TbUser4、TbUserMapper5、TestServiceImpl6、TestService7、TestApplication8、TbUserMapper.xml9、MyBatisTest 五、浏览器测试结果六、…

语音大模型引领自然交互新时代,景联文科技推出高质量语音大模型数据库

近期,OpenAI正式发布语音大模型GPT-4o,可以综合利用语音、文本和视觉信息进行推理,扮演一个个人语音交互助手。 在音频处理方面,它不仅能识别和转录多种口音和方言,改变语音的速度音调和振动,还能进行声音模…

中国桥梁空间分布数据

2020年中国桥梁空间分布数据,共包含102000余条数据。 数据属性表包括:地级市名、区县名、桥梁名称和经纬度。有shp和EXCEl两种格式数据。目前暂没有广西、广东和台湾三个省份数据。

新创建spring项目打包启动直接报错没有主清单

springboot程序打成jar包执行报错: 启用 repackage 目标: 将 true 注释以启用 repackage 目标。 这样会确保在构建过程中生成具有正确清单属性的可执行 JAR 文件。

石墨烯分散液制备方法众多 应用领域广泛

石墨烯分散液制备方法众多 应用领域广泛 石墨烯分散液指将石墨烯纳米片均匀分散在特定溶剂中制成的溶液。石墨烯分散液具有化学稳定性好、生物相容性好、热稳定性好等优势,未来有望在涂料、纤维制品、电池制造、油墨等领域获得广泛应用。 石墨烯分散液以石墨…

银河麒麟V10SP1Nginx代理转发故障socket() failed (24: Too many open files)修改操作系统ulimit值解决实战

银河麒麟V10SP1Nginx代理转发故障socket() failed (24: Too many open files)修改操作系统ulimit值解决实战 一、事故描述 Nginx转发失败,转发代理服务器宕机! 翻看Nginx日志 /var/log/nginx日志大量报错如下: socket() failed (24: Too m…

sklearn(Python机器学习库)介绍

0 引言 Sklearn (全称 Scikit-Learn)是基于Python 编程语言的免费软件机器学习库。 Scikit-learn主要是用Python编写的,它建立在 NumPy, SciPy, Pandas 和 Matplotlib 之上,里面API 的设计非常好,所有对象的接口简单,很适合新手上路。 Scikit-learn与许多其他Python库很好地…

Zookeeper:Zookeeper集群角色

文章目录 一、Leader选举二、Zookeeper集群角色 一、Leader选举 Serverid:服务器ID;比如有三台服务器,编号越大在选择算法中的权重越大。Zxid:数据ID;服务器中存放的最大数据ID,值越大说明数据越新&#x…

携手共筑爱的桥梁:引导接纳自闭症同学

在孩子的班级中,当自闭症儿童成为我们共同的一员时,作为老师和家长,我们肩负着特别的责任——引导孩子们以开放的心态接纳、善待并关爱他们。 首先,我们要以身作则,展现接纳与尊重。无论是老师还是家长,都…

vue3自定义指令(图文教程)

序: 简单,但是没怎么用,但是小伙伴问了,所以做个教程。 自定义指令我只关心3件事 干啥用的,怎么用的,解决什么痛点怎么全局博文有查阅及参考过以下文章, vue3:自定义指令_vue3自定…

深度学习实战82-新的研究方向:大模型与图模型结合生成大型图模型,大图模型相关挑战和机遇的观点

大家好,我是微学AI,今天给大家介绍一下深度学习实战82-新的研究方向:大模型与图模型结合生成大型图模型,大图模型相关挑战和机遇的观点。随着人工智能的飞速发展,大型模型已成为人工智能领域最新的突破性成就。在图方面,大型模型尚未取得与自然语言处理和计算机视觉等其他…

14-15 为什么我们现在对阅读如此难以接受

写出来感觉很奇怪,但最近我感觉自己失去了阅读能力。长篇文本对我来说尤其具有挑战性。句子很难读完。更别提章节了。章节有很多段落,而段落又由许多句子组成。 啊。 即使在极少数情况下,我读完了一章,下一页上已经有另一章等着…

Next.js 实战 (一):项目搭建指南

前言 时间过得好快,一下就来到2024下半年了。 上半年我为了学习 Nuxt3,从 0 到 1 开发了一个导航网站:Dream Site,目前主要的功能都已完成了,后续有时间再慢慢添加有趣的功能。 下半年开始进攻 Next.js,…

关于 VuePress 的插件

插件就好比第三方功能,例如增加一个阅读进度条、增加光标效果等。VuePress 官网对插件的介绍:插件通常会为 VuePress 添加全局功能。 这里简单介绍几个本站用的插件吧! ‍ ‍ 插件就好比第三方功能,例如增加一个阅读进度条、增…

计算机提示找不到xinput1_3.dll缺失,七个详细不同修复方法

在电脑中下载或许启动运行游戏时候我相信各位都会遇到xinput1_3.dll丢失或许找不到xinput1_3.dll文件问题,当遇到这个问题时候要如何修复呢?今天我就给大家详细讲解一下xinput1_3.dll是什么与xinput1_3.dll作用和丢失原因以及xinput1_3.dll丢失要怎么处理…

嵌入式c语言2——预处理

在c语言中,头部内容,如include与define是不参与编译而直接预先处理的 如include相当于把头文件扩展,define相当于做了替换 c语言大型工程创建时,会有调试版本与发行版本,发行时不希望看到调试部分内容,此时…

【数据分享】国家级旅游休闲街区数据(Excel/Shp格式/免费获取)

之前我们分享过从我国文化和旅游部官网整理的2018-2023年我国50个重点旅游城市星级饭店季度经营状况数据(可查看之前的文章获悉详情)!文化和旅游部官网上也分享有很多与旅游相关的常用数据,我们基于官网发布的名单文件整理得到全国…

汇聚全球智慧 上海打造人工智能“核爆点”和“新风口”

以下文章来源:证券时报 “以共商促共享 以善治促善智”为主题的世界人工智能大会暨人工智能全球治理高级别会议将于7月4日—6日在上海召开。证券时报记者注意到,大会自2018年创办以来已成功举办六届,成为全球人工智能最具影响力的综合性会议。…