Pythonチュートリアル（第４版）4章 制御構造ツール

# はじめに
Pythonエンジニア認定試験に興味をもったので、
Pythonチュートリアル（第4版）をひたすら写経していきたくなったので、
写経したいと思います。（コード部分のみ）
ただし、プロンプト表記のところは全部pyファイル化して書きなおします。
今回は4章部分のみです。

# 4章　制御構造ツール
## 4.1 if文
```python
x = int(input("整数を入れてください:"))

# 整数を入れてください:42
# もっと
if x < 0:
    x = 0
    print('負数はゼロとする')
elif x == 0:
    print('ゼロ')
elif x == 1:
    print('1つ')
else:
    print('もっと')
```

## 4.2 for文
```python
words = ['cat', 'window', 'defenestrate']
# cat 3
# window 6
# defenestrate 12
for w in words:
    print(w,len(w))

users = {'taro': 'inactive', 'jiro': 'active', 'saburo': 'inactive'}

for user, status in users.copy().items():
    if status == 'inactive':
        del users[user]

# {'jiro': 'active'}
print(users)

#初期化
users = {'taro': 'inactive', 'jiro': 'active', 'saburo': 'inactive'}
active_users = {}
for user, status in users.items():
    if status == 'active':
        active_users[user] = status

# {'jiro': 'active'}
print(active_users)
```

## 4.3 range()関数
```python
# 0 1 2 3 4 
for i in range(5):
    print(i, end=' ')

print()
#  5 6 7 8 9
for i in range(5, 10):
    print(i, end=' ')

print()
# 0 3 6 9
for i in range(0, 10, 3):
    print(i, end=' ')

print()
# -10 -40 -70
for i in range(-10,-100,-30):
    print(i, end=' ')

print()


a = ['Mary', 'had', 'a', 'little', 'lamb']
# 0 Mary
# 1 had
# 2 a
# 3 little
# 4 lamb
for i in range(len(a)):
    print(i, a[i])

# range(0, 10)
print(range(10))

# 6
print(sum(range(4))) # 0 + 1 + 2 + 3

# [0, 1, 2, 3]
print(list(range(4)))

```

## 4.4 break文とcontinue文、ループにおけるelse節
```python
# 2 is a prime number
# 3 is a prime number
# 4 ezuals 2 * 2
# 5 is a prime number
# 6 ezuals 2 * 3
# 7 is a prime number
# 8 ezuals 2 * 4
# 9 ezuals 3 * 3
for n in range(2, 10):
    for x in range(2, n):
        if n % x == 0:
            print(n, 'ezuals', x, '*', n//x)
            break
    else:
        # ループで約数を見つけられなかった場合
        print(n, 'is a prime number')


# Found an even number 2
# Found an odd number 3
# Found an even number 4
# Found an odd number 5
# Found an even number 6
# Found an odd number 7
# Found an even number 8
# Found an odd number 9
for num in range(2, 10):
    if num % 2 == 0:
        print("Found an even number", num)
        continue
    print("Found an odd number", num)
```

## 4.5　pass文
```python
while True:
    pass # ビジーウェイトでキーボード割り込み(Ctrl+C)をまつ
print("test") # 実行されない

# class MyEmptyClass:
#    pass

def intlog(*args):
    pass # 実装を忘れないこと！
```

## 4.6　関数の定義
```python
def fib(n):
    """nまでのフィボナッチ級数を表示する"""
    a , b= 0, 1
    while a < n:
        print(a, end= ' ')
        a, b = b, a+b
    print()

# ではこの関数を呼び出してみよう
# 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 
fib(2000)

# <function fib at 0x0000026EA2BD5750>
print(fib)

f = fib
# 0 1 1 2 3 5 8 13 21 34 55 89
f(100)

# 
fib(0)

# None
print(fib(0))

def fib2(n): # nまでのフィボナッチ級数を書き出す
    """nまでのフィボナッチ級数から成るリストを返す"""
    result = []
    a , b= 0, 1
    while a < n:
        result.append(a)
        a, b = b, a+b
    return result
f100 = fib2(100)
# [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
print(f100)
```

## 4.7　さらに関数定義について
### 4.7.1 引数のデフォルト値
```python
def ask_ok(prompt, retries=4, reminder='Please try again!'):
    while True:
        ok = input(prompt)
        if ok in ('y', 'ye', 'yes'):
            return True
        if ok in ('n', 'no', 'nop', 'nope'):
            return False
        retries = retries - 1
        if retries < 0:
            raise ValueError('invalid user response')
        print(reminder)

ask_ok('Do you really want to quit?')

ask_ok('OK to overwrite the file?', 2)

ask_ok('OK to overwrite the file?', 2, 'Come on, only yes or no')

i = 5

def f(arg=i):
    print(arg)

i = 6
# 5
f()

def f(a, L=[]):
    L.append(a)
    return L

# [1]
# [1, 2]
# [1, 2, 3]
print(f(1))
print(f(2))
print(f(3))

def f(a, L=None):
    if L is None:
        L = []
    L.append(a)
    return L

# [1]
# [2]
# [3]
print(f(1))
print(f(2))
print(f(3))
```

### 4.7.2 キーワード引数
```python
def parrot(voltage, state='a stiff', action='voom',
           type='Norwegian Blue'):
    print("-- This parrot wouldn't", action, end=' ')
    print("if you put", voltage, "voltes through it.")
    print("-- Lovely plumage, the", type)
    print("-- It's", state, "!")

# -- This parrot wouldn't voom if you put 1000 voltes through it.
# -- Lovely plumage, the Norwegian Blue
# -- It's a stiff !
parrot(1000)

# -- This parrot wouldn't voom if you put 1000 voltes through it.
# -- Lovely plumage, the Norwegian Blue
# -- It's a stiff !
parrot(voltage=1000)

# -- This parrot wouldn't V00000M if you put 1000000 voltes through it.
# -- Lovely plumage, the Norwegian Blue
# -- It's a stiff !
parrot(voltage=1000000, action='V00000M')

# -- This parrot wouldn't V00000M if you put 1000000 voltes through it.
# -- Lovely plumage, the Norwegian Blue
# -- It's a stiff !
parrot(action='V00000M', voltage=1000000)

# -- This parrot wouldn't jump if you put a million voltes through it.
# -- Lovely plumage, the Norwegian Blue
# -- It's bereft of life !
parrot('a million', 'bereft of life', 'jump')

# -- This parrot wouldn't voom if you put a thousand voltes through it.
# -- Lovely plumage, the Norwegian Blue
# -- It's pushing up the daisies !
parrot('a thousand', state='pushing up the daisies')

# しかし次のようなコールは無効である：
# parrot() #必要な引数がない
# parrot(voltage=5.0, 'dead') # キーワード引数の後に非キーワード引数
# parrot(110, voltage=220) # 同じ引数に値を2度与えた
# parrot(actor='John Cleese') # 未知のキーワード引数

def function(a):
    pass
# エラー
# function(0, a=0)

def cheeseshop(kind, *arguments, **keywords):
    print("-- Do you have any", kind, "?")
    print("-- I'm sorry, we'", kind, "?")
    for arg in arguments:
        print(arg)
    print("-" * 40)
    for kw in keywords:
        print(kw, ":", keywords[kw])

# It's very runny, sir.
# It's really very, VERY runny, sir.
# ----------------------------------------
# shopkeeper : Michael Palin
# client : John Cleese
# sketch : Cheese Shop Sketch
cheeseshop("Limburger", "It's very runny, sir.",
           "It's really very, VERY runny, sir.",
           shopkeeper="Michael Palin",
           client="John Cleese",
           sketch="Cheese Shop Sketch")
```

### 4.7.3 特殊引数

```python
def f (pos1, pos2, / , pos_or_kwd, * , kwd1, kwd2):
    pass

def standard_arg(arg):
    print(arg)

def pos_only_arg(arg, /):
    print(arg)

def kwd_only_arg(*, arg):
    print(arg)

def combined_example(pos_only, / , standard, *, kwd_only):
    print(pos_only, standard, kwd_only)

# 2
standard_arg(2)

# 2
standard_arg(arg=2)

# 1
pos_only_arg(1)

# エラー
# pos_only_arg(arg=1)

# エラー
# kwd_only_arg(3)

# 3
kwd_only_arg(arg=3)

# エラー
# combined_example(1, 2, 3)

# 1 2 3
combined_example(1, 2, kwd_only=3)

# 1 2 3
combined_example(1, standard=2, kwd_only=3)

# エラー
# combined_example(pos_only=1, standard=2, kwd_only=3)

def foo(name, **kwds):
    return 'name' in kwds

# エラー
# foo(1,**{'name': 2})

def foo(name, /, **kwds):
    return 'name' in kwds

f = foo(1,**{'name': 2})

# True
print(f)
```

### 4.7.4 任意引数のリスト

```python
def write_multiple_items(file, separator, *args):
    file.write(separator.join(args))


def concat(*args, sep="/"):
    return sep.join(args)

a = concat("earth", "mars", "venus")
# earth/mars/venus
print(a)

b = concat("earth", "mars", "venus", sep=".")
# earth.mars.venus
print(b)
```

### 4.7.5 引数リストのアンパック

```python
a = list(range(3,6)) # 個別の引数を使った普通のコール
# [3, 4, 5]
print(a)

args = [3, 6]
b = list(range(*args)) # リストからアンパックした引数でコール
# [3, 6]
print(b)

def parrot(voltage, state='a stiff', action='voom'):
    print("-- This parrot would't", action, end=' ')
    print("If you put", voltage, "volts through it.", end= ' ')
    print("E's", state, "!")

d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"}

# -- This parrot would't VOOM If you put four million volts through it. E's bleedin' demised !
parrot(**d)
```

### 4.7.6 lambda（ラムダ）式

```python
def make_incrementor(n):
    return lambda x: x + n

f = make_incrementor(42)
a = f(0)
# 42
print(a)
b = f(1)
# 43
print(b)
c = f(2)
# 44
print(c)

#こういう使い方もできるはず
# 32
print(make_incrementor(20)(12))

pairs = [(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four')]

pairs.sort(key=lambda pair: pair[1])
# [(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')]
print(pairs)
```

### 4.7.7 ドキュメンテーション文字列(docstring)
```python
def my_function():
    """Do nothing, but document it.
    
    No, really, it doesn't do anything.
    """
    pass
# Do nothing, but document it.
# 
#    No, really, it doesn't do anything.
print(my_function.__doc__)
```

### 4.7.8 関数注釈（関数アノテーション）
```python
def f(ham: str, eggs: str = 'eggs') -> str:
    print("Annotations:", f.__annotations__)
    print("Arguments:", ham, eggs)
    return ham + ' and ' + eggs
# Annotations: {'ham': <class 'str'>, 'eggs': <class 'str'>, 'return': <class 'str'>}
# Arguments: spam eggs
a = f('spam')

# spam and eggs
print(a)
```