coLinux日記

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

SimplePrograms で Python を学ぶ その05

2024-03-31 09:00:55 | Python
SimplePrograms - Python Wiki
https://wiki.python.org/moin/SimplePrograms

の 5番目のプログラムは、関数定義です。

def greet(name):
print ('Hello', name)

greet('Jack')
greet('Jill')
greet('Bob')


最初の2行が関数定義で、残りの3行が関数の実行例ですね。実行結果は次の通りです。(例によって、インデントがある前提でご覧下さい。)
>>> def greet(name):
... print('Hello', name)
...
>>> greet('Jack')
Hello Jack
>>> greet('Jill')
Hello Jill
>>> greet('Bob')
Hello Bob
>>>

関数定義は、関数名と引数を決めて、その引数を使って実際の関数の動きを指定する、のが一般的だと思います。と、言うことで

def 関数名(引数1,引数2....):

が Python での関数定義ですね。最後が 「:」 で終わるのは for や while と一緒ですね。ループの例と同じくインデントが続く限り関数の中身(動きを指定する部分)でしょう。
外から関数に値が引数に渡され、関数の中身に引数の名前を使うとこの値が使えるわけです。

試して見ましょう。二つの引数を指定した例を試します。

>>> def abc(f, g):
...      print(f)
...      print(g)
...
>>> abc(1,2)
1
2
>>>

考えずに複数引数定義を試みましたが、やはり複数の引数の分離はカンマでした。
関数のもう一つの重要機能である出力方法はこの段階ではまだ出てきていません。

ちなみに、Python では、入力した行の履歴を覚えているので、矢印キーで簡単に再現できます。この履歴は Python を終了してもう一度 Python を動かしても有効なので、複数行の関数定義を試すときに活用できます。これは便利ですね
コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

SimplePrograms で Python を学ぶ その04

2024-03-23 09:31:48 | Python
SimplePrograms - Python Wiki
https://wiki.python.org/moin/SimplePrograms

の 4番目のプログラムは、

parents, babies = (1, 1)
while babies < 100:
print ('This generation has {0} babies'.format(babies))
parents, babies = (babies, parents + babies)


1行目の右側がタプルですので、これはタプルの代入に関する例ですね。試して見ましょう。
Pythonでは、"#"文字の後ろがコメント扱いだそうで、これを利用してみました。

>>> a = (1,2)   # タプルをそのまま変数に代入できる。
>>> print(a)
(1, 2) 
>>> b,c = a     # タプルの各要素の値ををそれぞれ変数に代入できる
>>> print(b)
1
>>> print(c)
2
>>>

つまりタプルを変数に代入するときに、= の前にタプルの要素分の変数をカンマで区切って指定することができ、各変数にタプルのそれぞれの要素が代入されるようです。

2行目以降は forに代わる while ループを表すようで、while文と呼ぶようです。
https://docs.python.org/ja/3/reference/compound_stmts.html#while

while ループと言えば、その後は条件で、その条件を満たす間はループを繰り返すのが一般的ですが、pythonの場合も同様ですね。
条件の終わりは for と同様に 「:」 で示すようです。条件は一般的な表記と同じで babies が 100 より小さい場合はループを継続する、です。ループの中身がインデントする点は、forループと同じですね。

3行目の print()は、formatメソッドを利用していますが、置換フィールドとして数値を指定する例ですね。

おそらく複数の数値が使えて、formatメソッドの中のカンマで区切ったものの値に対応すると思われます。今回は babies の値だけなので {0} ですね。先頭が0番なのが python の標準のようです。

4行目もタプルを変数に代入する例で、今回のタプルはその場で作成しています。

babies と parents + babies の計算結果でタプルを新たに作成し、それを parents と babies に代入するということです。当然前の値はここで廃棄されるわけです。それで babies の値がどんどん増えるわけです。

実行結果はこんなかんじです。(例によって、while文の中のインデントはうまく表示されない可能性があるので、インデントがある前提でご覧下さい。)

>>> parents, babies = (1, 1)
>>> while babies < 100:
... print ('This generation has {0} babies'.format(babies))
... parents, babies = (babies, parents + babies)
...
This generation has 1 babies
This generation has 2 babies
This generation has 3 babies
This generation has 5 babies
This generation has 8 babies
This generation has 13 babies
This generation has 21 babies
This generation has 34 babies
This generation has 55 babies
This generation has 89 babies
>>>

つまりフィボナッチ数列の第2項目から11項目までです。
コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

SimplePrograms で Python を学ぶ その03

2024-03-15 08:46:37 | Python
SimplePrograms - Python Wiki
https://wiki.python.org/moin/SimplePrograms

の 3番目のプログラムは、

friends = ['john', 'pat', 'gary', 'michael']
for i, name in enumerate(friends):
print ("iteration {iteration} is {name}".format(iteration=i, name=name))


です。最後の行は表示で折り曲げられていたとしても、長い1行です。

3行なのでプログラムらしくなって来ました。1行目は形から配列ですね。多くの言語のように配列名の後に"[" と "]" があり、各要素を "," で分けるのですね。

説明文からfor によるループ表現と、enumerate() というビルトイン関数と、"%"とは別のフォーマットの方法がわかるようです。早速実行してみましょう。長い行は折れ曲がっているように見えますが1行です。

>>> friends = ['john', 'pat', 'gary', 'michael']
>>> for i, name in enumerate(friends):
... print ("iteration {iteration} is {name}".format(iteration=i, name=name))
...
iteration 0 is john
iteration 1 is pat
iteration 2 is gary
iteration 3 is michael
>>>

ここで各行のインデントが for ループの中を表すことが分かります。ループの中のプロンプトが "..." に変わるので、インデントしている行が続く限りループの中にあることになるようです。(インデントされていないように見える場合はインデントがあるという前提でご覧下さい。)ちなみに、... の後にインデントのない行を入れると

IndentationError: expected an indented block

のエラーになります。

問題は、for の後の、

i, name in enumerate(friends):

です。 まず Python では for の終わりに":"を付けるようです。よくある言語のように、 in の後ろのものから一つデータを生成して、in の前のものに代入するようです。in の前に ',' で分けた2つの変数に代入しているようですが、流石に類推は困難です。ここは、

The Python Language Reference
https://docs.python.org/3/reference/

を参照することにします。ちなみに、日本語ページはこちらです。(今はブラウザから適時翻訳できるので、そちらも活用できますね。)

https://docs.python.org/ja/3/reference/

リファレンスマニュアルで重要なのは索引ですが、右上の検索窓でも検索できます。

「enumerate(iterable,start=0)
enumerate オブジェクトを返します。 iterable は、シーケンスか iterator か、あるいはイテレーションをサポートするその他のオブジェクトでなければなりません。 enumerate() によって返されたイテレータの __next__() メソッドは、 (デフォルトでは 0 となる start からの) カウントと、 iterable 上のイテレーションによって得られた値を含むタプルを返します。」


と言うわけで、enumerate()関数は0から始まるカウンターとそれに対応するfriendsの要素の値を「タプル」(tuple)というペアにして返すようです。最初のカウンターは、friendsの何番目の要素かを示す値ですね。つまりループするたびに、enumerate()は、
0 , john
1 , pat
.....
のようにタプルを返す?わけです。返されたタプルの2つの値をそれぞれ i , name に代入して、friendsの全要素終了するまでループするのがこの記述ですね。

このenumerate()ですが、
>>> a,b = enumerate(friends,start=1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: too many values to unpack (expected 2)
のような代入はできず。以下のように1つの変数には代入できます。
>>> a = enumerate(friends,start=0)

しかし、aの値は、
>>> print(a)
<enumerate object at 0x768749e0>
>>>
となるので、そのため a,b = のような代入ができなかったようです。当面は for の中で使うだけにしておいたほうが良さそうです。

ループの中の print()ですが、% の代わりに文字列の後ろに.format()が付加されています。「.」で繋ぐこういう形式はオブジェクトに対するメソッドとなることがよくあるものですが、python でも formatメソッドと言うそうです。

オブジェクトにあたる文字列は「置換フィールド」を含む文字列だそうで、{iteration} と {name} が置換フィールドに「キーワード」を指定した場合です。このキーワードの値は、formatメソッドのなかで、
キーワード=値
の形式で指定できるようです。ですから、
.format(iteration=i, name=name)
で、キーワードiterationの値を変数iの値に、キーワードnameの値を変数nameの値に指定するということのようです。
キーワードの値は文字列の指定場所に埋め込まれて、print()がその文字列を表示するわけですね。

formatメソッドは、他にも色々できそうなので今後に期待します。

また、
https://docs.python.org/ja/3/reference/compound_stmts.html#for
によると、「for文」と呼ぶのですね。

今後はプログラムからの推定が難しくなりそうなので、リファレンスを参考にすることになりそうです。
コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

SimplePrograms で Python を学ぶ その02

2024-03-09 21:43:30 | Python
SimplePrograms - Python Wiki
https://wiki.python.org/moin/SimplePrograms

の 2番目のプログラムは、

name = input('What is your name?\n')
print ('Hi, %s.' % name)

です。

 ここは、1行づつ実行してみます。

>>> name = input('What is your name?\n')
What is your name?
Espiya       (Espiyaと入力しました。)
>>> print ('Hi, %s.' % name)
Hi, Espiya.
>>>

 多くのプログラミング言語では、「 = 」は変数への代入を表します。Python でも同じですね。つまり name は変数を表します。代入する値は、input()の出力です。この行を実行すると、関数 input() の引数の文字列が標準出力から表示され、入力待ちになります。ここで「Espiya」と入力すると、この入力した文字列がinput()の出力となり、nameに代入されるわけです。

 次の行のprint()関数の引数が、

%s を含んだ文字列 % 変数

となっています。

 その形状から「 % 」は演算子と思われますが、左の文字列に %s が含まれているので、右側の変数の値を %s の位置に埋め込む演算子であることが、print()の表示から確認できます。早速 Hello, world! のプログラムが使われおり、1番目のプログラムの重要性が分かります。%s があれば、整数を埋め込む %d や小数を表す %f がありそうですので試して見ます。

 まず変数への代入を使って変数a に数字を代入します。
>>> a = 1.234
>>> print(a)
1.234
>>>
print()の引数に変数を入れるとそのまま表示されますね。(空白文字の連続は正しく表示されない可能性があります。実際の Python で確かめて下さい。)

>>> print('a is %d .' % a)
a is 1 .
>>> print('a is %f .' % a)
a is 1.234000 .
>>> print('a is %.3f .' % a)
a is 1.234 .
>>> print('a is %10.3f .' % a)
a is 1.234 .
>>>

 予想通り、C言語で言うところのフォーマット指定子が使えそうです。%f の.3 は小数点以下3桁表示で、%10.3f は10文字の中に右詰めで小数点以下3桁表示の数字を入れる事ですね。

 ところで、print()の「出力」としないで「表示」としたのは、print()を実行しても通常の関数とは異なり出力があってその値を変数に代入できないからです。いい加減ですが、一応切り分けて書いています。

 例えば、

>>> print( 'a is %f .' % a )
a is 1.234000 .
>>> b = print( 'a is %f .' % a )
a is 1.234000 .
>>> print( b )
None
>>>

のように print() の出力を bに代入しても、bの値は 「None」です。
コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

SimplePrograms で Python を学ぶ その01

2024-03-02 21:55:47 | Python
今回から、Raspberry Pi を使って Python を学ぼうと思います。と、言っても入門等は多数のサイトがあるので、別の方法を探ってみます。

そこで目を付けたのは、Python の公式サイト、

https://www.python.org/

です。ここの、「Documentation」のサブメニュー「Beginner's Guide」をクリックして、そこの「Learning Python」にあるプログラム経験者用の「BeginnersGuide/Programmers」をクリックして、「BeginnersGuide/Overview」を見ると、「SimplePrograms」という短いサンプルプログラムをまとめたものがありました。

SimplePrograms - Python Wiki
https://wiki.python.org/moin/SimplePrograms

見ると、1行から、2行、3行、・・・と順番にプログラムの行数が増えて、複雑になるようにまとめられています。段々複雑になるそうで初心者向けサンプルプログラム集としてとても凝っています。

最後の方は難しそうなのでどうなるか分かりませんが、今回はこれを使って実際に Python を学んで見たいと思います。

一つ一つのプログラムは、実際に Raspberry Pi の python3 で1行づつ実行して、確かめて理解を深めます。いちから文法を見てというのはやらないで、その他のプログラミング言語からの類推で個々のサンプルプログラムを試して、確認を取るやり方で行います。

まずは、python3 を起動してみます。(Raspbian 12 の標準のものです。)

$ python3
Python 3.11.2 (main, Mar 13 2023, 12:18:29) [GCC 12.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>

バージョンは 3.11.2 でやや古いですがそのまま利用します。

「>>>」 がプログラムの各行の入力待ちのプロンプトですね。

標準入力待ちですので、Ctrl-D で終了できます。その他に、

>>> quit()
$

のように終了できます。python はインタープリタですから1行づつ入力しても動作するはずです。
早速 Python を学んでみましょう。

「SimplePrograms」の 1番目のプログラムは、

print ('Hello, world!')

です。早速実行してみます。

>>> print ('Hello, world!')
Hello, world!
>>>

いわゆる Hello, world! を表示するプログラムですが、このプログラムは極めて重要です。
プログラミング言語を習得する場合、その結果がどのようになるかを表示する必要があり、それはすなわち Hello, world! の変形で実現するからです。早速見てみますと、Python のいくつかの特徴がわかります。

1) print という関数を使って表示(標準出力への出力)を行う。
  関数は高校数学で y=f(x) のように表記するので、関数名とカッコで表し、カッコ内に関数に渡す引数を指定するのが一般的です。というわけで、この表記から python3 では print の命令文みたいなものは無く、関数で指示を行うと考えられます。つまりカッコの中は、引数であると考えてよさそうです。
 そこで、print という関数を表すために、print() と書くことにします。

2) print() に引数を指定するとそのまま表示される。
  引数が複数の場合はどうなるかは今後分かるでしょう。

3) 文字列は 'Hello, world!' のように「 ' 」文字で囲む。
  現在のプログラミング言語で、数値、文字列という概念は必須だと思うのでここで文字列の表記方法が分かりました。

4) 1行の終わりに何も無い。
  となると、長い行はどうなるのか興味深いです。

 ここで試しに、print()の前に空白文字をいれるとエラーになります。

>>> print( 'Hello, world!' )
File "<stdin>", line 1
print( 'Hello, world!' )
IndentationError: unexpected indent
>>>

 つまり、行の先頭の空白(インデント)に意味があるようです。

 おまけで、print と 「(」 文字の間の空白は無視されるようです。
>>> print ('Hello, world!')
Hello, world!
>>>
 分かりにくいので通常はそうしませんが。

 まだ、1番目なので簡単ですが、早速色々な事が分かったつもりになりました。今後、途切れないようにしたいと思います。
コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする