coLinux日記

coLinuxはフリーソフトを種として、よろずのシステムとぞなれりける。

SimplePrograms で Python を学ぶ + docstring 関連とPEPについて

2024-06-11 16:41:30 | Python
引き続き14番目のプログラムに関連した投稿をします。

前回使っていた LINE AI アシスタントは、3日使うと「有料」になったので、今後生成AIを使う時は Microsoft Copilot (1日30問無料)を使います。

「Python の入門時に docstring を使うことは非常に一般的であり、推奨されるベストプラクティスです。」
とお勧めされたので、 docstring の重要性からもう少し調べてみようと思いました。

前回の生成AIの回答の中で、「PEP 257]というドキュメントが言及されています。早速 PEP 257 を探すと、アブストラクトにあるように、Pythonのdocstringに関連するセマンティクスと規則のドキュメント、みたいです。
英文ですが、現在はブラウザが翻訳してくれるので、すべての入門者に優しくなっていますね。 
その文書の中で、PEP 8 を参考にしているみたいなのでそれも探してみると、表題が、

PEP 8 - Style Guide for Python Code

となっていて、入門者にとって重要な文書(しかも著者は Python の生みの親として知られる人!)でした。全然知りませんでした。

もしかして PEP って RFC みたいなものかと思い、Copilot に聞いてみました。

ここから -------
Q1:
python における PEP文書の位置付けを教えてください。もしかしてネットワーク技術におけるRFC文書と同じものですか?
A1:
PythonにおけるPEP(Python Enhancement Proposal)文書は、Pythonコミュニティによって提案され、議論され、採択されたPythonプログラミング言語の変更や新機能に関する設計文書です3。PEPはPythonの設計と開発プロセスの一部として使用され、新しい機能の提案や言語の改善を進めるための枠組みを提供します3。

一方で、RFC(Request For Comments)文書は、インターネット技術の標準化を行うIETF(Internet Engineering Task Force)が発行している技術仕様などについての文書群です?。これにはTCP/IP関連のプロトコルの標準仕様などが記されており、インターネット上で公開されています?。

つまり、PEPとRFCは似た役割を持っていますが、対象とする技術領域が異なります。PEPはPython言語の改善に特化しているのに対し、RFCはインターネット全般の技術標準に関するものです。どちらもその分野の開発者や研究者にとって重要なガイドラインとなっています。
----- ここまで

Pythonでは、PEP が重要なのですね。

PEP 8 は長い文書なのでここでは触れませんが、既に日本語訳も公開されています。その最初のところで PEP 20 という文章があることがわかりました。
https://peps.python.org/pep-0020/

早速 Copilot に聞いてみました。

ここから -------
Q2:
PEP20 にある19の格言を、Python初心者向けに分かりやすく解説してください。
A2:
もちろんです。PEP 20、別名「Pythonの禅」には、Pythonの設計哲学を表す19の格言があります。これらはPythonのコードがどのように書かれるべきか、そしてPythonコミュニティが価値を置く原則を示しています。ここでは、それぞれの格言を初心者向けに簡単に解説します。

1. **美しい方が醜いより良い** - コードは読みやすく、整理されているべきです。
2. **明示的な方が暗黙的なより良い** - コードは自己説明的であるべきで、その動作が明確であるべきです。
3. **単純な方が複雑なより良い** - シンプルな解決策を目指しましょう。
4. **複雑な方が複雑化したより良い** - 必要ならば複雑さを受け入れますが、無駄に複雑にしないでください。
5. **フラットな方がネストしたより良い** - 深いネストは避け、フラットな構造を目指しましょう。
6. **疎な方が密なより良い** - 情報は適度に配置し、過密状態を避けましょう。
7. **可読性は重要** - コードは他の人にとっても理解しやすいものであるべきです。
8. **特別な例外は特別扱いに値しない** - 一貫性を保ち、例外を作らないようにしましょう。
9. **実用性は純粋さに勝る** - 完璧を求めるよりも、実用的なコードを書きましょう。
10. **エラーは黙って通過させるな** - エラーは明確にし、適切に処理する必要があります。
11. **曖昧さに直面したら、推測する誘惑に負けるな** - 明確な解決策を見つけましょう。
12. **明白なやり方が一つあるべき** - ある問題に対しては、一つの明確な解決策があるはずです。
13. **今やる方が、やらないより良い** - 行動を起こしましょうが、急ぐ必要はありません。
14. **実装が説明しにくいなら、それは悪いアイデア** - シンプルで説明しやすいコードを書きましょう。
15. **名前空間は素晴らしいアイデア** - 名前空間を活用して、コードの整理をしましょう。

これらの格言は、Pythonのコードを書く際の指針となります。コードを書くときは、これらの原則を心に留めておくと良いでしょう。
----- ここまで

19 の格言のはずが、15しかないのは、いくつかの2つの格言を一つにして紹介しているからみたいです。
PEP 20 の最後の方に 「Easter Egg」として、

>>> import this

とあるので、実際にPythonで実行してみます。

>>> import this
he Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
>>>

やっぱり、Python は面白いですね。

こうして生成AIを使ってきたわけですが、 Python でののプログラム作成時に生成AIを使うと、Python言語入門者として技術が身につかない可能性があります。
しかし、今回 SimplePrograms の14番目で出てきた docstring はどうでしょう。
自分でプログラムを作って、そこに説明を入れるのは入門者には難しいと感じて、ついついそこを素通りしていつの間にか作成したプログラムに説明をいれるのを怠ってしまいがちになることが考えられます。Pythonではdocstring が用意されているので、なれないうちはとりあえず生成AIに docstring を作ってもらった方が良いのでは、と感じました。

そこで、SimpleProgramsの 18番目のプログラム内の関数 under_attack() の docstring を Copilot に作ってもらいましょう。

ここから -------
Q3:
次の Python で書かれた関数 under_attack()のために、最適な docstring を作成してください。
def under_attack(col, queens):
    left = right = col
    for r, c in reversed(queens):
       left, right = left - 1, right + 1

    if c in (left, col, right):
       return True
    return False


A3:
もちろんです!以下に、`under_attack` 関数のための適切なドックストリングを提供します。

```python
def under_attack(col, queens):
    """
    Checks if placing a queen in the specified column (`col`) would result in an attack
    from any of the previously placed queens (`queens`).

    Args:
       col (int): The column index where the new queen is to be placed.
       queens (list): A list of (row, column) tuples representing the positions of
          previously placed queens.

    Returns:
       bool: True if the new queen would be under attack, False otherwise.
    """

    left = right = col
    for r, c in reversed(queens):
       left, right = left - 1, right + 1

       if c in (left, col, right):
          return True
    return False
```

このドックストリングは、関数の目的、引数、および戻り値を明確に説明しています。関数を使用する際に参考にしてくださいね!ーーーーーーーーーーーーー
----- ここまで

だいたい狙い通りですね。

英語しか出てこないと思う場合は、DeepL とかを使って翻訳してから、最後に自分なりに直すというのが良いかもしれません。
参考までにDeepLの翻訳例を示します。

    指定された列(`col`)にクイーンを置くことで、それまでに置かれたクイーン(`queens`)のいずれかが攻撃されるかどうかをチェックする。
    引数:
       col (int): 新女王が配置される列のインデックス
       queens (list): 以前に配置されたクイーンの位置を表す(row, column)タプルのリスト。
    戻り値:
       新女王が攻撃を受けていれば真、そうでなければ偽。

質問では 8 クイーンでの関数とは書いていないのですが、検索結果から Copilot が判断したようです。

この回答では、doctest 用の部分がないみたいなので、それはまた別の質問方法が必要そうです。

Python入門時に、
Pythonプログラムで関数やクラスを作成するとき、とりあえず生成AIを使って docstring を追加しておこう。
という流れになっているのか気になります。
コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする