pythonchallenge问题记录

本文将针对pythonchallenge中的问题,做一些学习笔记和解决答案,该网站以看图解谜的方式让玩家通过代码去解决答案,还是比较有意思的,有兴趣的可以独立的去做做看,在解谜中学习代码。

warm up

如图所示,只需要计算2的38次幂,然后把结果填入url中的数字即可
核心代码:2**38

level 4

问题4链接
这道题会做的人十分有技巧性,不会做的只能一番抓耳挠腮后憋出不是很美观的代码,虽然也能实现,但希望你能多思考该问题的解决方案
当你点击图片时,页面会发生跳转
在这里插入图片描述
在这里插入图片描述
看到这个数字,你肯定会想着把拿到的数字去替换掉原来url中的数字。等你替换几次后,他还是不断的跳出数字,系统也提醒你是不是复制累了,这时候就该上代码解决了。
核心步骤:

  • 发送请求,获取响应中的数字
  • 将上一请求拿到的数字去替换原来url中的数字
  • 直至响应没有数字,此时的url就是通往下一关的大门。
    先看看我的笨办法:
import re
import urllib.request
def listToString(s):  
    
    # initialize an empty string 
    str1 = " " 
    
    # return string   
    return (str1.join(s)) 
num="52899"
baseurl="http://www.pythonchallenge.com/pc/def/linkedlist.php?nothing="
url=baseurl+num
result=urllib.request.urlopen(url).read().decode('GBK')
pattern=re.compile(r'\d{1}.*')
resultNum=pattern.findall(result)
resultNum=listToString(resultNum)

while "next" in result :
    num=resultNum
    url=baseurl+num
    result=urllib.request.urlopen(url).read().decode('GBK')
    pattern=re.compile(r'\d{1}.*')
    if "next" in result:
        resultNum=pattern.findall(result)
        resultNum=listToString(resultNum)
print(resultNum)

来讲几个核心函数:

result=urllib.request.urlopen(url).read().decode('GBK')

为什么这里要有read()和decode函数,最好的办法亲自动手去掉他,去掉decode,你会发现
在这里插入图片描述
在做字符串包含判断时,编译器提示,你不能在byte里用string的方法,decode就是将byte变成string,那么read呢,如果你去掉了

<http.client.HTTPResponse object at 0x03203450>
#没去掉的
'peak.html'

read就是将响应变得可读,接下来就是正则匹配的问题了,将响应中的进行数字匹配并提取,如果没匹配到数字了,说明已经到头了。

pattern=re.compile(r'\d{1}.*')
#\d代表数字,{1}代表重复次数。{3}时就代表有三个数字,.*代表至少后面还跟一位
resultNum=pattern.findall(result)
#findall匹配出的结果是存到list中,这时还需要将list转为string,这样才能将其加到url后
resultNum=listToString(resultNum)
def listToString(s):  
    
    # initialize an empty string 
    str1 = " " 
    
    # return string   
    return (str1.join(s)) 

看了这个方案是不是觉得太繁琐了,又要正则,又得list转换,重复代码还多,那就来看看四两拨千斤的方案

import urllib
import urllib2

data= {}
number = '12345'

for i in range(400):
	data['nothing'] = number
	url_values = urllib.urlencode(data)
	url = 'http://www.pythonchallenge.com/pc/def/linkedlist.php'
	full_url = url + '?' + url_values
	
	foo = urllib2.urlopen(full_url)
	foo = foo.read()
	print foo
	foo = foo.split(" ")
	
	number = [i for i in foo if i.isdigit()][0]

惊讶于代码整洁性的同时,或许你会疑惑number = [i for i in foo if i.isdigit()][0]是干嘛的,这也是最关键的一句,功能你能猜出来,但用法可能会有些疑惑:
在这里插入图片描述
明白了吗?他只是功能代码的缩写。expression代表你要对提取的数字的操作,来看个例子

foo = "next 12 4 5 6"
foo = foo.split(" ")
number = [int(i)+1 for i in foo if i.isdigit()]
print(number)

输出结果:

[13, 5, 6, 7]

详细解释摸我
知道了这个用法,其实你还可以发散一下思维,原来的list转string,用这个也能做了

s = ['I', 'want', 4, 'apples', 'and', 18, 'bananas'] 
  
# using list comprehension 
listToStr = ' '.join([str(elem) for elem in s]) 
  
print(listToStr)  

convert-a-list-to-string

level 5

这题显得有些匪夷所思,还要做题者会读英文,当然也需要一定python基础才会知道,他要考察的是python的pickle,序列化,反序列化的函数,题目往往隐藏在页面源码的注释中,

import urllib2, sys, pickle
data = pickle.loads(urllib2.urlopen('http://www.pythonchallenge.com/pc/def/banner.p').read())
for line in data:
    for char, count in line: sys.stdout.write(char * count)
    sys.stdout.write("\n")

执行结果:图形是个channel英文
在这里插入图片描述
pickle的使用可以参看这篇文章:pickle tutorial

level 6

本题比较花里胡哨,先要下载一个zip文件,主要考察对zip文件的读取,解压后里面的txt文件内容显示的是Next nothing is 2144,主要找到没有next的文件就是答案了,同样需要用到正则匹配。

import  zipfile
from zipfile import ZipFile
with ZipFile('E:\workspace\python\challenge\channel.zip', 'r') as zipObj:
   # Get list of files names in zip
   listOfiles = zipObj.namelist()
   f=1
   # Iterate over the list of file names in given list & print them
   for elem in listOfiles:
       a=zipObj.read(elem).decode('utf-8')
       if "Next" in a:
           f=1
       else:
           f=0
       if f ==0:
           print(a)
           print(elem)
           break
   zipObj.close()

这里代码要排除readme的特殊文件,其他的都可以进行遍历去正则匹配,最后输出的文件内容为:Collect the comments.到了这里,发现离答案还有距离
python操作zip

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值