使用Jupyter Notebook 学习 Python


本文摘自php中文网,作者coldplay.xixi,侵删。

有了 Jupyter、PyHamcrest,用一点测试的代码把它们连在一起,你就可以教任何适用于单元测试的 Python 内容。

Python视频教程栏目为大家详细介绍~

e4222a2cfaaa41c1b9d80757885bf747_tplv-k3u1fbpfcp-zoom-1.png

关于 Ruby 社区的一些事情一直让我印象深刻,其中两个例子是对测试的承诺和对易于上手的强调。这两方面最好的例子是 Ruby Koans,在这里你可以通过修复测试来学习 Ruby。

要是我们能把这些神奇的工具也用于 Python,我们应该可以做得更好。是的,使用 Jupyter Notebook、PyHamcrest,再加上一点类似于胶带的粘合代码,我们可以做出一个包括教学、可工作的代码和需要修复的代码的教程。

首先,需要一些“胶布”。通常,你会使用一些漂亮的命令行测试器来做测试,比如 pytest 或 virtue。通常,你甚至不会直接运行它。你使用像 tox 或 nox 这样的工具来运行它。然而,对于 Jupyter 来说,你需要写一小段粘合代码,可以直接在其中运行测试。

幸运的是,这个代码又短又简单:

import unittest

 

def run_test(klass):

    suite = unittest.TestLoader().loadTestsFromTestCase(klass)

    unittest.TextTestRunner(verbosity=2).run(suite)

    returnklass复制代码

现在,装备已经就绪,可以进行第一次练习了。

在教学中,从一个简单的练习开始,建立信心总是一个好主意。

那么,让我们来修复一个非常简单的测试:

@run_test

class TestNumbers(unittest.TestCase):

    

    def test_equality(self):

        expected_value = 3# 只改这一行

        self.assertEqual(1+1, expected_value)复制代码

test_equality (__main__.TestNumbers) ... FAIL

 

======================================================================

FAIL: test_equality (__main__.TestNumbers)

----------------------------------------------------------------------

Traceback (most recent call last):

  File"<ipython-input-7-5ebe25bc00f3>", line 6,intest_equality

    self.assertEqual(1+1, expected_value)

AssertionError: 2 != 3

 

----------------------------------------------------------------------

Ran 1 testin0.002s

 

FAILED (failures=1)复制代码

“只改这一行” 对学生来说是一个有用的标记。它准确地表明了需要修改的内容。否则,学生可以通过将第一行改为return来修复测试。

在这种情况下,修复很容易:

@run_test

class TestNumbers(unittest.TestCase):

    

    def test_equality(self):

        expected_value = 2# 修复后的代码行

        self.assertEqual(1+1, expected_value)复制代码

test_equality (__main__.TestNumbers) ... ok

 

----------------------------------------------------------------------

Ran 1 testin0.002s

 

OK复制代码

然而,很快,unittest库的原生断言将被证明是不够的。在pytest中,通过重写assert中的字节码来解决这个问题,使其具有神奇的属性和各种启发式方法。但这在 Jupyter notebook 中就不容易实现了。是时候挖出一个好的断言库了:PyHamcrest。

from hamcrest import *

@run_test

class TestList(unittest.TestCase):

    

    def test_equality(self):

        things = [1,

                  5,# 只改这一行

                  3]

        assert_that(things, has_items(1, 2, 3))复制代码

test_equality (__main__.TestList) ... FAIL

 

======================================================================

FAIL: test_equality (__main__.TestList)

----------------------------------------------------------------------

Traceback (most recent call last):

  File"<ipython-input-11-96c91225ee7d>", line 8,intest_equality

    assert_that(things, has_items(1, 2, 3))

AssertionError:

Expected: (a sequence containing <1> and a sequence containing <2> and a sequence containing <3>)

     but: a sequence containing <2> was <[1, 5, 3]>

 

 

----------------------------------------------------------------------

Ran 1 testin0.004s

 

FAILED (failures=1)复制代码

PyHamcrest 不仅擅长灵活的断言,它还擅长清晰的错误信息。正因为如此,问题就显而易见了。[1, 5, 3]不包含2,而且看起来很丑:

@run_test

class TestList(unittest.TestCase):

    

    def test_equality(self):

        things = [1,

                  2,# 改完的行

                  3]

        assert_that(things, has_items(1, 2, 3))复制代码

test_equality (__main__.TestList) ... ok

 

----------------------------------------------------------------------

Ran 1 testin0.001s

 

OK复制代码

使用 Jupyter、PyHamcrest 和一点测试的粘合代码,你可以教授任何适用于单元测试的 Python 主题。

例如,下面可以帮助展示 Python 从字符串中去掉空白的不同方法之间的差异。

source_string ="  hello world  "

 

@run_test

class TestList(unittest.TestCase):

    

    # 这是个赠品:它可以工作!

    def test_complete_strip(self):

        result = source_string.strip()

        assert_that(result,

                   all_of(starts_with("hello"), ends_with("world")))

 

    def test_start_strip(self):

        result = source_string# 只改这一行

        assert_that(result,

                   all_of(starts_with("hello"), ends_with("world  ")))

 

    def test_end_strip(self):

        result = source_string# 只改这一行

        assert_that(result,

                   all_of(starts_with("  hello"), ends_with("world")))复制代码

test_complete_strip (__main__.TestList) ... ok

test_end_strip (__main__.TestList) ... FAIL

test_start_strip (__main__.TestList) ... FAIL

 

======================================================================

FAIL: test_end_strip (__main__.TestList)

----------------------------------------------------------------------

Traceback (most recent call last):

  File"<ipython-input-16-3db7465bd5bf>", line 19,intest_end_strip

    assert_that(result,

AssertionError:

Expected: (a string startingwith'  hello'and a string endingwith'world')

     but: a string endingwith'world'was'  hello world  '

 

 

======================================================================

FAIL: test_start_strip (__main__.TestList)

----------------------------------------------------------------------

Traceback (most recent call last):

  File"<ipython-input-16-3db7465bd5bf>", line 14,intest_start_strip

    assert_that(result,

AssertionError:

Expected: (a string startingwith'hello'and a string endingwith'world  ')

     but: a string startingwith'hello'was'  hello world  '

 

 

----------------------------------------------------------------------

Ran 3 testsin0.006s

 

FAILED (failures=2)复制代码

理想情况下,学生们会意识到.lstrip()和.rstrip()这两个方法可以满足他们的需要。但如果他们不这样做,而是试图到处使用.strip()的话:

source_string ="  hello world  "

 

@run_test

class TestList(unittest.TestCase):

    

    # 这是个赠品:它可以工作!

    def test_complete_strip(self):

        result = source_string.strip()

        assert_that(result,

                   all_of(starts_with("hello"), ends_with("world")))

 

    def test_start_strip(self):

        result = source_string.strip()# 改完的行

        assert_that(result,

                   all_of(starts_with("hello"), ends_with("world  ")))

 

    def test_end_strip(self):

        result = source_string.strip()# 改完的行

        assert_that(result,

                   all_of(starts_with("  hello"), ends_with("world")))复制代码

相关阅读 >>

Python是面向对象的语言吗

Python判断闰年程序是什么

Python使用re模块正则提取字符串中括号内的内容

string在Python中是什么意思

Python中的map怎么使用(方法详解)

Python如何做词云

Python字典的值可以是字典吗

如何使用Python读取excel文件?(代码示例)

Python通过伪装头部数据抵抗反爬虫

Python函数式编程是什么?

更多相关阅读请进入《Python》频道 >>




打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...