2021-02-21

【問題】Python チュートリアル 制御構文と関数

python_code_img

Pythonチュートリアルの「形式ばらない Python の紹介>プログラミングへの第一歩(while文)」「その他の制御フローツール」に関連した問題を掲載します。各問いに対話モードへの記述かスクリプトの記述で解答してください。

問題

Q1. while文

数値123456789を変数にnに代入して、nの値が1未満になるまで変数nを3で除算してください。除算した結果をprintを使って出力してください。

Q2.for文(1)

forとrangeを使って、1~15までの数値を合計した値を出力してください。

Q3.for文(2)

Q2の書き換えて、計算途中の合計値を出力してください。

Q4.for文(3)

以下のリストの値と、値の長さを出力してください。

fruits = ["Apple", "Orange", "Banana"]

Q5.enumerate

enumerateを使って、fruits変数のリストの値とインデックス番号を出力してください。

Q6.if文

if文を使って、変数nが奇数であればodd、偶数であればevenと出力し、変数nの値もあわせて出力してください。変数nはfor文を使って、1から10`までの値を順番に代入してください。

Q7.continue

forで1から100までの値を順番に取り出し、その合計値を出力してください。ただし、forから取り出した値が3の倍数である場合は、continueを使って加算処理をスキップしてください。

Q8.break

Q7の処理で加算処理をしたあと、合計値が2000を超えたらループを終了する処理を追加し、その時点の合計値を出力してください。

Q9.関数の定義(1)

何もしない関数empty_funcを定義してください。

Q10.関数の定義(2)

数値を引き取る引数a, bを持つ関数addを定義してください。add関数内で引数abの和を出力してください。記述後、a5b3を設定して関数addを実行してください。

Q11.関数の定義(3)

関数addの和を出力する処理を削除して、abの和を返す処理を記述してください。記述後、a4b2を設定して関数addの実行結果を出力してください。

Q12.デフォルト引数(1)

引数numから引数minusを引いた値を返す関数decrementを定義してください。引数minusのデフォルト値は1にしてください。
引数numには任意の値(e.g. 10)を設定し、引数minusにはデフォルト値と任意の値(e.g. 3)を設定して、その返り値を出力してください。

Q13.デフォルト引数(2)

引数startから引数endまでの数値を、引数numsのリストに格納して、numsを返す関数number_listを作成してください。number_list関数を実行する都度、引数numsに値が蓄積されるようにしてください。その後、以下の設定で関数を2回実行してください。

1回目の実行ではstart引数に1end引数には10を設定して実行結果を出力してください。2回目はstart引数に11end引数には20して実行結果を出力してください。

Q14.デフォルト引数(3)

Q13の関数number_listを書き換えて、number_listを実行する都度、引数numsに空のリストが生成されるように書き換えてください。その後、以下の設定で関数を2回実行してください。

1回目の実行ではstart引数に1end引数には10を設定して実行結果を出力してください。2回目はstart引数に11end引数には20して実行結果を出力してください。

Q15.タプル形式の引数

リスト形式で引数を受け取り、リストの合計値を返す関数my_sumを定義して、引数に1, 2, 3, 4, 5を設定して結果を出力してください。

Q16.辞書形式の引数

辞書形式で引数を引き取り、その引数をそのまま出力する関数print_key_argsを定義してください。定義したprint_key_argsに以下の引数と値を定義して実行してください。

引数
one 1
two 2
three 3

Q17.位置専用引数

下記の関数incrementのうちnum引数を位置引数でのみ実行できるように書き換えてください。その後、位置引数で実行でき、キーワード引数で実行できないことを確認してください。

def increment(num, plus=1):
    return num + plus

Q18.キーワード専用引数

下記の関数incrementのうちplus引数をキーワード引数でのみ実行できるように書き換えてください。その後、キーワード引数で実行でき、位置引数で実行できないことを確認してください。

def increment(num, plus):
    return num + plus

Q19.リストのアンパック

下記コードにある変数alphabetをアンパックして、関数my_concatを実行してください。実行後、関数の返り値を出力してください。

def my_concat(*args):
  ret = ""
  for char in args:
     ret += char
  return ret

alphabet = ["a", "b", "c", "d", "e", "f", "g"]

Q20.辞書のアンパック

下記コードにある変数order_dictをアンパックして、関数calc_sales_amountを実行してください。実行後、関数の返り値を出力してください。

def calc_sales_amount(ramen_qty, gyoza_qty, beer_qty):  
  TAX = 1.1  
  RAMEN_PRICE = 800  
  GYOZA_PRICE = 400  
  BEER_PRICE = 300  
  return int(  
    (RAMEN_PRICE * ramen_qty  
     + GYOZA_PRICE * gyoza_qty  
     + BEER_PRICE * beer_qty) * TAX  
  )  

 
order_dict = {"ramen_qty": 28, "gyoza_qty": 14, "beer_qty": 7}

Q21. ドキュメンテーション文字列(Docstring)

Q20の関数calc_sales_amountにドキュメンテーション文字列を追加してください。日本語でも英語でも書きやすい言語で問題ありません。

Q22.関数のアノテーション(Type Hint)

Q21で追記したcalc_sales_amountに関数のアノテーションを追加してください。

発展問題

難しい場合には、飛ばしていただいても問題ありません。

Q23.ラムダ式(無名関数)

引数a, bの和を返すラムダ式を変数fに格納してください。引数aには13、引数bには17を設定してラムダ式を実行してください。

Q24.クロージャー

1次関数[ $y = ax + b$ ]のabに値を代入する関数create_linear_funcを記述してください。create_linear_funcの返り値には、xに値を代入すると、yを返すlambda式を記述してください。

create_linear_funcを使って関数fgを以下に従って定義して、それぞれの関数のx4を代入したときの値を出力してください。

関数 数式
$f(x)$ $y = 2x + 4$
$g(x)$$y = x + 3$

Q25.再帰関数

Q1の処理する関数keep_dividing_threeを、forwhileを使わずに書いてください。引数にはnを設定して、123456789以外の数値でも動作するようにしてください。

解答

A1.while文

>>> n = 123456789
>>> while n >= 1:
...     n /= 3 # n = n / 3
...
>>> print(n)
0.9559906548979655

A2.for文(1)

>>> ret = 0
>>> for n in range(1, 16):
...     ret += n
...
>>> print(ret)
120

A3.for文(3)

>>> ret = 0
>>> for n in range(1, 16):
...     ret += n
...     print(ret)
...
1
3
6
10
15
21
28
36
45
55
66
78
91
105
120

A4.for文(3)

>>> fruits = ["Apple", "Orange", "Banana"]
>>> for fruit in fruits:
...     print(fruit, len(fruit))
...
Apple 5
Orange 6
Banana 6

A5.enumerate

>>> fruits = ["Apple", "Orange", "Banana"]
>>> for num, fruit in enumerate(fruits):
...     print(fruit, num)
...
Apple 0
Orange 1
Banana 2

A6.if文

>>> for n in range(1, 11):
...     if n % 2:
...         ans = "Odd"
...     else:
...         ans = "Even"
...     print(ans, n)
...
Odd 1
Even 2
Odd 3
Even 4
Odd 5
Even 6
Odd 7
Even 8
Odd 9
Even 10

A7.continue

>>> ans = 0
>>> for n in range(1, 101):
...     if n % 3 == 0:
...         continue
...     ans += n
...
>>> print(ans)
3367`

A8.break

>>> ans = 0
>>> for n in range(1, 101):
...     if n % 3 == 0:
...         continue
...     ans += n
...     if ans > 2000:
...         break
...
>>> print(ans)
2028

A9.関数の定義(1)

>>> def empty_func():
...   pass
...

A10.関数の定義(2)

>>> def add(a, b):
...   print(a + b)
...
>>> add(3, 5)
8

A11.関数の定義(3)

>>> def add(a, b):
...   return a  + b
...
>>> ret = add(4, 2)
>>> print(ret)
6

A12.デフォルト引数(1)

>>> def decrement(num, minus=1):
...     return num - minus
...
>>> num = 100
>>> print(decrement(num))
99
>>> print(decrement(num, 3))
97

A13.デフォルト引数(2)

>>> def number_list(start, end, nums=[]):
...     for num in range(start, end+1):
...         nums.append(num)
...     return nums
...
>>>
>>> print(number_list(1, 10))
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> print(number_list(11, 20))
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]

A14.デフォルト引数(3)

>>> def number_list(start, end, nums=None):
...     if nums is None:
...         nums = []
...     for num in range(start, end+1):
...         nums.append(num)
...     return nums
...
>>>
>>> print(number_list(1, 10))
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> print(number_list(11, 20))
[11, 12, 13, 14, 15, 16, 17, 18, 19, 20]

A15.タプル形式の引数

>>> def my_sum(*args):
...     ret = 0
...     for num in args:
...         ret += num
...     return ret # sum(args)と同じ
...
>>>
>>> ret = my_sum(1, 2, 3, 4, 5)
>>> print(ret)
15

A16.辞書形式の引数

>>> def print_key_args(**args):
...     print(args)
...
>>>
>>> print_key_args(one=1, two=2, three=3)
{'one': 1, 'two': 2, 'three': 3}

A17.位置専用引数

>>> def increment(num, /, plus=1):
...     return num + plus
...
>>> print(increment(100))
101
>>> print(increment(num=100))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: increment() got some positional-only arguments passed as keyword argument
s: 'num'

A18.キーワード専用引数

>>> def increment(num, *, plus):
...     return num + plus
...
>>> num = 100
>>> print(increment(num, plus=5))
105
>>>
>>> # 位置引数で実行するとエラーが生じることを確認できる
>>> print(increment(num, 5))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
Typ.eError: increment() takes 1 positional argument but 2 were given
>>>
>>> # キーワード引数だけで実行できることを確認できる
>>> print(increment(num))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: increment() missing 1 required keyword-only ar
gument: 'plus'

A19.リストのアンパック

>>> def my_concat(*args):
...   ret = ""
...   for char in args:
...      ret += char
...   return ret
...
>>> alphabet = ["a", "b", "c", "d", "e", "f", "g"]
>>> ret = my_concat(*alphabet) # my_concat("a", "b", "c", ..., "g")となる
>>> print(ret)
ab
cdefg

A20.辞書のアンパック

>>> def calc_sales_amount(ramen_qty, gyoza_qty, beer_qty):
...     TAX = 1.1
...     RAMEN_PRICE = 800
...     GYOZA_PRICE = 400
...     BEER_PRICE = 300
...     return int(
...         (RAMEN_PRICE * ramen_qty
...          + GYOZA_PRICE * gyoza_qty
...          + BEER_PRICE * beer_qty) * TAX
...     )
...
>>> order_dict = {"ramen_qty": 28, "gyoza_qty": 14, "beer_qty": 7}
>>> sales_amount = calc_sales_amount(**order_dict)
>>> print(sales_amount)
33110

A21.ドキュメンテーション文字列(Docstring)

>>> # 以下の書き方は、一例として参考程度にしてください。
>>> # PEP8というコードの書き方の決まりごとにあわせるため、
>>> # ドキュメンテーション文字列はダブルクォーテーションを
>>> # 3つ使って囲うことを推奨します。
>>> def calc_sales_amount(ramen_qty, gyoza_qty, beer_qty):
...     """
...     注文された料理の数量を引き取り、税込みの売上金額を返します。
...     :param ramen_qty: 注文されたラーメンの数量
...     :param gyoza_qty: 注文された餃子の数量
...     :param beer_qty: 注文されたビールの数量
...     :return: 税込みの売上金額
...     """
...     TAX = 1.1
...     RAMEN_PRICE = 800
...     GYOZA_PRICE = 400
...     BEER_PRICE = 300
...     return int(
...         (RAMEN_PRICE * ramen_qty
...          + GYOZA_PRICE * gyoza_qty
...          + BEER_PRICE * beer_qty) * TAX
...     )

A22.関数のアノテーション(Type Hint)

>>> def calc_sales_amount(ramen_qty: int, gyoza_qty: int, beer_qty: int) -> int:
...     """
...     注文された料理の数量を引き取り、税込みの売上金額を返します。
...     :param ramen_qty: 注文されたラーメンの数量
...     :param gyoza_qty: 注文された餃子の数量
...     :param beer_qty: 注文されたビールの数量
...     :return: 税込みの売上金額
...     """
...     TAX = 1.1
...     RAMEN_PRICE = 800
...     GYOZA_PRICE = 400
...     BEER_PRICE = 300
...     return int(
...         (RAMEN_PRICE * ramen_qty
...          + GYOZA_PRICE * gyoza_qty
...          + BEER_PRICE * beer_qty) * TAX
...     )

A23.ラムダ式(無名関数)

>>> f = lambda a, b: a + b
>>> ret = f(13, 17)
>>> print(ret)
30

A24.クロージャー

>>> def create_linear_func(a, b):
...     return lambda x: a * x + b
...
>>> f = create_linear_func(2, 4)
>>> g = create_linear_func(1, 3)
>>> print(f(4))
12
>>> print(g(4))
7

A25.再帰関数

>>> def keep_dividing_three(n):
...     if n > 1:
...         return keep_dividing_three(n / 3)
...     return n
...
>>>
>>> ret = keep_dividing_three(123456789)
>>> print(ret)
0.9559906548979655