Python Sample Scripts

  • 用同一個 folder 下的 python_sample_answer.ipynb 默寫

[17]:
# sphinx version。一定有辦法直接把這個 button 加到 sphinx config 裡,有空再研究

from IPython.display import HTML

HTML('''<script>
code_show=true;
function code_toggle() {
 if (code_show){
 $('div.nbinput').hide();
 } else {
 $('div.nbinput').show();
 }
 code_show = !code_show
}
$( document ).ready(code_toggle);
</script>
<form action="javascript:code_toggle()"><input type="submit" value="Click here to toggle on/off the raw code."></form>''')
[17]:

fix_seed as a Context Manager

[1]:
import numpy as np

class fix_seed:
    def __init__(self, seed=0):
        self.seed = seed

    def __enter__(self):
        np.random.seed(self.seed)

    def __exit__(self, exc_type=None, exc_value=None, traceback=None):
        np.random.seed()

with fix_seed(seed=0):
    print(np.random.uniform())
print(np.random.uniform())
0.5488135039273248
0.7731968705194575

Exception

  • Open file in a try block with exception handling

[1]:
try:
    file = open('circles_.py')
except FileNotFoundError as e:
    print(e)
else:
    print(file.readline())
    file.close()
finally:
    print('Done!')
[Errno 2] No such file or directory: 'circles_.py'
Done!

unittest

  • 寫一個 circle_area 計算圓面積,要檢查輸入半徑是否為非負 intfloat 然後寫 test case 測這些 input:1, 0, 2.1, -2, 3+5j, True, 'radius'

  • 如果是 script 可以在最下面寫 unittest.main() 開始跑,但在 Jupyter 不行

[4]:
from math import pi
import unittest

def circle_area(r):
    if type(r) not in [float, int]:
        raise TypeError('Radius must be int or float.')
    if r < 0:
        raise ValueError('Radius can not be negative.')

    return pi*(r**2)

class TestCircleArea(unittest.TestCase):
    def test_areas(self):
        self.assertAlmostEqual(circle_area(1), pi)
        self.assertAlmostEqual(circle_area(0), 0)
        self.assertAlmostEqual(circle_area(2.1), pi*(2.1**2))

    def test_values(self):
        with self.assertRaises(ValueError):
            circle_area(-2)

    def test_types(self):
        with self.assertRaises(TypeError):
            circle_area(3+5j)
            circle_area(True)
            circle_area('radius')

OOP

  • Person and SuperHero classes with reveal_id methods

[3]:
class Person:
    def __init__(self, name):
        self.name = name

    def reveal_id(self):
        print(f"My name is {self.name}.")

class SuperHero(Person):
    def __init__(self, name, hero_name):
        super().__init__(name)
        self.hero_name = hero_name

    def reveal_id(self):
        super().reveal_id()
        print(f"And I'm {self.hero_name}.")

corey = Person('Corey')
corey.reveal_id()

wade = SuperHero('Wade Wilson', 'Deadpool')
wade.reveal_id()
My name is Corey.
My name is Wade Wilson.
And I'm Deadpool.

Generator

  • 印 1000 以內的所有 2 的冪次

[2]:
def pow2():
    n = 2
    while n < 1000:
        yield n
        n *= 2

list(pow2())
[2]:
[2, 4, 8, 16, 32, 64, 128, 256, 512]

Decorator

fix_seed (No Argument)

[4]:
# fix_seed:固定 seed = 0 版本。離開函數 seed 會還原成 None

import numpy as np
import functools

def fix_seed(fnc):
    @functools.wraps(fnc)
    def wrapper_fix_seed(*args, **kargs):
        np.random.seed(0)
        res = fnc(*args, **kargs)
        np.random.seed()
        return res
    return wrapper_fix_seed

@fix_seed
def print_rand():
    print(np.random.uniform())

print_rand()
print(np.random.uniform())
0.5488135039273248
0.6487172323362883

fix_seed With Argument

[6]:
# 接受 argument 版本,但變成一定要指定 seed

import numpy as np
import functools

def fix_seed(seed=0):
    def decorator_fix_seed(fnc):
        @functools.wraps(fnc)
        def wrapper_fix_seed(*args, **kargs):
            np.random.seed(seed)
            res = fnc(*args, **kargs)
            np.random.seed()
            return res
        return wrapper_fix_seed
    return decorator_fix_seed

@fix_seed(seed=100)
def print_rand():
    print(np.random.uniform())

print_rand()
print(np.random.uniform())
0.5434049417909654
0.5834370961600464