What is expected from a scripting language:
- can work with files (read/write csv/yaml/json)
- can work with the network (send an http request)
- make some kind of logic
- does not require environment installation and compilation
- all in one file
BASH satisfies all of this, but it has its own problems.:
- It’s hard to read
- It’s hard to debug
- It’s hard to write nontrivial logic
It would seem that Python allows you to solve all these problems, but very quickly you want to install some packages on Python.
How can I make it more comfortable?
- We put `poetry'.
- Create a folder for the script:
mkdir my-script-1
- Initialize poetry there:
cd my-script-1 && poetry init'. Or take the ready-made file
myproject.toml`:
[tool.poetry]
package-mode = false
[tool.poetry.dependencies]
python = "^3.12"
pandas = "^2.2.1"
requests = "^2.31.0"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
- Create a file for our script: `touch main.py && chmod +x main.py '
- Download the dependencies:
poetry install --no-root' (or just
poetry installif the
package-mode=false` property is set) - Go into the virtual environment (from there already you can run the script):
poetry shell
, or directly runpoetry ru ./main.py
The script itself (just a starting example):
#!/usr/bin/env python3
# https://docs.python.org/3/library/dataclasses.html
from dataclasses import dataclass
# https://pandas.pydata.org/
import pandas as pd
# https://requests.readthedocs.io/en/latest/
import requests
from numpy import ndarray
@dataclass
class DocTags:
id: str
tags: [str]
def parse_line(values: ndarray) -> [DocTags]:
assert values.size == 2
doc_id: str = values[0]
tags_str: str = values[1]
tags = list(map(str.strip, tags_str.split(",")))
return DocTags(doc_id, tags)
def read_file(filename: str) -> [DocTags]:
data = pd.read_csv(filename, sep="\t", header=None)
return list(map(parse_line, data.values))
def main():
docs = read_file("example.tsv")
for doc in docs:
with open(f"out/{doc.id}.txt", 'w') as file:
file.write(str(doc) + "\n")
response = requests.put(f"https://httpbin.org/anything/{doc.id}", json=doc.tags)
file.write(f"status_code={response.status_code} json={response.text}\n")
if __name__ == '__main__':
main()
Естественно, это все открывается в PyCharm: там можно запускать и вставать в отладку.
В итоге, все-таки есть дополнительные шаги, но их не так уж и много.
PS. Домашнее задание: написать то же, но на чистом BASH. У меня получилось 22 строчки, но сложно читаемых и не поддерживаемых. Впрочем, для скриптов это не особо надо. Тем не менее, это заставило задуматься почему изначально все-таки выбрал BASH, а не Python.
PPS. Домашнее задание 2: переписать скрипт так, чтобы внешние библиотеки (pandas
и requests
не требовались – по идее это должно быть просто). Решение, если писать не хочется.
PPPS. Можно еще то же самое посмотреть на Kotlin (link1, link2), Ruby и других языках.