本质上,该程序使用OEIS序列号(例如
55
表示序列A000055
),并返回序列中的第n个数字。代码获取OEIS页,对其进行解析使用BeautifulSoup,并返回结果,如果不存在,则返回“ OEIS在给定索引的序列中没有数字”。
import sys, re from urllib2 import* from bs4 import BeautifulSoup # Main logic def execute(code, nth): # Decode input stuff num = int(code) try: f = urlopen("http://oeis.org/A%06d/list" % num) # global tree, data # Debugging # >:D I'm sorry but I have to use RegEx to parse HTML print {key: int(value) for key, value in re.findall( r'(\d+) (\d+)', re.sub(r'\D+', " ", re.sub(r'<[^>]+>', "", str(BeautifulSoup(f, "lxml").find(lambda tag: tag.name == "table" and # A table not tag.get('cellspacing') == "0" and # A table table len(tag.contents) > 1 # A two column table )) )) ) }.get(nth, "OEIS does not have a number in the sequence at the given index") except HTTPError: print "Could not find sequence A%06d" % num except URLError: print "Could not connect to sources"; except: print "Verify your numbers are correct" raise if __name__ == '__main__': if len(sys.argv) > 1: execute(sys.argv[1], sys.argv[2]) else: print """This is the OEIS lookup tool You haven't entered the sequence""" % (LANGNAME)
。我使用的是我只会理解的东西。我主要关心的是我如何布置此程序。尤其是HTML解析,我真的怀疑我是否以最好的方式做到了。
#1 楼
import*
:请避免不惜一切代价
import
所有模块。分别导入您使用的每个模块Regexಠ_ಠ
Regex是邪恶的,最糟糕的。认真地。停下来。马上。立即杀死python.exe并进行更改。
几秒钟后,您实际上会使用dom解析库beautifulsoup,但是您选择使用regex。
您,先生,这是邪恶的。
我建议您进一步研究beautifulsoup,或者看看Scrapy,这是一个Python的抓取库,它利用生成器来抓取大元素集(甚至具有云支持!)
Lisp
您的代码读起来像Lisp。
))
)) )
,严重的是,您需要更好地设置其格式。
请尝试使用Python的样式指南PEP8。通过在线分析器运行代码时,它立即引发20个错误。
编写良好的Python时,PEP8应该是您的goto样式文档。
循环
不应像这样循环:
print {key: int(value) for key, value in
如果要减少代码缩进级别,那么您应该使用单独的变量来存储过程中的每个步骤,或者仅使用标准循环即可。
字符串格式化
而不是使用
% (myString)
,您应该使用string.format
,因为这是出于以下原因的改进:参数顺序的独立性
更易读
"My name is {name}, and I work for {work_name} as a {job_name}".format(name="Batman", work_name="Gotham City", job_name="Crimestopper")
评论
\ $ \ begingroup \ $
string.format和%mystring有什么区别
\ $ \ endgroup \ $
–下山羊
16年2月16日在1:48
\ $ \ begingroup \ $
解析OEIS HTML的原因将是一个混蛋
\ $ \ endgroup \ $
–下山羊
16年2月16日在2:22
\ $ \ begingroup \ $
这与我在评论中建议的相反。
\ $ \ endgroup \ $
– Quill
16-2-16在4:29
\ $ \ begingroup \ $
@Downgoat string.format具有更多的格式化选项,与%格式化相比,它可以使您做更多的事情。 string.format还可以将类型强制转换为字符串,因此通常不需要将内容显式转换为字符串。
\ $ \ endgroup \ $
–SuperBiasedMan
16年2月16日在9:33
\ $ \ begingroup \ $
@Downgoat:
td> table>是合法的HTML,请参阅w3.org/TR/html5/tabular-data.html#the-tr-element
\ $ \ endgroup \ $ –查尔斯 16-2-16在13:53 #2 楼您根本不需要HTML解析。 OEIS具有不错的JSON输出格式。https://oeis.org/search?fmt=json&q=id:A000045 所以程序的核心功能可以是写成类似 评论\ $ \ begingroup \ $ 这可以变得更好-我认为-与请求:从请求导入get和doc = get(“ https://oeis.org/search”,params = {“ fmt”:“ json”,“ q “:” id:“ +代码})。json()。 \ $ \ endgroup \ $ – FinnÅrupNielsen 16-2-16在13:37 #3 楼冗余代码 这很容易变成 您不小心将Putt的一些剩余代码留在那里。 ♫让我们一起跳上代码审查总线...♫ #4 楼错误消息 错误消息应该发送至STDERR,而不是打印至STDOUT 。这样可以从实际输出中过滤错误消息,这对于调试和日志记录很有用。 文档和变量命名 类似 < pre class =“ lang-py prettyprint-override”> # Decode input stuff
对于不知道 code 是什么的人来说不是特别有用(“为什么一段代码是数字?”),对于知道code 是什么的人来说可能仍然没有用。 不那么模棱两可。 当我们讨论这个主题时,这里使用的许多变量名都是非常通用的。像 key, value 这样的一次性名称很好,但是code 和num 对其所指的含义并不特别清楚。代替num ,而是sequence_number ,seqnum 还是a_number 的原因,因为它与OEIS相关,所以execute 的方法也没有得到很好的记录,即使您很好地描述了print {key: int(value) for key, value in
re.findall( r'(\d+) (\d+)', re.sub(r'\D+', " ", re.sub(r'<[^>]+>', "",
str(BeautifulSoup(f, "lxml").find(lambda tag:
tag.name == "table" and # A table
not tag.get('cellspacing') == "0" and # A table table
len(tag.contents) > 1 # A two column table
))
)) )
}.get(nth, "OEIS does not have a number in the sequence at the given index")
方法的工作原理。帖子的顶部。考虑将您的解释或类似内容作为文档字符串放入其中。一般可读性 此 一次执行的操作太多,因此很难说出从哪里开始阅读。将其分成几部分-如果您有将非数字游程转换为空格的步骤,请将其放在自己的行上,而不是将所有内容链接在一起。 检查不等式 为什么不 cellspacing ?或者,如果int(tag.get('cellspacing')) > 0 是数字,则q4312079q吗?#5 楼这里是一些问题:考虑docopt。它迫使您考虑脚本文档。 还考虑将脚本作为有关命名和文档的模块来使用。我想这取决于您的应用。 将 print 与函数分开。考虑从一或零开始索引。当前,您正在使用从零开始索引 get(nth, ...) 。我宁愿从一个索引,所以第一个数字称为1。OEIS是否将第一个值称为第零? request 可能比urllib2 更好这是我尝试使用@Vortico建议的JSON接口(也应考虑缺少异常处理) : |
评论
“>:D很抱歉,我必须使用RegEx来解析HTML”-相关。