整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

PyScript:让Python在HTML中运行

家好,我是DD,已经是封闭在家的第51天了!

最近一直在更新Java新特性(https://www.didispace.com/java-features/)和IDEA Tips(https://www.didispace.com/idea-tips/)两个原创专栏,其他方向内容的动态关注少了。昨天天晚上刷推的时候,瞄到了这个神奇的东西,觉得挺cool的,拿出来分享下:

相信你看到图,不用我说,你也猜到是啥了吧?html里可以跑python代码了

看到好多Python公众号已经开始猛吹未来了,但乍看怎么觉得有点像JSP?或者一些模版引擎?是进步还是倒退呢?与其瞎想,不如仔细看看这个东东的能力吧!

根据官方介绍,这个名为PyScript的框架,其核心目标是为开发者提供在标准HTML中嵌入Python代码的能力,使用 Python调用JavaScript函数库,并以此实现利用Python创建Web应用的功能。

看到介绍里提到了调用JavaScript函数库的能力,看来跟JSP或者模版引擎还是有区别的。

PyScript 快速体验

官方给了一个例子,可以帮助我们观的感受这个开发框架的能力,不妨跟着DD看看,它能做啥吧!

第一个案例,hello world

代码很简单,就下面这几行。你只需要创建一个html文件,然后复制进去就可以了。

<html>
  <head>
    <link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
    <script defer src="https://pyscript.net/alpha/pyscript.js"></script>
  </head>
  <body> 
    <py-script> 
        print('Hello, World!') 
    </py-script> 
  </body>
</html>

保存好之后,在浏览器里打开就能看到这样的页面了:

回头再看看这个html里的内容,三个核心内容:

  • 引入pyscript的样式文件:<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
  • 引入pyscript的脚本文件:<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
  • <py-script>标签中写具体的python代码来输出Hello World

如果你懒得自己敲代码的话,本文的两个案例代码我打包放在公众号了,需要的朋友可以关注公众号“程序猿DD”,回复:pyscript 获取。

第二个案例,数据定义 + 数据展示

先创建一个data.py文件,然后加入前面的代码。功能很简单,就是随机生成(x,y)的坐标

import numpy as np

def make_x_and_y(n):
    x = np.random.randn(n)
    y = np.random.randn(n)
    return x, y

再创建一个html文件,加入下面的代码

<html>
    <head>
      <link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
      <script defer src="https://pyscript.net/alpha/pyscript.js"></script>
      <py-env>
        - numpy
        - matplotlib
        - paths:
          - /data.py
      </py-env>
    </head>

  <body>
    <h1>Let's plot random numbers</h1>
    <div id="plot"></div>
    <py-script output="plot">
    import matplotlib.pyplot as plt
    from data import make_x_and_y

    x, y = make_x_and_y(n=1000)

    fig, ax = plt.subplots()
    ax.scatter(x, y)
    fig
    </py-script>
  </body>
</html>

这里就稍微复杂一些了,除了hello world中的几个要点外,这里还有这几个要关注的地方:

  • <py-env>标签:这里声明要引入的包和要引入的文件(上面创建的data.py
  • <py-script output="plot">:这里定义了要在<div id="plot"></div>中输出的内容,可以看到这里的逻辑都是用python写的

这个页面的执行效果是这样的:

是不是很神奇呢?整个过程中都没有大家熟悉的cs、js内容,就完成了这样一个图的页面实现。

小结

最后,谈谈在整个尝试过程中,给我的几个感受:

  1. 开发体验上高度统一,对于python开发者来说,开发Web应用的门槛可以更低了
  2. 感觉性能上似乎有所不足,几个复杂的案例执行有点慢,开始以为是部分国外cdn的缘故,后来移到本地后,还是慢。这部分可能还需要进一步优化。

这个开发框架目前还只是alpha版本,未来一定还会有更多特性与优化出来,总体上我觉得这个框架还是非常cool的,尤其对于刚学会Python,或者只会Python,但又想快速开发Web应用的小伙伴来说,可能将会是个不错的选择,那你觉得这个框架如何?未来会不会火?留言区聊聊吧!

数字的游戏

根据官方教程,照写一个程序,来体验一下rust的程序开发过程。

需求

游戏很简单, 就是一次次输入比对预先生成的随机数。

  1. 随机产生一个数字
  2. 让用户输入,并比对大小,给出提示
  3. 直到猜中数字。

涉及到的知识点

  1. cargo 引入随机数包
  2. 基本的rust语句使用,基本的rust的函数使用。
  3. 了解工程从搭建到编写到编译生成的完成过程。

开始

Cargo是rust的包管理工具, 对于本需求需要rand的方法, 但是该方法再rust中并不存在, 所以通过Cargo引入了第三方包的方式进行使用。

Cargo 说明

Cargo 不仅仅是一个包管理器,同时还是Rust项目的管理工具。

可以通过cargo的帮助信息查看命令以及功能说明. cargo -h

 Rust's package manager
 
 Usage: cargo [+toolchain] [OPTIONS] [COMMAND]
        cargo [+toolchain] [OPTIONS] -Zscript <MANIFEST_RS> [ARGS]...
 
 Options:
   -V, --version             Print version info and exit
       --list                List installed commands
       --explain <CODE>      Provide a detailed explanation of a rustc error message
   -v, --verbose...          Use verbose output (-vv very verbose/build.rs output)
   -q, --quiet               Do not print cargo log messages
       --color <WHEN>        Coloring: auto, always, never
   -C <DIRECTORY>            Change to DIRECTORY before doing anything (nightly-only)
       --frozen              Require Cargo.lock and cache are up to date
       --locked              Require Cargo.lock is up to date
       --offline             Run without accessing the network
       --config <KEY=VALUE>  Override a configuration value
   -Z <FLAG>                 Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details
   -h, --help                Print help
 
 Commands:
     build, b    Compile the current package
     check, c    Analyze the current package and report errors, but don't build object files
     clean       Remove the target directory
     doc, d      Build this package's and its dependencies' documentation
     new         Create a new cargo package
     init        Create a new cargo package in an existing directory
     add         Add dependencies to a manifest file
     remove      Remove dependencies from a manifest file
     run, r      Run a binary or example of the local package
     test, t     Run the tests
     bench       Run the benchmarks
     update      Update dependencies listed in Cargo.lock
     search      Search registry for crates
     publish     Package and upload this package to the registry
     install     Install a Rust binary. Default location is $HOME/.cargo/bin
     uninstall   Uninstall a Rust binary
     ...         See all commands with --list
 
 See 'cargo help <command>' for more information on a specific command.

可以通过cargo --list查看所提供的命令

 Installed Commands:
     add                  Add dependencies to a Cargo.toml manifest file
     b                    alias: build
     bench                Execute all benchmarks of a local package
     build                Compile a local package and all of its dependencies
     c                    alias: check
     check                Check a local package and all of its dependencies for errors
     clean                Remove artifacts that cargo has generated in the past
     clippy               Checks a package to catch common mistakes and improve your Rust code.
     config               Inspect configuration values
     d                    alias: doc
     doc                  Build a package's documentation
     fetch                Fetch dependencies of a package from the network
     fix                  Automatically fix lint warnings reported by rustc
     fmt                  Formats all bin and lib files of the current crate using rustfmt.
     generate-lockfile    Generate the lockfile for a package
     git-checkout         This command has been removed
     help                 Displays help for a cargo subcommand
     init                 Create a new cargo package in an existing directory
     install              Install a Rust binary. Default location is $HOME/.cargo/bin
     locate-project       Print a JSON representation of a Cargo.toml file's location
     login                Log in to a registry.
     logout               Remove an API token from the registry locally
     metadata             Output the resolved dependencies of a package, the concrete used versions including overrides, in machine-readable format
     miri
     new                  Create a new cargo package at <path>
     owner                Manage the owners of a crate on the registry
     package              Assemble the local package into a distributable tarball
     pkgid                Print a fully qualified package specification
     publish              Upload a package to the registry
     r                    alias: run
     read-manifest        Print a JSON representation of a Cargo.toml manifest.
     remove               Remove dependencies from a Cargo.toml manifest file
     report               Generate and display various kinds of reports
     rm                   alias: remove
     run                  Run a binary or example of the local package
     rustc                Compile a package, and pass extra options to the compiler
     rustdoc              Build a package's documentation, using specified custom flags.
     search               Search packages in crates.io
     t                    alias: test
     test                 Execute all unit and integration tests and build examples of a local package
     tree                 Display a tree visualization of a dependency graph
     uninstall            Remove a Rust binary
     update               Update dependencies as recorded in the local lock file
     vendor               Vendor all dependencies for a project locally
     verify-project       Check correctness of crate manifest
     version              Show version information
     yank                 Remove a pushed crate from the index

Cargo中,每个命令均可通过-help的方式来查看具体命令的用法, 例如:cargo run -help

较为常用的如下:

  • cargo build :编译当前项目
  • cargo check:分析当前项目并报告,但不产出文件
  • cargo run:执行src/main.rs
  • Cargo clear:移除当前项目的target目录
  • Cargo update:更新当前项目中的依赖
  • cargo new: 创建一个新工程。

cargo 创建rust项目

作为包管理工具,cargo可以下载第三方库。

同时cargo 也可以用来建立自己的rust项目, 包括可行性程序以及库。

可以通过

cargo new project_name -bin 创建一个rust程序

cargo new project_name --lib 创建一个库

cargo 库

再rust 第三方库叫crates, 可以通过https://crates.io/上找到。

本例子中使用rand, 可以找到该库文件。



开始建立工程

工程建立一些代码的编写, 本章节不做细节描述。 概要说明一下

建立工程

 $ cargo new guess-game-app
 Created binary (application) `guess-game-app` package
 $ cd guess-game-app

加入依赖

修改toml文件,加入rand依赖

 [package]
 name = "guess-game-app"
 version = "0.1.0"
 edition = "2021"
 
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
 [dependencies]
 rand="0.8.5"

编译

编译cargo buildcargo check

引入包后,习惯的执行编译, 会导入对应的包文件。

     Updating crates.io index
   Downloaded rand_chacha v0.3.1
   Downloaded cfg-if v1.0.0
   Downloaded ppv-lite86 v0.2.17
   Downloaded rand_core v0.6.4
   Downloaded getrandom v0.2.11
   Downloaded rand v0.8.5
   Downloaded libc v0.2.150
   Downloaded 7 crates (910.0 KB) in 4.23s
    Compiling libc v0.2.150
    Compiling cfg-if v1.0.0
    Compiling ppv-lite86 v0.2.17
    Compiling getrandom v0.2.11
    Compiling rand_core v0.6.4
    Compiling rand_chacha v0.3.1
    Compiling rand v0.8.5
    Compiling guess-game-app v0.1.0 (/Users/zhuchunlei/work/08_rust/guess-game-app)
     Finished dev [unoptimized + debuginfo] target(s) in 12.11s

源码

修改源文件,src/main.rs(代码来源教程中,目前为止只是照着敲, 具体含义再逐渐学习理解)

 use rand::Rng;
 use std::cmp::Ordering;
 use std::io;
 
 fn main() {
     println!("Guess the number!");
 
     let secret_number = rand::thread_rng().gen_range(1..=100);
 
     loop {
         println!("Please input your guess.");
 
         let mut guess = String::new();
 
         io::stdin()
             .read_line(&mut guess)
             .expect("Failed to read line");
 
         let guess: u32 = match guess.trim().parse() {
             Ok(num) => num,
             Err(_) => continue,
         };
 
         println!("You guessed: {guess}");
 
         match guess.cmp(&secret_number) {
             Ordering::Less => println!("Too small!"),
             Ordering::Greater => println!("Too big!"),
             Ordering::Equal => {
                 println!("You win!");
                 break;
             }
         }
     }
 }

编译执行

序员宝藏库:https://gitee.com/sharetech_lee/CS-Books-Store

你想要的,这里都有!

作为程序员用的比较多的工具是什么?

我觉得搜索引擎绝对能名列前茅。

在开发过程中,总会遇到这样或者那样的问题超出我们自身的知识范围。这些问题可能是编程语言方面的,可能是Linux操作系统方面的,可能是服务部署方面的等等。

当遇到这种问题时,很多同学会选择求助于搜索引擎,懂得懂得,搜索引擎搜出的很多结果要么和问题无关、要么是个大坑。

所以,从事开发工作这么多年,我深刻意识一个道理,能够快速解决问题真的是一项非常突出的本领,哪怕是在借助于互联网的情况下。

话说回来,正是因为寻求问题的道路非常曲折繁琐,因此,网上出现了各种各样的速查表「CheatSheet」,估计有不少同学过去都看到过很多了。

但是,我认为这并没有从效率上彻底解决问题。

今天我在浏览Github时发现一款非常不错的开源工具,真的让我眼前一亮。

这款开源工具的名字叫做cheat.sh,目前已经33K+ Star了。

这款工具的简洁是「你唯一需要的速查表」,简单概括,这款工具把知名、权威社区的答案、资料进行了统一汇总,我们只需要这一款工具就可以快速得到最准确、最可靠的答案。

它背后的知识来源于tldr、StackOverflow、cheat.sheets等社区或者开源项目。

为了更加清晰的理解它的用处,下面先来看一个示例:

$ curl cht.sh/lua/table+keys
    -- lua: retrieve list of keys in a table

    local keyset={}
    local n=0

    for k,v in pairs(tab) do
      n=n+1
      keyset[n]=k
    end

    --[[
       [ Note that you cannot guarantee any order in keyset. If you want the
       [ keys in sorted order, then sort keyset with table.sort(keyset).
       [ 
       [ [lhf] [so/q/12674345] [cc by-sa 3.0]
       ]]

上面执行的curl命令包含下面几个信息:

  • cht.sh:工具名称
  • lua:编程语言
  • table+keys:要查询的问题,多个关键词用加好链接

通过这样,它就可以快速在终端下给出问题的答案。

如果你不想要文字描述,只想要「纯净」的答案,还可以通过参数来处理:

 $ curl cht.sh/lua/table+keys\?Q
    local keyset={}
    local n=0

    for k,v in pairs(tab) do
      n=n+1
      keyset[n]=k
    end

想必到这里,很多同学都已经知道它的用法了,概括一下这款工具的价值,主要有以下几点:

  • 简洁——它应该只包含你需要的东西,没有杂乱的信息
  • 快速——能够快速得到问题的答案,「所见即所得」
  • 全面——编程语言、操作系统等等,覆盖面非常全
  • 通用——随时随地可用,

可能很多同学还有一丝疑虑,感觉用curl每次都要输入很长的命令,太麻烦。

没事,前面只是一个小示例,下面系统的介绍一下如何安装并使用客户端。

安装

方式1

PATH_DIR="$HOME/bin"  # or another directory on your $PATH
mkdir -p "$PATH_DIR"
curl https://cht.sh/:cht.sh > "$PATH_DIR/cht.sh"
chmod +x "$PATH_DIR/cht.sh"

方式二

curl -s https://cht.sh/:cht.sh | sudo tee /usr/local/bin/cht.sh && sudo chmod +x /usr/local/bin/cht.sh

安装后就可以在终端下使用了。

如果想用交互式命令模式,还需要通过命令sudo apt install rlwrap安装rlwrap。

用法

通过上述命令安装客户端之后,就不用再像前面curl命令那样每次输入很长的命令,可以用更加贴近人为描述的方式查询问题答案。

举几个例子:

$ cht.sh go reverse a list
$ cht.sh python random list elements
$ cht.sh js parse json

这样看,估计很多开发同学都能够懂得它的用法了,「命令+语言+问题」。

可以看看效果:

$ cht.sh python random number
#  Try:

 from random import randrange
 print(randrange(10))

#  **Docs:**
#  https://docs.python.org/3/library/random.htmlrandom.randrange
#  
#  [kovshenin] [so/q/3996904] [cc by-sa 3.0]

再尝试一个:

$ cht.sh python matplotlib plot line
#  You can directly plot the lines you want by feeding the `plot` command
#  with the corresponding data (boundaries of the segments):
#  
#  `plot([x1, x2], [y1, y2], color='k', linestyle='-', linewidth=2)`
#  
#  (of course you can choose the color, line width, line style, etc.)
#  
#  From your example:

 import numpy as np
 import matplotlib.pyplot as plt

 np.random.seed(5)
 x = np.arange(1, 101)
 y = 20 + 3 * x + np.random.normal(0, 60, 100)
 plt.plot(x, y, "o")

 # draw vertical line from (70,100) to (70, 250)
 plt.plot([70, 70], [100, 250], 'k-', lw=2)

 # draw diagonal line from (70, 90) to (90, 200)
 plt.plot([70, 90], [90, 200], 'k-')

 plt.show()

#  ![new chart](https://i.imgur.com/76drc.png)
#  
#  [gcalmettes] [so/q/12864294] [cc by-sa 3.0]

可以看得出来,它不仅支持编程语言的基本语法,还支持查询语言基础之外的工具包的用法。

IDE+编辑器

前面介绍了它在命令行下的用法,其实,cht.sh更强大的是它不仅支持命令行,它还可以在常用的IDE、编辑器下用。

例如:

  • Vim
  • Emacs
  • Sublime
  • IDEA
  • VS Code
  • IDEA
  • ...

除此之外,它还是跨平台的,在Windows、Linux、macOS下都可以用。

另外,这款工具在编辑器、IDE下功能更加丰富,甚至可以自动生成代码片段,直接补全答案。

下面看一下效果!

Sublime:

IDEA:

VS Code:

最后再补充一点,在知识方面,它覆盖也非常全,Python、JavaScript、Go、C++、Linux、php,我们在开发中遇到的很多问题通过cht.sh都可以快速得到答案!

传送门

建议大家有空可以多浏览Github,有很多好用的开源免费工具。但是,目前Github上项目多如牛毛,而且刷榜现在也非常严重,想要找到优质的项目变得越来越难。这里,给大家推荐Github上一个非常不错的项目《DevWeekly》,这个项目每周都会精挑细选一些优质的开源项目,涵盖C++、JAVA、JavaScript、Python、Go等不同编程语言。此外,还有一些开源工具、优秀的技术文章:

https://github.com/Jackpopc/DevWeekly