Skip to content

Instantly share code, notes, and snippets.

@takatakamanbou
Created October 19, 2020 04:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save takatakamanbou/a0d57c759a4439a4566dcb22a68f3b08 to your computer and use it in GitHub Desktop.
Save takatakamanbou/a0d57c759a4439a4566dcb22a68f3b08 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# AProg2020 ex05 Notebook その1\n",
"\n",
"AProgのページ https://www-tlab.math.ryukoku.ac.jp/wiki/?AProg/2020"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"----\n",
"## 繰り返し処理の話のつづき (pp.139-144)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"C言語と同様に,Python にも `while` 文があります. `for` 文は\n",
"```\n",
"for ループ変数 in シーケンス:\n",
" 繰り返し実行するブロック\n",
"```\n",
"という構造でしたが, `while` 文は次のような構造です.\n",
"```\n",
"while 条件式:\n",
" 繰り返し実行するブロック\n",
"```\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"以下の `for` ループと同じ処理を,`while` を使って書いてみよう."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"for i in range(5):\n",
" print(i)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"以下の条件式の部分を書き加えて完成させよう."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"i = 0\n",
"while :\n",
" print(i)\n",
" i += 1"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### 練習\n",
"以下のセルを修正して,\n",
"\n",
"$$\n",
"\\sum_{k=1}^{n} k^2 = 1^2 + 2^2 + \\dots + n^2 > 100\n",
"$$\n",
"\n",
"となる最小の $n$ と,そのときの左辺の和の値を表示するコードを書きなさい."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"s = 0 # 和の値\n",
"k = 0 # 上記の式の k \n",
"while :\n",
"\n",
"print('n =', k, 'まで足すと和が', s, 'となり100を超える')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"以下は,検算用の for ループバージョン."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"s = 0\n",
"for k in range(1, 100):\n",
" s += k*k\n",
" if s > 100:\n",
" break\n",
"\n",
"print('n =', k, 'まで足すと和が', s, 'となり100を超える')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Python には,C言語と同様に, `break`文,`continue`文もあります.機能/使い方もC言語と同様です.簡単に説明すると,次のようなものです.\n",
"\n",
"- `break`: あるブロックから一つ外に抜け出す.「for や while のループで,特定の条件が成り立ったらブロックから抜け出す」という時に使う,というのが代表的\n",
"- `continue`: ループブロック内のそれ以降の内容を飛ばして,ブロックの最初に戻る."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### 練習\n",
"次のコードの実行結果がどうなるか予想しなさい.その後,実行して動作を確認しなさい."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"for i in range(1, 11):\n",
" if i % 4 == 0:\n",
" break\n",
" print(i)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"for i in range(1, 11):\n",
" if i % 4 == 0:\n",
" continue\n",
" print(i)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"C言語にはない機能として,「`for`や`while`で`else`文が使える」というのがあります(p.143, 144)."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"----\n",
"## 関数の話のつづき (pp.144-150)\n",
"\n",
"引数のデフォルト値/キーワード引数の話"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"組み込み関数 `int()` は,引数として渡されたものを整数に変換して返す関数でした."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"int(\"10\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"上記の例では引数は1つですが,以前も説明したように,実は2つ目の引数に自然数 `p` を指定すると,1つ目の引数の内容を `p`進法で表現された数と解釈して変換した数を10進数で返してくれるのでした."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"int(\"10\", 2)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"int(\"10\", 16)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"int(\"ff\", 16)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"このように,Pythonでは**渡すことのできる引数のうち一部だけを指定しても動作するように関数を作ることができます**. \n",
"このような関数は,引数の一部に**デフォルト値** (値が指定されなかったときに用いられる,あらかじめ定められた値)を指定して定義されています."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"組み込み関数 `int()` のオンラインドキュメントを見てみましょう.\n",
"https://docs.python.jp/3/library/functions.html#int\n",
"\n",
"そこに記されている\n",
"```\n",
"int(x, base=10)\n",
"```\n",
"という表現は,\n",
"\n",
"- この関数は引数を2つとる\n",
"- 2つ目の引数(`base`)の**デフォルト値**は `10` である\n",
"\n",
"ということを表しています.デフォルト値の指定されている引数を**デフォルト引数**といいます.\n",
"**デフォルト引数については,呼び出し時に値が渡されなかった場合,デフォルト値が引数として指定されたのと同じ動作をする**ことになっています.\n",
"\n",
"`int()` の例では,引数を1つしか指定しなかったら2つ目の引数に `10` を指定したことになる → 10進数と解釈して変換する,ということになります."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"このようにデフォルト値を指定した関数は,上記の書き方をそのまま使って定義します.\n",
"以下の例で確認してみましょう."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def echo(n, s=\"ほげ\"):\n",
" print(s*n)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"まずは,引数を1つだけ(`n`の方だけ)指定して関数 `echo()` を呼んでみましょう."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# 第1引数だけ指定して echo を呼ぶ\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"次に,2つ目の引数も指定して呼んでみましょう."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# 第2引数も指定(適当な文字列を指定しよう)して echo を呼ぶ\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"さて,C言語でもPythonでも,引数の順番には意味があります.\n",
"関数を呼び出す際には,通常は定義された順番どおりに引数を指定しないといけません.\n",
"例えば,次のようにするとエラーになります."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"int(16, \"ff\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"このことは,引数の多い関数では問題となりがちです."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def fournumbers(x1, x3=3, x4=4, x2=2):\n",
" print(x1, x2, x3, x4)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"fournumbers(1)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"fournumbers(1, 999)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"この例はわざわざ混乱させるよう書き方をしている悪い例ですが,引数が多くなってくると,どれが何番目の引数かに気を使って書くのは大変です.\n",
"\n",
"そこでPythonでは,関数の定義に使用されている引数の名前を使って引数を指定できるようになっています(**引数のキーワード指定**)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"fournumbers(x2=2, x1=1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"上記の例から明らかにように,キーワード指定する場合,本来の関数定義における引数の順序を守らなくても,ちゃんと解釈してくれます.\n",
"\n",
"ただし,**キーワード指定した引数の後にキーワード指定のない引数を書いて呼び出すことはできません**.\n",
"以下はエラーになります."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"fournumbers(x2=2, 1, x3=3)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"また,関数を定義する際には,**デフォルト値を指定した引数より後にデフォルト値を指定しない引数を書くことはできません**.例えば,次の関数定義はエラーになります."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def fournumbers2(x3=3, x4=4, x1, x2=2):\n",
" print(x1, x2, x3, x4)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"つまり,関数定義の際は,引数にはまずはデフォルト値の指定のないものを並べ,その後にデフォルト値を指定したものを並べる,という書き方をしないといけません."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### 練習\n",
"次のような仕様の関数 `hoge` の定義を書いてください.\n",
"\n",
"1. 引数はデフォルト値をもつもの3つ,それぞれの名前とデフォルト値は次の通り:\n",
" `start=0, stop=10, step=1`\n",
"1. `start` からはじめて `step` ずつ数を大きくしながら `stop` 未満の数を空白を開けて表示する.例えば引数が `start=3, stop=8, step=2` ならば,出力は `3 5 7` となる."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# このセルに関数 hoge の定義を書く\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"以下のセルを実行して, `hoge` の動作確認をしましょう."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"hoge(start=3)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"hoge(stop=7)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"hoge(step=3)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"hoge(stop=7, start=3)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"hoge(3, 7)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"pp.147-150の「関数とローカル変数」の内容については,以前の回で一部をすでに学習していますので,ここでは触れません."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<font size=\"-1\">(よだんだよん)</font> 引数のキーワード指定の話とローカル変数/変数のスコープの話を組み合わせると,C言語とPythonで一見異なる振る舞いをするように見える,嫌がらせのようなコードを書くことができます."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"```\n",
"// C言語\n",
"int x1 = 1;\n",
"fournumbers(x1=111); // 変数 x1 に 111 を代入してから,その値を関数に渡すことになる\n",
"printf(\"%d\", x1); // だからこの出力は 111\n",
"```"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Python\n",
"x1 = 1\n",
"fournumbers(x1=111) # この x1 は 関数 fournumbers のキーワード引数\n",
"print(x1) # 出力は..."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.5"
},
"toc": {
"base_numbering": 1,
"nav_menu": {
"height": "146px",
"width": "258px"
},
"number_sections": false,
"sideBar": true,
"skip_h1_title": true,
"title_cell": "目次",
"title_sidebar": "Contents",
"toc_cell": true,
"toc_position": {},
"toc_section_display": true,
"toc_window_display": false
}
},
"nbformat": 4,
"nbformat_minor": 4
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment