分类 技术 下的文章

学习如何使用 Lua 编程语言为物联网(IoT)设备编程,并与树莓派上的通用输入/输出(GPIO)引脚互动。

Lua 是一种有时会被误解的语言。它与 Python 等其他语言不同,但它是一种通用的扩展语言,广泛用于游戏引擎、框架等。总的来说,我发现 Lua 对开发人员来说是一个有价值的工具,可以让他们以一些强大的方式增强和扩展他们的项目。

你可以按照 Seth Kenlon 的文章《Lua 值得学习吗?》的介绍下载并运行常用的 Lua,该文章中还包括了简单的 Lua 代码示例。但是,要充分利用 Lua,最好将它与采用该语言的框架一起使用。在本教程中,我演示了如何使用名为 Mako Server 的框架,该框架旨在使 Lua 程序员能够轻松地编写 IoT 和 Web 应用代码。我还向你展示了如何使用 API 扩展此框架以使用树莓派的 GPIO 引脚。

要求

在学习本教程之前,你需要一个可以登录的正在运行的树莓派。虽然我将在本教程中编译 C 代码,但你不需要任何 C 代码经验。但是,你需要一些使用 POSIX 终端的经验。

安装

首先,在树莓派上打开一个终端窗口并安装以下工具,以使用 Git 下载代码和编译 C 代码:

$ sudo apt install git unzip gcc make

接下来,通过运行以下命令编译开源 Mako Server 代码和 lua-periphery 库(树莓派的 GPIO 库):

$ wget -O Mako-Server-Build.sh \
  https://raw.githubusercontent.com/RealTimeLogic/BAS/main/RaspberryPiBuild.sh

查看脚本以了解它的作用,并在你觉得没问题后运行它:

$ sh ./Mako-Server-Build.sh

编译过程可能需要一些时间,尤其是在较旧的树莓派上。编译完成后,脚本会要求你将 Mako Server 和 lua-periphery 模块安装到 /usr/local/bin/。我建议安装它以简化软件的使用。别担心,如果你不再需要它,你可以卸载它:

$ cd /usr/local/bin/
$ sudo rm mako mako.zip periphery.so

要测试安装,请在终端中输入 mako。这将启动 Mako 服务器,并在你的终端中看到一些输出。你可以按 CTRL+C 停止服务器。

IoT 和 Lua

现在 Mako 服务器已在你的树莓派上设置好,你可以开始对 IoT 和 Web 应用进行编程,并使用 Lua 操作树莓派的 GPIO 引脚。Mako Server 框架为 Lua 开发人员提供了一个强大而简单的 API 来创建物联网应用,而 lua-periphery 模块让 Lua 开发人员可以与树莓派的 GPIO 引脚和其他外围设备进行交互。

首先创建一个应用目录和一个 .preload 脚本,其中插入用于测试 GPIO 的 Lua 代码。.preload 脚本是一个 Mako 服务器扩展,在应用启动时作为 Lua 脚本加载和运行。

$ mkdir gpiotst
$ nano gpiotst/.preload

将以下内容复制到 Nano 编辑器 中并保存文件:

-- Load periphery.so and access the LED interface
local LED = require('periphery').LED

local function doled()
  local led = LED("led0") -- Open LED led0
  trace"Turn LED on"
  led:write(true)   -- Turn on LED (set max brightness)
  ba.sleep(3000)    -- 3 seconds
  trace"Turn LED off"
  led:write(false)  -- Turn off LED (set zero brightness)
  led:close()
end

ba.thread.run(doled) -- Defer execution
                     -- to after Mako has started

上面的 Lua 代码使用你编译并包含在 Mako 服务器中的 Lua-periphery 库控制树莓派 LED。该脚本定义了一个名为 doled 的函数来控制 LED。该脚本首先使用 Lua require 函数加载 periphery 库(共享库 periphery.so)。返回的数据是一个包含所有 GPIO API 函数的 Lua 表。但是,你只需要 LED API,你可以通过在调用 require 后附加 .LED 来直接访问它。接下来,代码定义了一个名为 doled 的函数,它执行以下操作:

  • 通过调用 periphery 库中的 LED 函数,并将字符串 led0 传给它,打开树莓派主 LED,识别为 led0
  • 将消息 Turn LED on 打印到跟踪(控制台)。
  • 通过调用 LED 对象上的 write 方法并将布尔值 true 传递给它来激活 LED,该值设置 LED 的最大亮度。
  • 通过调用 ba.sleep(3000) 等待 3 秒。
  • 将消息 Turn LED off 打印到跟踪。
  • 通过调用 LED 对象上的 write 方法并将布尔值 false 传递给它来停用 LED,这会将 LED 的亮度设置为零。
  • 通过调用 LED 对象上的 close 函数关闭 LED

.preload 脚本的末尾,doled 函数作为参数传递给 ba.thread.run 函数。这允许将 doled 函数的执行推迟到 Mako 服务器启动之后。

要启动 gpiotst 应用,请按如下方式运行 Mako 服务器:

$ mako -l::gpiotst

控制台中打印以下文本:

Opening LED:
opening 'brightness': Permission denied.

访问 GPIO 需要 root 访问权限,因此按 CTRL+C 停止服务器并重新启动 Mako 服务器,如下所示:

$ sudo mako -l::gpiotst

现在树莓派 LED 亮起 3 秒。成功!

Lua 解锁 IoT

在本入门教程中,你学习了如何编译 Mako 服务器,包括 GPIO Lua 模块,以及如何编写用于打开和关闭树莓派 LED 的基本 Lua 脚本。在以后的文章中,我将在本文的基础上进一步介绍 IoT 功能。

同时,你可以通过阅读它的 文档 来更深入地研究 Lua-periphery GPIO 库,以了解有关功能以及如何将其与不同外设一起使用的更多信息。要充分利用本教程,请考虑关注 交互式 Mako Server Lua 教程 以更好地了解 Lua、Web 和 IoT。编码愉快!

(题图:MJ/4514210d-5697-4cd3-8c44-450bbe56be64)


via: https://opensource.com/article/23/3/control-your-raspberry-pi-lua

作者:Alan Smithee 选题:lkxed 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

这个开源工具可以轻松将 Markdown 转换为网页。

将 Markdown 文件直接变成网页,还无需搭建网站和生成过程,写完文档即可直接发布,你对这个内容感兴趣吗?你是否希望将 Markdown 或 HTML 自由地嵌入到多个平台(如内容管理系统或学习管理系统)中?由 Docsify.js 构建的开源项目 Docsify-This 提供了一种简单的方法来发布、分享和复用 Markdown 文件内容。

Docsify-This 是什么?

使用 Docsify-This,你可以立即将任何 Markdown 文件转换为响应式的独立网页。你还可以将多个 Markdown 文件链接起来,以创建一个简单的网站。网页设计师可以简单地通过点击 Web 页面生成器界面或改变网页的地址参数(即 URL),来更改所显示页面的视觉外观。在创建自己的 Markdown 文件内容时,你还可以使用一组提供的 Markdown CSS 类。此外,如果你使用 Codeberg 或 GitHub 仓库存储 Markdown 文件的话,每个页面都会自动提供一个 “ 编辑此页面 Edit this Page ” 的链接,以支持协同创作。

并且 Docsify-This 是开源的,因此你可以使用自定义域名托管 Docsify-This 实例,而不会有被平台锁定的风险。

使用 Docsify-This 网页生成器

要使用网页生成器,请先打开浏览器,导航到 Docsify-This 网站 或你在本地的实例。在 “ 网页生成器 Web Page Builder ” 部分,输入 Codeberg 或 GitHub 上公共存储仓库中的一个 Markdown 文件的 URL(其他 Git 主机可以通过 Docsify-This URL 参数进行使用,但不能在网页生成器中使用),然后点击 “ 发布为独立网页 Publish as Standalone Web Page ” 的按钮,如下图所示。

The Docsify-This web page builder interface

Markdown 文件将呈现为一个独立的网页,并生成一个可复制和共享的 URL。以下是一个示例 URL:

https://docsify-this.net/?basePath=https://raw.githubusercontent.com/hibbitts-design/docsify-this-one-page-article/main&homepage=home.md

Docsify-This 生成的网页非常适合嵌入,可以将 Docsify-This 页面的视觉样式调整到目标平台上去。

Docsify-This rendered Markdown file

渲染同一存储库中的其他文件

你也可以通过直接编辑 Docsify-This URL 参数 homepage 来渲染同一存储库中的其他 Markdown 文件。例如:

https://docsify-this.net/?basePath=https://raw.githubusercontent.com/hibbitts-design/docsify-this-one-page-article/main&homepage=anotherfile.md

修改网页的外观

你可以使用 URL 参数 更改 Docsify-This 中显示的任何 Markdown 文件的外观。例如,font-family(文本字体系列)、font-size(字体大小)、link-color(超链接颜色)和 line-height(行高)都是常见的 CSS 属性,同时也是 Docsify-This 中的有效参数:

https://docsify-this.net/?basePath=https://raw.githubusercontent.com/hibbitts-design/docsify-this-one-page-article/main&homepage=home.md&font-family=Open%20Sans,sans-serif

你也可以使用一组特殊的 Markdown CSS 类 来改变网页的外观。例如,你可以为一个链接添加“按钮类”:

[Required Reading Quiz due Jun 4th](https://canvas.sfu.ca/courses/44038/quizzes/166553 ':class=button')

这将产生一个按钮,而不是一个文本链接:

A button rendered by Docsify-This

除了 Docsify-This 支持的 Markdown CSS 类,你也可以在Markdown 文件中使用自定义类。例如:

<style>
.markdown-section .mybutton, .markdown-section .mybutton:hover {
  cursor: pointer;
  color: #CC0000;
  height: auto;
  display: inline-block;
  border: 2px solid #CC0000;
  border-radius: 4rem;
  margin: 2px 0px 2px 0px;
  padding: 8px 18px 8px 18px;
  line-height: 1.2rem;
  background-color: white;
  font-family: -apple-system, "Segoe UI", "Helvetica Neue", sans-serif;
  font-weight: bold;
  text-decoration: none;
}
</style>

[Custom CSS Class Button](# ':class=mybutton')

使用这个自定义类将生成这样的按钮:

A custom button image rendered with Docsify-This

在 Markdown 文件中包含 HTML 片段

正如标准 Markdown 所支持的那样,你可以在 Markdown 文件中包括 HTML 片段。这允许你在你的 HTML 渲染中添加布局元素。例如:

<div class="row">
    <div class="column">
        Lorem ipsum dolor sit amet, consectetur adipiscing elit.
    </div>
    <div class="column">
        Lorem ipsum dolor sit amet, consectetur adipiscing elit.
    </div>
</div>

使用 iFrame 嵌入 Docsify-This 网页

你可以在几乎所有的平台上使用 iFrame 嵌入 Docsify-This 网页。你还可以使用 URL 参数来确保你的嵌入内容与你的目标平台相匹配:

<p><iframe style="overflow: hidden; border: 0px #ffffff none; margin-top: -26px; background: #ffffff;" src="https://docsify-this.net/?basePath=https://raw.githubusercontent.com/paulhibbitts/cmpt-363-222-pages/main&homepage=home.md&font-family=Lato%20Extended,Lato,Helvetica%20Neue,Helvetica,Arial,sans-serif&font-size=1&hide-credits=true" width="800px" height="950px" allowfullscreen="allowfullscreen"></iframe></p>

A Docsify-This page embedded in an LMS

使用外部 URL 嵌入 Docsify-This

在某些学习管理系统中,包括开源的 Moodle,或者专有的 Canvas,你可以将外部网页链接到课程导航菜单。例如,你可以使用 Canvas 中的重定向工具来显示 Docsify-This 网页。

url=https://docsify-this.net/?basePath=https://raw.githubusercontent.com/paulhibbitts/cmpt-363-222-pages/main&homepage=resources.md&edit-link=https://github.com/paulhibbitts/cmpt-363-222-pages/blob/main/resources.md&font-family=Lato%20Extended,Lato,Helvetica%20Neue, Helvetica,Arial,sans-serif&font-size=1&hide-credits=true

整合 Docsify-This 和 Git

为了充分利用版本控制的好处,并使用 “ 编辑此页面 Edit this Page ” 的链接进行协同工作,请将你的 Docsify-This Markdown 文件存储在 Codeberg 或 GitHub 的 Git 存储库中。一些开源工具为 Git 提供了一个图形界面,包括 GitHub Desktop(最近已开源)、Git-ColaSparkleShare。文本编辑器 VSCode 和 Pulsar Edit(以前的 Atom.io)也都有整合 Git 的功能。

轻松实现 Markdown 文件在网页发布

由于 Docsify 的存在,每个人都能享受到 Markdown 文件的在网上发布的好处。而且由于 Docsify-This 的出现,这个工作变得很容易。不妨在 Docsify-This 网站 上试试吧。

(题图:MJ/f38f0a40-002b-4e93-9697-e008205c1211)


via: https://opensource.com/article/23/5/docsify-markdown-html

作者:Paul Hibbitts 选题:lkxed 译者:chai001125 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

压力测试 CPU 是检查处理器在重负载下性能表现以及系统在此情况下的温度的最佳方法之一。

当你压力测试 CPU 时,可以监视系统资源,观察它们在最高工作负载下的表现。虽然性能不会改变,但如果处理器不具备良好散热能力,温度可能会影响其运作。

对于发烧友来说,压力测试是建造新系统时必不可少的,特别是如果你打算以后超频 CPU。

例如,在压力测试过程中,如果你的 CPU 很快变得太热,你需要通过更换 CPU 风扇、使用更好的通风机箱等方式来改进散热解决方案。

现在你已经了解到压力测试的好处,接下来我将为你介绍在 Linux 中压力测试 CPU 的以下两种方法:

  • 使用 GtkStressTesting(图形界面方式)
  • 使用 stress 和 s-tui 实用程序(命令行方式)

接下来,让我们从第一种方法开始。

使用图形界面方法压力测试 Linux CPU ?️

如果你更喜欢使用图形界面方法,而不是通过终端操作,我有一个最简单的方法来帮助你进行系统压力测试。

有一个名为 GtkStressTesting 的图形界面实用工具,可以帮助你进行压力测试和同时监视温度。它提供了多种预设来进行系统压力测试,并提供了选择在测试期间需要使用多少个内核的功能。

? 该工具在 GitLab 上已不再积极维护。但是它仍能按预期工作。

GtkStressTesting 可以作为 Flatpak 安装,因此如果你尚未启用 Flatpak 支持,请参考我们的 Flatpak 安装指南

一旦你启用了 Flatpak 支持,可以通过终端(如果没有软件中心)使用以下命令来安装 GtkStressTesting 实用工具:

flatpak install flathub com.leinardi.gst

安装完成后,你可以从系统菜单中启动 GtkStressTesting 实用工具。

在这里,我建议你点击“ 读取全部 Read all ”按钮,并输入 sudo 密码,以便工具可以获取你系统的全部信息:

授予 GtkStressTesting 读取所有的权限

从这里,你可以选择压力测试系统的时间(如果温度过高,随时可以停止进程),并在“ 工作线程:自动 Workers: Auto ”下拉菜单中选择可用的的最大数量。

我选择了 12 核心和 5 分钟的压力测试

选择 Linux 中 CPU 压力测试的时间和核心数

完成后,单击“ 开始 Start ”按钮,监视温度,如果超过 90 度,请停止压力测试。

在我的系统上,压力测试过程中最高温度为 85 度:

使用图形界面压力测试 Linux CPU

这是一种非常简便的压力测试 CPU 的方法,是不是很简单呢? ?

使用命令行终端压力测试 Linux CPU

使用 s-tui 命令行实用程序进行压力测试

使用命令行终端压力测试需要两个实用工具:s-tuistress

你可以从默认软件仓库或 使用 pip 来安装这些工具。如果你可以接受使用旧版本的工具,使用默认软件仓库更容易。

以下是适用于流行 Linux 发行版的安装命令:

基于 Ubuntu/Debian 的发行版:

sudo apt install s-tui stress

Arch Linux:

sudo pacman -S s-tui stress

Fedora/RHEL:

sudo dnf install s-tui stress

如果想要使用 pip 安装最新版本,可以使用以下命令:

pip install s-tui --user

安装完成后,在终端中启动 s-tui 实用工具:

s-tui

你将会看到以下内容:

在 Linux 中监控 CPU 的时钟速度、负荷和利用率

你可以使用鼠标或键盘箭头键浏览菜单,然后点击“ 压力选项 Stress options ”,选择你想要压力测试系统的时间(以“秒”为单位):

设置 Linux 中 CPU 压力测试的时间长度

最后,选择“ 压力 Stress ”选项,它会在指定时间内开始压力测试:

使用终端压力测试 Linux 中的 CPU

如果温度失控,你可以点击“ 退出 Quit ”按钮手动停止压力测试。另外,如果你想要将数据存储在 .csv 格式中,该工具也提供了相应的功能。

要存储数据,你只需要在启动 s-tui 实用工具时附加 -c 标记,如下所示:

s-tui -c

如果你想用自己喜欢的名称保存文件,则必须使用 --csv-file 标记,如下所示:

s-tui --csv-file <file 名称>.csv

例如,这里我将文件命名为 Hello.scv

s-tui --csv-file Hello.scv

你可以在它的 GitHub 页面 上了解更多关于这个工具的信息。

系统快乐,人生快乐 ?

并非每个用户都意识到进行压力测试的好处。有时候它会让他们感到害怕,认为系统无缘无故地达到其极限。

但是,测试将帮助你快速评估和监视系统的状况。例如,温度异常上升和 CPU 无法处理现有负载等问题,可以帮助你及早识别硬件问题。

在任何情况下,如果你想在不进行压力测试的情况下 保持 CPU 温度正常,可以参考我们提供的温度监控资源。

你还可以查看一些 Linux 的 系统监控工具htop 的替代品,以监控系统资源的使用情况。

? 你对于在 Linux 中压力测试 CPU 有什么看法?你认为我们应该这样做吗?请在评论区分享你的想法。

(题图:MJ/e5f3fc49-5e47-4f8a-8970-43a445849172)


via: https://itsfoss.com/stress-test-cpu-linux/

作者:Sagar Sharma 选题:lkxed 译者:ChatGPT 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

当你坚持最简场景时,你最终会得到最简单的解决方案。

在前面的文章中,我已经解释了为什么将编程问题看作一整群丧尸来处理是错误的。我用 ZOMBIES 方法来解释为什么循序渐进地处理问题更好。

ZOMBIES 表示以下首字母缩写:

  • Z – 最简场景(Zero)
  • O – 单元素场景(One)
  • M – 多元素场景(Many or more complex)
  • B – 边界行为(Boundary behaviors)
  • I – 接口定义(Interface definition)
  • E – 处理特殊行为(Exercise exceptional behavior)
  • S – 简单场景用简单的解决方案(Simple scenarios, simple solutions)

在系列的前四篇文章中,我展示了 ZOMBIES 方法的前六个原则(LCTT译注:原文为前五个,应为笔误)。

第一篇中 实现了最简场景,它为代码提供了最简可行路径。第二篇文章中执行了 单元素场景和多元素场景上的测试。第三篇中介绍了 边界和接口。 第四篇中处理 特殊行为。在本文中,我将介绍最后一项:简单场景用简单的解决方案。

简单场景用简单的解决方案

回顾这个网购 API 的实现过程,你会发现总是有目的性地坚持考虑最简单的场景。在这个过程中,最终你会得到最简单的解决方案。

ZOMBIES 方法通过坚持简洁性来帮助你交付健壮优雅的解决方案。

胜利了吗?

似乎一切工作都结束了,一个不那么认真负责的工程师很可能会宣布胜利。但开明的工程师总是会探索得更深一点。

我一直推荐做 变异测试 mutation testing 。在圆满结束这个练习项目,开始新的征程之前,用变异测试来敲打敲打你的解决方案是明智的。况且你也不得不承认,变异很适合对付丧尸的。

你可以在开源网站 Stryker.NET 上进行变异测试。

Mutation testing

看起来有一个存活的变异体。这可不是好兆头。

这意味着什么呢?当你自认为解决方案无懈可击的时候,Stryker.NET 却表示在你的地盘上并非一切安好。

让我们来看看这个存活下来的烦人变异体:

Surviving mutant

变异测试工具将

if(total > 500.00) {

变异为:

if(total >= 500.00) {

然后运行测试,结果对于这个变化没有一个测试失败。如果业务处理代码中发生了一处变动却没有任何一个测试失败,这就意味着你遇到一个存活的变异体。

为什么要在意变异体

为什么存活的变异体是麻烦的征兆呢?因为你写的业务处理逻辑代码控制着整个系统的行为。如果业务处理逻辑改变,系统的行为也应该随之改变。而系统行为的改变应该会导致测试表示的期望被违反。如果没有期望被违反,那就说明这些期望对系统行为的描述还不够准确。这也意味着你的业务处理逻辑中存在漏洞。

要解决这个问题,你需要干掉这个存活下来的变异体。要怎么做呢?一般来说,有存活的变异体意味着有期望被遗漏了。

仔细检查代码,梳理已定义的期望,看看漏掉了什么:

  • 期望 0:新建购物框里有零个商品(这隐含了总价为 ¥0)。
  • 期望 1:向购物框添加一件商品的结果是购物框里有一件商品,如果这件商品的价格是 ¥10,那么总价为 ¥10。
  • 期望 2:向购物框添里加入一件价值 ¥10 的商品,再加入一件价值 ¥20 的商品,总价是 ¥30 。
  • 期望 3:关于从购物框移除商品的期望。
  • 期望 4:总价大于 ¥500 时打,享受九折优惠。

缺了什么呢?根据变异测试报告,你没有定义订单总价刚好为 ¥500 的销售策略。你已经定义订单总额大于 ¥500 和小于 ¥500 时的情况。

定义边界情况的期望:

[Fact]
public void Add2ItemsTotal500GrandTotal500() {
    var expectedGrandTotal = 500.00;
    var actualGrandTotal = 450;
    Assert.Equal(expectedGrandTotal, actualGrandTotal);
}

第一步先写一个假的实现让测试失败。现在共有 9 个微测试。其中 8 个通过,第 9 个失败了:

[xUnit.net 00:00:00.57] tests.UnitTest1.Add2ItemsTotal500GrandTotal500 [FAIL]
  X tests.UnitTest1.Add2ItemsTotal500GrandTotal500 [2ms]
  Error Message:
   Assert.Equal() Failure
Expected: 500
Actual: 450
[...]
Test Run Failed.
Total tests: 9
     Passed: 8
     Failed: 1
 Total time: 1.5920 Seconds

将硬编码值替换成正样例的预期代码:

[Fact]
public void Add2ItemsTotal500GrandTotal500() {
    var expectedGrandTotal = 500.00;
    Hashtable item1 = new Hashtable();
    item1.Add("0001", 400.00);
    shoppingAPI.AddItem(item1);
    Hashtable item2 = new Hashtable();
    item2.Add("0002", 100.00);
    shoppingAPI.AddItem(item2);
    var actualGrandTotal = shoppingAPI.CalculateGrandTotal(); }

共添加了两件商品,一件价值 ¥400,另一件价值 ¥100,总价是 ¥500。调用计算总价的函数,期望的总价是 ¥500。

运行,9 个测试全部通过!

Total tests: 9
     Passed: 9
     Failed: 0
 Total time: 1.0440 Seconds

现在是揭晓真相的时刻。这个新增的期望能够清理掉所有的变异体吗?运行变异测试来看看结果:

Mutation testing success

成功了!10 个变异体全都被干掉了。太棒了!现在你可以放心地发布这个 API 了。

结语

如果从这次练习中有什么收获的话,那就是 技术性拖延 skillful procrastination 这一概念的提出。这个是一个重要的概念,因为我们中的许多人往往会在客户描述完他们的问题之前,就盲目地去设想解决方案。

主动拖延

拖延对于软件工程师来说并不是一件容易的事情。我们总是急于动手写代码。我们熟悉各种设计模式、反模式、编程原则和现成的解决方案。我们总是迫不及待想将它们应用到可执行的代码中,并且倾向于一次性做大量的工作。所以在行动之前仔细考虑每个步骤是一种美德。

这个练习说明 ZOMBIES 方法能够通过一系列深思熟虑的小步骤来帮你实现解决方案。但是有一点需要特别注意,根据 Yagni 原则,这些深思熟虑常常会飞得太远,以至于最终形成一个大而全的系统。这会产生臃肿、紧密耦合的系统。

迭代式开发与增量式开发

在这次练习给我们的另一个重要收获是让我们意识到保持系统持续可用的唯一方法是采用迭代式的开发方法。你通过改造已有代码开发出整个购物 API。这种改造工作是在迭代优化解决方案的过程中不可避免的。

很多团队混淆了迭代和增量。这是两个完全不同的概念。

增量式方法是假设是你有完整清晰的需求,然后通过增量累加的方式来构建解方案。大体上来说,你一点点地构建各个部分,然后将所有的部分组装在一起。大功告成!解决方案已经准备好交付了!

相比之下,迭代式方法中,你并不很确定自己需要交付给客户的是什么。因为这个原因,你更加小心谨慎。你会小心翼翼地避免破坏能够运行的系统(也就是说系统处于稳态)。如果不得不扰动已有的平衡,你也会采取最小侵入性的方式。你专注于用尽可能小的工作量来快速完成每次得改动工作。你倾向于让系统尽快回到稳态。

这就是为什么迭代式方法在真正实现一个功能之前总是先提供一个假实现。你硬编码一系列的期望,以验证小的修改不会导致系统无法运行。然后进行必要的修改,用实际处理代码替换硬编码的值。

作为经验法则,在迭代方法中,你的目标是通过设计期望(微测试),对代码进行不断改进。每进行一次改进,你都要检验系统,以确保它处于工作状态。以这种方式不断前进,最终会达到满足所有期望的程度,并且此时代码已经被重构,没有任何存活的变异体了。

一旦达到了这种状态,你就可以相当自信地交付解决方案了。

由衷感谢 Kent BeckRon JeffriesGeePaw Hill 在我的软件工程学习道路的启发。

愿 ZOMBIES 方法在软件开发的征程上帮助到你。

(题图:MJ/ca463fc6-021b-4818-ba3d-9cd3c8736577)


via: https://opensource.com/article/21/2/simplicity

作者:Alex Bunardzic 选题:lkxed 译者:toknow-gh 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

修复 Arch Linux 中 “invalid or corrupted package” 错误的简单指南。

我在物理机和虚拟机中都安装有一些 Arch Linux 系统,我会在需要时访问它们。将近两个月后,当我尝试使用 sudo pacman -Syu 升级其中一个中的 Arch Linux 时,我遇到了数百个这样的错误:

Arch Linux 中无效或损坏的包错误示例

问题是当你遇到上面的错误时,你无法升级/更新你的 Arch 系统。即使你同步镜像或获得更快的镜像。所以,如果你运行 sudo pacman -Syyu,错误仍然存在。这就造成了困难,因为在修复此问题之前你无法安装任何其他软件包。

原因

当你在 Arch Linux 系统上安装或升级软件包时,pacman 会根据 archlinux-keyring 软件包中的密钥检查软件包的数字签名。此验证过程可确保你下载和安装的软件包未经修改且来自受信任的来源。

它包含用于 验证包的真实性和完整性 和 pacman 中的密钥环。archlinux-keyring 包由 Arch Linux 开发人员定期更新,以包含新的可信密钥并撤销任何泄露的密钥。

如果你的 Arch Linux 系统很长时间没有更新,那么各种包的数字签名可能会不匹配。更改后的密钥可能与你系统中的密钥不匹配。

因此出现错误了。

修复

要修复 Arch Linux 中的 “invalid or corrupted package (PGP signature)” 错误,你需要从 Core 仓库安装/更新 archlinux-keyring 包。从终端运行以下命令:

sudo pacman -S archlinux-keyring

上述命令完成后,运行升级:

sudo pacman -Syu

这将解决问题,你可以在 Arch Linux 中继续你的正常活动。建议始终保持 archlinux-keyring 包为最新,以维护 Arch Linux 系统的安全性和完整性。

(题图:MJ/7ed6d549-93c6-463d-823e-3a8c3957790f)


via: https://www.debugpoint.com/invalid-corrupted-package-arch/

作者:Arindam 选题:lkxed 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

以下是如何使用 OpenAI ChatGPT AI 创建聊天助手的 Python 程序的方法。

易于使用的 AI “ChatGPT” 已经以 API 提供。ChatGPT 的创造者 OpenAI 宣布,模型('gpt-3.5-turbo')现在适用于自定义产品和解决方案。而且成本也非常实惠。目前的价格为每 1000 个令牌 0.002 美元。

该模型目前与 Whisper API 一起提供,后者也用于文本到语音解决方案。该 API 目前具备以下功能:

  • 创建自定义的对话代理和机器人
  • 为你编写 Python 代码
  • 起草电子邮件或任何你想要的文档
  • 你可以将自然语言界面集成到你当前的产品/应用/服务或软件中,为你的消费者提供服务
  • 语言翻译服务
  • 成为许多科目的导师
  • 模拟视频游戏角色

正如你所见,机会无限。

如果你计划尝试该 API 并开始使用它,这里有一个简单的指南,为你提供逐步指导。

OpenAI ChatGPT API: 入门指南

先决条件

确保你拥有一个 OpenAI 账户。如果你没有,访问此页面 并创建一个账户。你也可以使用你的谷歌或微软账号。

创建一个账户后,生成一个专属于你的 API 密钥。访问 此页面 并创建一个新的秘密密钥。

创建 OpenAI API 密钥的位置

记录该密钥或在安全的地方保存它。基于安全原因,它将不会从 OpenAI 账户部分再次可见。而且不要与任何人分享此密钥。如果你计划使用企业解决方案,请向你的组织查询 API 密钥。由于该密钥与你的付费 OpenAI 计划相关,因此请谨慎使用。

设置环境

安装 Python 和 pip

本指南使用 Python 编程语言来调用 OpenAI API 密钥。你可以使用 Java 或其他任何语言来调用它。

首先,请确保你在 Linux 或 Windows 中已经安装了 Python。如果没有,请按照以下指南安装 Python。如果你使用现代 Linux 发行版(例如 Ubuntu),Python 应该已经安装好了。

在安装 Python 后,确保 pip 在 Linux 发行版中可用。运行以下命令进行安装。对于 Windows,你应该已经在 Python 安装的一部分中安装了它。

Ubuntu、Debian 和其他基于 Debian 的发行版:

sudo apt install python3-pip

Fedora、RHEL、CentOS 等:

sudo dnf install python3-pip

Arch Linux:

sudo pacman -S python-pip

将 OpenAI API 密钥设置为环境变量

上述步骤中创建的 API 密钥,你可以直接在程序中使用。但这并不是最佳实践。

最佳实践是从文件或你系统的环境变量中调用它。

对于 Windows,请设置一个任何名字的环境变量,例如 API-KEY。并添加密钥值。

对于 Linux,请使用超级用户权限打开 /etc/environment 文件并添加密钥。例如:

API-KEY="<你的密钥>"

对于基于文件的密钥访问,请在你的代码中使用以下语句:

openai.api_key_path = <你的 API 密钥路径>

对于直接在代码中访问(不建议),你可以在你的代码中使用以下语句:

openai.api_key = "你的密钥"

注意:如果验证失败,OpenAI API 将抛出以下错误。你需要验证你的密钥值、路径和其他参数以进行更正:openai.error.AuthenticationError: No API key provided

安装 OpenAI API

最后一步是安装 OpenAI 的 Python 库。打开终端或命令窗口,使用以下命令安装 OpenAI API。

pip install openai

在此阶段,你已经准备好撰写你的第一个程序了!

编写助手程序(逐步)

OpenAI API 提供了各种接口模式。例如“聊天补完”、“代码补完”、“图像生成”等。在本指南中,我将使用 API 的“聊天补完”功能。使用此功能,我们可以创建一个简单的对话聊天机器人。

首先,你需要导入 OpenAI 库。你可以使用以下语句在你的 Python 程序中完成:

import openai

在这个语句之后,你应该确保启用你的 API 密钥。你可以使用上面解释的任何方法来完成。

openai.api_key="your key here"
openai.api_key="your environment variable"
openai.api_key_path = <your path to API key>

OpenAI 聊天 API 的基本功能如下所示。openai.ChatCompletion.create 函数以 JSON 格式接受多个参数。这些参数的形式是 “角色”(role) 和 “内容”(content):

openai.ChatCompletion.create(   
  model = "gpt-3.5-turbo",   
  messages = [         
    {"role": "system", "content": "You are a helpful assistant."},
    {"role": "user", "content": "Who won the world series in 2020?"},
    {"role": "assistant", "content": "The Los Angeles Dodgers won the World Series in 2020."},
    {"role": "user", "content": "Where was it played?"}     
  ]
)

说明:

role: 有效的值为 systemuserassistant

  • system: 指示 API 如何行动。基本上,它是 OpenAI 的主提示。
  • user: 你要问的问题。这是单个或多个会话中的用户输入。它可以是多行文本。
  • assistant: 当你编写对话时,你需要使用此角色来添加响应。这样,API 就会记住讨论的内容。

注意:在一个单一的消息中,你可以发送多个角色。如上述代码片段所示的行为、你的问题和历史记录。

让我们定义一个数组来保存 OpenAI 的完整消息。然后向用户展示提示并接受 system 指令。

messages = []
system_message = input("What type of chatbot you want me to be?")
messages.append({"role":"system","content":system_message})

一旦设置好了,再次提示用户进行关于对话的进一步提问。你可以使用 Python 的 input 函数(或任何其他文件输入方法),并为角色 user 设置 content

print("Alright! I am ready to be your friendly chatbot" + "\n" + "You can now type your messages.")
message = input("")
messages.append({"role":"user","content": message})

现在,你已经准备好了具有基本 JSON 输入的数组,用于调用“聊天补完”服务的 create 函数。

response=openai.ChatCompletion.create(model="gpt-3.5-turbo",messages=messages)

现在,你可以对其进行适当的格式化,要么打印响应,要么解析响应。响应是以 JSON 格式提供的。输出响应提供了 choices 数组。响应在 message JSON 对象下提供,其中包括 content 值。

对于此示例,我们可以读取 choices 数组中的第一个对象并读取其 content

reply = response["choices"][0]["message"]["content"]
print(reply)

最后,它将为你提供来自 API 的输出。

运行代码

你可以从你的 喜好的 Python IDE 或直接从命令行运行代码。

python OpenAIDemo2.py

未格式化的 JSON 输出

以下是使用未格式化的 JSON 输出运行上述程序供你参考。正如你所看到的,响应在 choices 数组下具有 content

[debugpoint@fedora python]$ python OpenAIDemo2.py
What type of chatbot you want me to be?a friendly friend
Alright! I am ready to be your friendly chatbot
You can now type your messages.
what do you think about kindness?
{
  "choices": [
    {
      "finish_reason": "stop",
      "index": 0,
      "message": {
        "content": "As an AI language model, I don't have personal opinions, but I can tell you that kindness is a very positive and essential trait to have. Kindness is about being considerate and compassionate towards others, which creates positive emotions and reduces negativity. People who are kind towards others are more likely to inspire kindness and compassion in return. It is an important quality that helps to build positive relationships, promote cooperation, and create a more peaceful world.",
        "role": "assistant"
      }
    }
  ],
  "created": <removed>,
  "id": "chatcmpl-<removed>",
  "model": "gpt-3.5-turbo-0301",
  "object": "chat.completion",
  "usage": {
    "completion_tokens": 91,
    "prompt_tokens": 22,
    "total_tokens": 113
  }
}

格式化的输出

这是一个适当的对话式输出。

[debugpoint@fedora python]$ python OpenAIDemo2.py
What type of chatbot you want me to be?a friendly friend
Alright! I am ready to be your friendly chatbot
You can now type your messages.
what do you think about artificial general intelligence?
As an AI language model, I am programmed to be neutral and not have personal opinions. However, artificial general intelligence (AGI) is a fascinating field of study. AGI refers to the development of machines and algorithms that can perform any intellectual task that a human being can. The potential benefits and risks of AGI are still widely debated, with some experts worried about the implications of machines reaching human-like intelligence. However, many believe that AGI has the potential to revolutionize fields such as healthcare, education, and transportation. The key is to ensure that AGI is developed in a responsible and ethical manner.

完整代码

这是上面演示中使用的完整代码。

import openai

openai.api_key = "<your key>"
messages = []
system_message = input("What type of chatbot you want me to be?")
messages.append({"role":"system","content":system_message})

print("Alright! I am ready to be your friendly chatbot" + "\n" + "You can now type your messages.")
message = input("")
messages.append({"role":"user","content": message})

response = openai.ChatCompletion.create(
  model="gpt-3.5-turbo",
  messages=messages
)

reply = response["choices"][0]["message"]["content"]
print(reply)

总结

希望这篇简单的指南能让你开始尝试 OpenAI CharGPT API。你可以将上述步骤扩展到更复杂的会话式聊天机器人。此外,你还可以使用 OpenAI 的其他产品。

请不要错过我后续的教程,我将会实验和分享给大家。最后,请不要忘记关注我们,以便及时获取我们的文章。

如果上述步骤对你有帮助,请在评论框中告诉我。

干杯!

参考资料

(题图:MJ/b206dd48-f698-4800-bccc-19ea11a17ea6)


via: https://www.debugpoint.com/openai-chatgpt-api-python

作者:Arindam 选题:lkxed 译者:ChatGPT 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出