Dsq: 用于针对JSON、CSV、Excel、Parquet等运行SQL查询的命令行工具

news2025/1/11 8:46:58

目录

About

Install

macOS Homebrew

macOS、Linux和WSL上的二进制文件

Windows上的二进制文件(非WSL)

从源代码生成和安装

Usage

Pretty print

dsq的管道数据

多个文件和连接

无需查询即可将数据转换为JSON

嵌套在对象中的对象数组

嵌套对象值

Nested arrays

REGEXP

Standard Library

输出列顺序

转储推断架构

Caching

Interactive REPL

转换CSV和TSV文件中的数字

Supported Data Types

Engine

Comparisons

Benchmark

Notes


About

这是DataStation(GUI)的CLI配套工具,用于对数据文件运行SQL查询。因此,如果您想要这个GUI版本,请查看DataStation。

Install

每个版本都提供了amd64(x86_64)的二进制文件。

macOS Homebrew

dsq在macOS Homebrew上可用:

$ brew install dsq

macOS、Linux和WSL上的二进制文件

在macOS、Linux和WSL上,您可以运行以下操作:

$ curl -LO "https://github.com/multiprocessio/dsq/releases/download/0.20.2/dsq-$(uname -s | awk '{ print tolower($0) }')-x64-0.20.2.zip"
$ unzip dsq-*-0.20.2.zip
$ sudo mv dsq /usr/local/bin/dsq

或者从发布页面手动安装,解压并将dsq添加到$PATH

Windows上的二进制文件(非WSL)

下载最新的Windows版本,解压它,并将dsq添加到$PATH

从源代码生成和安装

如果您在另一个平台或架构上,或者想要获取最新版本,可以使用Go1.18+:

$ go install github.com/multiprocessio/dsq@latest

dsq可能会在Go移植到的其他平台上工作,如AARC64和OpenBSD,但测试和构建仅在x86_64 Windows/Linux/macOS上运行。

Usage

您可以将数据管道传输到dsq,也可以将文件名传递给它。注意:管道数据在Windows上不起作用。

如果要传递文件,则其内容类型必须具有通常的扩展名。

For example:

$ dsq testdata.json "SELECT * FROM {} WHERE x > 10"

Or:

$ dsq testdata.ndjson "SELECT name, AVG(time) FROM {} GROUP BY name ORDER BY AVG(time) DESC"

Pretty print

默认情况下dsq打印丑陋的JSON。这是最有效的模式。

$ dsq testdata/userdata.parquet 'select count(*) from {}'
[{"count(*)":1000}
]

如果您想要更漂亮的JSON,可以通过管道dsqjq

$ dsq testdata/userdata.parquet 'select count(*) from {}' | jq
[
  {
    "count(*)": 1000
  }
]

或者,您可以使用-p--pretty中的dsq启用漂亮打印,这将在ASCII表中显示您的结果。

$ dsq --pretty testdata/userdata.parquet 'select count(*) from {}'
+----------+
| count(*) |
+----------+
|     1000 |
+----------+

dsq的管道数据

当将数据传输到dsq时,需要设置-s标志并指定文件扩展名或MIME类型。

For example:

$ cat testdata.csv | dsq -s csv "SELECT * FROM {} LIMIT 1"

Or:

$ cat testdata.parquet | dsq -s parquet "SELECT COUNT(1) FROM {}"

多个文件和连接

您可以将多个文件传递给DSQ。只要支持有效格式的数据文件,就可以对所有文件作为表运行SQL。每个表都可以通过字符串{N}访问,其中N是命令行上传递的文件列表中文件的0-based索引。

例如,这连接了两个不同来源类型的数据集(CSV和JSON)。

$ dsq testdata/join/users.csv testdata/join/ages.json \
  "select {0}.name, {1}.age from {0} join {1} on {0}.id = {1}.id"
[{"age":88,"name":"Ted"},
{"age":56,"name":"Marjory"},
{"age":33,"name":"Micah"}]

由于dsq使用标准SQL,您还可以提供file-table-names别名:

$ dsq testdata/join/users.csv testdata/join/ages.json \
  "select u.name, a.age from {0} u join {1} a on u.id = a.id"
[{"age":88,"name":"Ted"},
{"age":56,"name":"Marjory"},
{"age":33,"name":"Micah"}]

无需查询即可将数据转换为JSON

作为dsq testdata.csv "SELECT * FROM {}"将支持的文件类型转换为JSON的缩写,您可以跳过查询,转换后的JSON将转储到stdout。

For example:

$ dsq testdata.csv
[{...some csv data...},{...some csv data...},...]

嵌套在对象中的对象数组

DataStation和dsq的SQL集成在对象数组上运行。如果对象数组恰好位于top-level,则无需执行任何操作。但是,如果数组数据嵌套在对象中,则可以向表引用添加“路径”参数。

例如,如果您有以下数据:

$ cat api-results.json
{
  "data": {
    "data": [
      {"id": 1, "name": "Corah"},
      {"id": 3, "name": "Minh"}
    ]
  },
  "total": 2
}

您需要告诉dsq数组数据的路径是"data.data"

$ dsq --pretty api-results.json 'SELECT * FROM {0, "data.data"} ORDER BY id DESC'
+----+-------+
| id | name  |
+----+-------+
|  3 | Minh  |
|  1 | Corah |
+----+-------+

如果只有一个表,也可以使用速记{"path"}{'path'}

$ dsq --pretty api-results.json 'SELECT * FROM {"data.data"} ORDER BY id DESC'
+----+-------+
| id | name  |
+----+-------+
|  3 | Minh  |
|  1 | Corah |
+----+-------+

可以对路径使用单引号或双引号。

多张Excel工作表

包含多个工作表的Excel文件存储为一个对象,键为工作表名称,值为作为对象数组的工作表数据。

如果您有一个Excel文件,其中包含两个名为Sheet1Sheet2的工作表,则可以在第二个工作表上运行dsq,方法是将工作表名称指定为路径:

$ dsq data.xlsx 'SELECT COUNT(1) FROM {"Sheet2"}'

限制:嵌套数组

不能指定通过数组的路径,只能指定对象。

嵌套对象值

举个例子最简单。假设您有以下名为user_addresses.json的JSON文件:

$ cat user_addresses.json
[
  {"name": "Agarrah", "location": {"city": "Toronto", "address": { "number": 1002 }}},
  {"name": "Minoara", "location": {"city": "Mexico City", "address": { "number": 19 }}},
  {"name": "Fontoon", "location": {"city": "New London", "address": { "number": 12 }}}
]

可以按如下方式查询嵌套字段:

$ dsq user_addresses.json 'SELECT name, "location.city" FROM {}'

如果需要消除表格的歧义:

$ dsq user_addresses.json 'SELECT name, {}."location.city" FROM {}'

Caveat: PowerShell, CMD.exe

在PowerShell和CMD.exe上,必须用反斜杠转义内部双引号:

> dsq user_addresses.json 'select name, \"location.city\" from {}'
[{"location.city":"Toronto","name":"Agarrah"},
{"location.city":"Mexico City","name":"Minoara"},
{"location.city":"New London","name":"Fontoon"}]

解释了嵌套对象

嵌套对象被折叠,它们的新列名成为.连接的值的JSON路径。路径中的实际点必须用反斜杠转义。因为.在SQL中是一个特殊字符,所以必须引用整个新列名。

限制:整个对象检索

您无法查询整个对象,必须请求生成标量值的特定路径。

例如,在上面的user_addresses.json示例中,您不能这样做:

$ dsq user_addresses.json 'SELECT name, {}."location" FROM {}'

因为location不是标量值。它是一个物体。

Nested arrays

嵌套数组存储在SQLite中时会转换为JSON字符串。由于SQLite支持查询JSON字符串,您可以将该数据作为结构化数据访问,即使它是一个字符串。

如果在fields.json中有这样的数据:

[
  {"field1": [1]},
  {"field1": [2]},
]

您可以请求整个字段:

$ dsq fields.json "SELECT field1 FROM {}" | jq
[
  {
    "field1": "[1]"
  },
  {
    "field1": "[2]",
  }
]

JSON operators

可以使用SQL JSON运算符获取数组中的第一个值。

$ dsq fields.json "SELECT field1->0 FROM {}" | jq
[
  {
    "field1->0": "1"
  },
  {
    "field1->0": "2"
  }
]

REGEXP

由于DataStation和dsq构建在SQLite上,因此可以使用x REGEXP 'y'进行过滤,其中x是某个列或值,y是REGEXP字符串。SQLite不选择regexp实现。DataStation和dsq使用Go的regexp实现,这比PCRE2更为有限,因为Go对PCRE2的支持还不是很成熟。

$ dsq user_addresses.json "SELECT * FROM {} WHERE name REGEXP 'A.*'"
[{"location.address.number":1002,"location.city":"Toronto","name":"Agarrah"}]

Standard Library

dsq注册go-sqlite3-stdlib,因此您可以访问许多不属于SQLite基的统计信息、url、数学、字符串和regexp函数。

查看所有可用扩展功能的项目文档。

输出列顺序

当发出JSON(即没有--pretty标志)时,对象内的键是无序的。

如果顺序对你很重要,你可以用jq过滤:dsq x.csv 'SELECT a, b FROM {}' | jq --sort-keys

使用--pretty标志,列顺序完全按字母顺序排列。目前,顺序不可能依赖于SQL查询顺序。

转储推断架构

对于任何受支持的文件,您都可以转储推断出的模式,而不是转储数据或运行SQL查询。为此,设置--schema标志。

推断的模式非常简单,只支持JSON类型。如果底层格式(如Parquet)支持finer-grained数据类型(如int64),则这不会显示在推断的模式中。它将显示为number

For example:

$ dsq testdata/avro/test_data.avro --schema --pretty
Array of
  Object of
    birthdate of
      string
    cc of
      Varied of
        Object of
          long of
            number or
        Unknown
    comments of
      string
    country of
      string
    email of
      string
    first_name of
      string
    gender of
      string
    id of
      number
    ip_address of
      string
    last_name of
      string
    registration_dttm of
      string
    salary of
      Varied of
        Object of
          double of
            number or
        Unknown
    title of
      string

通过在设置--schema标志时省略--pretty标志,可以将其打印为结构化JSON字符串。

Caching

有时,您希望对不经常更改的数据集进行一些探索。通过打开--cache-C标志,DataStation将把导入的数据存储在磁盘上,而不会在运行结束时删除它。

启用缓存后,DataStation将计算您指定的所有文件的SHA1总和。如果总和发生变化,则它将重新导入所有文件。否则,当运行带有缓存标志的其他查询时,将重用该现有数据库,而不会重新导入文件。

由于DataStation上没有缓存时使用in-memory数据库,因此打开缓存时的初始查询可能比关闭缓存时稍长。不过,后续查询将大大加快(对于大型数据集)。

例如,在此查询上使用缓存的第一次运行可能需要30秒:

$ dsq some-large-file.json --cache 'SELECT COUNT(1) FROM {}'

但是,当您运行另一个查询时,可能只需要1s。

$ dsq some-large-file.json --cache 'SELECT SUM(age) FROM {}'

不是因为我们缓存了任何结果,而是因为我们缓存了将文件导入SQLite的过程。

因此,即使您更改了查询,只要文件没有更改,缓存也是有效的。

为了使其永久化,您可以在您的环境中导出DSQ_CACHE=true

Interactive REPL

使用-i--interactive标志输入交互式REPL,您可以在其中运行多个SQL查询。

$ dsq some-large-file.json -i
dsq> SELECT COUNT(1) FROM {};
+----------+
| COUNT(1) |
+----------+
|     1000 |
+----------+
(1 row)
dsq> SELECT * FROM {} WHERE NAME = 'Kevin';
(0 rows)

转换CSV和TSV文件中的数字

CSV和TSV文件不允许指定其中包含的单个值的类型。默认情况下,所有值都被视为字符串。

这可能导致查询中出现意外结果。考虑以下示例:

$ cat scores.csv
name,score
Fritz,90
Rainer,95.2
Fountainer,100

$ dsq scores.csv "SELECT * FROM {} ORDER BY score"
[{"name":"Fountainer","score":"100"},
{"name":"Fritz","score":"90"},
{"name":"Rainer","score":"95.2"}]

注意score列仅包含数值。不过,按该列排序会产生意外的结果,因为这些值被视为字符串,并按词汇进行排序。(可以看出,单个分数作为字符串导入,因为它们在JSONresult.中被引用)

使用-n--convert-numbers标志auto-detect并转换导入文件中的数值(整数和浮点):

$ dsq ~/scores.csv --convert-numbers "SELECT * FROM {} ORDER BY score"
[{"name":"Fritz","score":90},
{"name":"Rainer","score":95.2},
{"name":"Fountainer","score":100}]

注意现在分数是如何作为数字导入的,以及结果集中的记录是如何按其数值排序的。还请注意,JSON结果中不再引用单个分数。

为了使其永久化,您可以在您的环境中导出DSQ_CONVERT_NUMBERS=true。启用此选项将禁用某些优化。

Supported Data Types

NameFile Extension(s)Mime TypeNotes
CSVcsvtext/csv
TSVtsvtabtext/tab-separated-values
JSONjsonapplication/json必须是对象数组或对象数组的路径。
Newline-delimited JSONndjsonjsonlapplication/jsonlines
Concatenated JSONcjsonapplication/jsonconcat
ORCorcorc
Parquetparquetparquet
Avroavroapplication/avro
YAMLyamlymlapplication/yaml
Excelxlsxxlsapplication/vnd.ms-excel如果有多张图纸,则必须指定图纸路径。
ODSodsapplication/vnd.oasis.opendocument.spreadsheet如果有多张图纸,则必须指定图纸路径。
Apache Error LogsNAtext/apache2error当前仅在管道中工作。
Apache Access LogsNAtext/apache2access当前仅在管道中工作。
Nginx Access LogsNAtext/nginxaccess当前仅在管道中工作。
LogFmt LogsNAtext/logfmt当前仅在管道中工作。

Engine

在后台,dsq使用DataStation作为库,在后台,DataStation使用SQLite支持对任意(结构化)数据的此类SQL查询。

Comparisons

NameLinkCachingEngineSupported File TypesBinary Size
dsqHereYesSQLiteCSV、TSV、JSON的一些变体、拼花地板、Excel、ODS(OpenOffice Calc)、ORC、Avro、YAML、日志49M
qhttp://harelba.github.io/q/YesSQLiteCSV, TSV82M
textqlhttps://github.com/dinedal/textqlNoSQLiteCSV, TSV7.3M
octoqlhttps://github.com/cube2222/octosqlNoCustom engineJSON, CSV, Excel, Parquet18M
csvqhttps://github.com/mithrandie/csvqNoCustom engineCSV15M
sqlite-utilshttps://github.com/simonw/sqlite-utilsNoSQLiteCSV, TSV不适用,不是一个二进制文件
trdsqlhttps://github.com/noborus/trdsqlNoSQLite、MySQL或PostgreSQLJSON、TSV、LTSV、TBLN、CSV的一些变体14M
spysqlhttps://github.com/dcmoura/spyqlNoCustom engineCSV, JSON, TEXT不适用,不是一个二进制文件
duckdbhttps://github.com/duckdb/duckdb?Custom engineCSV, Parquet35M

Not included:

  • clickhouse-local:这里列出的所有工具中速度最快的,但它太大了(超过2GB),不能合理地被认为是任何环境的好工具
  • sqlite3:需要多个命令来接收CSV,对于one-liners来说并不太好
  • datafusion-cli:非常快(仅比clickhouse-local慢),但需要多个命令来接收CSV,因此对于one-liners来说并不太好

Benchmark

该基准测试于2022年6月19日运行。它在OVH上的专用裸机实例上运行,具有:

  • 64 GB DDR4 ECC 2133 MHz
  • 软RAID中的2x450 GB SSD NVMe
  • 英特尔至强E3-1230v6-4c/8t-3.5GHz/3.9 GHz

它对well-known纽约黄色出租车出行数据集运行SELECT passenger_count, COUNT(*), AVG(total_amount) FROM taxi.csv GROUP BY passenger_count查询。具体来说,使用2021 4月份的CSV文件。这是一个200MB的CSV文件,大约有200万行,18列,大部分是数值。

脚本在这里。它是octosql开发人员运行的基准测试的一种修改。

ProgramVersionMean [s]Min [s]Max [s]Relative
dsq0.20.1(缓存打开)1.151 ± 0.0101.1311.1591.00
duckdb0.3.41.723 ± 0.0231.7081.7571.50 ± 0.02
octosql0.7.32.005 ± 0.0081.9912.0151.74 ± 0.02
q3.1.6(缓存打开)2.028 ± 0.0102.0212.0551.76 ± 0.02
sqlite3 *3.36.04.204 ± 0.0184.1774.2293.64 ± 0.04
trdsql0.10.012.972 ± 0.22512.55413.39211.27 ± 0.22
dsq0.20.1 (default)15.030 ± 0.08614.89515.14913.06 ± 0.13
textqlfca00ec19.148 ± 0.18318.86519.50016.63 ± 0.21
spyql0.6.016.985 ± 0.10516.85417.16114.75 ± 0.16
q3.1.6 (default)24.061 ± 0.09523.95424.22020.90 ± 0.20

*虽然dsq和q构建在sqlite3之上,但sqlite3中没有内置的方法来缓存摄取的文件,而无需编写脚本

Not included:

  • clickhouse-local:比任何一个都快,但超过2GB,因此不是合理的general-purposeCLI
  • datafusion-cli:只比clickhouse-local慢,但需要多个命令来接收CSV,不能执行one-liners
  • sqlite-utils:需要几分钟才能完成

Notes

OctoSQL、duckdb和SpyQL实现了自己的SQL引擎。dsq、q、trdsql和textql将数据复制到SQLite中,并依赖SQLite引擎执行查询。

实现自己的SQL引擎的工具在1)摄取和2)作用于数据子集(例如有限列或有限行)的查询方面可以做得更好。这些工具实现了SQL的ad-hoc子集,这些子集可能缺失或与您喜欢的语法不同。另一方面,依赖SQLite的工具具有提供well-tested和well-documentedSQL引擎的优势。DuckDB与众不同,因为它背后有一家专注的公司。

dsq在SQLite内置函数的基础上还附带了许多有用的函数(例如best-effort日期解析、URL解析/提取、统计函数等)。

转自项目内 README.md

multiprocessio/dsq: Commandline tool for running SQL queries against JSON, CSV, Excel, Parquet, and more. (github.com)icon-default.png?t=N3I4https://github.com/multiprocessio/dsq

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

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

相关文章

ASRock Z690 Extreme WiFi 6E i7 13700KF电脑 Hackintosh 黑苹果efi引导文件

原文来源于黑果魏叔官网,转载需注明出处。(下载请直接百度黑果魏叔) 硬件型号驱动情况 主板ASRock Z690 Extreme WiFi 6E 处理器Intel Core i7 13700KF已驱动 内存KINGBANK 2x32GB DDR4-3600CL18已驱动 硬盘Predator SSD GM7000 1TB已驱动…

qt5.15.2配置android

qt安装安卓编译器就直接跳过,我们开始将如何进行配置。 如果专门开发的app,则应该使用android进行开发,qt是熟悉qt语言,或者app需要进行跨平台的话则使用qt for android比较好。 下载 首先安装jdk,最好安装 jdk11&am…

[Java] Socket (UDP , TCP)

目录 什么是Socket ? TCP api 与 UDP api 的特点 : UDP api 使用UDP Socket 实现一个单词翻译 : TCP api 使用TCP协议来实现一个回显服务 什么是Socket ? 应用层和传输层之间的桥梁 . 程序猿写网络代码 (应用层) , 要想发送这个数据 , 就需要去调用下层协议 , 应用层…

uniapp图片转base64及JS各文件类型相互转换

uniapp图片转base64及JS各文件类型相互转换 1、chooseImage request arrayBufferToBase642、chooseImage getFileSystemManager3、chooseImage FileReader4、扩展-JS各文件类型相互转换4.1 File 转成 ArrayBuffer4.2 File 转成 blob4.3 File 转成 base644.4 ArrayBuffer 转…

【数据结构】前序遍历,中序遍历,后序遍历(二叉树)

一:给图求前序,中序,后序 前序遍历(先序遍历) 核心思想:根左右 前序序列:ABDEFCGH 先访问根结点A,打印A,然后访问左子树,此时左子树B又作为根节点&#xf…

JAVAWeb05-xml、DOM4J

1. xml概述 1.1 官方文档 地址: https://www.w3school.com.cn/xml/index.asp 1.2 为什么需要 XML 需求 1 : 两个程序间进行数据通信?需求 2 : 给一台服务器,做一个配置文件,当服务器程序启动时,去读取它应当监听的端口号、还有…

【数字人】使用Metahuman创建数字人模型(上)

这两年数字人类的概念可谓是风头正盛,市面上也流行起各式各样的数字人技术,效果能力及实现成本各不相同。本系列介绍基于Unreal Engine的Metahuman工具低成本构建一个拥有完整的控制权、免费、可商用、高仿真的数字人。本篇为构建基础人物模型 MetaHuma…

PHP快速入门14-Composer包管理安装与使用,附常见的20个使用例子

文章目录 前言一、关于Composer二、如何安装Composer2.1 Windows安装Composer2.2 Linux安装Composer 三、Composer常见的20个使用例子3.1 查找并安装依赖包3.2 更新依赖包3.3 安装指定版本的依赖包3.4 卸载依赖包3.5 查看当前项目依赖包列表3.6 初始化composer.json文件3.7 安装…

FAT32文件系统学习

FAT32文件系统组成及介绍 FAT32文件系统结构图: 下图演示了FAT32文件系统的DBR: 1.DBR及其保留扇区:含义是DOS引导记录,也称为操作系统引导记录,在DBR之后往往有一些保留扇区 跳转指令:跳转指令本身占用2字…

python程序打包成可执行文件【进阶篇】

python程序打包成可执行文件【进阶篇】 提示:博主取舍了很多大佬的博文并亲测有效,分享笔记邀大家共同学习讨论 文章目录 python程序打包成可执行文件【进阶篇】[TOC](文章目录) 前言安装PyInstaller包打包深度学习模型生成spec文件修改spec文件运行spec文件进行打包执行exe可执…

为什么倒谱可以分析回声

一个有趣的现象:倒谱上的第一个峰,恰好对应回声相比原声的延时。回声 y y y 是原始声音 x x x 延迟 t 0 t_0 t0​ 秒后的、带有衰减 α α α 的副本 y α x ( t − t 0 ) y αx (t - t_0) yαx(t−t0​) 方便起见,这里取 α 1 α …

抖音强势入局服装生意,出手就是1个亿,服装实体店出路在哪?

最近,抖音盯上了服装生意。 据悉,抖音近期组建了一个自营服装团队,在APP推出了一家“飞云织上”的店铺,店铺主体公司是“上海歆湃信息科技有限公司”。 根据爱企查显示,这家公司由抖音集团(香港&#xff09…

RabbitMQ-消息模型

什么是MQ MQ全称是Message Queue,即消息对列!消息队列是典型的:生产者、消费者模型。生产者不断向消息队列中生产消息,消费者不断的从队列中获取消息。因为消息的生产和消费都是异步的,而且只关心消息的发送和接收,没…

IPV4与IPV6是什么?有什么区别?

目录 一. IPV4是什么? 二. IPV6是什么 三. IPv4和IPv6有什么区别? 1.地址类型 2.数据包大小 3.header区域字段数 4.可选字段 5.配置 6.安全性 7.与移动设备的兼容性 8.主要功能 IP协议(互联网协议)是互联网协议群&#…

USB TO SPI / USB TO I2C 软件概要 6--- 专业版调试器

所需设备: 1、USB转SPI_I2C适配器(专业版); 软件概述: SPI类: USB TO SPI 1.0-Slave SPI从机软件,适合单步调试,支持SPI工作模式0、1、2、3,自动跟随主机通讯速率,自动接收数据; USB TO S…

大城市的IT岗位,饱和了么?

现在学或即将更要学习IT专业的同学,经常会考虑这样一个问题:现在的计算机专业到处都有,大学里有、职业学校有,就连社会上的培训机构也有,而且专业分类更细化,有这么多的地方都在培训计算机相关专业&#xf…

二本4年测龄年仅25岁,五面阿里(定薪25K).....

体验了一下阿里的面试,不愧是大厂,考察范围既有深度也有宽度。努力回想了下面试的内容和自己当时的回答,这里给大家分享下自己的经验,也给自己做个归档,希望能给正在准备跳槽,找工作的朋友一点帮助&#xf…

每一个软件测试工程师都有要牢记的误区

最近跟一些刚刚进入软件测试行业的朋友去交流,发现了一个有趣的现象,就是对于这个行业的很多问题的认识都是一致的片面,当然也可以理解为误区。自己利用一点时间,把他们对于这个行业的认识误区都罗列出来,然后结合自己…

【Python从入门到进阶】16、文件的打开和关闭

接上篇《15、函数的定义和使用》 上一篇我们学习了Python中函数的定义和使用,包括函数的参数、返回值、局部变量和全景变量等操作。从本篇开始我们来开始学习Python对文件的一些操作,本篇我们主要讲解如何使用Python打开和关闭文件。 一、打开/创建文件…

全国青少年编程等级考试scratch四级真题2023年3月(含题库答题软件账号)

青少年编程等级考试scratch真题答题考试系统请点击 电子学会-全国青少年编程等级考试真题Scratch一级(2019年3月)在线答题_程序猿下山的博客-CSDN博客_小航答题助手 1.编写一段程序,从26个英文字母中,随机选出10个加入列表a。空白…