代码之美 - 28漂亮的调试

 

 《漂亮的调试》,Andreas Zellerddd的一个bug为引,介绍了增量调试(Delta Debugging),主要思想类同二分,算法好理解,可是程序看不大明白。

程序如下。

  1. def dd(c_pass, c_fail, test):
  2.     """Return a triple (DELTA, C_PASS', C_FAIL') such that
  3.        - C_PASS subseteq C_PASS' subset C_FAIL' subseteq C_FAIL holds
  4.        - DELTA = C_FAIL' - C_PASS' is a minimal difference
  5.          between C_PASS' and C_FAIL' that is relevant with respect
  6.          to TEST."""
  7.     n = 2 # Number of subsets
  8.     while 1:
  9.         assert test(c_pass) == PASS # Invariant
  10.         assert test(c_fail) == FAIL # Invariant
  11.         assert n >= 2
  12.         delta = listminus(c_fail, c_pass)
  13.         if n > len(delta):
  14.             # No further minimizing
  15.             return (delta, c_pass, c_fail)
  16.         deltas = split(delta, n)
  17.         assert len(deltas) == n
  18.         offset = 0
  19.         j = 0
  20.         while j < n:
  21.             i = (j + offset) % n
  22.             next_c_pass = listunion(c_pass, deltas[i])
  23.             next_c_fail = listminus(c_fail, deltas[i])
  24.             if test(next_c_fail) == FAIL and n == 2:
  25.                 c_fail = next_c_fail
  26.                 n = 2; offset = 0break
  27.             elif test(next_c_fail) == PASS:
  28.                 c_pass = next_c_fail
  29.                 n = 2; offset = 0break
  30.             elif test(next_c_pass) == FAIL:
  31.                 c_fail = next_c_pass
  32.                 n = 2; offset = 0break
  33.             elif test(next_c_fail) == FAIL:
  34.                 c_fail = next_c_fail
  35.                 n = max(n - 12); offset = i; break
  36.             elif test(next_c_pass) == PASS:
  37.                 c_pass = next_c_pass
  38.                 n = max(n - 12); offset = i; break
  39.             else:
  40.                 j = j + 1
  41.         if j >= n:
  42.             if n >= len(delta):
  43.                 return (delta, c_pass, c_fail)
  44.             else:
  45.                 n = min(len(delta), n * 2)

1,第三行注释翻译成:“C_PASS是C_PASS'的子集,C_FAIL'是C_FAIL的子集”。想了一想,没错,函数是逐步缩小c_pass和c_fail之间的差异,在书中例子里,也是通常情况下,c_pass是空的,c_fail是“失败全集”。

2,在 j < n 这个循环里,n = 2, i = 0, 把全集分成两部分,如果第一个 if 成立,c_fail等于其中一部分,n = 2, offset = 0, break是否是跳出这一堆if-elif-else?跳出的话回到循环开始,j 没有机会改变,i 也就仍然等于0。我尝试着模拟几种情况,n等于2、4、8,似乎程序跑步到 else 里,j = j + 1 没有机会被执行,i 的值也就得不到改变。也许我对 test 函数的返回理解有误。摇头叹息看不懂看不懂。

作者说在这本书的O'Reilly网页上也有这段代码,于是去下载,下载的代码和书上的不大一样,算法是一致的,清楚多了,一看就明白。再回头看上面这一段,还是觉得不大对。作罢作罢。

文中还提到Continuout Testing。作者说他开了一门课,专门讲授科学方法和增量调试,课程幻灯片和参考文献在:http://www.whyprogramsfail.com/,可是我打不开这个网页。还有增量调试的主页:http://www.st.cs.uni-sb.de/dd/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值