分类 软件开发 下的文章

通过这个分步教程,开始用人类可读的文本编写 WebAssembly。

 title=

WebAssembly 是一种字节码格式,几乎所有的浏览器 都可以将它编译成其宿主操作系统的机器代码。除了 JavaScript 和 WebGL 之外,WebAssembly 还满足了将应用移植到浏览器中以实现平台独立的需求。作为 C++ 和 Rust 的编译目标,WebAssembly 使 Web 浏览器能够以接近原生的速度执行代码。

当谈论 WebAssembly 应用时,你必须区分三种状态:

  1. 源码(如 C++ 或 Rust): 你有一个用兼容语言编写的应用,你想把它在浏览器中执行。
  2. WebAssembly 字节码: 你选择 WebAssembly 字节码作为编译目标。最后,你得到一个 .wasm 文件。
  3. 机器码(opcode): 浏览器加载 .wasm 文件,并将其编译成主机系统的相应机器码。

WebAssembly 还有一种文本格式,用人类可读的文本表示二进制格式。为了简单起见,我将其称为 WASM-text。WASM-text 可以比作高级汇编语言。当然,你不会基于 WASM-text 来编写一个完整的应用,但了解它的底层工作原理是很好的(特别是对于调试和性能优化)。

本文将指导你在 WASM-text 中创建经典的 “Hello World” 程序。

创建 .wat 文件

WASM-text 文件通常以 .wat 结尾。第一步创建一个名为 helloworld.wat 的空文本文件,用你最喜欢的文本编辑器打开它,然后粘贴进去:

(module
    ;; 从 JavaScript 命名空间导入
    (import  "console"  "log" (func  $log (param  i32  i32))) ;; 导入 log 函数
    (import  "js"  "mem" (memory  1)) ;; 导入 1 页 内存(64kb)
   
    ;; 我们的模块的数据段
    (data (i32.const 0) "Hello World from WebAssembly!")
   
    ;; 函数声明:导出 helloWorld(),无参数
    (func (export  "helloWorld")
        i32.const 0  ;; 传递偏移 0 到 log
        i32.const 29  ;; 传递长度 29 到 log(示例文本的字符串长度)
        call  $log
        )
)

WASM-text 格式是基于 S 表达式的。为了实现交互,JavaScript 函数用 import 语句导入,WebAssembly 函数用 export 语句导出。在这个例子中,从 console 模块中导入 log 函数,它需要两个类型为 i32 的参数作为输入,以及一页内存(64KB)来存储字符串。

字符串将被写入偏移量 为 0 的数据段。数据段是你的内存的 叠加投影 overlay ,内存是在 JavaScript 部分分配的。

函数用关键字 func 标记。当进入函数时,栈是空的。在调用另一个函数之前,函数参数会被压入栈中(这里是偏移量和长度)(见 call $log)。当一个函数返回一个 f32 类型时(例如),当离开函数时,一个 f32 变量必须保留在栈中(但在本例中不是这样)。

创建 .wasm 文件

WASM-text 和 WebAssembly 字节码是 1:1 对应的,这意味着你可以将 WASM-text 转换成字节码(反之亦然)。你已经有了 WASM-text,现在将创建字节码。

转换可以通过 WebAssembly Binary Toolkit(WABT)来完成。从该链接克隆仓库,并按照安装说明进行安装。

建立工具链后,打开控制台并输入以下内容,将 WASM-text 转换为字节码:

wat2wasm helloworld.wat -o helloworld.wasm

你也可以用以下方法将字节码转换为 WASM-text:

wasm2wat helloworld.wasm -o helloworld_reverse.wat

一个从 .wasm 文件创建的 .wat 文件不包括任何函数或参数名称。默认情况下,WebAssembly 用它们的索引来识别函数和参数。

编译 .wasm 文件

目前,WebAssembly 只与 JavaScript 共存,所以你必须编写一个简短的脚本来加载和编译 .wasm 文件并进行函数调用。你还需要在 WebAssembly 模块中定义你要导入的函数。

创建一个空的文本文件,并将其命名为 helloworld.html,然后打开你喜欢的文本编辑器并粘贴进去:

<!DOCTYPE  html>
<html>
  <head>
    <meta  charset="utf-8">
    <title>Simple template</title>
  </head>
  <body>
    <script>
   
      var memory = new  WebAssembly.Memory({initial:1});

      function  consoleLogString(offset, length) {
        var  bytes = new  Uint8Array(memory.buffer, offset, length);
        var  string = new  TextDecoder('utf8').decode(bytes);
        console.log(string);
      };

      var  importObject = {
        console: {
          log:  consoleLogString
        },
        js : {
          mem:  memory
        }
      };
     
      WebAssembly.instantiateStreaming(fetch('helloworld.wasm'), importObject)
      .then(obj  => {
        obj.instance.exports.helloWorld();
      });
     
    </script>
  </body>
</html>

WebAssembly.Memory(...) 方法返回一个大小为 64KB 的内存页。函数 consoleLogString 根据长度和偏移量从该内存页读取一个字符串。这两个对象作为 importObject 的一部分传递给你的 WebAssembly 模块。

在你运行这个例子之前,你可能必须允许 Firefox 从这个目录中访问文件,在地址栏输入 about:config,并将 privacy.file_unique_origin 设置为 true

 title=

注意: 这样做会使你容易受到 CVE-2019-11730 安全问题的影响。

现在,在 Firefox 中打开 helloworld.html,按下 Ctrl+K 打开开发者控制台。

 title=

了解更多

这个 Hello World 的例子只是 MDN 的 了解 WebAssembly 文本格式 文档中的教程之一。如果你想了解更多关于 WebAssembly 的知识以及它的工作原理,可以看看这些文档。


via: https://opensource.com/article/21/3/hello-world-webassembly

作者:Stephan Avenwedde 选题:lujun9972 译者:geekpi 校对:wxy

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

通过这三个工具和框架,为你的企业级 Java 应用和你的职业生涯提供助力。

 title=

尽管在 Kubernetes 上广泛使用 PythonGoNode.js 实现 人工智能 和机器学习应用以及 无服务函数,但 Java 技术仍然在开发企业应用中发挥着关键作用。根据 开发者经济学 的数据,在 2020 年第三季度,全球有 800 万名企业 Java 开发者。

虽然这门语言已经存在了超过 25 年,但 Java 世界中总是有新的趋势、工具和框架,可以为你的应用和你的职业生涯赋能。

绝大多数 Java 框架都是为具有动态行为的长时间运行的进程而设计的,这些动态行为用于运行可变的应用服务器,例如物理服务器和虚拟机。自从 Kubernetes 容器在 2014 年发布以来,情况已经发生了变化。在 Kubernetes 上使用 Java 应用的最大问题是通过减少内存占用、加快启动和响应时间以及减少文件大小来优化应用性能。

3 个值得考虑的新 Java 框架和工具

Java 开发人员也一直在寻找更简便的方法,将闪亮的新开源工具和项目集成到他们的 Java 应用和日常工作中。这极大地提高了开发效率,并激励更多的企业和个人开发者继续使用 Java 栈。

当试图满足上述企业 Java 生态系统的期望时,这三个新的 Java 框架和工具值得你关注。

1、Quarkus

Quarkus 旨在以惊人的快速启动时间、超低的常驻内存集(RSS)和高密度内存利用率,在 Kubernetes 等容器编排平台中开发云原生的微服务和无服务。根据 JRebel 的 第九届全球 Java 开发者生产力年度报告,Java 开发者对 Quarkus 的使用率从不到 1% 上升到 6%,MicronautVert.x 均从去年的 1% 左右分别增长到 4% 和 2%。

2、Eclipse JKube

Eclipse JKube 使 Java 开发者能够使用 DockerJibSource-To-Image 构建策略,基于云原生 Java 应用构建容器镜像。它还能在编译时生成 Kubernetes 和 OpenShift 清单,并改善开发人员对调试、观察和日志工具的体验。

3、MicroProfile

MicroProfile 解决了与优化企业 Java 的微服务架构有关的最大问题,而无需采用新的框架或重构整个应用。此外,MicroProfile 规范(即 Health、Open Tracing、Open API、Fault Tolerance、Metrics、Config)继续与 Jakarta EE 的实现保持一致。

总结

很难说哪个 Java 框架或工具是企业 Java 开发人员实现的最佳选择。只要 Java 栈还有改进的空间,并能加速企业业务的发展,我们就可以期待新的框架、工具和平台的出现,比如上面的三个。花点时间看看它们是否能在 2021 年改善你的企业 Java 应用。


via: https://opensource.com/article/21/3/enterprise-java-tools

作者:Daniel Oh 选题:lujun9972 译者:geekpi 校对:wxy

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

在本教程中,教你如何设置和使用 Pythonic 来编程。它是一个图形化编程工具,用户可以很容易地使用现成的函数模块创建 Python 程序。

 title=

然而,不像纽约证券交易所这样的传统证券交易所一样,有一段固定的交易时间。对于加密货币而言,则是 7×24 小时交易,这使得任何人都无法独自盯着市场。

在以前,我经常思考与加密货币交易相关的问题:

  • 一夜之间发生了什么?
  • 为什么没有日志记录?
  • 为什么下单?
  • 为什么不下单?

通常的解决手段是使用加密交易机器人,当在你做其他事情时,例如睡觉、与家人在一起或享受空闲时光,代替你下单。虽然有很多商业解决方案可用,但是我选择开源的解决方案,因此我编写了加密交易机器人 Pythonic。 正如去年 我写过的文章 一样,“Pythonic 是一种图形化编程工具,它让用户可以轻松使用现成的函数模块来创建 Python 应用程序。” 最初它是作为加密货币机器人使用,并具有可扩展的日志记录引擎以及经过精心测试的可重用部件,例如调度器和计时器。

开始

本教程将教你如何开始使用 Pythonic 进行自动交易。我选择 币安 Binance 交易所的 波场 Tron 比特币 Bitcoin 交易对为例。我之所以选择这个加密货币对,是因为它们彼此之间的波动性大,而不是出于个人喜好。

机器人将根据 指数移动平均 exponential moving averages (EMA)来做出决策。

 title=

TRX/BTC 1 小时 K 线图

EMA 指标通常是一个加权的移动平均线,可以对近期价格数据赋予更多权重。尽管移动平均线可能只是一个简单的指标,但我对它很有经验。

上图中的紫色线显示了 EMA-25 指标(这表示要考虑最近的 25 个值)。

机器人监视当前的 EMA-25 值(t0)和前一个 EMA-25 值(t-1)之间的差距。如果差值超过某个值,则表示价格上涨,机器人将下达购买订单。如果差值低于某个值,则机器人将下达卖单。

差值将是做出交易决策的主要指标。在本教程中,它称为交易参数。

工具链

将在本教程使用如下工具:

  • 币安专业交易视图(已经有其他人做了数据可视化,所以不需要重复造轮子)
  • Jupyter 笔记本:用于数据科学任务
  • Pythonic:作为整体框架
  • PythonicDaemon :作为终端运行(仅适用于控制台和 Linux)

数据挖掘

为了使加密货币交易机器人尽可能做出正确的决定,以可靠的方式获取资产的 美国线 open-high-low-close chart OHLC)数据是至关重要。你可以使用 Pythonic 的内置元素,还可以根据自己逻辑来对其进行扩展。

一般的工作流程:

  1. 与币安时间同步
  2. 下载 OHLC 数据
  3. 从文件中把 OHLC 数据加载到内存
  4. 比较数据集并扩展更新数据集

这个工作流程可能有点夸张,但是它能使得程序更加健壮,甚至在停机和断开连接时,也能平稳运行。

一开始,你需要 币安 OHLC 查询 Binance OHLC Query 元素和一个 基础操作 Basic Operation 元素来执行你的代码。

 title=

数据挖掘工作流程

OHLC 查询设置为每隔一小时查询一次 TRXBTC 资产对(波场/比特币)。

 title=

配置 OHLC 查询元素

其中输出的元素是 Pandas DataFrame。你可以在 基础操作 元素中使用 输入 input 变量来访问 DataFrame。其中,将 Vim 设置为 基础操作 元素的默认代码编辑器。

 title=

使用 Vim 编辑基础操作元素

具体代码如下:

import pickle, pathlib, os
import pandas as pd

outout = None

if isinstance(input, pd.DataFrame):
    file_name = 'TRXBTC_1h.bin'
    home_path = str(pathlib.Path.home())
    data_path = os.path.join(home_path, file_name)

    try:
        df = pickle.load(open(data_path, 'rb'))
        n_row_cnt = df.shape[0]
        df = pd.concat([df,input], ignore_index=True).drop_duplicates(['close_time'])
        df.reset_index(drop=True, inplace=True)
        n_new_rows = df.shape[0] - n_row_cnt
        log_txt = '{}: {} new rows written'.format(file_name, n_new_rows)
    except:
        log_txt = 'File error - writing new one: {}'.format(e)
        df = input

    pickle.dump(df, open(data_path, "wb" ))
    output = df

首先,检查输入是否为 DataFrame 元素。然后在用户的家目录(~/)中查找名为 TRXBTC_1h.bin 的文件。如果存在,则将其打开,执行新代码段(try 部分中的代码),并删除重复项。如果文件不存在,则触发异常并执行 except 部分中的代码,创建一个新文件。

只要启用了复选框 日志输出 log output ,你就可以使用命令行工具 tail 查看日志记录:

$ tail -f ~/Pythonic_2020/Feb/log_2020_02_19.txt

出于开发目的,现在跳过与币安时间的同步和计划执行,这将在下面实现。

准备数据

下一步是在单独的 网格 Grid 中处理评估逻辑。因此,你必须借助 返回元素 Return element 将 DataFrame 从网格 1 传递到网格 2 的第一个元素。

在网格 2 中,通过使 DataFrame 通过 基础技术分析 Basic Technical Analysis 元素,将 DataFrame 扩展包含 EMA 值的一列。

 title=

在网格 2 中技术分析工作流程

配置技术分析元素以计算 25 个值的 EMA。

 title=

配置技术分析元素

当你运行整个程序并开启 技术分析 Technical Analysis 元素的调试输出时,你将发现 EMA-25 列的值似乎都相同。

 title=

输出中精度不够

这是因为调试输出中的 EMA-25 值仅包含六位小数,即使输出保留了 8 个字节完整精度的浮点值。

为了能进行进一步处理,请添加 基础操作 元素:

 title=

网格 2 中的工作流程

使用 基础操作 元素,将 DataFrame 与添加的 EMA-25 列一起转储,以便可以将其加载到 Jupyter 笔记本中;

 title=

将扩展后的 DataFrame 存储到文件中

评估策略

在 Juypter 笔记本中开发评估策略,让你可以更直接地访问代码。要加载 DataFrame,你需要使用如下代码:

 title=

用全部小数位表示

你可以使用 iloc 和列名来访问最新的 EMA-25 值,并且会保留所有小数位。

你已经知道如何来获得最新的数据。上面示例的最后一行仅显示该值。为了能将该值拷贝到不同的变量中,你必须使用如下图所示的 .at 方法方能成功。

你也可以直接计算出你下一步所需的交易参数。

 title=

买卖决策

确定交易参数

如上面代码所示,我选择 0.009 作为交易参数。但是我怎么知道 0.009 是决定交易的一个好参数呢? 实际上,这个参数确实很糟糕,因此,你可以直接计算出表现最佳的交易参数。

假设你将根据收盘价进行买卖。

 title=

回测功能

在此示例中,buy_factorsell_factor 是预先定义好的。因此,发散思维用直接计算出表现最佳的参数。

 title=

嵌套的 for 循环,用于确定购买和出售的参数

这要跑 81 个循环(9x9),在我的机器(Core i7 267QM)上花费了几分钟。

 title=

在暴力运算时系统的利用率

在每个循环之后,它将 buy_factorsell_factor 元组和生成的 profit 元组追加到 trading_factors 列表中。按利润降序对列表进行排序。

 title=

将利润与相关的交易参数按降序排序

当你打印出列表时,你会看到 0.002 是最好的参数。

 title=

交易要素和收益的有序列表

当我在 2020 年 3 月写下这篇文章时,价格的波动还不足以呈现出更理想的结果。我在 2 月份得到了更好的结果,但即使在那个时候,表现最好的交易参数也在 0.002 左右。

分割执行路径

现在开始新建一个网格以保持逻辑清晰。使用 返回 元素将带有 EMA-25 列的 DataFrame 从网格 2 传递到网格 3 的 0A 元素。

在网格 3 中,添加 基础操作 元素以执行评估逻辑。这是该元素中的代码:

 title=

实现评估策略

如果输出 1 表示你应该购买,如果输出 2 则表示你应该卖出。 输出 0 表示现在无需操作。使用 分支 Branch 元素来控制执行路径。

 title=

分支元素:网格 3,2A 位置

因为 0-1 的处理流程一样,所以你需要在最右边添加一个分支元素来判断你是否应该卖出。

 title=

分支元素:网格 3,3B 位置

网格 3 应该现在如下图所示:

 title=

网格 3 的工作流程

下单

由于无需在一个周期中购买两次,因此必须在周期之间保留一个持久变量,以指示你是否已经购买。

你可以利用 Stack 元素来实现。顾名思义,栈元素表示可以用任何 Python 数据类型来放入的基于文件的栈。

你需要定义栈仅包含一个布尔类型,该布尔类型决定是否购买了(True)或(False)。因此,你必须使用 False 来初始化栈。例如,你可以在网格 4 中简单地通过将 False 传递给栈来进行设置。

 title=

将 False 变量传输到后续的栈元素中

在分支树后的栈实例可以进行如下配置:

 title=

设置栈元素

在栈元素设置中,将 对输入的操作 Do this with input 设置成 Nothing 。否则,布尔值将被 10 覆盖。

该设置确保仅将一个值保存于栈中(TrueFalse),并且只能读取一个值(为了清楚起见)。

在栈元素之后,你需要另外一个 分支 元素来判断栈的值,然后再放置 币安订单 Binance Order 元素。

 title=

判断栈中的变量

将币安订单元素添加到分支元素的 True 路径。网格 3 上的工作流现在应如下所示:

 title=

网格 3 的工作流程

币安订单元素应如下配置:

 title=

编辑币安订单元素

你可以在币安网站上的帐户设置中生成 API 和密钥。

 title=

在币安账户设置中创建一个 API 密钥

在本文中,每笔交易都是作为市价交易执行的,交易量为 10,000 TRX(2020 年 3 月约为 150 美元)(出于教学的目的,我通过使用市价下单来演示整个过程。因此,我建议至少使用限价下单。)

如果未正确执行下单(例如,网络问题、资金不足或货币对不正确),则不会触发后续元素。因此,你可以假定如果触发了后续元素,则表示该订单已下达。

这是一个成功的 XMRBTC 卖单的输出示例:

 title=

成功卖单的输出

该行为使后续步骤更加简单:你可以始终假设只要成功输出,就表示订单成功。因此,你可以添加一个 基础操作 元素,该元素将简单地输出 True 并将此值放入栈中以表示是否下单。

如果出现错误的话,你可以在日志信息中查看具体细节(如果启用日志功能)。

 title=

币安订单元素中的输出日志信息

调度和同步

对于日程调度和同步,请在网格 1 中将整个工作流程置于 币安调度器 Binance Scheduler 元素的前面。

 title=

在网格 1,1A 位置的币安调度器

由于币安调度器元素只执行一次,因此请在网格 1 的末尾拆分执行路径,并通过将输出传递回币安调度器来强制让其重新同步。

 title=

网格 1:拆分执行路径

5A 元素指向 网格 2 的 1A 元素,并且 5B 元素指向网格 1 的 1A 元素(币安调度器)。

部署

你可以在本地计算机上全天候 7×24 小时运行整个程序,也可以将其完全托管在廉价的云系统上。例如,你可以使用 Linux/FreeBSD 云系统,每月约 5 美元,但通常不提供图形化界面。如果你想利用这些低成本的云,可以使用 PythonicDaemon,它能在终端中完全运行。

 title=

PythonicDaemon 控制台

PythonicDaemon 是基础程序的一部分。要使用它,请保存完整的工作流程,将其传输到远程运行的系统中(例如,通过 安全拷贝协议 Secure Copy SCP),然后把工作流程文件作为参数来启动 PythonicDaemon:

$ PythonicDaemon trading_bot_one

为了能在系统启动时自启 PythonicDaemon,可以将一个条目添加到 crontab 中:

# crontab -e

 title=

在 Ubuntu 服务器上的 Crontab

下一步

正如我在一开始时所说的,本教程只是自动交易的入门。对交易机器人进行编程大约需要 10% 的编程和 90% 的测试。当涉及到让你的机器人用金钱交易时,你肯定会对编写的代码再三思考。因此,我建议你编码时要尽可能简单和易于理解。

如果你想自己继续开发交易机器人,接下来所需要做的事:

  • 收益自动计算(希望你有正收益!)
  • 计算你想买的价格
  • 比较你的预订单(例如,订单是否填写完整?)

你可以从 GitHub 上获取完整代码。


via: https://opensource.com/article/20/4/python-crypto-trading-bot

作者:Stephan Avenwedde 选题:lujun9972 译者:wyxplus 校对:wxy

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

字典数据结构可以帮助你快速访问信息。

 title=

字典是 Python 编程语言使用的数据结构。一个 Python 字典由多个键值对组成;每个键值对将键映射到其关联的值上。

例如你是一名老师,想把学生姓名与成绩对应起来。你可以使用 Python 字典,将学生姓名映射到他们关联的成绩上。此时,键值对中键是姓名,值是对应的成绩。

如果你想知道某个学生的考试成绩,你可以从字典中访问。这种快捷查询方式可以为你节省解析整个列表找到学生成绩的时间。

本文介绍了如何通过键访问对应的字典值。学习前,请确保你已经安装了 Anaconda 包管理器Jupyter 笔记本

1、在 Jupyter 中打开一个新的笔记本

首先在 Web 浏览器中打开并运行 Jupyter。然后,

  1. 转到左上角的 “File”。
  2. 选择 “New Notebook”,点击 “Python 3”。

 title=

开始时,新建的笔记本是无标题的,你可以将其重命名为任何名称。我为我的笔记本取名为 “OpenSource.com Data Dictionary Tutorial”。

笔记本中标有行号的位置就是你写代码的区域,也是你输入的位置。

在 macOS 上,可以同时按 Shift + Return 键得到输出。在创建新的代码区域前,请确保完成上述动作;否则,你写的任何附加代码可能无法运行。

2、新建一个键值对

在字典中输入你希望访问的键与值。输入前,你需要在字典上下文中定义它们的含义:

empty_dictionary = {}
grades = {
    "Kelsey": 87,
    "Finley": 92
}

one_line = {a: 1, b: 2}

 title=

这段代码让字典将特定键与其各自的值关联起来。字典按名称存储数据,从而可以更快地查询。

3、通过键访问字典值

现在你想查询指定的字典值;在上述例子中,字典值指特定学生的成绩。首先,点击 “Insert” 后选择 “Insert Cell Below”。

 title=

在新单元格中,定义字典中的键与值。

然后,告诉字典打印该值的键,找到需要的值。例如,查询名为 Kelsey 的学生的成绩:

# 访问字典中的数据
grades = {
    "Kelsey": 87,
    "Finley": 92
}

print(grades["Kelsey"])
87

 title=

当你查询 Kelsey 的成绩(也就是你想要查询的值)时,如果你用的是 macOS,只需要同时按 Shift+Return 键。

你会在单元格下方看到 Kelsey 的成绩。

4、更新已有的键

当把一位学生的错误成绩添加到字典时,你会怎么办?可以通过更新字典、存储新值来修正这类错误。

首先,选择你想更新的那个键。在上述例子中,假设你错误地输入了 Finley 的成绩,那么 Finley 就是你需要更新的键。

为了更新 Finley 的成绩,你需要在下方插入新的单元格,然后创建一个新的键值对。同时按 Shift+Return 键打印字典全部信息:

grades["Finley"] = 90
print(grades)

{'Kelsey': 87; "Finley": 90}

 title=

单元格下方输出带有 Finley 更新成绩的字典。

5、添加新键

假设你得到一位新学生的考试成绩。你可以用新键值对将那名学生的姓名与成绩补充到字典中。

插入新的单元格,以键值对形式添加新学生的姓名与成绩。当你完成这些后,同时按 Shift+Return 键打印字典全部信息:

grades["Alex"] = 88
print(grades)

{'Kelsey': 87, 'Finley': 90, 'Alex': 88}

 title=

所有的键值对输出在单元格下方。

使用字典

请记住,键与值可以是任意数据类型,但它们很少是 扩展数据类型 non-primitive types 。此外,字典不能以指定的顺序存储、组织里面的数据。如果你想要数据有序,最好使用 Python 列表,而非字典。

如果你考虑使用字典,首先要确认你的数据结构是否是合适的,例如像电话簿的结构。如果不是,列表、元组、树或者其他数据结构可能是更好的选择。


via: https://opensource.com/article/21/3/dictionary-values-python

作者:Lauren Maffeo 选题:lujun9972 译者:DCOLIVERSUN 校对:wxy

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

Google API 可以凸显出有关 Google 如何对网站进行分类的线索,以及如何调整内容以改进搜索结果的方法。

 title=

作为一名技术性的搜索引擎优化人员,我一直在寻找以新颖的方式使用数据的方法,以更好地了解 Google 如何对网站进行排名。我最近研究了 Google 的 自然语言 API 能否更好地揭示 Google 是如何分类网站内容的。

尽管有 开源 NLP 工具,但我想探索谷歌的工具,前提是它可能在其他产品中使用同样的技术,比如搜索。本文介绍了 Google 的自然语言 API,并探究了常见的自然语言处理(NLP)任务,以及如何使用它们来为网站内容创建提供信息。

了解数据类型

首先,了解 Google 自然语言 API 返回的数据类型非常重要。

实体

实体 Entities 是可以与物理世界中的某些事物联系在一起的文本短语。 命名实体识别 Named Entity Recognition (NER)是 NLP 的难点,因为工具通常需要查看关键字的完整上下文才能理解其用法。例如, 同形异义字 homographs 拼写相同,但是具有多种含义。句子中的 “lead” 是指一种金属:“铅”(名词),使某人移动:“牵领”(动词),还可能是剧本中的主要角色(也是名词)?Google 有 12 种不同类型的实体,还有第 13 个名为 “UNKNOWN”(未知)的统称类别。一些实体与维基百科的文章相关,这表明 知识图谱 对数据的影响。每个实体都会返回一个显著性分数,即其与所提供文本的整体相关性。

 title=

情感

情感 Sentiment ,即对某事的看法或态度,是在文件和句子层面以及文件中发现的单个实体上进行衡量。情感的 得分 score 范围从 -1.0(消极)到 1.0(积极)。 幅度 magnitude 代表情感的 非归一化 non-normalized 强度;它的范围是 0.0 到无穷大。

 title=

语法

语法 Syntax 解析包含了大多数在较好的库中常见的 NLP 活动,例如 词形演变 lemmatization 词性标记 part-of-speech tagging 依赖树解析 dependency-tree parsing 。NLP 主要处理帮助机器理解文本和关键字之间的关系。语法解析是大多数语言处理或理解任务的基础部分。

 title=

分类

分类 Categories 是将整个给定内容分配给特定行业或主题类别,其 置信度 confidence 得分从 0.0 到 1.0。这些分类似乎与其他 Google 工具使用的受众群体和网站类别相同,如 AdWords。

 title=

提取数据

现在,我将提取一些示例数据进行处理。我使用 Google 的 搜索控制台 API 收集了一些搜索查询及其相应的网址。Google 搜索控制台是一个报告人们使用 Google Search 查找网站页面的术语的工具。这个 开源的 Jupyter 笔记本 可以让你提取有关网站的类似数据。在此示例中,我在 2019 年 1 月 1 日至 6 月 1 日期间生成的一个网站(我没有提及名字)上提取了 Google 搜索控制台数据,并将其限制为至少获得一次点击(而不只是 曝光 impressions )的查询。

该数据集包含 2969 个页面和在 Google Search 的结果中显示了该网站网页的 7144 条查询的信息。下表显示,绝大多数页面获得的点击很少,因为该网站侧重于所谓的长尾(越特殊通常就更长尾)而不是短尾(非常笼统,搜索量更大)搜索查询。

 title=

为了减少数据集的大小并仅获得效果最好的页面,我将数据集限制为在此期间至少获得 20 次曝光的页面。这是精炼数据集的按页点击的柱状图,其中包括 723 个页面:

 title=

在 Python 中使用 Google 自然语言 API 库

要测试 API,在 Python 中创建一个利用 google-cloud-language 库的小脚本。以下代码基于 Python 3.5+。

首先,激活一个新的虚拟环境并安装库。用环境的唯一名称替换 <your-env>

virtualenv <your-env>
source <your-env>/bin/activate
pip install --upgrade google-cloud-language
pip install --upgrade requests

该脚本从 URL 提取 HTML,并将 HTML 提供给自然语言 API。返回一个包含 sentimententitiescategories 的字典,其中这些键的值都是列表。我使用 Jupyter 笔记本运行此代码,因为使用同一内核注释和重试代码更加容易。

# Import needed libraries
import requests
import json

from google.cloud import language
from google.oauth2 import service_account
from google.cloud.language import enums
from google.cloud.language import types

# Build language API client (requires service account key)
client = language.LanguageServiceClient.from_service_account_json('services.json')

# Define functions
def pull_googlenlp(client, url, invalid_types = ['OTHER'], **data):
   
        html = load_text_from_url(url, **data)
   
        if not html:
        return None
   
        document = types.Document(
        content=html,
        type=language.enums.Document.Type.HTML )

        features = {'extract_syntax': True,
                'extract_entities': True,
                'extract_document_sentiment': True,
                'extract_entity_sentiment': True,
                'classify_text': False
                }
   
        response = client.annotate_text(document=document, features=features)
        sentiment = response.document_sentiment
        entities = response.entities
   
        response = client.classify_text(document)
        categories = response.categories
         
        def get_type(type):
        return client.enums.Entity.Type(entity.type).name
   
        result = {}
   
        result['sentiment'] = []    
        result['entities'] = []
        result['categories'] = []

        if sentiment:
        result['sentiment'] = [{ 'magnitude': sentiment.magnitude, 'score':sentiment.score }]
         
        for entity in entities:
        if get_type(entity.type) not in invalid_types:
                result['entities'].append({'name': entity.name, 'type': get_type(entity.type), 'salience': entity.salience, 'wikipedia_url': entity.metadata.get('wikipedia_url', '-')  })
         
        for category in categories:
        result['categories'].append({'name':category.name, 'confidence': category.confidence})
         
         
        return result


def load_text_from_url(url, **data):

        timeout = data.get('timeout', 20)
   
        results = []
   
        try:
         
        print("Extracting text from: {}".format(url))
        response = requests.get(url, timeout=timeout)

        text = response.text
        status = response.status_code

        if status == 200 and len(text) > 0:
                return text
         
        return None
         

        except Exception as e:
        print('Problem with url: {0}.'.format(url))
        return None

要访问该 API,请按照 Google 的 快速入门说明 在 Google 云主控台中创建一个项目,启用该 API 并下载服务帐户密钥。之后,你应该拥有一个类似于以下内容的 JSON 文件:

 title=

命名为 services.json,并上传到项目文件夹。

然后,你可以通过运行以下程序来提取任何 URL(例如 Opensource.com)的 API 数据:

url = "https://opensource.com/article/19/6/how-ssh-running-container"
pull_googlenlp(client,url)

如果设置正确,你将看到以下输出:

 title=

为了使入门更加容易,我创建了一个 Jupyter 笔记本,你可以下载并使用它来测试提取网页的实体、类别和情感。我更喜欢使用 JupyterLab,它是 Jupyter 笔记本的扩展,其中包括文件查看器和其他增强的用户体验功能。如果你不熟悉这些工具,我认为利用 Anaconda 是开始使用 Python 和 Jupyter 的最简单途径。它使安装和设置 Python 以及常用库变得非常容易,尤其是在 Windows 上。

处理数据

使用这些函数,可抓取给定页面的 HTML 并将其传递给自然语言 API,我可以对 723 个 URL 进行一些分析。首先,我将通过查看所有页面中返回的顶级分类的数量来查看与网站相关的分类。

分类

 title=

这似乎是该特定站点的关键主题的相当准确的代表。通过查看一个效果最好的页面进行排名的单个查询,我可以比较同一查询在 Google 搜索结果中的其他排名页面。

  • URL 1 |顶级类别:/法律和政府/与法律相关的(0.5099999904632568)共 1 个类别。
  • 未返回任何类别。
  • URL 3 |顶级类别:/互联网与电信/移动与无线(0.6100000143051147)共 1 个类别。
  • URL 4 |顶级类别:/计算机与电子产品/软件(0.5799999833106995)共有 2 个类别。
  • URL 5 |顶级类别:/互联网与电信/移动与无线/移动应用程序和附件(0.75)共有 1 个类别。
  • 未返回任何类别。
  • URL 7 |顶级类别:/计算机与电子/软件/商业与生产力软件(0.7099999785423279)共 2 个类别。
  • URL 8 |顶级类别:/法律和政府/与法律相关的(0.8999999761581421)共 3 个类别。
  • URL 9 |顶级类别:/参考/一般参考/类型指南和模板(0.6399999856948853)共有 1 个类别。
  • 未返回任何类别。

上方括号中的数字表示 Google 对页面内容与该分类相关的置信度。对于相同分类,第八个结果比第一个结果具有更高的置信度,因此,这似乎不是定义排名相关性的灵丹妙药。此外,分类太宽泛导致无法满足特定搜索主题的需要。

通过排名查看平均置信度,这两个指标之间似乎没有相关性,至少对于此数据集而言如此:

 title=

这两种方法对网站进行规模审查是有意义的,以确保内容类别易于理解,并且样板或销售内容不会使你的页面与你的主要专业知识领域无关。想一想,如果你出售工业用品,但是你的页面返回 “Marketing(销售)” 作为主要分类。似乎没有一个强烈的迹象表明,分类相关性与你的排名有什么关系,至少在页面级别如此。

情感

我不会在情感上花很多时间。在所有从 API 返回情感的页面中,它们分为两个区间:0.1 和 0.2,这几乎是中立的情感。根据直方图,很容易看出情感没有太大价值。对于新闻或舆论网站而言,测量特定页面的情感到中位数排名之间的相关性将是一个更加有趣的指标。

 title=

实体

在我看来,实体是 API 中最有趣的部分。这是在所有页面中按 显著性 salience (或与页面的相关性)选择的顶级实体。请注意,对于相同的术语(销售清单),Google 会推断出不同的类型,可能是错误的。这是由于这些术语出现在内容中的不同上下文中引起的。

 title=

然后,我分别查看了每个实体类型,并一起查看了该实体的显著性与页面的最佳排名位置之间是否存在任何关联。对于每种类型,我匹配了与该类型匹配的顶级实体的显著性(与页面的整体相关性),按显著性排序(降序)。

有些实体类型在所有示例中返回的显著性为零,因此我从下面的图表中省略了这些结果。

 title=

“Consumer Good(消费性商品)” 实体类型具有最高的正相关性, 皮尔森相关度 Pearson correlation 为 0.15854,尽管由于较低编号的排名更好,所以 “Person” 实体的结果最好,相关度为 -0.15483。这是一个非常小的样本集,尤其是对于单个实体类型,我不能对数据做太多的判断。我没有发现任何具有强相关性的值,但是 “Person” 实体最有意义。网站通常都有关于其首席执行官和其他主要雇员的页面,这些页面很可能在这些查询的搜索结果方面做得好。

继续,当从整体上看站点,根据实体名称和实体类型,出现了以下主题。

 title=

我模糊了几个看起来过于具体的结果,以掩盖网站的身份。从主题上讲,名称信息是在你(或竞争对手)的网站上局部查看其核心主题的一种好方法。这样做仅基于示例网站的排名网址,而不是基于所有网站的可能网址(因为 Search Console 数据仅记录 Google 中展示的页面),但是结果会很有趣,尤其是当你使用像 Ahrefs 之类的工具提取一个网站的主要排名 URL,该工具会跟踪许多查询以及这些查询的 Google 搜索结果。

实体数据中另一个有趣的部分是标记为 “CONSUMER\_GOOD” 的实体倾向于 “看起来” 像我在看到 “ 知识结果 Knowledge Results ”的结果,即页面右侧的 Google 搜索结果。

 title=

在我们的数据集中具有三个或三个以上关键字的 “Consumer Good(消费性商品)” 实体名称中,有 5.8% 的知识结果与 Google 对该实体命名的结果相同。这意味着,如果你在 Google 中搜索术语或短语,则右侧的框(例如,上面显示 Linux 的知识结果)将显示在搜索结果页面中。由于 Google 会 “挑选” 代表实体的示例网页,因此这是一个很好的机会,可以在搜索结果中识别出具有唯一特征的机会。同样有趣的是,5.8% 的在 Google 中显示这些知识结果名称中,没有一个实体的维基百科 URL 从自然语言 API 中返回。这很有趣,值得进行额外的分析。这将是非常有用的,特别是对于传统的全球排名跟踪工具(如 Ahrefs)数据库中没有的更深奥的主题。

如前所述,知识结果对于那些希望自己的内容在 Google 中被收录的网站所有者来说是非常重要的,因为它们在桌面搜索中加强高亮显示。假设,它们也很可能与 Google Discover 的知识库主题保持一致,这是一款适用于 Android 和 iOS 的产品,它试图根据用户感兴趣但没有明确搜索的主题为用户浮现内容。

总结

本文介绍了 Google 的自然语言 API,分享了一些代码,并研究了此 API 对网站所有者可能有用的方式。关键要点是:

  • 学习使用 Python 和 Jupyter 笔记本可以为你的数据收集任务打开到一个由令人难以置信的聪明和有才华的人建立的不可思议的 API 和开源项目(如 Pandas 和 NumPy)的世界。
  • Python 允许我为了一个特定目的快速提取和测试有关 API 值的假设。
  • 通过 Google 的分类 API 传递网站页面可能是一项很好的检查,以确保其内容分解成正确的主题分类。对于竞争对手的网站执行此操作还可以提供有关在何处进行调整或创建内容的指导。
  • 对于示例网站,Google 的情感评分似乎并不是一个有趣的指标,但是对于新闻或基于意见的网站,它可能是一个有趣的指标。
  • Google 发现的实体从整体上提供了更细化的网站的主题级别视图,并且像分类一样,在竞争性内容分析中使用将非常有趣。
  • 实体可以帮助定义机会,使你的内容可以与搜索结果或 Google Discover 结果中的 Google 知识块保持一致。我们将 5.8% 的结果设置为更长的(字计数)“Consumer Goods(消费商品)” 实体,显示这些结果,对于某些网站来说,可能有机会更好地优化这些实体的页面显著性分数,从而有更好的机会在 Google 搜索结果或 Google Discovers 建议中抓住这个重要作用的位置。

via: https://opensource.com/article/19/7/python-google-natural-language-api

作者:JR Oakes 选题:lujun9972 译者:stevenzdg988 校对:wxy

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

了解在 Firefox 上运行 WebAssembly 的机会和局限性。

 title=

WebAssembly 是一种可移植的执行格式,由于它能够以近乎原生的速度在浏览器中执行应用而引起了人们的极大兴趣。WebAssembly 本质上有一些特殊的属性和局限性。但是,通过将其与其他技术结合,将出现全新的可能性,尤其是与浏览器中的游戏有关的可能性。

本文介绍了在 Firefox 上运行 WebAssembly 的概念、可能性和局限性。

沙盒

WebAssembly 有 严格的安全策略。 WebAssembly 中的程序或功能单元称为模块。每个模块实例都运行在自己的隔离内存空间中。因此,即使同一个网页加载了多个模块,它们也无法访问另一个模块的虚拟地址空间。设计上,WebAssembly 还考虑了内存安全性和控制流完整性,这使得(几乎)确定性的执行成为可能。

Web API

通过 JavaScript Web API 可以访问多种输入和输出设备。根据这个 提案,将来可以不用绕道到 JavaScript 来访问 Web API。C++ 程序员可以在 Emscripten.org 上找到有关访问 Web API 的信息。Rust 程序员可以使用 rustwasm.github.io 中写的 wasm-bindgen 库。

文件输入/输出

因为 WebAssembly 是在沙盒环境中执行的,所以当它在浏览器中执行时,它无法访问主机的文件系统。但是,Emscripten 提供了虚拟文件系统形式的解决方案。

Emscripten 使在编译时将文件预加载到内存文件系统成为可能。然后可以像在普通文件系统上一样从 WebAssembly 应用中读取这些文件。这个 教程 提供了更多信息。

持久化数据

如果你需要在客户端存储持久化数据,那么必须通过 JavaScript Web API 来完成。请参考 Mozilla 开发者网络(MDN)关于 浏览器存储限制和过期标准 的文档,了解不同方法的详细信息。

内存管理

WebAssembly 模块作为 堆栈机 在线性内存上运行。这意味着堆内存分配等概念是没有的。然而,如果你在 C++ 中使用 new 或者在 Rust 中使用 Box::new,你会期望它会进行堆内存分配。将堆内存分配请求转换成 WebAssembly 的方式在很大程度上依赖于工具链。你可以在 Frank Rehberger 关于 WebAssembly 和动态内存 的文章中找到关于不同工具链如何处理堆内存分配的详细分析。

游戏!

WebGL 结合使用时,WebAssembly 的执行速度很高,因此可以在浏览器中运行原生游戏。大型专有游戏引擎 Unity虚幻 4 展示了 WebGL 可以实现的功能。也有使用 WebAssembly 和 WebGL 接口的开源游戏引擎。这里有些例子:

有关 WebAssembly 的更多信息

WebAssembly 是一项很有前途的技术,我相信我们将来会越来越多地看到它。除了在浏览器中执行之外,WebAssembly 还可以用作可移植的执行格式。Wasmer 容器主机使你可以在各种平台上执行 WebAssembly 代码。

如果你需要更多的演示、示例和教程,请看一下这个 WebAssembly 主题集合。Mozilla 的 游戏和示例合集 并非全是 WebAssembly,但仍然值得一看。


via: https://opensource.com/article/21/3/webassembly-firefox

作者:Stephan Avenwedde 选题:lujun9972 译者:geekpi 校对:wxy

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