分类 软件开发 下的文章

我将演示如何利用提供的全球病毒传播的开放数据,使用开源库来创建两个可视效果。

使用 Python 和一些图形库,你可以预测 COVID-19 确诊病例总数,也可以显示一个国家(本文以印度为例)在给定日期的死亡总数。人们有时需要帮助解释和处理数据的意义,所以本文还演示了如何为五个国家创建一个动画横条形图,以显示按日期显示病例的变化。

印度的确诊病例和死亡人数预测

这要分三步来完成。

1、下载数据

科学数据并不总是开放的,但幸运的是,许多现代科学和医疗机构都乐于相互之间及与公众共享信息。关于 COVID-19 病例的数据可以在网上查到,并且经常更新。

要解析这些数据,首先必须先下载。 https://raw.githubusercontent.com/datasets/covid-19/master/data/countries-aggregated.csv

直接将数据加载到 Pandas DataFrame 中。Pandas 提供了一个函数 read_csv(),它可以获取一个 URL 并返回一个 DataFrame 对象,如下所示。

import pycountry
import plotly.express as px
import pandas as pd
URL_DATASET = r'https://raw.githubusercontent.com/datasets/covid-19/master/data/countries-aggregated.csv'
df1 = pd.read_csv(URL_DATASET)
print(df1.head(3))  # 获取数据帧中的前 3 项
print(df1.tail(3))  # 获取数据帧中的后 3 项

数据集的顶行包含列名。

  1. Date
  2. Country
  3. Confirmed
  4. Recovered
  5. Deaths

head 查询的输出包括一个唯一的标识符(不作为列列出)和每个列的条目。

0 2020-01-22 Afghanistan 0 0 0
1 2020-01-22 Albania 0 0 0
1 2020-01-22 Algeria 0 0 0

tail 查询的输出类似,但包含数据集的尾端。

12597 2020-03-31 West Bank and Gaza 119 18 1
12598 2020-03-31 Zambia 35 0 0
12599 2020-03-31 Zimbabwe 8 0 1

从输出中,可以看到 DataFrame(df1)有以下几个列:

  1. 日期
  2. 国家
  3. 确诊
  4. 康复
  5. 死亡

此外,你可以看到 Date 栏中的条目从 1 月 22 日开始到 3 月 31 日。这个数据库每天都会更新,所以你会有当前的值。

2、选择印度的数据

在这一步中,我们将只选择 DataFrame 中包含印度的那些行。这在下面的脚本中可以看到。

#### ----- Step 2 (Select data for India)----
df_india = df1[df1['Country'] == 'India']
print(df_india.head(3))

3、数据绘图

在这里,我们创建一个条形图。我们将把日期放在 X 轴上,把确诊的病例数和死亡人数放在 Y 轴上。这一部分的脚本有以下几个值得注意的地方。

  • plt.rcParams["figure.figsize"]=20,20 这一行代码只适用于 Jupyter。所以如果你使用其他 IDE,请删除它。
  • 注意这行代码:ax1 = plt.gca()。为了确保两个图,即确诊病例和死亡病例的图都被绘制在同一个图上,我们需要给第二个图的 ax 对象。所以我们使用 gca() 来完成这个任务。(顺便说一下,gca 代表 “ 获取当前坐标轴 get current axis ”)

完整的脚本如下所示。

#  Author:- Anurag Gupta # email:- [email protected]
%matplotlib inline
import matplotlib.pyplot as plt
import pandas as pd

#### ----- Step 1 (Download data)----
URL_DATASET = r'https://raw.githubusercontent.com/datasets/covid-19/master/data/countries-aggregated.csv'
df1 = pd.read_csv(URL_DATASET)
# print(df1.head(3))  # Uncomment to see the dataframe

#### ----- Step 2 (Select data for India)----
df_india = df1[df1['Country'] == 'India']
print(df_india.head(3))

#### ----- Step 3 (Plot data)----
# Increase size of plot
plt.rcParams["figure.figsize"]=20,20  # Remove if not on Jupyter
# Plot column 'Confirmed'
df_india.plot(kind = 'bar', x = 'Date', y = 'Confirmed', color = 'blue')

ax1 = plt.gca()
df_india.plot(kind = 'bar', x = 'Date', y = 'Deaths', color = 'red', ax = ax1)
plt.show()

整个脚本可在 GitHub 上找到

为五个国家创建一个动画水平条形图

关于 Jupyter 的注意事项:要在 Jupyter 中以动态动画的形式运行,而不是静态 png 的形式,你需要在单元格的开头添加一个神奇的命令,即: %matplotlib notebook。这将使图形保持动态,而不是显示为静态的 png 文件,因此也可以显示动画。如果你在其他 IDE 上,请删除这一行。

1、下载数据

这一步和前面的脚本完全一样,所以不需要重复。

2、创建一个所有日期的列表

如果你检查你下载的数据,你会发现它有一列 Date。现在,这一列对每个国家都有一个日期值。因此,同一个日期会出现多次。我们需要创建一个只具有唯一值的日期列表。这会用在我们条形图的 X 轴上。我们有一行代码,如 list_dates = df[‘Date’].unique()unique() 方法将只提取每个日期的唯一值。

3、挑选五个国家并创建一个 ax 对象。

做一个五个国家的名单。(你可以选择你喜欢的国家,也可以增加或减少国家的数量。)我也做了一个五个颜色的列表,每个国家的条形图的颜色对应一种。(如果你喜欢的话,也可以改一下。)这里有一行重要的代码是:fig, ax = plt.subplots(figsize=(15, 8))。这是创建一个 ax 对象所需要的。

4、编写回调函数

如果你想在 Matplotlib 中做动画,你需要创建一个名为 matplotlib.animation.FuncAnimation 的类的对象。这个类的签名可以在网上查到。这个类的构造函数,除了其他参数外,还需要一个叫 func 的参数,你必须给这个参数一个回调函数。所以在这一步中,我们会写个回调函数,这个回调函数会被反复调用,以渲染动画。

5、创建 FuncAnimation 对象

这一步在上一步中已经部分说明了。

我们创建这个类的对象的代码是:

my_anim = animation.FuncAnimation(fig = fig, func = plot_bar,
                    frames = list_dates, blit = True,
                    interval=20)

要给出的三个重要参数是:

  • fig,必须给出一个 fig 对象,也就是我们之前创建的 fig 对象。
  • func,必须是回调函数。
  • frames,必须包含要做动画的变量。在我们这里,它是我们之前创建的日期列表。

6、将动画保存为 mp4 文件

你可以将创建的动画保存为 mp4 文件。但是,你需要 ffmpeg。你可以用 pip 下载:pip install ffmpeg-python,或者用 conda(在 Jupyter 上):install -c conda-forge ffmpeg

最后,你可以使用 plt.show() 运行动画。请注意,在许多平台上,ffmpeg 可能无法正常工作,可能需要进一步“调整”。

%matplotlib notebook
#  Author:- Anurag Gupta # email:- [email protected]
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from time import sleep

#### ---- Step 1:- Download data
URL_DATASET = r'https://raw.githubusercontent.com/datasets/covid-19/master/data/countries-aggregated.csv'
df = pd.read_csv(URL_DATASET, usecols = ['Date', 'Country', 'Confirmed'])
# print(df.head(3)) # uncomment this to see output

#### ---- Step 2:- Create list of all dates
list_dates = df['Date'].unique()
# print(list_dates) # Uncomment to see the dates

#### --- Step 3:- Pick 5 countries. Also create ax object
fig, ax = plt.subplots(figsize=(15, 8))
# We will animate for these 5 countries only
list_countries = ['India', 'China', 'US', 'Italy', 'Spain']
# colors for the 5 horizontal bars
list_colors = ['black', 'red', 'green', 'blue', 'yellow']

### --- Step 4:- Write the call back function
# plot_bar() is the call back function used in FuncAnimation class object
def plot_bar(some_date):
    df2 = df[df['Date'].eq(some_date)]
    ax.clear()
    # Only take Confirmed column in descending order
    df3 = df2.sort_values(by = 'Confirmed', ascending = False)
    # Select the top 5 Confirmed countries
    df4 = df3[df3['Country'].isin(list_countries)]
    # print(df4)  # Uncomment to see that dat is only for 5 countries
    sleep(0.2)  # To slow down the animation
    # ax.barh() makes a horizontal bar plot.
    return ax.barh(df4['Country'], df4['Confirmed'], color= list_colors)

###----Step 5:- Create FuncAnimation object---------
my_anim = animation.FuncAnimation(fig = fig, func = plot_bar,
                    frames= list_dates, blit=True,
                    interval=20)

### --- Step 6:- Save the animation to an mp4
# Place where to save the mp4. Give your file path instead
path_mp4 = r'C:\Python-articles\population_covid2.mp4'  
# my_anim.save(path_mp4, fps=30, extra_args=['-vcodec', 'libx264'])
my_anim.save(filename = path_mp4, writer = 'ffmpeg',
             fps=30,
             extra_args= ['-vcodec', 'libx264', '-pix_fmt', 'yuv420p'])
plt.show()

完整的脚本可以在 GitHub 上找到


via: https://opensource.com/article/20/4/python-data-covid-19

作者:AnuragGupta 选题:lujun9972 译者:wxy 校对:wxy

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

GTWS 是一系列脚本,它使我们在开发环境中管理不同的项目和项目的各个版本变得很容易。

Great Teeming Workspaces(GTWS)是一个 Git 的复杂工作空间管理工具包,它使我们在开发环境中管理不同的项目和项目的各个版本变得很容易。

有点像 Python 的 venv,但不是为 Python 语言准备的。GTWS 用来管理多个项目的多个版本的工作空间。你可以很容易地创建、更新、进入和离开工作空间,每个项目或版本的组合(最多)有一个本地的 origin,用来与 upstream 同步 — 其余的所有工作空间都从本地的 origin 更新。

部署

${GTWS_ORIGIN}/<project>/<repo>[/<version>]
${GTWS_BASE_SRCDIR}/<project>/<version>/<workspacename>/{<repo>[,<repo>...]}

源代码目录的每一级(包括全局的家目录)可以包含一个 .gtwsrc 文件,这个文件中维护与当前级相关的设置和 bash 代码。每一级的配置会覆盖上一级。

安装

用下面的命令检出 GTWS:

git clone https://github.com/dang/gtws.git

配置你的 ${HOME}/.gtwsrc。它应该包含 GTWS_ORIGIN,也可以再包含 GTWS_SETPROMPT

把仓库目录加到环境变量中:

export PATH="${PATH}:/path/to/gtws

配置

通过级联 .gtwsrc 文件来进行配置。它从根目录向下遍历,会执行在每级目录中找到的 .gtwsrc 文件。下级目录的文件会覆盖上一级。

在你最上层的文件 ~/.gtws/.gtwsrc 中进行如下设置:

  • GTWS_BASE_SRCDIR:所有项目源文件目录树的基目录。默认为 $HOME/src
  • GTWS_ORIGIN: 指定 origin git 目录树的路径。默认为 $HOME/origin
  • GTWS_SETPROMPT: 可选配置。如果配置了这个参数,shell 提示符会有工作空间的名字。
  • GTWS_DEFAULT_PROJECT: 不指定项目或项目未知时默认的项目名。如果不指定,使用命令行时必须指明项目。
  • GTWS_DEFAULT_PROJECT_VERSION: 检出的默认版本。默认为 master

在每个项目的根目录进行以下设置:

  • GTWS_PROJECT: 项目的名字(和基目录)。
  • gtws_project_clone: 这个函数用于克隆一个项目的指定版本。如果未定义,它会假定项目的 origin 对每一个版本都有一个单独的目录,这样会导致克隆一堆 Git 仓库。
  • gtws_project_setup: 在克隆完所有的仓库后,可以选择是否调用这个函数,调用后可以对项目进行必要的配置,如在 IDE 中配置工作空间。

在项目版本级进行以下设置:

  • GTWS_PROJECT_VERSION: 项目的版本。用于正确地从 origin 拉取代码。类似 Git 中的分支名字。

下面这些参数可以在目录树的任意地方进行配置,如果能生效,它们可以被重写多次:

  • GTWS_PATH_EXTRA: 这些是工作空间中加到路径后的额外的路径元素。
  • GTWS_FILES_EXTRA: 这些是不在版本控制内,但应该在工作空间中被检出的额外的文件。这些文件包括 .git/info/exclude,每个文件都与仓库的基目录相关联。

origin 目录

GTWS_ORIGIN (大部分脚本中)指向拉取和推送的原始 Git 检出目录。

${GTWS_ORIGIN} 部署:

  • /<project>

    • 这是一个项目的仓库的基目录。
    • 如果指定了 gtws_project_clone,你可以配置任意的部署路径。
    • 如果没有指定 gtws_project_clone,这个路径下必须有个名为 git 的子目录,且 git 目录下有一系列用来克隆的裸 Git 仓库。

工作流示例

假设你有一个项目名为 Foo,它的 upstream 为 github.com/foo/foo.git。这个仓库有个名为 bar 的子模块,它的 upstream 是 github.com/bar/bar.git。Foo 项目在 master 分支开发,使用稳定版本的分支。

为了能在 Foo 中使用 GTWS,你首先要配置目录结构。本例中假设你使用默认的目录结构。

  • 配置你最上层的 .gtwsrc

    • cp ${GTWS_LOC}/examples/gtwsrc.top ~/.gtwsrc
    • 根据需要修改 ~/.gtwsrc
  • 创建顶级目录:

    • mkdir -p ~/origin ~/src
  • 创建并配置项目目录:
+ `mkdir -p ~/src/foo`


`cp ${GTWS_LOC}/examples/gtwsrc.project ~/src/foo/.gtwsrc`
+ 根据需要修改 `~/src/foo/.gtwsrc`。
  • 创建并配置 master 版本目录:
+ `mkdir -p ~/src/foo/master`


`cp ${GTWS_LOC}/examples/gtwsrc.version ~/src/foo/master/.gtwsrc`
+ 根据需要修改 `~/src/foo/master/.gtwsrc`。
  • 进入版本目录并创建一个临时工作空间来配置镜像:
+ `mkdir -p ~/src/foo/master/tmp`


`cd ~/src/foo/master/tmp`


`git clone --recurse-submodules git://github.com/foo/foo.git`


`cd foo`


`gtws-mirror -o ~/origin -p foo`(译注:这个地方原文有误,不加 `-s` 参数会报错)
+ 上面命令会创建 `~/origin/foo/git/foo.git` 和 `~/origin/foo/submodule/bar.git`。
+ 以后的克隆操作会从这些 origin 而不是 upstream 克隆。
+ 现在可以删除工作空间了。

到现在为止,Foo 的 master 分支的工作可以结束了。假设你现在想修复一个 bug,名为 bug1234。你可以脱离你当前的工作空间为修复这个 bug 单独创建一个工作空间,之后在新创建的工作空间中开发。

  • 进入版本目录,创建一个新的工作空间:
+ `cd ~/src/foo/master`


`mkws bug1234`
+ 上面的命令创建了 `bug1234/`,在这个目录下检出了 Foo(和它的子模块 `bar`),并创建了 `build/foo` 来构建它。
  • 有两种方式进入工作空间:
+ `cd ~/src/foo/master/bug1234`


`startws`


或者


`cd ~/src/foo/master/`


`startws bug1234`
+ 上面的命令在 `bug1234` 工作空间中开启了一个子 shell。这个 shell 有 GTWS 的环境和你在各级 `.gtwsrc` 文件中设置的环境。它也把你工作空间的基目录加入到了 CD,因此你可以从 base 路径 `cd` 到相关的目录中。
+ 现在你可以修复 `bug1234` 了,构建、测试、提交你的修改。当你可以把代码推送到 upstream 时,执行下面的命令:


`cd foo`


`wspush`
+ `wspush` 会把代码推送到与你工作空间相关的分支 — 先推送到本地的 origin,再推送到 upstream。
+ 当 upstream 有修改时,你可以用下面的命令同步到本地:


`git sync`
+ 上面的命令调用了 GTWS 的 `git-sync` 脚本,会从本地 origin 更新代码。使用下面的命令来更新本地的 origin:


`git sync -o`
+ 上面的命令会更新你本地的 origin 和子模块的镜像,然后用那些命令来更新你的检出仓库的代码。`git-sync` 也有一些其他的很好的工鞥。
+ 当要结束工作空间中的工作时,直接退出 shell:


`exit`
+ 你可以在任何时间重复进入工作空间,也可以在同一时间在相同的工作空间中开多个 shell。
  • 当你不需要某个工作空间时,你可以使用 rmws 来删除它,或者直接删除它的目录树。
  • 还有一个脚本 tmws 使用 tmux 进入工作空间,能创建一系列的窗口/窗格,这完美契合我的工作流。你可以根据你自己的需求来修改它。

via: https://opensource.com/article/20/2/git-great-teeming-workspaces

作者:Daniel Gryniewicz 选题:lujun9972 译者:lxbwolf 校对:wxy

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

了解如何使用 dh\_virtualenv 来让你的 Python 应用可作为 .deb 包安装。

在基于 Debian 的操作系统(例如 Debian 或 Elementary OS)上安装 Python 应用的一种方法是使用 dh\_virtualenv 工具。它可以构建一个 .deb 包,在应用之外封装了一个 Python 虚拟环境,并在安装时进行部署。

在本文中,我将以构建一个包含 HTTPie 工具的包为例来解释如何使用它,以便在无需激活虚拟环境的情况下从命令行测试 HTTP API。

使用 dh\_virtualenv 打包

首先,你需要安装 dh_virtualenv 所需的工具。dh_virtualenv文档提供了所有安装选项。在基于 Debian 的系统上,我输入:

apt-get install dh-virtualenv devscripts

尽管不需要 devscripts 包,但它可以简化后续操作。

现在,创建一个目录来保存源码。由于这是一个本地的、非官方的 HTTPie 打包,因此我将其称为 myhttp。接下来,让我们在 myhttp 内创建一些文件,向 Debian 构建系统提供元数据。

首先,创建 debian/control 文件:

Source: myhttp
Section: python
Priority: extra
Maintainer: Jan Doe <[email protected]>
Build-Depends: debhelper (>= 9), python3.7, dh-virtualenv (>= 0.8)
Standards-Version: 3.9.5

Package: myhttp
Architecture: any
Pre-Depends: dpkg (>= 1.16.1), python3.7, ${misc:Pre-Depends}
Depends: ${misc:Depends}
Description: http client
 Useful for doing stuff

那么这些是什么信息呢?正如 Debian 文档指出的:

“第 1–7 行是源码包的控制信息。第 9–13 行是二进制包的控制信息。”

以下是我使用的:

  • Section 的值对于我们来说大多没有意义,但需要存在。它对给引导式 UI 安装程序提供信息是有意义的,但对于这个包来说,没有意义。
  • Priority 对像这样的第三方包的正确值是 extra
  • 强烈建议在 Maintainer 字段中填写正确的联系人信息。但不一定非得是你的个人电子邮件,如果包由团队维护,并且你希望将问题发送到团队的邮件别名,例如 Infrastructure Team <[email protected]>
  • Build-Depends 字段标识你需要 debhelperpythondh-virtualenv 来构建包:包构建过程中将确保这些依赖项在包构建时已安装。
  • Standards-Version 字段主要给人看。它表明你遵循的指南。本指南基于 dh-virtualenv 的官方文档,它是基于 Debian 的 3.9.5 指南。最好一直将源码包和二进制包命名相同。
  • Architecture 字段应为 Any,因为除非虚拟环境可能包含一些特定于体系结构的文件。否则,最好选择该字段为 any
  • 保持 Pre-Depends 列表不变:它是一种非常严格的依赖关系形式,你很少会需要比这里建议的最小依赖更多的依赖项。依赖项通常由构建系统准确计算,因此没有理由手动指定它们。
  • 如果你的包主要用于内部,那么 Description 字段可能只需要最少的信息或者指向公司 wiki 的链接,不然更多的信息会更有用。

然后创建 debian/compat 文件,它主要出于历史目的而存在

$ echo "9" > debian/compat

接下来,创建更新日志以告知包用户自上次发布以来发生了什么变化。最简单的方法是使用 dch --create 创建模板,然后填写值。

填写后,它看起来像:

myhttp (2.0.0-1) stable; urgency=medium

  * Initial release.

 -- Jan Doe <[email protected]>  Fri, 27 Mar 2020 01:09:22 +0000

现在你需要告诉工具安装 HTTPie,但是哪个版本?

创建一个宽松版本的 requirements.in 文件:

httpie

通常,宽松的需求文件将仅包含项目的直接依赖项,并在需要时指定最低版本。不一定总是需要指定最低版本:这些工具通常偏向于将依赖关系转化为“可能的最新版本”。如果你的 Debian 包与一个内部 Python 包相对应,这是内部应用中的一种常见情况,那么宽松的需求文件看起来将很相似:仅包含包名的一行。

然后使用 pip-compile(可通过安装 PyPI 包 pip-tools 获得):

$ pip-compile requirements.in > requirements.txt

这会生成一个严格的依赖文件,名为 requirements.txt

#
# This file is autogenerated by pip-compile
# To update, run:
#
#    pip-compile requirements.in
#
certifi==2019.11.28       # via requests
chardet==3.0.4            # via requests
httpie==2.0.0             # via -r requirements.in
idna==2.9                 # via requests
pygments==2.6.1           # via httpie
requests==2.23.0          # via httpie
urllib3==1.25.8           # via requests

最后,写一个 debian/rules 文件来创建包。因为 dh_virtualenv 会处理所有困难的事,因此规则文件很简单:

#!/usr/bin/make -f

%:
        dh $@ --with python-virtualenv --python /usr/bin/python3.7

确保指定 Python 解释器。默认它会使用 /usr/bin/python,这是 Python2,但是你应该使用一个受支持的 Python 版本

完成了,接下来就是构建包:

$ debuild -b -us -uc

这会在父目录生成一个类似 myhttp_2.0.0-1_amd64.deb 的文件。该文件可在任何兼容的系统上安装。

通常,最好在同一平台上构建用于特定平台(例如 Debian 10.0)的 Debian 包。

你可以将此 Debian 包保存在软件仓库中,并使用例如 Ansible 的工具将其安装在所有相关系统上。

总结

给基于 Debian 的系统的打包应用是一个有着多个步骤的过程。使用 dh_virtualenv 将使过程变得简单明了。


via: https://opensource.com/article/20/4/package-python-applications-linux

作者:Moshe Zadka 选题:lujun9972 译者:geekpi 校对:wxy

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

通过这个简单的工作流程创建的研讨会幻灯片,可以在任何浏览器、设备和平台上获得一致的查看效果。

无论你是学习者还是教师,你可能都会认识到采用幻灯片放映来传播知识的在线 研讨会 workshop 的价值。如果你曾经偶然看到过这样一个逐页、逐章设置的井井有条的教程,你可能会想知道创建这样的一个网站有多难。

好吧,让我在这里向你展示,使用全自动化的流程来生成这样的教程是多么容易。

介绍

当我开始将学习内容放到网上置时,体验并不是很好。我想要的是一种可重复的、一致的、易于维护的东西,因为我的内容会随着我教学的技术发展而变化。

我尝试了许多交付模型,从 Asciidoctor 这样的低级代码生成器到在单个 PDF 文件中放置教程。全都不能让我满意。当我举办现场的在座研讨会时,我喜欢使用幻灯片放映,因此我想知道我是否可以为我自己的在线的,自定进度的研讨会体验做同样的事情。

经过一番挖掘,我为创建无痛的研讨会网站打下了基础。当时我已经在使用一个演示文稿生成框架,这对我来说是很有帮助的,因为这个框架可以产生对网站友好的格式(HTML)。

设置

这里是这个项目所需要的基本组件。

  • 研讨会的想法(这是你的问题,我帮不了你)
  • 用于研讨会幻灯片的 Reveal.js
  • GitLab 项目仓库
  • 你常用的 HTML 代码编辑器
  • Web 浏览器
  • 在你的机器上安装好 Git

如果这个列表看起来令人望而生畏,那么有一个快速入门的方法,不需要把所有的东西一个个都拉到一起。你可以用我的模板项目来给你提供幻灯片和项目设置的入门教程。

本文假设你熟悉 Git 和在 Git 平台(如 GitLab)上托管项目。如果你需要指导或教程,请查看我们的Git 入门系列

首先,将模板项目克隆到本地机器上。

$ git clone https://gitlab.com/eschabell/beginners-guide-automated-workshops.git

为此设置一个新的 GitLab 项目,导入模板项目作为初始导入。

研讨会网站有一些重要的文件。在根目录下,你会发现一个名为 .gitlab-ci.yml 的文件,当你向主分支提交修改时(即将拉取请求合并到 master 分支),这个文件会作为触发器。它可以触发将 slides 目录的全部内容复制到 GitLab 项目的 website 文件夹中。

我把它托管在我的 GitLab 账户中,名为 beginners-guide-automated-workshops。当它部署完毕后,你可以在浏览器中通过导航到下列地址查看 slides 目录的内容:

https://eschabell.gitlab.io/beginners-guide-automated-workshops

对于你的用户帐户和项目,URL 如下所示:

https://[YOUR_USERNAME].gitlab.io/[YOUR_PROJECT_NAME]

这些是你开始创建网站内容所需要的基本素材。当你推送修改后,它们会自动生成更新过的研讨会网站。请注意,默认模板包含了几个示例幻灯片,这将是你完成对存储库的完整签入后的第一个研讨会网站。

研讨会模板生成的结果是一个 receive.js 幻灯片,可以在任何浏览器中运行,并可以自动调整大小,几乎可以让任何人在任何地方、任何设备上观看。

这样创建一个方便、易访问的研讨会怎么样?

它是如何工作的

有了这些背景信息,你就可以开始探索研讨会的这些素材,并开始把你的内容放在一起了。你需要的一切都可以在项目的 slides 目录中找到;这里是使用 reveal.js 在浏览器中创建研讨会幻灯片的地方。

你将用来制作研讨会的文件和目录是:

  • default.css文件
  • images 目录
  • index.html文件

在你常用的 HTML/CSS 编辑器中打开每一个文件,然后进行下面描述的修改。你用哪个编辑器并不重要,我更喜欢 RubyMine IDE,因为它能在本地浏览器中提供页面预览。这对我在将内容推送到研讨会网站之前测试内容时很有帮助。

default.css 文件

文件 css/theme/default.css 是一个基础文件,你将在这里为你的研讨会幻灯片设置重要的全局设置。其中值得注意的两个主要的项目是所有幻灯片的默认字体和背景图片。

default.css 中,看一下标有 GLOBAL STYLES 的部分。当前的默认字体在这一行中列出了。

font-family: "Red Hat Display", "Overpass", san-serif;

如果你使用的是非标准字体类型,则必须在以下行中将其导入(Overpass 字体类型就是这样做的):

@import url('SOME_URL');

background 是你创建的每张幻灯片的默认图像。它存储在 images 目录下(见下面),并在下面这一行中设置(重点是图像路径)。

background: url("…/…/images/backgrounds/basic.png")

要设置一个默认背景,只需将这一行指向你要使用的图片。

images 目录

顾名思义,images 目录是用来存储你想在研讨会幻灯片上使用的图片。例如,我通常会把展示研讨会主题进展的截图放在我的个人幻灯片上。

现在,你只需要知道你需要将背景图片存储在一个子目录(backgrounds)中,并将你计划在幻灯片中使用的图片存储在 images 目录中。

index.html 文件

现在你已经把这两个文件整理好了,剩下的时间你就可以在 HTML 文件中创建幻灯片了,从 index.html 开始。为了让你的研讨会网站开始成形,请注意这个文件中的以下三个部分。

  • head部分,在这里你可以设置标题、作者和描述。
  • body 部分,你可以在这里找到要设计的单个幻灯片。
  • 你可以在每个 section 中定义各个幻灯片的内容。

head 部分开始,因为它在顶部。模板项目有三个占位符行供你更新。

<title>INSERT-YOUR-TITLE-HERE</title>
<meta name="description" content="YOUR DESCIPTION HERE.">
<meta name="author" content="YOUR NAME">

title 标签包含文件打开时显示在浏览器选项卡中的文字。请将其改为与你的研讨会的标题相关的内容(或研讨会的某个部分),但记得要简短,因为标签页的标题空间有限。description 元标签包含了对你的工作坊的简短描述,而 author 元标签是你应该把你的名字(如果你是为别人写的,则是工作坊创建者的名字)。

现在继续到 body 部分。你会注意到它被分成了许多 section 标签。body 的开头包含了一个注释,说明你正在为每个标有 section 的打开和关闭的标签创建幻灯片。

<body>
        <div class="reveal">

        <!-- Any section element inside of this container is displayed as a slide -->
        <div class="slides">

接下来,创建你的各个幻灯片,每张幻灯片都用 section 标签封装起来。这个模板包括了一些幻灯片来帮助你开始制作。例如,这里是第一张幻灯片。

<section>
      <div style="width: 1056px; height: 300px">
            <h1>Beginners guide</h1>
            <h2>to automated workshops</h2>
      </div>
      <div style="width: 1056px; height: 200px; text-align: left">
            Brought to you by,<br/>
            YOUR-NAME<br/>
      </div>
      <aside class="notes">Here are notes: Welcome to the workshop!</aside>
</section>

这张幻灯片有两个区域,用 div 标签分隔。用空格隔开了标题和作者。

如果你有一定的 HTML 使用知识,可以尝试各种东西来开发你的研讨会。使用浏览器预览结果的时候真的很方便。有些 IDE 提供了本地查看修改,但你也可以打开 index.html 文件查看你的修改,然后再推送到资源库中。

一旦你对你的研讨会感到满意,推送你的修改,然后等待它们通过持续集成管道。它们将像模板项目一样被托管在 https://eschabell.gitlab.io/beginners-guide-automated-workshops

了解更多

要了解更多关于这个工作流程可以做什么,请查看下面的示例研讨会和托管了研讨会集合的网站。所有这些都是基于本文中描述的工作流程。

研讨会例子:

研讨会集合:

我希望这本新手指南和模板研讨会项目能让你看到,在开发和维护研讨会网站的过程中,可以轻松、无痛地完成。我也希望这个工作流程能让你的研讨会受众几乎在任何设备上都能完全访问你的内容,这样他们就能从你分享的知识中学习到你的知识。


via: https://opensource.com/article/20/4/create-web-tutorial-git

作者:Eric D. Schabell 选题:lujun9972 译者:wxy 校对:wxy

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

Python 是最流行、功能最强大的编程语言之一。由于它是自由开源的,因此每个人都可以使用。大多数 Fedora 系统都已安装了该语言。Python 可用于多种任务,其中包括处理逗号分隔值(CSV)数据。CSV文件一开始往往是以表格或电子表格的形式出现。本文介绍了如何在 Python 3 中处理 CSV 数据。

CSV 数据正如其名。CSV 文件按行放置数据,数值之间用逗号分隔。每行由相同的字段定义。简短的 CSV 文件通常易于阅读和理解。但是较长的数据文件或具有更多字段的数据文件可能很难用肉眼解析,因此在这种情况下计算机做得更好。

这是一个简单的示例,其中的字段是 NameEmailCountry。在此例中,CSV 数据将字段定义作为第一行,尽管并非总是如此。

Name,Email,Country
John Q. Smith,[email protected],USA
Petr Novak,[email protected],CZ
Bernard Jones,[email protected],UK

从电子表格读取 CSV

Python 包含了一个 csv 模块,它可读取和写入 CSV 数据。大多数电子表格应用,无论是原生(例如 Excel 或 Numbers)还是基于 Web 的(例如 Google Sheet),都可以导出 CSV 数据。实际上,许多其他可发布表格报告的服务也可以导出为 CSV(例如,PayPal)。

Python csv 模块有一个名为 DictReader 的内置读取器方法,它可以将每个数据行作为有序字典 (OrderedDict) 处理。它需要一个文件对象访问 CSV 数据。因此,如果上面的文件在当前目录中为 example.csv,那么以下代码段是获取此数据的一种方法:

f = open('example.csv', 'r')
from csv import DictReader
d = DictReader(f)
data = []
for row in d:
    data.append(row)

现在,内存中的 data 对象是 OrderedDict 对象的列表:

[OrderedDict([('Name', 'John Q. Smith'),
               ('Email', '[email protected]'),
               ('Country', 'USA')]),
  OrderedDict([('Name', 'Petr Novak'),
               ('Email', '[email protected]'),
               ('Country', 'CZ')]),
  OrderedDict([('Name', 'Bernard Jones'),
               ('Email', '[email protected]'),
               ('Country', 'UK')])]

引用这些对象很容易:

>>> print(data[0]['Country'])
USA
>>> print(data[2]['Email'])
[email protected]

顺便说一句,如果你需要处理没有字段名标题行的 CSV 文件,那么 DictReader 类可以让你定义它们。在上面的示例中,添加 fieldnames 参数并传递一系列名称:

d = DictReader(f, fieldnames=['Name', 'Email', 'Country'])

真实例子

我最近想从一长串人员名单中随机选择一个中奖者。我从电子表格中提取的 CSV 数据是一个简单的名字和邮件地址列表。

幸运的是,Python 有一个有用的 random 模块,可以很好地生成随机值。该模块 Random 类中的 randrange 函数正是我需要的。你可以给它一个常规的数字范围(例如整数),以及它们之间的步长值。然后,该函数会生成一个随机结果,这意味着我可以在数据的总行数范围内获得一个随机整数(或者说是行号)。

这个小程序运行良好:

from csv import DictReader
from random import Random

d = DictReader(open('mydata.csv'))
data = []
for row in d:
    data.append(row)

r = Random()
winner = data[r.randrange(0, len(data), 1)]
print('The winner is:', winner['Name'])
print('Email address:', winner['Email'])

显然,这个例子非常简单。电子表格本身包含了复杂的分析数据的方法。但是,如果你想在电子表格应用之外做某事,Python 或许是一种技巧!

题图由 Isaac Smith 拍摄,发表于 U​​nsplash


via: https://fedoramagazine.org/using-data-from-spreadsheets-in-fedora-with-python/

作者:Paul W. Frields 选题:lujun9972 译者:geekpi 校对:wxy

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

本文是 Python 之禅特别系列的第三篇,此篇着眼于其中第五与第六条原则:扁平与稀疏。

Python 之禅 之所以得名,正是由于它那简明扼要的规则被设计出的意图在于让读者进行深入地思考,而绝不单是为编程提供一份易于遵守的指南。

读后不去三思其意,断然难以体会 Python 之禅的妙处。倘若 Python 之禅仅仅罗列出一组清晰的法则,那法则之间的矛盾是一种缺憾,然而作为引导读者沉思最优方案沉思的工具,矛盾却是绝佳的。

扁平胜过嵌套 Flat is better than nested

迫于对缩进的强硬要求,Python 对“扁平化”的需求显然远超它者。其余编程语言为了缓解对缩进的需求,通常会在嵌套结构里加入一种“作弊”的手段。为了理解这一点,不妨一同来看看 JavaScript。

JavaScript 本质上是异步的,这意味着程序员用 JavaScript 写的代码会用到大量的回调函数。

a(function(resultsFromA) {
  b(resultsFromA, function(resultsfromB) {
    c(resultsFromC, function(resultsFromC) {
      console.log(resultsFromC)
   }
  }
}

忽略这段代码的具体内容,只去观察这段代码的形状与缩进带来一个最右边的点的方式。这种独特的“箭头”图形在我们扫看代码时格外扎眼,这种写法也因此被视作不可取,甚至得到了“回调地狱”的绰号。不过,在 JavaScript 中,这种反映嵌套关系的缩进可以通过“作弊”来回避。

a(function(resultsFromA) {
b(resultsFromA,
  function(resultsfromB) {
c(resultsFromC,
  function(resultsFromC) {
    console.log(resultsFromC)
}}}

Python 并没有提供这种作弊手段:每一级嵌套在代码中都如实的对应着一层缩进。因此,Python 深层的嵌套关系在视觉上也一定是深层嵌套的。这使得“回调地狱”的问题对于 Python 而言要比在 JavaScript 中严重得多:嵌套的回调函数必定带来缩进,而绝无使用花括号来“作弊”的可能。

这项挑战与 Python 之禅的指导原则相结合后,在我参与的库中催生出了一个优雅的解决方案。我们在 Twisted 框架里提出了 deferred 抽象,日后 JavaScript 中流行的 promise 抽象亦是受其启发而生。正是由于 Python 对整洁代码的坚守,方能推动 Python 开发者去发掘新的、强力的抽象。

future_value = future_result()
future_value.addCallback(a)
future_value.addCallback(b)
future_value.addCallback(c)

(现代 JavaScript 程序员也许会觉得这段代码十分眼熟:promise 着实受到了 Twisted 里 deferred 抽象的深远影响。)

稀疏胜过密集 Sparse is better than dense

最易降低代码密集程度的方法是引入嵌套。这种习惯也正是有关稀疏的原则要随着前一条提出的原因:在竭尽所能地减少嵌套之后,我们往往会遗留下密集的代码或数据结构。此处的密集,是指塞进过量信息的小段代码,它们会导致错误发生后的解析变得困难。

这种密集性唯有通过创造性的思考方可改善,此外别无捷径。Python 之禅并不为我们提供简单的解决方案,它只会指明改善代码的方向,而非提供“如何”去做的向导。

起身走走,泡个热水澡,抑或是闻闻花香。盘坐冥思,直至灵感袭来。当你终于得到启发,便是动身写代码之时。


via: https://opensource.com/article/19/12/zen-python-flat-sparse

作者:Moshe Zadka 选题:lujun9972 译者:caiichenr 校对:wxy

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