【show me the code】Python练习题&语法笔记 1

00题. 微信未读信息数量提示

0. 问题描述及代码

将你的 QQ 头像(或者微博头像)右上角加上红色的数字,类似于微信未读信息数量那种提示效果。

from PIL import Image, ImageDraw, ImageFont

def add_num_to_img(image_path, sign="2019"):
	im = Image.open(image_path)
	width, height = im.size
	
	draw = ImageDraw.Draw(im)
	#truetype是一种字体库,参数分别是字体,大小
	font = ImageFont.truetype("arial.ttf", min(width//6, height//6))
	draw.text((width*0.75, height*0.075), sign, font=font, fill=(255,33,33,255))

	#rsplit分割,.左边是路径和文件名,.右边是文件格式
	left, right = image_path.rsplit(".", 1)
	new_iamge_path = left + "_" + sign + "." + right
	im.save(new_iamge_path)

if __name__ == '__main__':
	# for test
	add_num_to_img("./sample.jpg")
	print("Finished.")

1. split( ) , rsplit( ) , splitlines( )

语法:

s.split([sep=None][,count=S.count(sep)])

参数:
sep – 可选参数,指定的分隔符,默认为所有的空字符,包括空格、换行(\n)、制表符(\t)等。
count – 可选参数,分割次数,默认为分隔符在字符串中出现的总次数。

返回值:
返回分割后的字符串列表

实例:

#!/usr/bin/python3
S = "this is string example....wow!!!"
print (S.rsplit( ))
print (S.rsplit('i',1))
print (S.rsplit('w'))
['this', 'is', 'string', 'example....wow!!!']
['this is str', 'ng example....wow!!!']
['this is string example....', 'o', '!!!']

split( )从左向右寻找,rsplit( )相反。

splitlines( )根据换行符( \n )分割并将元素放入列表中。

c = "hello\nworld\ndlrb"
c1 = c.splitlines()
print(c1)
['hello', 'world', 'dlrb']

2. Pillow

PIL:Python Imaging Library,Python平台事实上的图像处理标准库。

PIL仅支持到python 2.7,Pillow 是其基础上的兼容版本,支持3.x

安装:

$ pip install pillow

操作图像:

ImageDraw画画,ImageFont字体,ImageFilter滤波处理(平滑、锐化、边界增强等)

from PIL import Image, ImageDraw, ImageFont, ImageFilter

import random

# 随机字母:
def rndChar():
    return chr(random.randint(65, 90))

# 随机颜色1:
def rndColor():
    return (random.randint(64, 255), random.randint(64, 255), random.randint(64, 255))

# 随机颜色2:
def rndColor2():
    return (random.randint(32, 127), random.randint(32, 127), random.randint(32, 127))

# 240 x 60:
width = 60 * 4
height = 60
image = Image.new('RGB', (width, height), (255, 255, 255))
# 创建Font对象:
font = ImageFont.truetype('Arial.ttf', 36)
# 创建Draw对象:
draw = ImageDraw.Draw(image)
# 填充每个像素:
for x in range(width):
    for y in range(height):
        draw.point((x, y), fill=rndColor())
# 输出文字:
for t in range(4):
    draw.text((60 * t + 10, 10), rndChar(), font=font, fill=rndColor2())
# 模糊:
image = image.filter(ImageFilter.BLUR)
image.save('code.jpg', 'jpeg')

01题. 生成激活码

0. 问题描述及代码

作为 Apple Store App 独立开发者,你要搞限时促销,为你的应用生成激活码(或者优惠券),使用 Python 如何生成 20 个激活码(或者优惠券)?

import random, string
 
def rand_str(num, length=7):
    f = open('01激活码.txt', 'w')
    for i in range(num):
        chars = string.ascii_letters + string.digits
        s = [random.choice(chars) for i in range(length)]
        f.write('{0}\n'.format(''.join(s)))
    f.close()
    print("Finished")
 
if __name__ == '__main__':
    rand_str(20)

1. random模块

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import random

print( random.randint(1,10) )       # 产生 1 到 10 的一个整数型随机数  
print( random.random() )            # 产生 0 到 1 之间的随机浮点数
print( random.uniform(1.1,5.4) )    # 产生  1.1 到 5.4 之间的随机浮点数,区间可以不是整数
print( random.choice('tomorrow') )  # 从序列中随机选取一个元素
print( random.randrange(1,100,2) )  # 生成从1到100的间隔为2的随机整数

a=[1,3,5,6,7]  # 将序列a中的元素顺序打乱
random.shuffle(a)
print(a)

2. string模块ascii_letters和digits方法

ascii_letters生成所有字母(a-z&A-Z);digits生成所有数字(0-9)。
示例:

>>> chars = string.ascii_letters + string.digits
>>> print(chars)
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789

3. 文件读写

写文件:

>>> f = open('/Users/michael/test.txt', 'w')
>>> f.write('Hello, world!')
>>> f.close()

这样更好:

with open('/Users/michael/test.txt', 'w') as f:
    f.write('Hello, world!')

读文件同理:

with open('/path/to/file', 'r') as f:
    print(f.read())

4. format 格式化函数

增强了字符串格式化的功能,基本语法是通过 {} 和 : 来代替以前的 %

>>>"{} {}".format("hello", "world")  # 不设置指定位置,按默认顺序
'hello world'

02题. 保存激活码到 MySQL 关系型数据库

0. 问题描述及代码

将 0001 题生成的 20 个激活码(或者优惠券)保存到 MySQL 关系型数据库中。

import random
import pymysql
import string

def creat_num(num,length):
    str = string.ascii_letters + string.digits
    b = []
    for i in range(num):
        a = ''
        for j in range(length):
            a += random.choice(str)
        b.append(a)
    return b

def InsertIntoMysql(codelist):
    # 打开数据库连接
    db = pymysql.connect(host='127.0.0.1',user='root',passwd='919824467',db='mysql')
    # 使用 cursor() 方法创建一个游标对象 cursor
    cur = db.cursor()
    #数据库语句
    cur.execute('CREATE DATABASE IF NOT EXISTS code')
    cur.execute('USE code')
    cur.execute('''CREATE TABLE IF NOT EXISTS num(
                    id INT NOT NULL AUTO_INCREMENT,
                    code VARCHAR(32) NOT NULL,
                    PRIMARY KEY(id) )''')
    for num in codelist:
        cur.execute('INSERT INTO num(code) VALUES(%s)',(num))
        cur.connection.commit()
    db.close()

InsertIntoMysql(creat_num(200,10))

1. MySQL 教程

MySQL 教程 | 菜鸟教程

游标(cursor)是系统为用户开设的一个数据缓冲区,存放SQL语句的执行结果。每个游标区都有一个名字,用户可以用SQL语句逐一从游标中获取记录,并赋给主变量,交由主语言进一步处理。

cursor() — 数据库连接操作 python

03题. 保存激活码到 Redis 非关系型数据库

0. 问题描述及代码

将 0001 题生成的 20 个激活码(或者优惠券)保存到 Redis 非关系型数据库中。

# -*- coding: utf-8 -*-

import redis
import random 
import string 

forSelect = string.ascii_letters + string.digits

def generate_code(count, length)
    for x in range(count):
        Re = ""
        for y in range(length):
            Re += random.choice(forSelect)
        yield Re # generator 生成器
        
def save_code():
    r = redis.Redis(host='127.0.0.1',port='6379',password='linyii')
    codes = generate_code(20,7)
    p = r.pipeline() # pipeline允许客户端一次发送多条命令
    for code in codes:
        # Redis Sadd 命令将一个或多个成员元素加入到集合中,已经存在于集合的成员元素将被忽略。
        p.sadd('code',code)
    p.execute() # 执行
    return r.scard('code') # Redis Scard 命令返回集合中元素的数量。
    
if __name__ == '__main__':
    save_code()

1. yield函数 — generator(生成器)

参考资料:Python yield 使用浅析 —— 廖雪峰

在一个生成数列的函数中,使用 print(),而不用 return 会导致复用性差,因为函数返回 None,会使其他函数无法获得该函数生成的数列。

要提高该函数的可复用性,最好不要直接打印出数列,而是返回一个 List。

新的问题是,该函数在运行中占用的内存会随着 List 的增大而增大,如果要控制内存占用,最好不要用 List 来保存中间结果,而是通过 iterable 对象来迭代。

如果我们想要保持函数的简洁性,同时又要获得 iterable 的效果,yield 就派上用场了:

def fab(max): 
    n, a, b = 0, 0, 1 
    while n < max: 
        yield b 
        # print b 
        a, b = b, a + b 
        n = n + 1 

仅仅把 print b 改为了 yield b,就在保持简洁性的同时获得了 iterable 的效果。

简单地讲,yield 的作用就是把一个函数变成一个 generator,带有 yield 的函数不再是一个普通函数,Python 解释器会将其视为一个 generator,调用 fab(5) 不会执行 fab 函数,而是返回一个 iterable 对象!

在 for 循环执行时,每次循环都会执行 fab 函数内部的代码,执行到 yield b 时,fab 函数就返回一个迭代值,下次迭代时,代码从 yield b 的下一条语句继续执行,而函数的本地变量看起来和上次中断执行前是完全一样的,于是函数继续执行,直到再次遇到 yield。

yield 的好处是显而易见的,把一个函数改写为一个 generator 就获得了迭代能力,比起用类的实例保存状态来计算下一个 next() 的值,不仅代码简洁,而且执行流程异常清晰。

另一个 yield 的例子来源于文件读取。如果直接对文件对象调用 read() 方法,会导致不可预测的内存占用。好的方法是利用固定长度的缓冲区来不断读取文件内容。通过 yield,我们不再需要编写读文件的迭代类,就可以轻松实现文件读取:

def read_file(fpath): 
   BLOCK_SIZE = 1024 
   with open(fpath, 'rb') as f: 
       while True: 
           block = f.read(BLOCK_SIZE) 
           if block: 
               yield block 
           else: 
               return

2. Redis 教程

Redis 教程 | 菜鸟教程

3. 关系型数据库和非关系型数据的比较

原文链接

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值