闪电侠接金币向后移动背景

闪电侠接金币封面设计


"""
   闪电侠接金币的滚动背景类。
"""

import pygame
from pygame.locals import *

class Background:
    """不断向后移动的滚动背景"""
    def __init__(self,image,screen):
        """初始化函数"""
        self.screen = screen
        self.w = screen.get_width()     # 记录屏幕宽度
        self.h = screen.get_height()    # 记录屏幕高度
      
        
    def update(self):
        """更新两个矩形的坐标"""
        

    def draw(self):
        """重画"""
         
    
if __name__ == "__main__":

    width,height = 960,720
    screen = pygame.display.set_mode((width,height))
    pygame.display.set_caption("闪电侠接金币滚动背景类 www.lixingqiu.com")

    bgs = pygame.image.load("space.png")
    background = Background(bgs,screen)

    clock = pygame.time.Clock()
    running = True
    while running:
        for event in pygame.event.get():
            if event.type == QUIT:running = False
            
        background.update()
        
        background.draw()
        pygame.display.update()

    pygame.quit()

        

下载完整源代码与素材,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 pygame, python | 闪电侠接金币向后移动背景已关闭评论

自动生成scratch2或scratch3作品核心代码

scratch2或scratch3的作品能通过Python编程自动生成吗?答案是肯定的,因为它的作品文件是一个压缩包,你把它解压后,分析它解压后的文件就能得出结论。对于一些简单的作品,如只是切换造型的,那可以通过Python编程读取gif文件,拆帧等操作,形成json文件,最后用zip打包,再改名或者连名都不要改,scratch2或scratch3就能自动加载。以下是一个函数,它能形成.sprite2角色文件!展示的是核心代码,基本原理都清楚了,其它的就要靠你自己了!

def make_scratch2_sprite(path,size):
   """生成scrach2.0角色,它的脚本只是不断地换造型"""
 
   sprite = {}            # 代表一个角色,这个角色有名称,声音列表,造型列表
   sprite['objName'] = "sprite1"
   sprite['scripts'] = [[131, 202, [["whenGreenFlag"], ["gotoX:y:", 0, 0],["doForever", [["wait:elapsed:from:", 0.2], ["nextCostume"]]]]]]
    
   costumes_list = []     # 造型列表
   md5_file_list = []     # md5值 图形文件列表
   # 形成每个png文件的由md5值文件名
   for filename in os.listdir(path):
        md5 = GetFileMd5(path + os.sep + filename)         
        md5_file_list.append(md5 + ".png")
   amounts = len(md5_file_list)
   
   # 下面的代码是形成角色的造型列表
   for index in range(1,amounts+1):      
      costume = {}           # 一个造型
      costume['costumeName'] = "shape" + str(index)   # 造型名称       
      costume['baseLayerID'] = index-1                # 造型编号
      costume['baseLayerMD5'] = md5_file_list[index-1]# MD5值文件名
      costume['bitmapResolution'] = 2                 # 位图  2
      costume['rotationCenterX'] = size[0]//2         # x旋转中心 
      costume['rotationCenterY'] = size[1]//2         # y旋转中心
      costumes_list.append(costume)                   # 添加一个造型到列表
   sprite['costumes'] = costumes_list
   sprite['currentCostumeIndex'] = 0
   sprite['scratchX'] = 0
   sprite['scratchY'] = 0
   sprite['scale'] = 2
   sprite['direction'] = 90
   sprite['rotationStyle'] = "normal"
   sprite['isDraggable'] = False
   sprite['indexInLibrary'] = 100000
   sprite['visible'] = True
   sprite['spriteInfo'] = {"url":"www.scratch8.net"}

   # 把sprite字典转换成json格式,写入文件
   json_string = json.dumps(sprite)
   f = open(path + os.sep + "sprite.json",mode='w')
   f.write(json_string)
   f.close()

   os.chdir(path)
   # 下面开始压缩图片和json档
   with zipfile.ZipFile( 'sprite.sprite2', mode='w') as zipf:
      for filename in os.listdir():
         ext = os.path.splitext(filename)[-1]
         if ext != ".sprite2":
            zipf.write(filename)
   zipf.close()

 

发表在 python, scratch | 自动生成scratch2或scratch3作品核心代码已关闭评论

winzipfile打包压缩文件夹小程序

"""winzipfile打包文件夹小程序,本程序会递归地把文件夹中的每一个文件添加到一个压缩包中"""

import os
import zipfile
from tkinter import *
from tkinter import filedialog,messagebox

window = Tk()
path = filedialog.askdirectory(parent=window,initialdir="/",title='请选择一个文件夹。')
print("你选择的文件夹是:",path)

zipf =  zipfile.ZipFile( 'c:/zipfile.zip', mode='w')  
for root,dirs,files in os.walk(path):
    for file in files:
        filename = root + os.sep + file
        print(filename)
        zipf.write(filename)
zipf.close()

messagebox.showinfo("完毕","OK")
window.destroy()
#os.system("explorer " + path)

 

发表在 python | winzipfile打包压缩文件夹小程序已关闭评论

风火轮走迷宫项目核心代码

"""风火轮走迷宫项目核心代码,本人去年计划的一个小项目的原型代码,修改turtle.py让图形角色可以直接旋转.
   启动程序后,输入代码,指挥风火轮移动! 可以把它完善为一个完整的编程入门教育游戏.
   下面的turtle模块为本人修改后的. 如果你要问迷宫呢?  这就得靠你自己了! 
"""


from turtle import TurtleScreen, RawTurtle, TK

def run_code():
    code_string = text_code.get("1.0",'end-1c')    
    "禁用运行按钮"
    run_command.config(state='disabled')
    exec(code_string)
    "启用运行按钮"
    run_command.config(state='normal')
    
def main():
    global text_code
    global cat
    global screen
    global run_command

    default_code = """for _ in range(4):
    cat.fd(100)
    cat.rt(90)
    """
    root = TK.Tk()
    root.geometry("740x660")
    root.title("风火轮走迷宫项目核心代码 www.lixingqiu.com")
    cv1 = TK.Canvas(root, width=540, height=420, bg="#000000")     
    cv1.place(x = 190,y = 10)    

    screen = TurtleScreen(cv1)
    screen.bgcolor(0.85, 0.85, 1)
    
    text_code=TK.Text(root,width=40,height=10,font=("黑体", 16, "normal"))
    text_code.insert("1.0",default_code)
    text_code.place(x = 190,y = 440)    

    run_command = TK.Button(root,text='运行',command=run_code,font=('黑体',20),bg='white',fg='red')
    run_command.place(x = 650,y = 480)

    #screen.addshape("风火轮子logox.png") # 支持png不需注册即可直接使用
    cat = RawTurtle(screen,visible=False) 
    cat.color("red")
    cat.width(3)
    cat.shape("风火轮子logox.png")
    cat.rotatemode("all")     # 新增旋转模式,角色可360度旋转
    cat.st()                  # 显示小猫     

    return "EVENTLOOP"


if __name__ == '__main__':
    
    main()
    TK.mainloop()  # 进入事件循环

风火轮走迷宫项目核心代码 www.lixingqiu.com

发表在 python, turtle | 风火轮走迷宫项目核心代码已关闭评论

pygame程序实现的是一个用图像模拟的3D效果地图

pygame程序实现的是一个用图像模拟的3D效果地图"""
下面是部分代码预览:

"""本pygame程序实现的是一个用图像模拟的3D效果地图"""

import pygame
from pygame.locals import *

width,height = 480,360

screen = pygame.display.set_mode((width,height))
pygame.display.set_caption("可移动3D背景 www.lixingqiu.com")

backgrounds = [pygame.image.load(f"frames/i-{index+1}.png") for index in range(36)]
amounts = len(backgrounds)
clock = pygame.time.Clock()
running = True

while running:
    for event in pygame.event.get():
        if event.type == QUIT:running = False
      
    clock.tick(30)
pygame.quit()

下载完整源代码与素材,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 pygame, python | pygame程序实现的是一个用图像模拟的3D效果地图已关闭评论

风火轮语音识别器

"""风火轮语音识别器,去年写的一个python程序,识别语音的,就是把wav,mp3转换成文本,调用的是百度API,有需要的把代码拿去,换成自己的APPID就行.
"""

import tkinter 
from tkinter import StringVar,filedialog
import tkinter.messagebox
import os
from aip import AipSpeech


def addToClipBoard(text):
    """把文本增加到剪粘板"""
    command = 'echo ' + text.strip() + '| clip'
    os.system(command)

def get_file_content(filePath):
    with open(filePath, 'rb') as fp:
        return fp.read()

def echo(audiofile,extname):
    """ 识别本地未压缩的wav文件和pcm文件,下表是dev_pid参数说明:
    1536	普通话(支持简单的英文识别)	搜索模型	无标点	支持自定义词库
    1537	普通话(纯中文识别)	输入法模型	有标点	不支持自定义词库
    1737	英语		有标点	不支持自定义词库
    1637	粤语		有标点	不支持自定义词库
    1837	四川话		有标点	不支持自定义词库
    1936	普通话远场	远场模型	有标点	不支持
    """
    result=""
    try:
       p=client.asr(get_file_content(audiofile), extname, 16000, {'dev_pid': 1536,})
       result = p['result'][0]
    except:
        pass
    
    return result

def showapp():
    # 创建应用程序窗口
    root = tkinter.Tk()
    root.title("风火轮语音识别器")
    varName = StringVar()
    varName.set('')
     
    # 设置窗口大小
    root.geometry('800x280+300+150')
 
    # 创建标签
    labelTitle = tkinter.Label(root, text=appName, justify=tkinter.CENTER , font=("微软雅黑", 24),fg='red')
    # 将标签放到窗口上
    labelTitle.place(x=280, y=50)
    
    # 创建标签
    labelName = tkinter.Label(root, text='结果:', justify=tkinter.RIGHT,width=80, font=("微软雅黑", 14))
    # 将标签放到窗口上
    labelName.place(x=00, y=150, width=90, height=20)


    # 创建标签
    labelWait = tkinter.Label(root, text='', justify=tkinter.RIGHT,width=80, font=("微软雅黑", 14),fg='blue')
    # 将标签放到窗口上
    labelWait.place(x=10, y=100, width=90, height=20)

    # 创建文本框,同时设置关联的变量 entryName.get()参获取文本
    entryName = tkinter.Entry(root, width=450,  textvariable=varName,bg='#E0E0C4',font=("微软雅黑", 16))

    entryName.place(x=80, y=140, width=700, height=35)
     
    
    def cancel():
        root.destroy()

    
    def aboutme():
        tkinter.messagebox.showinfo(appName,"作者:李兴球")
    def helpyou():
        helpinfo = "请单击'浏览'按钮选择未经压缩的wav、pcm或amr音频文件。\n\n音频文件的时长不要超过一分钟。\n\n成功后会自动把内容放置在剪粘板里。"
        tkinter.messagebox.showinfo(appName,helpinfo)
    def select():
   
        filename=filedialog.askopenfilename(filetypes=[("未压缩的wav", "*.wav"),("pcm文件", "*.pcm"),("amr文件", "*.amr"),("所有文件", "*.*")])
        extname = os.path.splitext(filename)[1]
        extname = extname[1:]
        extname = extname.lower()
         
        labelWait.config(text= "请稍候...")
        root.update()
        result = echo(filename,extname)
        labelWait.config(text= "") 
        if result != "" :
            varName.set(result)
            addToClipBoard(result)   #放到剪粘板上
        else:
            labelWait.config(text= "无法识别...")       
 
    
    buttonSelect = tkinter.Button(root, text='浏览', bg="#ADA758", font=("微软雅黑", 14),command=select)
    buttonSelect.place(x=160, y=220, width=75, height=35)
        
    buttonAbout = tkinter.Button(root, text='关于', bg="#ADA758", font=("微软雅黑", 14),command=aboutme)
    buttonAbout.place(x=260, y=220, width=75, height=35)

    buttonOk = tkinter.Button(root, text='帮助', bg="#ADA758", font=("微软雅黑", 14),command=helpyou)
    buttonOk.place(x=360, y=220, width=75, height=35)

    buttonCancel = tkinter.Button(root, text='退出', bg="#ADA758",
                                  font=("微软雅黑", 14), command=cancel)
    buttonCancel.place(x=460, y=220, width=75, height=35)
    # 启动消息循环
    root.mainloop()

if __name__ == "__main__":
    
    appName = '风火轮语音识别器'

    """ 百度开发者蓝杰稀饭的 APPID AK SK """
    APP_ID = '你的ID'
    API_KEY = '你的KEY'
    SECRET_KEY = '你的安全key'

    client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)
    
    showapp()

风火轮语音识别器

发表在 python, Uncategorized | 风火轮语音识别器已关闭评论

动态背景_蓝天绿地太阳云朵户外场景动画演示

动态背景_蓝天绿山绿地太阳云朵
一个蓝天白云太阳动态场景,配的音乐效果不错!
以下是部分代码预览:

"""动态背景_蓝天绿地太阳云朵户外场景动画演示"""

__author__ = "李兴球"
__date__ = "2019/6/3"
__website__ = "www.lixingqiu.com"

import time
import pygame
from random import *
from pygame.locals import *

class Sun:
    def __init__(self,images,position):
        self.images = images
        self.index = 0             # 造型索引
        
    def update(self):
        pass

    def set_costume(self,index):
        """设置造型"""
        self.image = self.images[index]

class Cloud(pygame.sprite.Sprite):
    def __init__(self,images,group,screen_width):
        super().__init__()
        pass

if __name__ == "__main__":

    width,heigt = 480,360
    screen = pygame.display.set_mode((480,360))
    pygame.display.set_caption("动态背景_蓝天绿地太阳云朵户外场景动画演示www.lixingqiu.com")

    pygame.mixer.init()
    pygame.mixer.music.load("Yonderboi - Pabadam.wav")
    pygame.mixer.music.play(-1,0)

    background = pygame.image.load("images/background.png")
   
    sun = Sun(sun_images,(150,50))

    clock = pygame.time.Clock()
    running = True
    while running:
        event = pygame.event.poll()
        if event.type == QUIT: running = False
        if randint(1,100) == 1 : Cloud(cloud_images,cloud_group,width )
 
        pygame.display.update()
        clock.tick(30)

    pygame.quit()
        

下载完整源代码与素材,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 pygame, python | 动态背景_蓝天绿地太阳云朵户外场景动画演示已关闭评论

大地图相对运动scratch小猫过桥源码

pygame大地图相对运动scratch小猫过桥
操作一只小猫在一个大花园里走来走去,配的音乐效果不错。
下面是部分代码预览:

"""本程序操作一只小猫在一个绿色的园林中行走,其实小猫的坐标是不变的,变的是地图坐标"""

import time
import pygame
from pygame.locals import *

width,height = 480,360
screen = pygame.display.set_mode((width,height))
pygame.display.set_caption("大地图相对运动scratch小猫过桥 www.lixingqiu.com")

pygame.mixer.init()
pygame.mixer.music.load("Grandia OST - Delightful Adventure.wav")
pygame.mixer.music.play(-1,0)

ground = pygame.image.load("地图.png")
size = ground.get_size()
ground = pygame.transform.scale(ground,(size[0] * 3,size[1] * 3)) # 放大3倍地图

cat = Actor(images_right,images_left)
cat.rect.center = width//2,height//2
running = True
cat.start_time = time.time()
clock = pygame.time.Clock()
while running:
    for event in pygame.event.get():
        if event.type == QUIT:running = False
    ground_rect.move_ip(ground_dx,ground_dy) 
    cat.update()
    screen.fill((102,226,60))
    screen.blit(ground,ground_rect)
    screen.blit(cat.image,cat.rect)
    
    pygame.display.update()
    clock.tick(60)
    
pygame.quit()
            

下载完整源代码与素材,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 pygame, python | 大地图相对运动scratch小猫过桥源码已关闭评论

梦幻背景_绿色瀑布风景dynamic background waterfall parallax

动态背景_绿色瀑布风景waterfall parallax www.lixingqiu.com
鼠标动一动,有一种3D效果,配的音乐确实不错哦,充满梦幻的感觉。

"""动态背景_绿色瀑布风景waterfall parallax,这本来是一个scratch作品,现在用Python把它做一下."""

import pygame
from pygame.locals import *

width,height = 480,360
screen = pygame.display.set_mode((width,height))
pygame.display.set_caption("动态背景_绿色瀑布风景waterfall parallax www.lixingqiu.com")

pygame.mixer.init()
pygame.mixer.music.load("The Departure - Max Richter.mp3.wav")
pygame.mixer.music.play(-1,0)

costume1 = pygame.Surface((width,height))
costume1.fill((0,102,34))

costume2 = pygame.image.load("images/costume2.png").convert_alpha()
costume2_rect = costume2.get_rect()

costume3 = pygame.image.load("images/costume3.png").convert_alpha()
costume3_rect = costume3.get_rect()

costume4 = pygame.image.load("images/costume4.png").convert_alpha()
costume4_rect = costume4.get_rect()

costume5 = pygame.image.load("images/costume5.png").convert_alpha()
costume5_rect = costume5.get_rect()

costume6 = pygame.image.load("images/costume6.png").convert_alpha()
costume6_rect = costume6.get_rect()

costume7 = pygame.image.load("images/costume7.png").convert_alpha()
costume7_rect = costume7.get_rect()
 
clock = pygame.time.Clock()
running = True

while running:
    event = pygame.event.poll()
    if event.type == QUIT:running = False
    mx,my = pygame.mouse.get_pos()
 
    pygame.display.update()
    clock.tick(30)     

pygame.quit()

下载完整源代码与素材,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 pygame, python | 梦幻背景_绿色瀑布风景dynamic background waterfall parallax已关闭评论

Chinese Music花瓣雨飞舞的春天_pygame动态背景样本

Chinese Music花瓣飞舞的春天_pygame动态背景样本程序
最浪漫的时刻莫过于在这幅画里海誓山盟。配的音乐也是挺恰当的。
下面是部分代码预览:


"""Chinese Music花瓣雨飞舞的春天,制作一个标准的帧动画以肆世人,2019/6/2,李兴球@萍乡"""

import time
import pygame
from pygame.locals import *

class Dynamic_background:
      pass

def main():
    """主要函数"""
    width,height = 960,538
    screen = pygame.display.set_mode((width,height))
    pygame.display.set_caption("Chinese Music花瓣雨飞舞的春天 by www.lixingqiu.com")

    pygame.mixer.init()
    pygame.mixer.music.load("Andy Lau - Wu (piano) [mp3clan.com].mp3.wav")
    pygame.mixer.music.play(-1,0)

    clock = pygame.time.Clock()
    running = True
    
    frames = [pygame.image.load(f"frames/{index}.png") for index in range(22)]
    background = Dynamic_background(frames)
    
    while pygame.event.poll().type != QUIT:
        background.update()
        screen.blit(background.image,(0,0))
        pygame.display.update()
        clock.tick(60)

    pygame.quit()

if __name__ == "__main__":

    main()    
        
    

下载完整源代码与素材,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 pygame, python | Chinese Music花瓣雨飞舞的春天_pygame动态背景样本已关闭评论

多个搜索引擎结果第一页分析程序

这是我两年前写的一个程序。有需要的可以拿去分析。

"""从搜索引擎查询结果返回的第一页html提取信息,本项目的核心程序。"""
import re
from bs4 import BeautifulSoup
import os
from random import choice
from time import time
import urllib
from urllib.request import urlopen 
import requests

手机号正则=re.compile(r"1[34578]\d{9}")
blacklist=['baishicha.com','dianping.com','135130.com', 'jiweixin168.com', '0595lh.com', 'chahaoyi.com', 'soudianhua.com', 'ip138.com', 'hiphop8.com', 'gpxz.com', 'sohao.org', 'shouji.360.cn', '911cha.com', 'shoujichahao.com', 'mv188.com', 'juzhao.net', 'qqdna.com', 'hdjr.org', 'quanzh.com', 'chahaoba.com', 'guisd.com', 'qzbst.net', 'qeayer.com', 'chazidian.com', 'sjhcx.com', 'jihaoba.com', '2dianying.net', '0597zp.com', 'supfree.net', 'xysjk.com', 'beyaiw.com', 'sjgsd.com', 'chaohaoyi.com', '03412.com', 'gdhaoma.com', 'haomadi.com', 'qq5533.com', 'guoguo-app.com', '9om.com', 'xingming.net', 'tongmengguo.com', '51so.cc', '27txt.com', '51hao.cc', 'dyndns.tv', 'tool.la', '17012345.com', 'phone001.com', 'dunkun.com', 'chaxuntu.com', 'chinxm.com', 'niukaba.com', 'tiaohao.com', 'sojkan.com', 'shoujigenzong.com', '139018.com', 'chincm.com', 'labelbao.com', 'ashercall.info', 'fpsjk.org', '13131313131.com', 'rrsms.com', '139018.com', 'search-phone-owner.com', 'netrui.com', '82029.com', 'wiki-numbers.ru', 'who-called.biz', 'haomazhuanjia.com', 'mshaoma.com', '100170.net', 'beyaiw.com', 'adorkablepet.net', 'xgfc.net', 'aviciifans.com', '135cha.com', 'tiantianxieye.com', 'yenwoop.com', 'chaxunw.com', 'aiqzu.net', 'fzrc.org', 'herowind.com']
def 随机生成文件名():
    字符集='abcdefghijklmnopqrstuvwxyz01234567890'
    filename="".join([ choice(字符集) for _ in range(10)]) 
    s=str(time())
    s=s.split(".")[-1]
    return filename + s + ".html"

def geturltext3(url):
    resp = requests.get(url, timeout=5, verify=True)    #可以返回resp.raw,resp.content,resp.text,resp.json
    #print(resp.status_code)                             #200正常
    resp.encoding='utf-8'             
    content=resp.text
    return content

def geturltext2(url):
    """得到文本型网页源代码"""
    content=""
    htmlcodestyle='utf-8'                   #根据网页的编码进行更改
    网页打开器 = urllib.request.URLopener() 
    网页打开器.addheaders = []
    网页打开器.addheader('User-Agent', 'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36')
    网页打开器.addheader('Accept-Language', 'zh-CN,zh;q=0.8,en;q=0.6')
    网页打开器.addheader('Accept', 'text/html,application/xhtml+xml,application/xml;q=0.9, image/png, image/webp, image/jpeg, image/gif, image/x-xbitmap, */*;')
    #print("正打开网址:" + url)
    try:
        f = 网页打开器.open(url)
        content = f.read().decode(htmlcodestyle)
        f.close()
    except:#如果发生意外,则调用requests模块的get方法进行获取网页源代码
        content= geturltext3(url)   
    return content

def geturltext(url):
    filename= 随机生成文件名()
    yy=os.popen("scrapy fetch " + url + " --nolog >> " + filename) #不会出现黑框的DOS命令提示符
    yy.close()  #等待上面的指令执行完毕
    f=open(filename,mode='rb')
    html=f.read()
    f.close()
    os.remove(filename)
    html=html.decode(encoding='utf-8')
    #这里针对webcrawler进行特殊处理,因为它可能会弹出验证码,要参加什么调查之类的
    #下载的网页里面有这样的标签:<div class="captcha-container">

    if len(html)<1000 or "captcha-container" in html:       #认为返回结果不正常
        html=geturltext2(url)
    return html



def puretitle(title):    
    title=title.split("–")[0]
    title=title.split("_")[0]
    title=title.split("-")[0]
    title=title.split("|")[0]        
    title=title.strip()
    return title

def  is_chinese(uchar):
         """ 判断一个unicode是否是汉字 """
         if  uchar >= u'\u4e00'  and  uchar<=u'\u9fa5':
                 return  True
         else :
                 return  False
def containchinese(astring):
    ischinesestring=False
    for c in astring:
        if is_chinese(c):
            ischinesestring=True
            break
    return ischinesestring

def extractdomain_bing(url):
    """从网址提取域名,for bing"""
    
    L=url.split("/")
    domain=L[0]
    if url.startswith("https://") or url.startswith("http://"):domain=L[2]
    words=domain.split(".")
    domain=words[-2] + "." + words[-1]
    return domain

def extractfrombing(mobile,html):
    """成功则返回元组(True,有意义数据),否则返回(False,'') """
    global 手机号正则,blacklist
    soup=BeautifulSoup(html,'lxml')

    result=soup.find_all('li',{'class':'b_algo'})
    availableitems=[]
    for item in result:
        #0:标题
        title=item.find_all('h2')[0].text
        if not containchinese(title):continue                 #不包括中文字,忽略
        title=puretitle(title)        
        
        sourceurl=item.find_all('cite')[0].text
        domain=extractdomain_bing(sourceurl)
        if  domain in blacklist:
            continue
        brief=item.find_all('p')[0].text
        rs=re.findall(手机号正则,brief)        #我们认为简介中有连续3个以上的手机号,这网站就没有此手机号的相关信息
        if len(rs)>=3:continue
        if not mobile in brief:continue            #如果简介中没有手机号,也忽略
        availableitems.append((title,brief,sourceurl))
        break
    if availableitems:
        return (True,(mobile,availableitems[0]))
    else:
        return (False,"")

def extractdomain_chinaso(url):
    """从网址提取域名,for chinaso"""
    
    if "..." in url:
        domain=url.split("...")[0]
    else:
        L=url.split("\xa0")
        url=L[-2]
        L=url.split("/")
        domain=L[0]
        if url.startswith("https://") or url.startswith("http://"):domain=L[2]
    words=domain.split(".")
    domain=words[-2] + "." + words[-1]
    return domain

def extractfromchinaso(mobile,html):
    """分析从中国搜索查询后的源码html,成功则返回元组(True,有意义数据),否则返回(False,'')
           http://www.chinaso.com/    """
    global 手机号正则,blacklist
    soup=BeautifulSoup(html,'lxml')
    result=soup.find_all('li',{'class':'reItem '})

    availableitems=[]
    for i in range(1,len(result)):
        item=result[i]
         
        #0:标题,
        title=item.find_all('h2')[0].text
        if not containchinese(title):continue                 #不包括中文字,忽略
        title=puretitle(title)
        
        sourceurl=item.find_all('p',{'class':'snapshot'})[0].text

        domain=extractdomain_chinaso(sourceurl)

        if  domain in blacklist:
            continue
        brief=item.find_all('p')[0].text
        rs=re.findall(手机号正则,brief)        #我们认为简介中有连续3个以上的手机号,这网站就没有此手机号的相关信息
        if len(rs)>=3:continue
        if not mobile in brief:continue            #如果简介中没有手机号,也忽略
        availableitems.append((title,brief,sourceurl))
        break
    if availableitems:
        return (True,(mobile,availableitems[0]))
    else:
        return (False,"")

def extractdomain_360(url):
    """从网址提取域名,for 360"""
    L=url.split("/")
    domain=L[2]
    words=domain.split(".")
    domain=words[-2] + "." + words[-1]
    return domain            

def extractfrom360(mobile,html):
    """分析从360搜索查询后的源码html,成功则返回元组(True,有意义数据),否则返回(False,'')
          http://www.so.com/  """
    global 手机号正则,blacklist
    soup=BeautifulSoup(html,'lxml')
    result=soup.find_all('li',{'class':'res-list'})

    availableitems=[]
    for i in range(1,len(result)):
        item=result[i]
         
        #0:标题,这个标题里包括了源网址
        h3tag=item.find_all('h3',{'class':'res-title'})[0]
        title=h3tag.text
        if not containchinese(title):continue                 #不包括中文字,忽略
        title=puretitle(title)       
        
        linkdata=h3tag.find_all('a')[0]
     
        if linkdata.has_attr('data-url'):
            sourceurl=linkdata['data-url']
        else:
            sourceurl=linkdata['href']
            
            
        domain=extractdomain_360(sourceurl)

        if  domain in blacklist:
            continue
        
        brieftag=item.find_all('p',{'class':'res-desc'})
        if len(brieftag)>0:
            brief=brieftag[0].text
        else:
            brieftag=item.find_all('div',{'class':'res-rich res-realty clearfix'})
            if len(brieftag)>0:
                brief=brieftag[0].text
            else:
                brieftag=item.find_all('p')
                if len(brieftag)>2:
                    brief=brieftag[1].text
                else:
                    continue
            
        rs=re.findall(手机号正则,brief)        #我们认为简介中有连续3个以上的手机号,这网站就没有此手机号的相关信息
        if len(rs)>=3:continue
        if not mobile in brief:continue            #如果简介中没有手机号,也忽略
        availableitems.append((title,brief,sourceurl))
        break                                      #查到一个可用的数据就行了
    if availableitems:
        return (True,(mobile,availableitems[0]))
    else:
        return (False,"")

        
def extractdomain_baidu(url):
    """从网址提取域名,for baidu"""
    L=url.split("/")
    if url.startswith("https://") or url.startswith("http://") :
        domain=L[2]
    else:
        domain=L[0]
    words=domain.split(".")
    domain=words[-2] + "." + words[-1]
    return domain

def extractfrombaidu(mobile,html):
    """分析从baidu搜索查询后的源码html,成功则返回元组(True,有意义数据),否则返回(False,'')
          http://www.baidu.com/  """
    global 手机号正则,blacklist
    soup=BeautifulSoup(html,'lxml')
    #查找有没有被百度手机卫士标记
    baiduguard=soup.find_all('div',{'class':'op_fraudphone_word'})
    title0=""
    if baiduguard:         #如果不是空的
        title0=baiduguard[0].find_all('strong')[0].text
        title0=title0.strip("\"")
        
    result=soup.find_all('div',{'class':'result c-container '})

    availableitems=[]
    for i in range(0,len(result)):
        item=result[i]
         
        #0:标题,
        h3tag=item.find_all('h3',{'class':'t'})[0]
        title=h3tag.text
        if not containchinese(title):continue                 #不包括中文字,忽略
        title=puretitle(title)        
        
                
        sourceurl=item.find_all('a',{'class':'c-showurl'})[0].text
        
        domain=extractdomain_baidu(sourceurl)

        if  domain in blacklist:
            continue
        
        brieftag=item.find_all('div',{'class':'c-abstract'})
        brief=brieftag[0].text
      
            
        rs=re.findall(手机号正则,brief)        #我们认为简介中有连续3个以上的手机号,这网站就没有此手机号的相关信息
        if len(rs)>=3:continue
        if not mobile in brief:continue            #如果简介中没有手机号,也忽略
        if not( title0 in title):
            title=title0 + ":" + title
        availableitems.append((title ,brief,sourceurl))
        break
    
    if availableitems:
        return (True,(mobile,availableitems[0]))
    else:
        if title0=="":
            return (False,"")
        else:
            return (True,(mobile,title0))

def extractdomain_sogou(url):
    """从网址提取域名,for sogou"""
    
    if "翻译此页" in url:
        url=url.split("翻译此页")[0]
    L=url.split("...")
    url=L[0]
    if "/" in url:
        url=url.split("/")[0]
    if "-" in url:
        url=url.split("-")[-1]


    domain=url
    words=domain.split(".")
    domain=words[-2] + "." + words[-1]
    return domain
def extracesogouhaomatong(html):
    """抓取搜狗搜索后出现的号码通信息"""
    号码通抓取正则=re.compile(r"var queryphoneinfo = '(.+)'\.replace")
    ret=re.findall(号码通抓取正则,html)
    if ret:
        company=ret[0]
        return company.split(":")[1]
    return ""
def extractfromsogou(mobile,html):
    """分析从sogou搜索查询后的源码html,成功则返回元组(True,有意义数据),否则返回(False,'')
          http://www.sogou.com/  """
    global 手机号正则,blacklist
    title0=extracesogouhaomatong(html)  #查找有没有被搜狗号码通用户标记
    soup=BeautifulSoup(html,'lxml')
    
    result=soup.find_all('div',{'class':'vrwrap'})
    
    availableitems=[]
    for i in range(1,len(result)):
        item=result[i]
         
        #0:标题,
        h3tag=item.find_all('h3',{'class':'vrTitle'})[0]
        title=h3tag.text
        if not containchinese(title):continue                 #不包括中文字,忽略
        title=puretitle(title)    
                        
        sourceurl=item.find_all('cite')[0].text
        
        domain=extractdomain_sogou(sourceurl)

        if  domain in blacklist:
            continue
        
        brieftag=item.find_all('p',{'class':'str_info'})
        if not brieftag:      #如果为空那么只有文字介绍
           brieftag=item.find_all('li',{'class':'str-text-info'})       
        if not brieftag:continue
        
        brief=brieftag[0].text
        rs=re.findall(手机号正则,brief)        #我们认为简介中有连续3个以上的手机号,这网站就没有此手机号的相关信息
        if len(rs)>=3:continue
        if not mobile in brief:continue            #如果简介中没有手机号,也忽略
        if not( title0 in title):
            title=title0 + ":" + title
        availableitems.append((title ,brief,sourceurl))
    #再次搜索标签,老的搜狗结果标签是div class="rb"
    if not availableitems:
         result=soup.find_all('div',{'class':'rb'})
         for i in range(0,len(result)):
             item=result[i]
             h3tag=item.find_all('h3',{'class':'pt'})
             if h3tag==[]:continue
             title=h3tag[0].text
             if not containchinese(title):continue                 #不包括中文字,忽略
             title=puretitle(title)
             #寻找简介描述
             brieftag=item.find_all("div",{'class':'ft'})
             if brieftag==[]:continue
             brief=brieftag[0].text
             rs=re.findall(手机号正则,brief)        #我们认为简介中有连续3个以上的手机号,这网站就没有此手机号的相关信息
             if len(rs)>=3:continue
             if not mobile in brief:continue            #如果简介中没有手机号,也忽略

             #寻找源URL
             sourceurltag=item.find_all("div",{'class':'fb'})
             if sourceurltag==[]:continue
             sourceurl=sourceurltag[0].text
             domain=extractdomain_sogou(sourceurl)
             if  domain in blacklist:continue
             if not( title0 in title):
                 title=title0 + ":" + title
             availableitems.append((title ,brief,sourceurl))
             break
        
    if availableitems:
        return (True,(mobile,availableitems[0]))
    else:
        if title0=="":
            return (False,"")
        else:
            return (True,(mobile,title0))

    
def extractdomain_webcrawler(url):
    """从网址提取域名,for webcrawler"""
    url=url.split("/")[0]
    domain=url
    words=domain.split(".")
    domain=words[-2] + "." + words[-1]
    return domain
def extractfromwebcrawler(mobile,html):
    """分析从webcrawler搜索查询后的源码html,成功则返回元组(True,有意义数据),否则返回(False,'')
          http://www.webcrawler.com/  """
    global 手机号正则,blacklist
    soup=BeautifulSoup(html,'lxml')
           
    result=soup.find_all('div',{'class':'result'})

    availableitems=[]
    for i in range(0,len(result)):
        item=result[i]
         
        #0:标题,
        titletag=item.find_all('a',{'class':'title'})
        if titletag==[]:continue
        title=titletag[0].text
        if not containchinese(title):continue                 #不包括中文字,忽略
        title=puretitle(title)
        #源网址
        sourceurltag=item.find_all('span',{'class':'url'})
        if sourceurltag==[]:continue
        sourceurl=sourceurltag[0].text
        domain=extractdomain_webcrawler(sourceurl)
        if  domain in blacklist:continue
        #简介与描述
        brieftag=item.find_all('span')
        if brieftag==[]:continue
        brief=brieftag[1].text.strip()
        rs=re.findall(手机号正则,brief)        #我们认为简介中有连续3个以上的手机号,这网站就没有此手机号的相关信息
        if len(rs)>=3:continue
        if not mobile in brief:continue    
        
        availableitems.append((title ,brief,sourceurl))
        break
    if availableitems:
        return (True,(mobile,availableitems[0]))
    else:
        return (False,"")
    

def extractdomain_search(url):
    """从网址提取域名,for search.com"""
    
    linksep=url.split("/")
    if url.startswith("http://") or url.startswith("https://"):
        url=linksep[2]
    else:
        url=linksep[0]
    domain=url
    words=domain.split(".")
    domain=words[-2] + "." + words[-1]
    return domain
def extractfromsearch(mobile,html):
    """分析从search.com搜索查询后的源码html,成功则返回元组(True,有意义数据),否则返回(False,'')
          https://www.search.com/  """
    global 手机号正则,blacklist
    soup=BeautifulSoup(html,'lxml')
           
    result=soup.find_all('div',{'class':'web-result'})

    availableitems=[]
    for i in range(0,len(result)):
        item=result[i]
         
        #0:标题,
        titletag=item.find_all('a',{'class':'web-result-title-link'})        
        if titletag==[]:continue
        title=titletag[0].text
        if not containchinese(title):continue                 #不包括中文字,忽略
        title=puretitle(title)
        #源网址
        sourceurltag=item.find_all('p',{'class':'web-result-url'})
        if sourceurltag==[]:continue
        sourceurl=sourceurltag[0].text

        domain=extractdomain_search(sourceurl)
        if  domain in blacklist:continue
        #简介与描述
        brieftag=item.find_all('p',{'class':'web-result-description'})
        if brieftag==[]:continue
        brief=brieftag[0].text.strip()
        rs=re.findall(手机号正则,brief)        #我们认为简介中有连续3个以上的手机号,这网站就没有此手机号的相关信息
        if len(rs)>=3:continue
        if not mobile in brief:continue
        
        availableitems.append((title ,brief,sourceurl))
        break
    if availableitems:
        return (True,(mobile,availableitems[0]))
    else:
        return (False,"")

def extractdomain_dogpile(url):
    """从网址提取域名,for dogpile.com"""
    
    linksep=url.split("/")
    url=linksep[0]
    
    domain=url
    words=domain.split(".")
    domain=words[-2] + "." + words[-1]
    return domain

def extractfromdogpile(mobile,html):
    """分析从dogpile.com搜索查询后的源码html,成功则返回元组(True,有意义数据),否则返回(False,'')
          https://www.dogpile.com/  """
    global 手机号正则,blacklist
    soup=BeautifulSoup(html,'lxml')
           
    result=soup.find_all('div',{'class':'searchResult webResult'})

    availableitems=[]
    for i in range(0,len(result)):
        item=result[i]
         
        #0:标题,
        titletag=item.find_all('a',{'class':'resultTitle'})        
        if titletag==[]:continue
        title=titletag[0].text
        if not containchinese(title):continue                 #不包括中文字,忽略
        title=puretitle(title)
        #源网址
        sourceurltag=item.find_all('a',{'class':'resultDisplayUrl'})
        if sourceurltag==[]:continue
        sourceurl=sourceurltag[0].text

        domain=extractdomain_dogpile(sourceurl)
        if  domain in blacklist:continue
        #简介与描述
        brieftag=item.find_all('div',{'class':'resultDescription'})
        if brieftag==[]:continue
        brief=brieftag[0].text.strip()
        rs=re.findall(手机号正则,brief)        #我们认为简介中有连续3个以上的手机号,这网站就没有此手机号的相关信息
        if len(rs)>=3:continue
        if not mobile in brief:continue
        
        availableitems.append((title ,brief,sourceurl))
        break
    if availableitems:
        return (True,(mobile,availableitems[0]))
    else:
        return (False,"")
    
def extractdomain_ecosia(url):
    """从网址提取域名,for ecosia.com"""
    linksep=url.split("/")
    if url.startswith("http://") or url.startswith("https://"):
        url=linksep[2]
    else:
        url=linksep[0]

    domain=url
    words=domain.split(".")
    domain=words[-2] + "." + words[-1]
    return domain

def extractfromecosia(mobile,html):
    """分析从ecosia.com搜索查询后的源码html,成功则返回元组(True,有意义数据),否则返回(False,'')
       https://www.ecosia.org/  """
    global 手机号正则,blacklist
    soup=BeautifulSoup(html,'lxml')
           
    result=soup.find_all('div',{'class':'result js-result card-mobile'})

    availableitems=[]
    for i in range(0,len(result)):
        item=result[i]
         
        #0:标题,
        titletag=item.find_all('a',{'class':'result-title js-result-title'})        
        if titletag==[]:continue
        title=titletag[0].text
        if not containchinese(title):continue                 #不包括中文字,忽略
        title=puretitle(title)
        #源网址
        sourceurltag=item.find_all('a',{'class':'result-url js-result-url'})
        if sourceurltag==[]:continue
        sourceurl=sourceurltag[0].text

        domain=extractdomain_ecosia(sourceurl)
        if  domain in blacklist:continue
        #简介与描述
        brieftag=item.find_all('p',{'class':'result-snippet'})
        if brieftag==[]:continue
        brief=brieftag[0].text.strip()
        rs=re.findall(手机号正则,brief)        #我们认为简介中有连续3个以上的手机号,这网站就没有此手机号的相关信息
        if len(rs)>=3:continue
        if not mobile in brief:continue
        
        availableitems.append((title ,brief,sourceurl))
        break
    if availableitems:
        return (True,(mobile,availableitems[0]))
    else:
        return (False,"")

def extractdomain_qwant(url):
    """从网址提取域名,for qwant.com"""
    linksep=url.split("/")
    if url.startswith("http://") or url.startswith("https://"):
        url=linksep[2]
    else:
        url=linksep[0]

    domain=url
    words=domain.split(".")
    domain=words[-2] + "." + words[-1]
    return domain

def extractfromqwant(mobile,html):
    """分析从lite.qwant.com搜索查询后的源码html,成功则返回元组(True,有意义数据),否则返回(False,'')
    https://lite.qwant.com/  """    
    global 手机号正则,blacklist
    soup=BeautifulSoup(html,'lxml')
           
    result=soup.find_all('div',{'class':'result'})
    
    availableitems=[]
    for i in range(0,len(result)):
        item=result[i]
         
        #0:标题,
        titletag=item.find_all('a')      
        if titletag==[]:continue
        title=titletag[0].text
        if not containchinese(title):continue                 #不包括中文字,忽略
        title=puretitle(title)
        #源网址
        sourceurltag=item.find_all('p',{'class':'url'})
        if sourceurltag==[]:continue
        sourceurl=sourceurltag[0].text

        domain=extractdomain_qwant(sourceurl)
        if  domain in blacklist:continue
        #简介与描述
        brieftag=item.find_all('p')
        if brieftag==[]:continue
        brief=brieftag[1].text.strip()
        rs=re.findall(手机号正则,brief)        #我们认为简介中有连续3个以上的手机号,这网站就没有此手机号的相关信息
        if len(rs)>=3:continue
        if not mobile in brief:continue
        
        availableitems.append((title ,brief,sourceurl))
        break
    if availableitems:
        return (True,(mobile,availableitems[0]))
    else:
        return (False,"")

   
def extractmobileinfo(se,mobile,html):
    """se的值可能为'bing','chinaso','360','baidu','sogou','webcrawler','search'
       ,'dogpile','ecosia','qwang'
       返回结果为:(True,(手机号,(标题,简述,源url)))或(False,"")
       
    """
    if se=='bing':
        ret=extractfrombing(mobile,html)
    if se=='chinaso':
        ret=extractfromchinaso(mobile,html)
    if se=='360':
        ret=extractfrom360(mobile,html)
    if se=='baidu':
        ret=extractfrombaidu(mobile,html)
    if se=='sogou':
        ret=extractfromsogou(mobile,html)
    if se=='webcrawler':
        ret=extractfromwebcrawler(mobile,html)
    if se=='search':
        ret=extractfromsearch(mobile,html)
        
    if se=='dogpile':
        ret=extractfromdogpile(mobile,html)
    if se=='ecosia':
        ret=extractfromecosia(mobile,html)
    if se=='qwant':
        ret=extractfromqwant(mobile,html)
        
    return ret

    
if __name__=='__main__':
    pass
    """
    se='360'
    mobilehead='137146809'
    for i in range(83,100):
        mobile=mobilehead + str(i)
        url="https://www.so.com/s?q=" + mobile
        print("搜索:" + url )
        html=geturltext(url)          #得到源码
        f=open("C:\\"+ se + "_" +  mobile + ".html",mode='w',encoding='utf-8')
        f.write(html)
        f.close()
        print(extractmobileinfo(se,mobile,html))
        print()
     """


    

 

 

发表在 python | 多个搜索引擎结果第一页分析程序已关闭评论

动态背景_月亮夜色情景_鼠标渐隐拖尾交互多媒体动画

动态背景_月亮夜色情景_鼠标渐隐拖尾交互多媒体动画 www.lixingqiu.com

以下是部分代码预览:

"""移动鼠标时,会有渐隐的拖尾现象scratch动画转Python代码, 这本来是一个scratch作品,现在用Python把它做一下. 问题: 本程序的叶子应该逐渐消失,但是在程序中它消失后在最后几帧或一帧为什么会完全显示,明明是把它的透明度不断减少啊....."""

import time
import pygame
from pygame.locals import *

class Leaf:
    """叶子类,它会不断克隆自己,从而形成渐隐的鼠标拖尾效果"""
    def __init__(self,image,position,group):
        """初始化方法,image:叶子的surface对象,position:坐标,group:所在组"""
        pygame.sprite.Sprite.__init__(self) # 初始化父类
        self.image = image
        self.rect = self.image.get_rect()   # 矩形对象
        self.rect.center = position         # 中心点坐标
        self.display_time = 1               # 显示时间
        self.start_time = time.time()       # 起始时间
        self.group = group                  # 这样能引用自己的组
        self.group.add(self)                # 加入到自己的组中
        self._alpha = 255                   # 自定义属性,完全不透明
        self.disapper = False
        
    def update(self):
        """超时从组中删除"""

width,height = 960,720
screen = pygame.display.set_mode((width,height))
pygame.display.set_caption("动态背景_月亮夜色情景_鼠标渐隐拖尾交互多媒体动画")

pygame.mixer.init()
pygame.mixer.music.load("Igor_Khabarov_-_Try.mp3.wav")
pygame.mixer.music.play(-1,0)                # 循环播放背景音乐

leaf_image = pygame.image.load("叶子.png").convert() 
leaf_image.set_colorkey((0,0,0))
leaf_group = set()

clock = pygame.time.Clock()
running = True
frame_counter = 0        

while running:

    frame_counter +=1        #  帧计数器
    #  事件检测
    event = pygame.event.poll()
    if event.type == QUIT:running = False

    # 更新逻辑
    mx,my = pygame.mouse.get_pos()

    if frame_counter % 2 ==0 : Leaf(leaf_image,(mx,my),leaf_group)
    [leaf.update() for leaf in leaf_group ]      # 更新所有叶子
    
    # draw all images
    screen.fill((0,0,0))
    screen.blit(background,background_rect)
 
    clock.tick(30)    

pygame.quit()

下载完整源代码与素材,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 pygame, python | 动态背景_月亮夜色情景_鼠标渐隐拖尾交互多媒体动画已关闭评论

动态背景之中国阁楼风景

一个微交互动画,用鼠标移动时,后面的凉亭会动,这本来是一个scratch作品,现在用Python把它做一下

以下是部分代码预览:

"""一个微交互动画,用鼠标移动时,后面的凉亭会动,这本来是一个scratch作品,现在用Python把它做一下."""

import pygame
from pygame.locals import *

width,height = 960,720
screen = pygame.display.set_mode((width,height))
pygame.display.set_caption("动态背景之中国阁楼风景 www.lixingqiu.com")

background = pygame.image.load("images/蓝天太阳背景.png")

clock = pygame.time.Clock()
running = True

while running:
    event = pygame.event.poll()
    if event.type == QUIT:running = False
    mx,my = pygame.mouse.get_pos()

    screen.blit(green1,(0,400))
    screen.blit(green2,(0,600))
    
    pygame.display.update()
    clock.tick(30)     

pygame.quit()

下载完整源代码与素材,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 pygame, python | 动态背景之中国阁楼风景已关闭评论

说话泡泡生成图片程序

以下是部分代码预览:

"""说话泡泡生成程序,这是为了给turtle.py模块增加"说话"功能的一个测试程序。就是在角色的头顶右上方或左上方的那个说话泡泡。这是实时生成的一个图片。"""

from PIL import ImageFont,Image,ImageDraw,ImageOps 

def make_string2image(string,width_every_line,font,fontcolor,bgcolor):
    """把字符串分成一行一行相等的,然后转换图形对象"""   
    if len(string) < 8 :
        unuber = 1+(8 - len(string)) // 2  # 左右两边要补偿的空格数
        string = " " * unuber   + string + " "* unuber
    width = 0 
    strings = []
    s = ""

def make_round_rectangle(width,height,radius,color):
    """画圆角矩形,圆角半径为radius"""

def make_bubble_border(size,radius,bgcolor):
    """角色面向右方向时的说话泡泡(不含文字),圆角半径为radius,圆角矩形宽高为size,'把柄'的高度为1.5*radius(三角形)"""
   
    return im    
 
def make_say_bubble(string,imagewidth,fontfile,fontsize,fontcolor,bgcolor,radius):
    """生成说话泡泡,带字的,参数说明:string:句子,imagewidth,每行无间距总宽度(并不是每行宽度),fontfile:ttf或ttc字体文件
       ,fontsize:字体大小,fontcolor:三元组字体颜色,bgcolor:三元组背景颜色,radius:圆角矩形的半径。
    """

string = r"""1角色面向右方向时的说话泡泡(不含文字),圆角半径为radius,圆角矩形宽高为size,'把柄'的高度为1.5*radius(三角形)
请用A4纸、以双倍行距单面打印或誊抄,字迹务必清晰。Please type or write clearly in double spacing on one side of A4 paper only.
"""
imagewidth = 200
fontfile = "simhei.ttf"
fontsize = 14
fontcolor = (23,23,23)
bgcolor = (240,240,240)
radius = 30
left,right = make_say_bubble(string,imagewidth,fontfile,fontsize,fontcolor,bgcolor,radius)
left.save("logoleft.png")
right.save("logoright.png")

如需要查看完整代码,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 pillow, python | 说话泡泡生成图片程序已关闭评论

左三圈右三圈女孩动画

左三圈右三圈女孩动画

简易的入门型动画,以下是代码预览:

"""左三圈右三圈女孩动画"""

import time
import turtle

# 定义一个列表,里面是一些图片的路径
images = ["girl1/0001.png",
          "girl1/0002.png",
          "girl1/0003.png",
          "girl1/0004.png",
          "girl1/0005.png",
          "girl1/0006.png",
          "girl1/0007.png",
          "girl1/0008.png",
          "girl1/0009.png",
          "girl1/0010.png",
          "girl1/0011.png",
          "girl1/0012.png"
              ]

screen = turtle.Screen()         # 新建屏幕
screen.delay(0)                  # 屏幕延时
screen.title("女孩跳舞")         # 屏幕标题
 

下载完整源代码与素材,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 python, turtle | 左三圈右三圈女孩动画已关闭评论

海锦宝宝与while循环(pygame播放gif)

 海锦宝宝与while循环pygame播放gif动画

"""海锦宝宝与while循环.py ,本程序用pygame播放gif图形"""

import pygame
from gifimage import *
from pygame.locals import *
 
def event_check():
    """事件检测函数"""
    for event in pygame.event.get():        # 检测每一个事件
        if event.type == QUIT:return False  # 如果按了关闭窗口按钮则返回False
    return True

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 pygame, python | 海锦宝宝与while循环(pygame播放gif)已关闭评论

哪吒拼图单图版_python解谜游戏

python解谜游戏哪吒拼图动画演示
以下是部分代码预览:

"""
单图拼图游戏,本游戏平均切分一张图片,打乱顺序后显示在屏幕上,用鼠标依次单击能交换图片的坐标顺序,直到拼好和原图一样,则成功结束。核心模块 block.py 扫码可见。
"""

__author__ = "lixingqiu"

from block import *

rows,cols = 2,2             # 行列数
amounts = rows*cols         # 初切分的图像总数
imagefile =  "nezha.jpg"    # 待切分的图像

screen = Screen()           # 新建屏幕对象

"成功切分,那么sliced_images_list就不是空的,if语句就成立"
if  sliced_images_list:
    random_index_list = list(range(amounts))               # random_index_list列表存储的是索引,如果是2x2切分,那么初始值为[0,1,2,3]
    shuffle(random_index_list)                             # 洗牌随机索引表,打扰顺序后的值可能是 2,3,0,1
    height_step = image_height//rows                       # 每个被切分的图像的高度
    width_step = image_width //cols                        # 每个被切分的图像的宽度
    left = -image_width//2                                 # 图像左上角x坐标
    top =  image_height//2                                 # 图像左上角y标
    coordinates = []                                       # 存储切分的每张图的中心点坐标,从左上角第一个数起
    "以下代码形成每块图片的中心点坐标,存储在coordinates列表中"
    for y in range(rows):                                  # 2x2切分的话,y的值是0,1
        for x in range(cols):                              # 2x2切分的话,x的值是0,1 
            startx = left + x * width_step                 # 每张切分的图像左上角x坐标
            starty = top  - y * height_step                # 每张切分的图像左上角y坐标             
            centerx = startx + width_step//2               # 每张切分的图像的中心点x坐标
            centery = starty - height_step//2              # 每张切分的图像的中心点y坐标
            coordinates.append((centerx,centery))          # 添加到坐标列表        
    
    [screen.addshape(image) for image in sliced_images_list]  # 注册每张图到形状列表
    
    blocks_list = []
     
    for i in range(amounts):
        "角色己的初始坐标"
        index = random_index_list[i]                          # 取出的索引号是按顺序取出的。
        """Block类,有它新建对象后,它能把分块图进行封装,让图能记住自己原始坐标及即将定位的坐标及接受鼠标单击事件,以便和其它图交换位置。" 
           coordinates[index]是它的初始坐标,coordinates[i]是它即将定位的坐标,把图形,coordinates和index与i传进去即可。           
        """
        s = Block(sliced_images_list[index],coordinates,index,i)   # 由于index已被打乱顺序,所以形成的图片就是随机的
        
        blocks_list.append(s)

    
screen.mainloop()

下载完整源代码与素材,包含各个子模块,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 python, turtle | 哪吒拼图单图版_python解谜游戏已关闭评论

turtle模拟时钟程序_函数

海龟模块制作的模拟时钟_python海龟画图模块制作_by_李兴球
这个是没有定义类的,使用函数完成的版本,以下是部分代码预览:

"""这是一个用海龟模块制作的模拟时钟程序,作者:李兴球,日期:2018/12/10于杭州"""

from turtle import *
from time import *

def init_screen():
    
    screen = Screen()
    screen.title("模拟时钟")
    screen.delay(0)
    screen.mode("logo")                                       # 此模式刚好和时钟转动相适配
    pointer = ((0,0),(5,0),(5,50),(10,50),(0,60),(-10,50),(-5,50),(-5,0)) #顶点表
    screen.addshape("pointer",pointer)                        # 添加大箭头各顶点到形状列表
    
    return screen
    
def draw_digital():
    
    #以下代码画时钟的数字
    radius = 300
    draw_turtle = Turtle(visible=False,shape='circle')


if __name__ == "__main__":

    screen = init_screen()

    draw_digital()                             # 画数字

    screen.mainloop()    

 

如需要查看完整代码,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 python, turtle | turtle模拟时钟程序_函数已关闭评论

漫天飞雪效果动画_pygame淡入淡出_scratch转python

漫天飞雪效果动画_pygame淡入淡出动态背景class类与播放背景音乐

以下是部分代码预览:

"""本程序描述了一幅满天飞雪的动画场景,动态背景之雪山下雪神秘音乐,这是把一个scratch作品用python表现出来的作品."""

import time
import pygame
from pygame.locals import *
from random import randint

class Snow(pygame.sprite.Sprite):
    
    def __init__(self,screen_size):
        
        self.sw,self.sh = screen_size
        pygame.sprite.Sprite.__init__(self)
        self.radius = randint(1,8)
        self.image = pygame.Surface((2*self.radius,2*self.radius))
        self.image.set_colorkey((0,0,0))
        
    def update(self):
        """往下移动雪花"""
        self.rect.move_ip(0,self.yspeed)
        if  self.rect.top > self.sh:self.reset()

    def reset(self):
        """ 设定位置"""
        self.rect.centerx = randint(0,self.sw)
        self.rect.bottom = randint(-2* self.sh,10)        
        

class Fade_background :
    """淡入淡出动态背景类,把一系列帧图像做为背景不断地渐隐渐现的显示"""
    
    def __init__(self,images,size):
        """images:已转换成surface的对象列表,size:屏幕尺寸"""        
        
        self.screen_size = size
        self.images = images                   # images是surface列表

    def update(self):
        """淡入淡出地显示图像,然后换一幅图像"""


    def set_shape(self,index):
        """设置初始造型和透明度为0"""

    def set_alpha(self):
        """设置透明度"""
        self.step = self.step % 50
        self.alpha = 10 * (25-abs(25-self.step)) # 自定义属性,0代表完全透明,255,代表透明
             

def main():
    """主要的调用函数"""

    title = "漫天飞雪效果动画_pygame淡入淡出动态背景class类与播放背景音乐,作者:李兴球"
    
    width,height = 960,720
    pygame.init()
    screen = pygame.display.set_mode((width,height))
    pygame.display.set_caption(title)
    
    images = ["bgs/No trees night.png","bgs/No trees.png","bgs/Trees night.png","bgs/Trees.png"]
    images = [pygame.image.load(image).convert()  for image in images]

    background = pygame.image.load("bgs/backdrop1.png")
    bgs = Fade_background(images,(width,height))

    # 播放背景音乐
    pygame.mixer.init()
    pygame.mixer.music.load("bgs/The Snow Queen.wav")
    pygame.mixer.music.play(-1,0)

    snows = pygame.sprite.Group()
    for i in range(500):
        snows.add(Snow((width,height)))    
    
    clock = pygame.time.Clock()
    running = True
    while running :
        event = pygame.event.poll()
        if event.type == QUIT:running = False
        bgs.update()
        snows.update()
        pygame.display.flip()
        clock.tick(60)

    pygame.quit()
       
if __name__ == "__main__":

    main()        

下载完整源代码与素材,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 pygame, python | 漫天飞雪效果动画_pygame淡入淡出_scratch转python已关闭评论

无现金社会的弊端

title = "无现金社会的弊端"
"""本Python程序演示多行字符串的使用方法,同是这篇文章,当然是本人写的"""

content = """
人们往往只看到无现金社会的好处,而忽略了所带来的弊端,其实无现金社会也有相当多的弊端,虽然是大势所趋,但如果冒进,则必然会引起诸多问题。

1、个人与团体等丧失支付或收款权。几个大公司把这个权力集中起来,以后支付或收款全都要依赖这几个大公司,否则就连买个包子都无法进行。
社会的稳定在于多样化,所谓狡兔三窟或者说生态丰富。只有这样,社会才能更加稳定。政府意识到这个问题,所以一定不会马上放弃现金支付。
这是一个非常好的后备选项。试想想,如果这个选项没有了,几个大公司被几心怀叵测的人掌握,那么他们可以立马让中国全社会陷入瘫痪。

2、金钱意识趋于淡泊。带来的问题是钱越来越不再是钱了。试想想,以后一个从来没见过现金的小孩,他还会有多少金钱的意识,对他来说只是一个完完全全的数字。
所以消费也就更无所忌惮,或许这不是个问题吧。消费也促进了社会的发展嘛。既然个人所有资产(在没有房产等其它硬资产情况下)都是个数字,那么这个数字是很脆弱的。
一不小心可能被黑客所划走。所以资产配置不应该只有这个数字,也一样要多样化。

3、增加部分群体的不方便。忘了带手机了,手机没电了,出门还得带个手机。能不能出门什么都不带,潇洒不再! 对于某部分人来说,还真是个麻烦事。
小孩也是不带手机的,他们拿着手机控制不住的玩,所以他们出门只带父母给的现金。

4、由于收付款都要经过无线网络与服务器等,个人行为将全被“监控”,好处是贪污腐化无所藏身,坏处是人类离开网络将无法生存。人完完全全地不再是一个独立的人了。

最终每个人都能被轻易控制,国家可以发钱给人,并且让这些“钱”只能购买生活必需品。无现金社会发展的下一阶段是货币消失。不知道还有没有经济活动。如果全部实现自动化了,人们就不必为生活而奔波了。或许那个时候经济活动就会消失吧。就像现在的蚂蚁社群组织?

综上所述,由于无现金支付所需要的必要条件较多,容易被攻击,所以不具备独立性,这就是它天生的缺憾。而现金支付独立性强,它的存在还将会是很长一段时间。人类社会演变的最终能源供给为太阳能。人类社会进入数字化只是太阳能供给地球能量,让地球上的物质越来越以光速移动的一个表现。这里来一个猜想,由于水星离太阳最近,所以它是首先产生智慧生物的星球。这些智慧生物难道全部灭绝了?不,他们实际上以数字化存在于太阳里或布满整个宇宙。数字化了,就无所谓温度等的概念了。金星是离太阳第二近的星球,也是一样,他们也实现了全部数字化。现在就是我们地球,正朝着向完全地虚拟化数字化生存方向发展。

"""

print(content)

print("谢谢查看本文章,于2019年5月28日8:19分写于萍乡")

 

发表在 python, 杂谈 | 无现金社会的弊端已关闭评论

turtle制作的中秋节的夜空云彩和仙女慢慢出现动画


python中秋节的夜空云彩和仙女慢慢出现动画

中秋节仙女给你送月饼了。本动画的显示顺序:首先云彩缓慢地从左边不断移动,然后明月几时有的诗词缓慢移入,最后仙女端着月饼从右边移进。可以加上一个明月几时有的音乐。
以下是部分代码预览:

"""中秋节的夜空云彩和仙女慢慢出现,这是用海龟画图像块制作的一个小动画."""

from turtle import Turtle,Screen

def slide_cloud(t):     
    t.setx(t.xcor() + 1)
    if t.xcor() > t.screen.window_width() // 2 + 300:
        t.hideturtle()
        t.setx(-100 - t.screen.window_width() // 2)
        t.showturtle()

    if hasattr(t,'name') :                         # 如果有这个属性,说明它是诗
        if t.xcor() ==0 :return
    
    t.screen.ontimer(lambda :slide_cloud(t),100)

def slide_fairy(t):     
    t.setx(t.xcor() - 1)
    if t.xcor() < -t.screen.window_width() // 2 - 300:
        t.hideturtle()
        return
    
    t.screen.ontimer(lambda :slide_fairy(t),100)
    
fairy = "仙女.gif"
cloud1 = "云1.gif"
cloud2 = "云2.gif"
cloud3 = "云3.gif"
poem  = "明月几时有x.gif"
images = [fairy,cloud1,cloud2,cloud3,poem]
width ,height = 800,600

screen = Screen()
screen.setup(width,height)
screen.title("中秋节的夜空云彩和仙女慢慢出现 by lixingqiu")
screen.bgcolor("black")
screen.bgpic('中秋夜空.png')
screen.delay(0)
[screen.addshape(image) for image in images]

t_cloud1 = Turtle(shape = cloud1,visible=False)
t_cloud1.penup()
t_cloud1.goto(-800,100)
t_cloud1.showturtle()
slide_cloud(t_cloud1)

t_cloud2 = Turtle(shape = cloud2,visible=False)
t_cloud2.penup()
t_cloud2.goto(-900,200)
t_cloud2.showturtle()
slide_cloud(t_cloud2)

t_cloud3 = Turtle(shape = cloud3,visible=False)
t_cloud3.penup()
t_cloud3.goto(-600,000)
t_cloud3.showturtle()
slide_cloud(t_cloud3)

t_poem = Turtle(shape = poem,visible=False)
t_poem.name = "我是诗"
t_poem.penup()
t_poem.goto(-1400,50)
t_poem.showturtle()
slide_cloud(t_poem)

t_fairy = Turtle(shape = fairy,visible=False)
t_fairy.penup()
t_fairy.goto(2000,0)
t_fairy.showturtle()
slide_fairy(t_fairy)

screen.mainloop()

 

下载完整源代码与素材,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 python, turtle | turtle制作的中秋节的夜空云彩和仙女慢慢出现动画已关闭评论

pygame动态背景之熊熊大火燃烧场景类

动态背景之熊熊大火燃烧场景,本程序的类是用来做动态背景的
你就像那冬天里的一把火,熊熊火焰燃烧了我的心窝。以下是部分代码预览:

"""动态背景之熊熊大火燃烧场景,本程序的类是用来做动态背景的"""

import time
import pygame
from pygame.locals import *

class Dynamic_background(pygame.sprite.Sprite):
    """动态背景类,把一系列帧图像做为背景不断地显示"""
    
    def __init__(self,images,size):
        """images:已转换成surface的对象列表,size:屏幕尺寸"""
        pygame.sprite.Sprite.__init__(self)
        self.screen_size = size
        self.images = images                   # images是surface列表
        self.image_index = 0                   # 切换造型从0开始
        self.images_amount = len(images)       # 造型数量
        self.image = self.images[0]            # 当前待渲染的图像
        self.rect = self.image.get_rect()      # 获取图像的矩形对象
 
def update(self):
        """超时更换图像"""
        if time.time() - self.start_time > self.interval:
            self.image_index += 1
            self.image_index = self.image_index % self.images_amount

def main():
    """主要的调用函数"""
    
    width,height = 960,720
    pygame.init()
    screen = pygame.display.set_mode((width,height))
    pygame.display.set_caption("pygame动态背景之熊熊大火燃烧场景,作者:李兴球")
    
    bgs = Dynamic_background(images,(width,height))
    running = True
    while running :
        event = pygame.event.poll()
        if event.type == QUIT:running = False
        bgs.update()
        pygame.display.update()

    pygame.quit()
       
if __name__ == "__main__":

    main()       
        

下载完整源代码与素材,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 pygame, python | pygame动态背景之熊熊大火燃烧场景类已关闭评论

单词炮弹.py (操作大炮打英文单词)

python turtle word canon shoot game单词炮弹演示

python turtle word canon shoot game单词炮弹演示

以下是部分代码预览:

"""本程序定义可旋转360度的角色类,它继承自海龟类,使用pillow模块让它旋转360次"""

import os
import sys 
import math
import time
import tempfile
from PIL import Image
from turtle import Turtle,Screen

def get_mouse_xy():
    """获取鼠标指针的坐标"""
    mousex = Sprite.mousex

def shoot(x,y):
    speed = 10
    position = (x,y)
    image = "bullet.png"

def check_collide(word_group,bullet_group):
    """碰撞检测"""
    global score
    removed_word = set()
    removed_bullet = set()
    wg = word_group.copy()       # 由于在迭代的过程中可能会改变集合所以用副本
    bg = bullet_group.copy()
       
if __name__ == "__main__":

    score = 0                       # 得分
    explosion_images = glob("explosion/*.gif")
    sprite_image = "大炮.png"       # 大炮图
    word_group = set()
    bullet_group = set()
    
    screen = Screen()
    screen.delay(0)
    screen.setup(800,600)
    screen.colormode(255)
    screen.bgcolor((4,21,104))
    
    screen.listen()
    screen.mainloop()     

 

本程序较长,下载完整源代码与素材,包括所有子模块,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 pillow, python, turtle | 单词炮弹.py (操作大炮打英文单词)已关闭评论

字母爆破机.py (Python打字练习)

python turtle letter explosioner字母爆炸机

python turtle letter explosioner字母爆炸机

用海龟画图模块制作的英文字母打字练习程序。以下是部分代码预览,模块扫码后都可见:

"""字母爆破机.py,这是一个用Python的海龟画图模块制作的打字练习小游戏,有着比较漂亮的界面,本版本增加了提示功能。"""

from random import randint,choice
from explosion import *                           # 导入爆炸效果类
from tipfunc import *                             
from keycodes import *
 
def spawn_letter():
    """产生一个字母对象,并且移动,使用screen的standard坐标系"""
          
    def init():
        """初始化字母,让它在左边或右边 随机出现。letter是一个字母对象""" 
        letter.clear()
        letter.go_on = True                       # 用于暂停
        letter.hitted = False                     # 描述是否击中
        letter.keycode = choice(letters_keys)     # 随机选择一个keycode
        letter.value = letters[letter.keycode]    # 随机选择一个字母
    
    def move():
        """移动字母,移动的距离超过屏幕长度并且没有被击中则换个字母重来"""
        if letter.go_on :                          
           letter.clear()
           letter.fd(letter.speed )
           letter.distance += letter.speed       
           letter.write(letter.value,align='center',font=ziti)         

    
    def eventfun(event):
       """按键事件执行函数,event如下所示,坐标是tkinter式坐标:
           KeyPress event state=Mod1 keysym=a keycode=65 char='a' x=314 y=355>"""      
       if event.keycode == 32 : letter.go_on = not letter.go_on
       if event.keycode == letter.keycode:    # 表示击中了
           
    def setspeed(x,y):
        """设置字母的移动速度"""
        letter.speed = screen.numinput("速度","请输入字母移动速度",default=5,maxval=30,minval=1)
        if letter.speed == None : letter.speed = 5 
        screen.listen()                       # 会失去焦点,需重新监听 

    ziti = ("黑体",56,'normal')
    tip_cors = TIP_CORS_DICT                  # 提示坐标映射表    
    letters = KEYCODE_DICT                    # 键码与字符串映射表
    letters_values = list(letters.values())   # 字母的值表,如D,9
    letters_keys = list(letters.keys())       # keycode表


if __name__ == "__main__":

    width,height = 800,600
    screen = Screen()
    screen.bgpic("bg.png")
    screen.setup(width,height)
    screen.title("字母爆破机,作者:李兴球")
    screen.delay(0)
    explosion_images = glob("explosion/*.gif")
    [screen.addshape(image) for image in explosion_images]
    spawn_letter()
    screen.mainloop()

下载完整源代码与素材,包含各个子模块,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 python, turtle | 字母爆破机.py (Python打字练习)已关闭评论

海龟每步画保存为png与合成gif程序源代码

以下是部分代码预览:

"""海龟每步画保存为png.py,
   本程序把海龟每步所画的图形都保存为png格式的图片,以便合成gif动画。
原理是用(画布)screen.cv.postscript命令,然后用ghostscript进行转换。
首先需要安装ghostscript,设定好搜索路径。"""

import os
import io
from PIL import Image
from turtle import * 

def savepng(canvas,path):
    """把canvas.postscript的内容转换成png写入文件"""     
    global counter
    psimage = canvas.postscript(colormode = 'color')    # 生成ps字符串
    filename = path + os.sep + str(counter) + ".png"    # 形成文件名

"下面变量需根据安装ghostscript的路径决定" 
ghostscrpit = 'C:\\Program Files\\gs\\gs9.26\\bin'    
counter = 0
"以下是添加搜索ghostscript的路径"
path = os.environ['path']
path = path.split(";")
path.append(ghostscrpit) 
path = ';'.join(path)
os.environ['path'] = path

screen = Screen()
screen.delay(10)
screen.setup(500,660) 

t = Turtle(shape='turtle')
t.shapesize(2,2)
t.color("blue")

t.penup()
t.pensize(4)
t.setheading(90)            
t.bk(200)
t.pendown()
draw_tree(200,4)
t.ht()
screen.mainloop()

 

如需要查看完整代码,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 pillow, turtle | 海龟每步画保存为png与合成gif程序源代码已关闭评论

tkinter窗体半透明效果演示

python演示了tkinte窗体的半透明效果

以下是部分代码预览:

"""本程序演示了tkinter窗体的半透明效果"""

import math
from turtle import *

width,height=640,640
screen = Screen()
screen.delay(0)
root = screen._root                         # 获取屏幕的根,就是窗体对象

screen.setup(width,height)
screen.bgpic("bg.png")
screen.addshape("redball.gif")

ball1 = Turtle(shape="redball.gif")
ball1.penup()
ball1.speed(0)
ball1.angle = 0
ball2 = ball1.clone()
ball2.angle = 180 

screen.exitonclick()   #  单击关闭窗口

如需要查看完整代码,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 python, tkinter, turtle | tkinter窗体半透明效果演示已关闭评论

webp图像文件拆帧split frames

想对webp文件进行拆帧,在网上查找方法,最后找到其实最新的枕头模块就能完成此任务,这真应了那句话叫踏破铁鞋无觅处,得来全不费功夫.代码如下所示:

from PIL import Image, ImageSequence

im = Image.open("200w.webp")

index = 1
for frame in ImageSequence.Iterator(im):
    
    frame.save(f"images/{index}.png")
    index += 1

 

发表在 pillow, python | webp图像文件拆帧split frames已关闭评论

tkinter和pymunk的Sprite类练习参考代码

"""本项目暂停2019/4/17,项目的初衷是编制一个受物理引擎pymunk的Sprite类,由于种种原因,本项目可能不会再重启,代码供人参考——李兴球"""

import time
import math
import tkinter

class Vec2D(tuple):
    """2D向量类,继承于元组,提供以下的向量操作,a,b是向量,k是数字

       a+b 向量加法
       a-b 向量减法
       a*b 向量内积
       k*a and a*k 缩放向量
       |a| 向量的绝对值
       a.rotate(angle) 旋转向量
    """
    def __new__(cls, x, y):
        return tuple.__new__(cls, (x, y))
    def __add__(self, other):
        return Vec2D(self[0]+other[0], self[1]+other[1])
    def __mul__(self, other):
        if isinstance(other, Vec2D):
            return self[0]*other[0]+self[1]*other[1]
        return Vec2D(self[0]*other, self[1]*other)
    def __rmul__(self, other):
        if isinstance(other, int) or isinstance(other, float):
            return Vec2D(self[0]*other, self[1]*other)
    def __sub__(self, other):
        return Vec2D(self[0]-other[0], self[1]-other[1])
    def __neg__(self):
        return Vec2D(-self[0], -self[1])
    def __abs__(self):
        return (self[0]**2 + self[1]**2)**0.5
    def rotate(self, angle):
        """旋转向量
        """
        perp = Vec2D(-self[1], self[0])
        angle = angle * math.pi / 180.0        
        c, s = math.cos(angle), math.sin(angle)
        return Vec2D(self[0]*c+perp[0]*s, self[1]*c+perp[1]*s)
    def __getnewargs__(self):
        return (self[0], self[1])
    def __repr__(self):
        return "(%.2f,%.2f)" % self
    
  
def negative_y_cors(points):
    """把每个点的y坐标取反"""
    amounts = len(points)
    points = [ (2*(1-(index%2)) -1)  * points[index] for index in range(amounts) ]
    return points

class _Window(tkinter.Tk):
    
    _screen = None
    def __init__(self,width,height,title="窗口标题",bgcolor='white',background=None):
        tkinter.Tk.__init__(self)
        
        self.__bgimages = {}         # 背景字典
        self.raw_title = title       # 仅记录原始标题
        self.resizable(False,False)  # noresize不可变窗口大小
        self.title(title)
        self.width = width
        self.height = height
        self.canvas = tkinter.Canvas(self,width=self.width,height=self.height,bg=bgcolor,border=0 )
        self.canvas.config(scrollregion=(-width//2, -height//2, width//2, height//2 ))
        self.canvas.pack()
        self.__blankimage = tkinter.PhotoImage(width=1, height=1) # 新建空白图形
         
        self.__background = self.canvas.create_image(0,0,image=self.__blankimage) # 这是背景item,是个id号

        self.set_background(background)

    def set_background(self,image):         
        
        if image:                   # 如果image有数据并且字典中有,则直接返回,否则添加到背景字典里。
            self.__background_image = self.__bgimages.setdefault(image,tkinter.PhotoImage(file=image))
        else:
            self.__background_image = self.__blankimage
        self.canvas.itemconfig(self.__background,image=self.__background_image)
        
    def set_bgcolor(self,color):
        
        self.canvas.config(bg=color)

    def set_width_and_height(self,width,height):
        
        """设置窗口画布的宽度和高度,别名是size"""
        
        self.canvas.config(width=width,height=height)
        self.canvas.config(scrollregion=(-width//2, -height//2, width//2, height//2 ))
        
    def ontimer(self,fun,millisecond=0):
        """定时器,在一定时间后再次调用fun,时间单位为毫秒"""
        if millisecond == 0:
            self.canvas.after_idle(fun)
        else:
            self.canvas.after(millisecond, fun)
            
    # 定义别名
    size = set_width_and_height
    background = set_background
    bgcolor = set_bgcolor

class Sprite():
    def __init__(self):
        if _Window._screen is None:            
            _Window._screen = create_window(480,360)            
        self.canvas = _Window._screen.canvas
        self.dx = 0           # 代表水平速度
        self.dy = 0           # 代表垂直速度
        self.angle = 0        # 角度
        self.itemid = 0       # 角色id号,具体在子类中的canvas分配
        
    def move(self):
        
        self.canvas.move(self.itemid,self.dx,-self.dy)
        self.canvas.update_idletasks()
        
    def bbox(self):
        
        x1,y1,x2,y2 =  self.canvas.bbox(self.itemid)
        return x1,-y1,x2,-y2
    
    
    def coords(self,position=None):
        """返回形状的两点坐标或设置坐标"""
        if position == None:
           points =  self.canvas.coords(self.itemid)
           return negative_y_cors(points)
        else:    
           self.canvas.coords(self.itemid,negative_y_cors(position))
           
    def show(self):
        """显示出来"""
        self.canvas.itemconfig(self.itemid,state='normal')
        self.canvas.update_idletasks()
        
    def hide(self):
        """隐藏"""
        self.canvas.itemconfig(self.itemid,state='hidden')
        self.canvas.update_idletasks()

    def point_list(self):
        """返回得到的每个顶点列表,旋转形状需要获取形状的每个顶点坐标。"""
        
    def get_center(self):
        points = self.coords()
        amounts = len(points)
        all_x = [points[i] for i in range(0,amounts,2)]
        all_y = [points[i] for i in range(1,amounts,2)]
        self._left = min(all_x)
        self._right = max(all_x)
        self._top = max(all_y)
        self._bottom = min(all_y)
        self._centerx = (self._left + self._right)/2.0
        self._centery = (self._bottom + self._top)/2.0
        return points
        
    def rotate(self,angle):
        
        points = self.get_center()   # 获取多边形的每一个顶点和得到中心点坐标
        print("点们:",points)       # 获取到的是这样的列表: [-50.0, 25.0, 50.0, -25.0]
        amounts = len(points)
        points = [ (points[i],points[i+1]) for i in range(0,amounts,2) ]
        x = self._centerx
        y = self._centery
        print("中心点:",x,y)
        points = [ Vec2D(point[0]-x,point[1]-y) for point in points]           # 转变成向量
        points = [ point.rotate(angle) for point in points]    # 旋转
        points = [ (point[0]+x,point[1]+y) for point in points]    # 转换回元组
        points_y = [ negative_y_cors(point) for point in points] # 把每个点的y坐标取负

##        if self.canvas.type(self.itemid) in ["arc","oval","rectangle"]:
##            self.canvas.coords(self.itemid, *points)
##             
##        elif self.canvas.type(self.itemid) in ["polygon"]:
        p = []
        for point in points_y:
            p.append(point[0])
            p.append(point[1])
        print(p)
        self.canvas.coords(self.itemid,p)
             
        self.angle = angle
        self.canvas.update_idletasks()
        
    def setheading(self,delta_angle):
        
        self.angle = self.angle + delta_angle
        self.angle = self.angle % 360
        print("角度=",self.angle)
        self.rotate(self.angle)
        
        
           
class Line(Sprite):
    
    def __init__(self,pointlist,color="blue",width=1,capstyle='round',joinstyle='round'):
        """画直线,pointlist:坐标点列表,color:颜色,width:笔迹宽度,
           capstyle:末端风格,值为'round'或'butt'或'projecting'
           joinstyle:连接风格,值为'round'、'bevel'、'miter' 。
       """
        Sprite.__init__(self)
        pointlist = negative_y_cors(pointlist)
        self.itemid = self.canvas.create_line(pointlist,fill=color,width=width,capstyle=capstyle,joinstyle=joinstyle)
    
    
class Polygon(Sprite):    
    def __init__(self,pointlist,color="blue"):
        Sprite.__init__(self)
        pointlist = negative_y_cors(pointlist)
        self.itemid = self.canvas.create_polygon(pointlist,fill=color,outline=color,width=0)

        
class Arc(Sprite):
    def __init__(self,bbox,color="blue",start=0.0,end=90.0,style='pieslice'):
        """画扇形,弦形,和弧形,bbox:绑定盒,color:颜色,start:起始角度,end:结束角度,style:样式(pieslice、chord、arc)
        tkinter.PIESLICE -> 'pieslice'扇, tkinter.CHORD ->'chord'弦, tkinter.ARC ->'arc'弧
        """
        Sprite.__init__(self)
        bbox = negative_y_cors(bbox)
        self.itemid = self.canvas.create_arc(bbox ,fill=color,outline=color,width=0,start=start,extent=end,style=style)
        
class Rectangle(Sprite):
    def __init__(self,bbox,color="blue"):
        Sprite.__init__(self)
        bbox = negative_y_cors(bbox)
        self.itemid = self.canvas.create_rectangle(bbox ,fill=color,outline=color,width=0)
        
class Circle(Sprite):
    def __init__(self,bbox,color="blue"):
        Sprite.__init__(self)
        bbox = negative_y_cors(bbox)
        self.itemid = self.canvas.create_oval(bbox,fill=color,outline=color)

class Text(Sprite):
    def __init__(self,position,string,color="blue",font=("黑体",24,"normal")):
        Sprite.__init__(self) 
        self.itemid = self.canvas.create_text(position,text=string,fill=color,font=font)

        
  
def create_window(width,height,title="窗口标题",bgcolor='white',background=None):
     
    if _Window._screen is None:
         _Window._screen = _Window(width,height,title=title,bgcolor=bgcolor,background=background)
          
    return _Window._screen
     
          
if __name__ == "__main__":

    
    def display_cursor(event):
        """在标题栏里显示标题"""    
        x = window.canvas.canvasx(event.x)
        y = -window.canvas.canvasy(event.y)
        window.title("(" + str(x) + "," + str(y) + ")_" + window.raw_title)
        
    
    背景表 = ["images/" + str(i) + ".png"  for i in range(40)]
    amounts = len(背景表)
    
    window = create_window(480,360,title="窗口标题",bgcolor='cyan',background='background.png')
    
    window.canvas.bind("<Motion>",display_cursor)
    window.size(800,600)
    index = 0
    def alt_background():
         global index 
         window.background(背景表[index])
         index = index + 1
         index = index % amounts
         window.canvas.update_idletasks()
         window.ontimer(alt_background,10)
         
    alt_background()
    window.canvas.bind("<Button-1>",lambda event:window.destroy())
 
 


   
 
        
         
     
 

 

发表在 pymunk, python, tkinter | tkinter和pymunk的Sprite类练习参考代码已关闭评论

turtle的ondrag与类的继承练习Durtle类

"""本程序新建Durtle类,生成的拖动角色会换一个造型,松开它会隐藏"""


from turtle import *

class Durtle(Turtle):
    def __init__(self,images):
        Turtle.__init__(self,visible=False)
        self.begin_drag = 0                  # 拖的标志
        self.penup()
        self.images = images                 # 造型列表
        self.index = 0                       # 初始造型索引
        self.amounts = len(images)           # 造型数量

        "设定初始造型"
        self.image = self.images[self.index] # 当前造型
        self.shape(self.image)               # 设定造型
        self.st()                            # 显示            
         
        self.onrelease(self.act2)
        
    def alt_costume(self):
        "切换到下一个造型"
        if self.begin_drag == 0:
            self.index = self.index + 1
            self.index = self.index % self.amounts
            self.image = self.images[self.index]
            self.shape(self.image)
        self.begin_drag += 1        
                
    def act1(self,x,y):
        """切换到下一个造型,定位到鼠标指针坐标"""
        self.alt_costume()
        self.goto(x,y)  
        

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 python, turtle | turtle的ondrag与类的继承练习Durtle类已关闭评论

pygame2D我的世界简易源代码

python 2d minecraft simple version我的世界2Dpygame

python 2d minecraft simple version我的世界2Dpygame

本人用pygame做的2D简单版本。我的世界,你懂的。这个版本用石头、碳、水可以合成钥匙。以下是代码预览:

import random
import pygame
from pygame.locals import *

TILE_SIZE = 30
STEVE_SPEED = 30
SIZE = SCREEN_WIDTH,SCREEN_HEIGHT = 900,750
TRAY_HEIGHT = 120
ROWS = SCREEN_HEIGHT // TILE_SIZE
COLS = SCREEN_WIDTH // TILE_SIZE

# 爆炸图像表
explosion_images = [pygame.image.load(f'explosion/{i}.gif') for i in range(6)]

class Block(pygame.sprite.Sprite):
    """方块类"""
    cors = []                             # 所有方块坐标表
    def __init__(self,master,group):
        pygame.sprite.Sprite.__init__(self)
        self.image_index = random.choice(list(block_images.keys()))
        self.image = block_images[self.image_index]                 
        self.rect = self.image.get_rect()        
        
class Spide(pygame.sprite.Sprite):
    """蜘蛛类,它一生成会自动攻击史蒂夫,给蜘蛛加上碰到边缘就反弹等AI行为"""
    def __init__(self,position,image,group):
        """image:蜘蛛的surface"""
        pygame.sprite.Sprite.__init__(self)
        self.image = image
        self.rect = self.image.get_rect()
         
class Explosion(pygame.sprite.Sprite):
    """爆炸类"""
    def __init__(self,position,screen,group):

 
class Bullet(pygame.sprite.Sprite):
    """子弹类,史蒂夫按空格会发射子弹"""
    def __init__(self,master):
        """master:史蒂夫"""

        

def make_background():
    """画格子,做为背景,返回一个surface"""
    color = (25,95,12)
    surface = pygame.Surface(SIZE)
    surface.fill((25,105,0))
        
def main():
    
    house_images = ["house/house_open.png","house/house_close.png"] 
    steve_images = ["player/player_up.png","player/player_down.png","player/player_left.png","player/player_right.png"]
    pygame.init()
    screen = pygame.display.set_mode((SCREEN_WIDTH,SCREEN_HEIGHT+TRAY_HEIGHT))
    pygame.display.set_caption("pygame我的世界简单版")

    block_group = pygame.sprite.Group()    # 方块组
    spide_group = pygame.sprite.Group()    # 蜘蛛组
    explosion_group = pygame.sprite.Group()# 爆炸组
    
    background = make_background()         # 产生背景图
    tip_tray = pygame.image.load("tray.png")
    keyimage = pygame.image.load("key.png")

    # 新建房子,有两个造型
    house_images = [pygame.image.load(image) for image in house_images]    
    house = House(house_images)

    steve_position = 2 * TILE_SIZE, SCREEN_HEIGHT - 2 * TILE_SIZE
    steve_images = [pygame.image.load(image).convert_alpha() for image in steve_images]    
    steve = Player(steve_images,steve_position,house,screen,block_group,spide_group,explosion_group)
    
    [Block(steve,block_group)for i in range(100)] # 生成一百个方块

    clock = pygame.time.Clock()
    running = True
    
    while running:                          # 尽量缩短while循环体长度
        event = pygame.event.poll()         # 从队列取一个事件
        if event.type == QUIT:running = False
        if event.type == KEYDOWN:
            steve.keypress_check(event)      # 按键检测会调用update更新坐标等            
            steve.house_detect()             # 是否在房子里外检测         

        spide_group.update()
        
        screen.blit(background,(0,0))        # 画背景
        screen.blit(tip_tray,(0,SCREEN_HEIGHT))
        block_group.draw(screen)             # 画所有方块 
        screen.blit(house.image,house.rect)  # 画房子
        spide_group.draw(screen)             # 画所有蜘蛛
        screen.blit(steve.image,steve.rect)  # 画史蒂夫
        
        [bomb.draw()  for bomb in  explosion_group] # 这里不用group的draw方法,因为它要切换造型             
        
        if steve.key ==  3 :  screen.blit(keyimage,(SCREEN_WIDTH-100,SCREEN_HEIGHT+30))
        
        pygame.display.update()
        clock.tick(60)
        
    pygame.quit()        

if __name__ == "__main__":

    main()  
    

下载完整源代码与素材,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 pygame, python | pygame2D我的世界简易源代码已关闭评论

python星际赛车 源代码 硬核游戏!turtle star race arcade game

python trutle star space race game

python trutle star space race game


主要用海龟画图制作的简易赛车接金币游戏,音乐效果比较硬核!借用的是pygamer的混音器模块。

以下是部分代码预览:

"""这是用Python的海龟画图模块制作的赛车小游戏"""

from turtle import Turtle,Screen
from random import randint,choice
from time import sleep
from car import *                           # 导入Car小汽车类

__author__ = "李兴球"
__date__ = "2018/11/26"
__company__ = "风火轮编程"

class ScrollBackground():
    """定义一个滚动背景类"""

class Coin(Turtle):
    def __init__(self,images,sprite,sound):
        Turtle.__init__(self,visible=False)
        self.images = images             
        self.sprite = sprite
        self.sound = sound
        self.penup()                          # 抬笔        
        self.goto_up()                        # 到上边        

        
def move_left():
    if main_sprite.xcor()>-80 and main_sprite.hp >= 0:   # 主角x坐标大于-80并且血大于等于0就能向左移动
        main_sprite.setx(main_sprite.xcor() - 40)
    
def move_right():
    if main_sprite.xcor()< 80 and main_sprite.hp >= 0:   # x坐标小于80并且血大于等于0就能向右移动
        main_sprite.setx(main_sprite.xcor() + 40)

def init_audio(music,collision_sound,coin_sound):
    """初始化音频"""
    metal_sound = None                            # 金属声
    try:
        import pygame                             # 导入pygame模块,无此模块本游戏不会发声
        pygame.mixer.init()                       # 初始化混音器
        pygame.mixer.music.load(music)            # 加载背景音乐
        pygame.mixer.music.play(-1,0)             # 循环播放背景音乐
        metal_sound = pygame.mixer.Sound(collision_sound) # 加载金属碰撞声
        coin_sound = pygame.mixer.Sound(coin_sound)       #加载金币声
         
    except:
        pass
    return metal_sound,coin_sound

def init_screen(background_image,sport_car_image):
    """初始化屏幕"""
    screen = Screen()                            # 新建屏幕对象
    screen.delay(0)                              # 屏幕绘画延时为0
    screen.setup(480,360)                        # 设置屏幕canvas大小
    screen.bgcolor("black")                      # 背景色为黑色
    screen.bgpic("封面2.png")                    # 显示封面
    screen.title("Python星际赛车_作者:李兴球_风火轮编程")

    
    return screen

def make_mainsprite(screen):
    global main_sprite
    main_sprite = Turtle(shape = sport_car_image)
    main_sprite.score = 0                        # 新增自定义属性,得分
    main_sprite.hp = 100                         # 新增自定义属性,血量
    main_sprite.dead = False                     # 新增死亡属性,表示是否死亡
    main_sprite.penup()
    main_sprite.sety(-110)
    screen.onkeypress(move_left,"Left")
    screen.onkeypress(move_right,"Right")
    return main_sprite
    
def begin_game():
    """开始游戏"""
    screen.onkeypress(None,"Return")             # 取消回车键的按键绑定
    screen.bgpic("rode480.png")                  # 背景图书片
    scrollbg = ScrollBackground(background_image,screen) #新建可滚动背景
    scrollbg.move()                              # 背景移动
    main_sprite = make_mainsprite(screen)        # 新建主角,也就是按左右键操作的跑车
    
    
if __name__ == "__main__":

    main_sprite = None
    
    music = "Chiptune.wav"
    collision_sound = "1.wav"
    coin_sound = "接金币.wav"
    metal_sound,coin_sound = init_audio(music,collision_sound,coin_sound)    

    background_image = "rode480.gif"
    sport_car_image = "跑车.gif"
    car_images = ["car" + str(i) + ".gif" for i in range(5)]
    coin_images = ["Coin_Normal.gif","Coin_Picked.gif"]
    screen = init_screen(background_image,sport_car_image)
    
    "按回车开始游戏"
    screen.onkeypress(begin_game,"Return")     #绑定回车键到begin_game函数
    screen.listen()                
    screen.mainloop() 
    

星际赛车_python赛车游戏

下载完整源代码与素材,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 python, turtle | python星际赛车 源代码 硬核游戏!turtle star race arcade game已关闭评论

Python相声<大数据>双人对话动画

python talk show big data相声大数据

python talk show big data相声大数据

人家用海龟画图进行绘画,我用海龟画图制作了一个相声。以下是部分代码预览:

"""这是一个Python动画,显示的是两个人讲相声,相声是我自己编的。"""

import os
from surtle import *
from face_and_functions  import *

def match_condition(line=""):
    """检测一行中是否包括两个冒号,本函数用下列一行也可以定义:
       match_condition = lambda line="":list(line).count(":") == 2
    """
    s = line.split(":")
    if len(s) == 3 :
        return True
    else:
        return False
    
def talk_end():
    """相声结束后显示的文字信息。"""
    screen.bgpic("images/背景.png")
    t = Turtle(visible=False)
    t.penup()
    t.sety(-50)
    t.color("cyan")
    info = "大数据,指互联网不断产生\n的海量数据集合,需要新处理\n模式才能让它转换为真正有\n价值的信息资产。"

    
def load(cross_talk_file):
    """加载装有相声文字的文本文件。"""
    words = []
    f = open(cross_talk_file)

    return words

def cross_talk(cross_talk_file):
    """说相声函数,轮流从列表中显示文字"""   
    boy = Surtle()    
    boy.goto(-150,-60)
    
    girl = Surtle() 
    girl.setheading(180)
    girl.goto(150,10)


def wait_fall_end():
    if face.shakecounter>0: 
        screen.ontimer(wait_fall_end,1000)
    else:
        face.hideturtle() 
        screen.bgpic("images/篮球场背景.png")

if __name__ =="__main__":

    project_name = "相声《大数据》_作者:李兴球"
    success_sound = "audios/胜利鼓掌吹.wav"
    aa_sound  = "audios/乌鸦叫.wav"
    xiao_sound = "audios/大笑.wav"
    silent_sound = "audios/silent.wav"
    sound_names = ['success_sound','aa_sound','xiao_sound','silent_sound']
    sound_files = [success_sound,aa_sound,xiao_sound,silent_sound]
    sounddict= init_sound(sound_names,sound_files)
    playsound(sounddict["success_sound"])      # 笑声来了...

    screen = init_screen(project_name,480,360,"images/背景.png",["images/笑掉牙.gif"]) 
    face = Face(shape = "images/笑掉牙.gif")

    wait_fall_end()

    screen.mainloop()

python相声《大数据》双人动画

下载完整源代码与素材,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 python, turtle | Python相声<大数据>双人对话动画已关闭评论

太空出租箭turtle版源代码

python space rent rocket太空出租箭

python space rent rocket太空出租箭

操作火箭小心翼翼地回家的小游戏。以下是部分代码预览:

"""请按上\左\右键操作火箭,让它平安着陆,着陆的时候速度不能太快哦,否则就会爆炸"""

import os
from turtle import *

def init_audio():
    """初始化音频"""
    try:
        import pygame        
        pygame.mixer.init()
        pygame.mixer.music.load("audios\\495046_The-War-W.wav")
        pygame.mixer.music.play(-1,0)        
        bumped_sound = pygame.mixer.Sound("audios\\中爆炸.wav")       
    except:        
        bumped_sound = None
        
    return bumped_sound


def init_screen():
    """初始化屏幕"""
    screen = Screen()
    screen.title("太空出租箭_作者:李兴球")
    screen.bgcolor("black")
    screen.bgpic(images_folder + "背景1.png")
    screen.setup(960,720)
    screen.delay(0)
    
    return screen

def makelevel():
    """生成关卡对象所需要的嵌套列表,以下代码可用关卡设计器生成。"""
    map1 = [(200,100),(-250,180),(-260,-200),(260,-200)]
    map2 = [(-200,-200),(200,180),(300,-180),(0,-90)]
    map3 = [(-100,-40),(120,160),(230,230),(-230,-230),(230,-230)]
    map4 = [(0,0),(-100,190),(230,230),(-180,-160),(130,-230),(-350,-210),(350,-0)]
    map5 = [(-100,0),(-100,190),(230,230),(-180,-160),(130,-230),(50,-210),(350,-100),(300,100)]
    maplist = [map1,map2,map3,map4,map5]
    
    return maplist

def main():
    """生成关卡对象,启动火箭"""    
    screen.onkeypress(None,"Return")
    screen.bgpic(images_folder + "背景2.png")
    
    levels = Level(maplist,screen)               # 根据每关卡的坐标点列表生成关卡对象

    images = [images_folder + '箭造型1.gif',images_folder + '箭造型2.gif'] # 火箭造型
    [screen.addshape(image) for image in images]                           # 注册到形状列表
    explode_images = [images_folder + "爆炸" + str(i) + ".gif" for i in range(1,21)]
    [screen.addshape(image) for image in explode_images]             # 注册爆炸造型到形状列表

    ps = images,explode_images,levels,bumped_sound    
    arrow = Firearrow(*ps)                                           # 火箭实例化后自动下落

if __name__=="__main__":

    images_folder = os.getcwd() + os.sep + "images" + os.sep
    
    bumped_sound = init_audio()                     
    screen = init_screen()                        # 初始化屏幕
    maplist = makelevel()                         # 每关卡的坐标点列表组成的列表。   
    
    screen.onkeypress(main,"Return")              # 按回车键启动main函数
    screen.listen()
    screen.mainloop()

Python游戏太空出租箭

下载完整源代码与素材,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 python, turtle | 太空出租箭turtle版源代码已关闭评论

Python创意多关卡游戏之二维码的梦

python二维码的梦闯关游戏
以下是部分代码预览:

"""二维码的梦.py
   操作一个二维码图片闯关找到扫描枪的小游戏。
"""
from turtle import *

def init_screen():
    """初始化屏幕"""
    screen = Screen()              #新建屏幕对象
    screen.delay(0)                #延时
    screen.setup(500,500)          #屏幕大小
    screen.title(game_name)        #标题
    screen.addshape(qrcode_image)  #增加二维码图像,这里引用的是全局变量
    screen.addshape(gun_image)     #扫描枪gif图
    screen.addshape(cry_image)     #哭脸gif图
    screen.bgpic(cover_image)      #封面png图
    
    return screen

def produce_scanner():
    """产生scanner对象"""
    scanner = Turtle(visible = False)
    scanner.shape(gun_image)      #形状为扫描枪
    scanner.penup()               #抬笔
    scanner.goto(0,150)           #坐标定位
    return scanner
    

def scanner_alt_status():
    """每隔10秒秒通二维码的关卡设定隐藏/显示状态"""
    if qrcode.level_number < 3 :   #前三关一直都在等
        scanner.hideturtle()        
    else:
        scanner.showturtle()       #到了第四关显示出来
        
    screen.ontimer(scanner_alt_status,10)
        
def check_condition():
    """到第四关时如果二维码和扫描枪距离小于30并且是可见的,那么表示闯关成功"""
    condition = qrcode.distance(scanner)<30 and scanner.isvisible() 
     

def start_game():
    """生成二维码对象和扫描枪对象"""
    global qrcode,scanner
    screen.onkeypress(None,"return")

    
if __name__ == "__main__":

    game_name = "二维码的梦,作者:李兴球"
    fail_sound,success_sound = init_audio()
    qrcode,scanner = None,None
    qrcode_image = "images/二维码.gif"
    gun_image   = "images/gun.gif"
    cry_image = "images/哭脸.gif"
    cover_image = "images/封面.png"    
    screen = init_screen()
    screen.onkeypress(start_game,"Return")
    screen.listen()
    screen.mainloop()

下载完整源代码与素材,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 python, turtle | Python创意多关卡游戏之二维码的梦已关闭评论

单词爆破机


单词爆破机是一个英文单词练习程序。用turtle模块开发的。以下是部分代码预览:

"""单词爆破机.py,这是没有定义类制作的一个英文单词打字练习小游戏。
单词会从上面的左边或边冒出来。正确输入后按回车键,它就会爆炸,
按空格键会在移动和暂停之间切换。"""

from random import randint,choice
from explosion import *
from words import *

def spawn_word():
    """产生一个单词对象,并且移动,使用screen的standard坐标系"""
          
    def init():
        """初始化字母,让它在左边或右边 随机出现。letter是一个字母对象"""
        nonlocal input_string                      # input_string是从键盘输入的字符序列
        wordobj.clear()
        input_string = ""
        wordobj.go_on = True                       # 用于移动和暂停的切换
        wordobj.hitted = False                     # 描述是否击中
        wordobj.word = choice(words_keys)          # 随机选择一个英文单词
        wordobj.translation = words[wordobj.word]  # 这是和上面的单词相对应的翻译      
        wordobj.setheading(randint(0,1) * 180)     # 设置方向0向右,180向左
        tmp = int(wordobj.heading()/180)
        x = ( 2 * tmp - 1 ) * screen_width//2      # 方向右,它会在左边出现
        y = randint(140,screen_height//2-150)
        wordobj.goto(x,y)                          # 定位到坐标
        wordobj.distance = 0                       # 注意这里重定义了distance
        screen.title(wordobj.word + " ," + wordobj.translation)
        
    def move():
        """移动字母,移动的距离超过屏幕宽度并且没有被击中则换个字母重来"""

    
    def eventfun(event):
       """按键事件执行函数,event如下所示,坐标是tkinter式坐标:
       pass
         
    def setspeed(x,y):
        """设置字母的移动速度"""
        wordobj.speed = screen.numinput("速度","请输入字母移动速度",default=5,maxval=30,minval=1)
        if wordobj.speed == None : wordobj.speed = 5 
        screen.listen()                    # 会失去焦点,需重新监听 

    screen.onclick(setspeed)
    screen.listen()    

if __name__ == "__main__":

    width,height = 800,600
    screen = Screen()
    screen.bgpic("bg.png")
    screen.setup(width,height)
    screen.delay(0)
    explosion_images = glob("explosion/*.gif")
    [screen.addshape(image) for image in explosion_images]
    spawn_word()
    screen.mainloop()

python英文打字游戏单词爆破机

下载完整源代码与素材,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 python, turtle | 单词爆破机已关闭评论

Python创意多媒动画菜根谭小猫

Python菜根谭小猫创意动画
turtle模块制作的动画。 以下是部分代码预览:

"""
   菜根谭小猫.py
   本程序演示四只行走的小猫,碰到屏幕边缘会反向,有时候它也会向后转。
   它会时不时地说《菜根谭》里面的句子。它有时候还会发出猫叫声。
   作者:李兴球,日期:2018/10/2。
"""

import os
from turtle import *
from random import randint,choice
 
class Sprite(Turtle):
    def __init__(self,ycor,imagesL,imagesR,sentence,sound = None):
        """参数说明:
           ycor:初始y坐标
           imagesL: 左行列表图
           imgaesR: 右行列表图
           sentence:话语列表
           sound:喵叫声
        """        
        
    def move(self):
        """让小猫移动,让它有时候会向后转,有时候会说话。"""
        self.word_turtle.clear()
        self.miao()                                        #有时候会发声。
           
    def turn_back(self):
        """向后转"""
        
        self.rt(180)             
        self.images = self.imagesL if self.heading()==180 else self.imagesR
        self.index = 0
        
    def next_image(self):
        """切换到下一个造型"""
        self.shape(self.images[self.index])
        self.index = self.index + 1
        self.index = self.index % self.images_amount
        
    def bounce_on_edge(self):
        
        """对象是离边缘50像素时,让它向后转"""
        if abs(self.xcor()) > self.screen_width //2  - 50:
            self.turn_back()                                #到了边缘会向后转
            
    def miao(self):
        """设置一定的机率,让小猫发出喵叫声"""
        if randint(1,300) == 1:
            try:self.sound.play()
            except:pass
        
    def speak(self):
        """让小猫的头顶上显示一行句子,好像小猫在说话"""
        pass
        
        
def load_sentence(filename):
    """读文件内容,返回句子组成的列表,参数为文件名路径"""
    words = []
    f = open(filename)
    for line in f:
        if line.strip() != "": words.append(line)
    f.close()
    return words

def init_screen(width,height,title,background):
    """初始化屏幕,参数分别是:宽度,高度,窗口标题,背景图路径"""
    screen = Screen()
    screen.bgpic(background)
    screen.setup(width,height)
    screen.title(title)    
    screen.delay(0)
    return screen
    
def register_gif(screen):
    """注册gif图形,参数为屏幕对象"""
    pass

def init_audio():
    """播放背景音乐,加载‘喵’声。"""


def main():
    
    """定义主程序,它的执行步骤为:
    初始化屏幕,注册gif图形,初始化音频,装载菜根谭名句,新建4个小猫对象,主循环
    """    
    screen = init_screen(960,720,"《菜根谭》小猫","stripes.png")  #初始化屏幕
    
    images0,images1 = register_gif(screen)                        #注册gif图到形状列表

    miao = init_audio()                                           #初始化音频
    
    句子 = load_sentence("菜根谭名句摘要.txt")                    #装载菜根谭名句到列表

    [Sprite(y,images0,images1,句子,miao) for y in (80,260,-120,-290)] #生成4只小猫
    
    screen.mainloop()                                            #主循环
    
               
    
if __name__=="__main__":

    main() 
                       

下载完整源代码与素材,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 pygame, python, turtle | Python创意多媒动画菜根谭小猫已关闭评论

编程娃娃Python版

"""bcwawa.py

《编程娃娃Python版》是继《编程娃娃》的姊妹篇。它不需要拖曳编程命令,采用的是直接编排图形化指令的模式,指挥一个娃娃回家。

此版本更重要的是能做为一个模块导入到Python原生环境,从而实现用真正的Python命令去指挥娃娃移动。

本版本新增命令如下:

forward:前进50像素,缩写为:fd,使用方法: fd()

backward:倒退50,缩写为:bk,back,使用方法:bk()

right:右转90,缩写:rt, 使用方法:rt()

left:左转90,缩写:lt,使用方法:lt()

jump:前进100,主要用来跳过炸弹。使用方法:jump()

bomb_ahead:检测娃娃前面是否有炸弹,返回布尔值。使用方法: bomb_ahead()

playmusic:播放音乐,不输入参数会播放小星星曲子。使用方法: playmusic()

pausemusic:暂停播放音乐。使用方法: playmusic()

stopmusic:停止播放音乐。使用方法: stopmusic()

unpausemusic:继续播放音乐。使用方法: unpausemusic()

set_level:设置当前关卡号。使用方法: set_level(3)

娃娃根据指令前进的主要原理如下:
在作品中设计了三排按钮,娃娃能访问这三排按钮。
第一排是子指令表1(相当于子程序1),以橙星开始,后面跟着9个指令按钮。
第二排也是子指令表2(相当于子程序2),以绿星开始,后面跟着9个指令按钮。
第三排代表主指令表(相当于主程序),以信封开始,后面跟着9个指令按钮.
程序启动后,娃娃对象生成,它会注册回车键绑定自己的execute方法。
当按回车键或单击信封按钮时,娃娃就像是收到了信的内容,会根据信的内容执行它的execute方法。
这个方法执行时会遍历主指令列表,从而根据主指令表中的命令让娃娃前进,转向或执行子指令表。
子程序也能调用子程序,但不能调用主程序。当子程序递归调用过多时,娃娃会自动停止移动。

让娃娃移动的三种方法:

1、按键:直接按上、下、左、右,空格键,手动操作娃娃。适合于体验按键。

2、编排图形化指令:单击信封及五角星后面的按钮,给娃娃编排指令。信封后面的9个按钮为主指令表,橙星为调用子程序1指令,绿星为调用子程序2指令。

向上箭头为前进指令(并不仅仅是向上移动,而是朝它当前的方向移动)。向右转箭头为右转指令,向左转箭头为左转指令,弯箭头为跳跃指令。

3、Python编程模式:把本程序做为模块导入,然后通过编写Python代码指挥娃娃前进。典型代码举例:

from bcwawa import *
set_level(9) # 设置当前关卡为第9关。
sleep(3)
for i in range(4): # 这个for循环的意思是重复4次“前进前进右转”
fd();fd()
rt()

配置文件名:cfg.txt
本程序的房子和炸弹这两种道具摆放方式分为过关模式与随机模式。过关模式是按内置的排列顺序每关摆放在固定的位置。
随机模式每个关卡都是随机的。
如果配置文件不存在,则默认为过关模式。
如果配置文件存在,里面的字符串为1,则也是关卡模式,其它字符则为随机摆放模式。
主要原理:在生成娃娃对象时,传递__game_mode__变量的值,让娃娃知道模式,当它碰到房子就能决定采用哪种方式重新摆放道具。

"""
__author__ = "李兴球"
__date__ = "2018/10"
__email__ = "406273900@qq.com"
__version__ = "1.0"

import sys,os,webbrowser
from turtle import *
from codewawa.gridturtle import *
from codewawa.bomb import *
from codewawa.house import *
from codewawa.wawa import *
from codewawa.command import *
from random import randint
from time import sleep

下载完整源代码与素材,包含各个子模块,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 python, turtle | 编程娃娃Python版已关闭评论

Python创意打砖块游戏埃及爆破砖

python pygame egypt brick埃及爆破砖

python pygame egypt brick埃及爆破砖


以下是部分代码预览:

"""
   一个创意打砖块游戏,用Python的pygame模块,这个版本实现了道具的设计。
   dead死亡道具,骷髅头,skeleton.png,不小心接到它后ball.lives减一,出现机率大
   life生命道具,15.png 核桃图形,接到后ball.lives加一
   speedup加速道具,speedup.png,接到它后球的速度翻倍
   slowdown减速道具,slowdown.png,接到它后球的速度减倍。

"""

import time
import pygame
from pygame.locals import *
from random import choice,randint

class Ball(pygame.sprite.Sprite):
    """弹球类"""
    def __init__(self,image,screen,board):
        pygame.sprite.Sprite.__init__(self)
        self.image = image
        self.rect = self.image.get_rect()
        self.screen = screen
        self.screen_width = screen.get_width()
        self.screen_height = screen.get_height()
        self.board = board           # 球能访问board
        self.dx = 0
        self.dy = 0
        self.shoot_flag = 0
        self.lives = 5                       # 球的数量
        
    def shoot(self):
        if self.shoot_flag == 0:             # 只有小球呆在拦板上才可以发射,否则在空中也能发射
           self.dx = choice([-10,-9,-8,-7,-6,-5,5,6,7,8,9,10])
           self.dy = choice([-10,-9,-8,-7,-6,-5])
           self.shoot_flag = 1
        
    def update(self):
        if self.shoot_flag == 0 :            
            self.rect.bottom =  self.board.rect.top
            self.rect.centerx = self.board.rect.centerx
        else:       
            self.rect.move_ip(self.dx,self.dy)
            if self.rect.top > self.screen_height + 200: # 弹球丢失,重新开始或结束游戏
               self.lives -= 1                         # 数量减去1
               self.shoot_flag = 0                     # 发射标志
               self.board.lost_ball()                  # 变短拦板
               pygame.display.set_caption("埃及爆破砖:" + str(self.lives))
   
        
class Explosion(pygame.sprite.Sprite):
    """爆炸类"""
    def __init__(self,images,position,group,screen):
        pygame.sprite.Sprite.__init__(self)
        self.images = images
               
def display_cover(cover_image):
    """显示封面"""
    cover_image = pygame.image.load(cover_image)
    clock = pygame.time.Clock()
    exit_game = False

def start_level(level_index):
    """生成砖块,启动这一关"""
    rows,cols = level_design[level_index]
    all_bricks_width = cols * 100 + (cols-1) * 20  # 所有砖块的宽度
    left_pad = (width - all_bricks_width) // 2     # 砖块两边的到屏幕边缘的距离

     
def collision_check():
    
    "小球和砖块组的碰撞"    
    b =  pygame.sprite.spritecollideany(ball, brick_group)    # 球和砖块组的碰撞,返回碰到的砖块

         
if __name__ == "__main__":

  
    pygame.init()
    screen = pygame.display.set_mode((width,height))
    pygame.display.set_caption("埃及爆破砖_道具的设计")
    
    ball_image = pygame.image.load(ball_image).convert_alpha()
    brick_image = pygame.image.load(brick_image).convert_alpha()
    board_images = [pygame.image.load(image).convert_alpha() for image in board_images]
    level_images = [pygame.image.load(image).convert_alpha() for image in level_images]
    explosion_images = [pygame.image.load(image).convert_alpha() for image in explosion_images]

    prop_images = {}
    prop_images['life'] = ball_image
    prop_images['dead'] = pygame.image.load("resources/skeleton.png").convert_alpha()
    prop_images['speedup'] = pygame.image.load("resources/speedup.png").convert_alpha()
    prop_images['slowdown'] = pygame.image.load("resources/slowdown.png").convert_alpha()
    
    
    
    exit_game = display_cover(cover_image)                  # 按空格键开始游戏
    if exit_game :
        pygame.quit()
    else:
        brick_group = pygame.sprite.Group()     # 砖块组
        explosion_group = pygame.sprite.Group() # 爆炸组
        prop_group = pygame.sprite.Group()      # 道具组
        
        board= Board(board_images,screen)
        ball = Ball(ball_image,screen,board)
        exit_game1 = False
        exit_game2 = False
        clock = pygame.time.Clock()
        level_index = 0
        while level_index < level_amounts:      # 遍历关卡
            exit_game1 = start_level(level_index)
            if exit_game1 != True:                 
                exit_game2 = wait_press_any_key() # 没有在游戏中按关闭按钮,那就等待按任意键开始下一关
                level_index += 1
                if exit_game2:break
            else:
                break
         
        if exit_game1 == False and exit_game2 == False:
            "以下是显示结束时的画面"
            running = True
            while running:
                event = pygame.event.poll() 
                if event.type in ( QUIT,KEYDOWN,MOUSEBUTTONDOWN ):
                      running = False
                      break
                screen.blit(level_images[level_index-1],(0,0))
                pygame.display.update()
                clock.tick(10)
        pygame.quit()
        print("游戏结束!")
            
    

Python创意打砖块游戏埃及爆破砖

下载完整源代码与素材,请

成为会员后,登陆才能继续浏览!联系微信scratch8即可办理会员。
(会员专属:能浏览所有文章,下载所有带链接的Python资源。)

发表在 pygame, python | Python创意打砖块游戏埃及爆破砖已关闭评论

Python循环之中断与继续教程

for循环里还有两个秘密,一个秘密叫break,一个秘密叫continue。它们配合默契,能让我们的编程水平更上一层楼,现在我们就来学习它们的用法吧。

break 语句

开运动会了,同学们跃跃欲试。只听见一声令下,同学们如离弦之箭地跑了出去。突然,山雨欲来风满城,雷公电母齐奏乐,倾盆大雨泻不止,淋得同学一声湿。校长先生立宣布:比赛中断把家还!中断的英文是break,在Python编程中,也有break命令,它能中断什么?看看下面小框框,学习中断莫慌张:

>>> for i in range(10):       #  迭代i拾次
   if  i > 5:break      # 如果i大于5,中断循环
print(i,end=' ')              # 打印i的值,以空格结束

  
0 1 2 3 4 5 
>>>

在上在的代码中,第2句,瞧准了,它的意思很好理解:如果i大于5,则中断。我们看到的结果是上面的for循环只打印了从0到5的数据,其它的数据被break强行“中断”了。

来次小小的总结,break是用来中断循环语句的,一般情况下,它会在一个条件判断语句中,当条件满足后,就会中断循环,循环也就运行结束了。需要注意的是,它只会中断自己所在的这一层for循环。如果有嵌套的for循环,那它可不会越级地中断上一层的for循环。请看下面的代码:

>>> for k in range(5):       # 迭代k伍次
       for i in range(10):   # 迭代i拾次
     if i > 5 :break         # 如果i大于5则中断
     print(i,end=' ')        # 打印i的值,以空格结束
  print()

  
0 1 2 3 4 5 
0 1 2 3 4 5 
0 1 2 3 4 5 
0 1 2 3 4 5 
0 1 2 3 4 5

上面的代码打印了5行0 1 2 3 4 5。这说明break对上一层的for循环一点影响也没有。

continue语句

天空放晴万里无云,学生上学比赛继续进行。前面,由于下了大雨,校运会被中断了,这次由于天气变好了,所以比赛又继续接着进行了。“继续”的英文为continue。在Python中也有continue语句,它是继续下一轮,或继续下一次迭代的意思。它像break语句一样,也是放在循环语句中。下面的代码展示了它的用法:

>>> for i in range(10):          # 迭代i拾次
  if i == 5 :continue      # 如果i等于5,继续下一次迭代
  print(i,end=' ')         # 打印i的值,以空格结束

  
0 1 2 3 4 6 7 8 9 
>>>

上面可怜的5,被忽略了,它并没有被打印出来。这是由于在for循环里的if语句捣的鬼。第2行的意思是说,如果i和5相等,那么继续下一次迭代,所以5就打印不到了。下面我们再看一个例子:

>>> import random                  # 导入随机模块
>>> for i in range(5):             # 迭代i伍次
        x = random.randint(-5,5)   # 生成 从-5到5之间的随机整数
  if x == 0: continue        # 如果x等于0,继续下一次迭代
  print(1/x)                 # 打印1/x的值

  
-0.5
0.2
0.3333333333333333
0.3333333333333333
0.25

在上面的代码,如果没有if语句,由于x的值可能为0,所以程序会出错,但是通过合理地运用continue语句避免了发生1除以0的情况,小兵也有大用途哦。

发表在 杂谈 | Python循环之中断与继续教程已关闭评论

python有参函数教程

有参函数(Parametric Function)

奶牛吃的是草,挤的是奶。工厂输入原料,输出产品。有句谚语叫物华天宝,人杰地灵,物华天宝是自然环境,如果把它看成是输入,那么“人”就是这个自然环境的输出。正所谓一方水土一方人。有种测试叫黑盒测试,测试人员根本不会去了解或理解黑盒里的东西是怎么实现的,只要给它输入条件,如果它能输出正确的结果,就说明功能已经OK了。上回我们提到了函数有返回值,返回值可以看成是函数的输出。函数还会有输入,这些输入是通过参数实现的。我们都用过print语句,它的参数就是逗号隔开的数据。它的返回值其实是None。每个函数都有返回值,我们没有写它具体的返回值的时候,它会默默地返回None,如果要写返回值的话,该如何定义函数呢?以下是语法图:

上面的参数列表是以逗号隔开的变量名称,类型可以是整数,字符串等。最后一句return语句用来返回数据的。return在英文中就是返回的意思。当调用函数的时候,小括号中的值会传递给参数,如下图所示:

下面我们来定义一个有参数的函数:

>>> def add(x,y):      #  定义函数,有两个参数
  z = x + y            # 把参数的值加起来赋值给z
  return z             # 返回z

>>> s = add(32,76)     # 调用函数,返回结果用s进行引用
>>> s
108

当调用add函数的时候,32会被赋值给x,76会被赋值给y。在函数进行一系列运算后它把z变量的值返回以供使用,这就是函数的输出。简而言之,这个add函数的输入是两个数据,输出是它们的和。需要注意的是,在调用函数时实际书写的顺序要和定义时的顺序一致,否则会发生牛头不对马嘴的情况,严重地会导致程序运行出错。请看下面一例:

>>> def do_stuff(first,second,third):
  string = "小明" + first + "后" + second  +"再" + third
  return string

>>> do_stuff("吃饭","刷牙","起床")
'小明吃饭后刷牙再起床'
>>> do_stuff("起床","刷牙","吃饭")
'小明起床后刷牙再吃饭'
>>>

形参与实参(Formal and Actual parameter)

上面我们提到了参数,在定义函数时小括号内的参数是形式上的参数,叫做形参,而在调用的时候用的是实际的具体数据,这叫实际参数,简称实参。形式参数在接收到数据时,它就成了一个局部变量了。以下是一个例子:

>>> def zsum(number):               #  定义函数,有形式参数为number
  s = 0
  for n in range(1,number+1):
    s = s + n
  return s

>>> zsum(10)                  # 调用函数,10 是实际参数
55
>>>

有个小问题,在函数内部能改变形式参数的值吗?这里需要说明的是,通过def是定义函数,并不是真正的执行函数。由于形式参数它已经接受到了实际参数的值,这时候它是一个本地变量了。这个变量的值当然能被改变。请看下列代码示例:

>>> def times(number):
        number = number * number
  return number

>>> times(8)
64
>>> times(16)
256
>>>

其实上面的times直接用return times*times就能达到同样的效果,上面这么写只是为了教学演示。

发表在 杂谈 | python有参函数教程已关闭评论

Python无参函数教程

函数概述(Overview of  Function)

在Python中有一个重要的概念叫函数。我们常常用不求甚解来形容对某些事物不去追究原理或原因。如,人们不会去追究发动机的原理而照样开小汽车,人们只要知道操控它就行了。人们也不知道大米酿造成白酒的化学原理,可是千百年来,照样是出了很多著名的白酒品牌。在Python中有print命令,相信大家都不知道它把字符串打印到IDLE中的具体原理。还有诸如随机模块的randint命令,os模块的那些命令,我们都不知道它们的原理。这些是预定义好的一些命令。命令,它能实现某种功能(function)。当我们要实现某种功能时,可以查找Python手册或其它模块中有没有相应的命令。如果找不到了,那就需要自己制造一个命令来实现这个功能了,这叫定义函数(在英文中它的翻译就是function)。函字通涵,它是蕴涵的意思。函数是组织好的,可重复使用的,用来实现某种功能的代码段。要使用函数,需要先定义它。函数定义好了,我们就能使用它们,这叫调用函数。在海龟画图中,我们接触过很多命令,它们都是事先定义好的函数。 接下来我们来定义函数,并且使用它们。

定义函数(Define Function)

在上面的图示中,def三个字是英文define的前三个字母,它就是定义的意思。在def之后是空格,接着就是函数名称,函数名称后是小括号号,最后面是冒号,需要注意一下的是,无论是小括号还是冒号,都是英文的半角符号,要不然就会出错。

上面的语句一、语句…和语句n就是语句组。给函数实现某种功能就要靠它的语句组了。最简单的语句组可以说是pass了。语句组中同样级别的语句们的缩进数要一致,否则就会出错。 以下是一个定义函数的例子:

>>> def  introduce():                 # 定义一个函数,名字叫introduce
   print("My name is rose")
print("My age is 11")
  
>>> 
>>>  introduce()                     # 调用函数 
My name is rose
My age is 11 

调用函数的方式就是写上函数名称,后面跟上小括号就行了。上面的第7行语句调用了函数,它只是简单地打印了一些字符串。我们可以用type命令查看函数的类型,也可以在调用函数的时候不输入小括号看看是个什么结果。

>>> introduce                                     # 不输入小括号,直接查看函数
<function introduce at 0x0000000002FDBBF8>        # 返回的是函数表述字符串
>>> type(introduce)                               # 查看introduce的类型
<class 'function'>                                # <类 ‘函数’>
>>>

在函数中当然也能使用导入进来的其它命令,接下来的例子命令使用了random中的randint和os模块中的mkdir命令。

>>> import random                    # 导入随机模块
>>> import os                        # 导入os模块
>>> def make_random_dir():           # 定义函数,名称为 make_random_dir
  s = ""
  for n in range(10):         # 迭代10次n
     s = s + str(random.randint(0,9)) # 产生0到9之间的随机数,转换成字符串,连接起来
  os.mkdir(s)                     # 在当前文件夹下建立名字为s的文件夹

  
>>> make_random_dir()              # 调用函数

上面定义了一个有一定使用价值的函数,它的名字叫make_random_dir,寓意为建立随机目录。当我们给函数,变量等取名字的时候,通常要给它们起一个恰当的名字,最好能直接表示函数的功能,当然不能和已有的命令、模块名等重名,更不能乱写。上面稍微难理解的是第6行代码,我们首先看str小括号里的命令。这个命令是:random.randint(0,9)。它会产生从0到9之间的随机整数。它产生后,str会把它转换成字符。最后这个字符和s连接起来了,结果就是s变长了一位。这个函数实现的功能就是,首先会产生一个随机的包括全是数字的字符串,然后在当前工作目录下以这个字符串为名称,建立一个新的目录。

现在,我们定义的函数都是没有参数的,可以称之为无参函数。所谓参数,先理解为在定义函数时候,在它的小括号有变量。既然有无参数的函数,那么可能某些函数就会有参数,暂且称之为有参函数,关于它,我们以后再学习。

发表在 杂谈 | Python无参函数教程已关闭评论

Python文件文件读写教程

书山有路勤为径,学海无边苦作舟。说的是读书方面的事情。在计算机里也有“读”的概念,它指的是把文件的内容加载到内存,方便让我们看到它的内容。下面我们就来看看文件长什么样吧。

文件概论(file Introduction)

打开计算机,双击播放器,欣赏小电影,阅读电子书。这些可能是你习以为常的动作。其实你都进行了打开文件的操作。当双击的时候,就会对应有一个程序来打开电影,电子书或图像。一部电影对应着一个视频文件,一部电子书可能对应着一个文本文件,而一幅图可能对应的就是一张图像文件。有部电影叫《正义联盟》,我们下载了它放在电脑中的某个文件夹。它的名称可能是下面这样,对着它单击右键,显示出它的一些信息,请看以下图示:

上面的文件名有三部分,分别是点号前面的字符,点号,点号后面的字符。点号后面的叫扩展名或后缀名,当然也有人把点号本身也连同进去说它们是后缀名。

Python源文件的后缀名是py。 对着Python的源代码文件单击右键。我们能清楚地看到文件的类型、大小、创建时间、打开方式等等。原来,扩展名也是可以用来标识文件的类型。我们说上面的文件是py文件也是可以的,它实质上是文本文件。文本文件的后缀名可能有很多,如txt,html,asp,php,bat等等。我们可以用Python打开它们,看看文本文件里有些什么东西。

读文本文件(read text file)

打开文本文件用open命令,它会返回一个文件对象,通过文件对象我们就能使用read方法读出它的内容,然后把内容通过一个变量名称进行引用,最后通过print打印,我们就能看到它的内容了。假设有一个文本文件的名字为“唐诗.txt”,以下是打开它的示例:

>>> f = open("唐诗.txt")   # 打开文件
>>> fc = f.read()         # 读取文件内容
>>> f.close()            # 关闭文件
>>> print(fc)            # 打印文件内容

在上面的代码中,open命令根据文件名打开文件,生成了文件对象, 我们用f来引用它。需要注意的时候,如果文件不存在,那么是打不开的,并且会显示文件找不到的错误。文件对象有read命令,通过这个命令就能读取的文件内容。不过,如果不把文件的内容用fc来引用,那么我们无法通过print打印了。当读出了文件内容后,我们一定要关闭文件,用f的close命令就行了。

其实在用open命令打开文件的时候,它还有一个参数。关于参数,我们现在理解为在命令中小括号里面的数据即可,参数可能有个名称,这叫关键词参数。open命令的第一个参数是文件名,第一个参数是模式,英文为mode。它决定了打开文件的时候是否是读还是写,上面我们没有写这个参数,那么open命令就默认为读文件。以下是示例代码:

>>> f = open("唐诗.txt",mode='r')
>>> fc = f.read()
>>> f.close()
>>> print(fc)

上面的open命令的小括号里有两个数据,第一个表示文件名,第二个表示读写模式。mode在英文中就是模式的意思。让mode的值为’r’,表示在用open命令打开它时,只能读取它的内容。我们是无法修改文件的内容的,如果要修改它的内容怎么办,这就要把模式改为’w’。接下来,我们来写一写文件。

写文本文件(write text file)

写文件会改变文件的内容,当我们以写的模式打开文件时,如果文件不存在,那么会自动创建那个文件。下面的代码将会创建一个新的文件:

>>> f = open("唐诗.txt",mode='w')
>>> f.write("这是一首李白写的诗。\n")
>>. f.write("静夜思............。\n")
>>> f.close()

上面的代码会在当前文件夹打开名为”唐诗.txt”的文件,如果它不存在,则会创建它。如果它存在,那么它的内容将会被改写。 如果它里面有非常重要的内容,那么当写完后,运行close命时,那么以前的数据会全部丢失,这将会造成损失。

附,在IDLE中的当前文件夹可以通过导入os模块,运行os.getcwd()获取。

加密解密(Encrypt and Decrypt)

我们可以把一串字符转换成另一种形式,让别人无法明白,而自己通过程序则可以把它恢复为原来的样子, 那么就能读懂了。怎么转换呢?有很多种方法,字母都有一个编号,这个编号叫ASCII码,是美国人制定的,现在已经成为国际标准了。这个编号可以用ord命令求出来。反过来,一个编号也就对应着一个字母,用chr命令可以把这个字母显示出来。以下是代码示例:

>>> ord('a')                     # 求字母a的编号
97
>>> chr(97)                      # 求编号为97对应的字符
'a'
>>> for number in range(48,58):   # 迭代number从48到57
      print(chr(number),end=' ')

  
0 1 2 3 4 5 6 7 8 9
>>> chr(ord('a'))               # 求字母a的编号所对应的字符
'a'
>>> chr(ord('a')+1)             # 求字母a的编号增加1后所对应的字符
'b'
>>>

从上面的例子中,我们看到48编号的字符为”0″,而57编号的字符为”9″ 。ord命令取自英文order的前三个字母,chr命令取自character(字符)的相关字符。

有趣的是第10行,它求出字母a的编号,然后又用chr去求这个编号所对应的字符,得到的结果当然是字母a了。这好像没有什么用处,其实不然。下面就运用这种方法对字符串进行加密。如果把某个字符的编号加上一个数字,再用chr把它转换成字符,好像这个字符就“加密”了一样。以下是把一串字符进行简易加密的代码。

>>> string = 'a rose and a cat'
>>> string2 = ""
>>> for c in string:                      # 迭代字符串
        string2 = string2 + chr(ord(c)+1) # 连接字符串
  
>>> string2
'b!sptf!boe!b!dbu'
>>>

string本来是一朵玫瑰和一只猫,现在它变成了一串我们谁也不认识的字符串了。这就是一个非常简单的加密过程。现在我们再编制一个程序,把它转换回去。

>>> string3 = "" 
>>> for c in string2:            # 迭代string2
       string3 = string3 + chr(ord(c)-1)

  
>>> string3
'a rose and a cat'
>>>

给字符串加密的方法加是把字符的编码加1,所以解密的方法就是反过来就行了,上面的代码又把字符串还原成一朵玫瑰和一只猫了。

发表在 杂谈 | Python文件文件读写教程已关闭评论

python随机取整教程randint

“随机”取整(“random” randint)

天有不测风云,人有祸福旦夕。买彩票的人说不定哪天会中奖,或者天上掉下金砖砸中你也说不定。貌似我们上天自有安排,很多事情我们无法决定,正所谓塞翁失马,焉知祸福。在现在所谓的“大数据”时代,对海量的数据进行统计分析还能对“未来”进行预测。不过,我敢肯定的时,这些数据都是在一定的范围之内的。前面我们学了range命令,它能取一系列范围内的整数,如果要取一系列范围内的随机一个数据,需要如何编写代码?Python本身可是无能为力了,这得搬求兵。这求兵的名字叫random。它就是鼎鼎大名的随机模块。怎么个搬法,用import random就行了。import是导入,输入的意思。救兵搬来了要怎么使用这个大神呢?大神有很多魔法,这之一是randint,下面我们来看看如何使用randint吧。代码如下所示:

>>> import random              # 导入随机模块
>>> random.randint(0,100)       # 随机取一个从0到100之间的整数
16
>>> random.randint(10,20)      # 随机取一个从10到20之间的整数
19
>>>  
>>> random.randint(-10,10)     # 随机取一个从-10到10之间的整数
9
>>>

randint命令是random和integer的组合。我们把它叫随机取整命令。 在上面的代码中,我们通过import random导入了随机模块,然后调用了它的randint命令。它是用来随机从某个范围内取一序列整数的。这个命令有两个参数,第一个参数表示数据的起始值,第二个参数表示数据的结束值。起始值要小于结束值,否则红色的字符给你的颜色会非常好看。

>>> import random
>>> random.randint(100,10)           # 起始数据大于结束数据,无法取得整数
Traceback (most recent call last):
  File "<pyshell#1>", line 1, in <module>
    random.randint(100,10)
  File "C:\Python\Python36\lib\random.py", line 221, in randint
    return self.randrange(a, b+1)
  File "C:\Python\Python36\lib\random.py", line 199, in randrange
    raise ValueError("empty range for randrange() (%d,%d, %d)" % (istart, istop, width))
ValueError: empty range for randrange() (100,11, -89)
>>>

创建列表 (create list)

前面我们犹抱琵琶半遮面地谈过列表。列表这位“仁兄”是现在要正式出场了。我们把它请出来,看看它的“庐山真面目”。怎么个请法,方法有二。第一种方法就是直接输入一对中括号,即[],第二个方法就是用命令list加小括号,这样列表就“光着膀子”诞生了。下面的代码生成了两个列表,一个名为one,一个名为two。只不过它们都是空空如也,就是说两个列表中没有数据。

>>> one = []              # 直接用中括号新建一个空列表
>>> two = list()          # 新list命令新建一个空列表
>>> one
[ ]
>>> type(one)             # 显示one的类型
<class 'list'>
>>>

有句谚语叫:墙上芦苇,头重脚轻根底浅,山间竹笋,嘴尖皮厚腹中空。上面的两个列表光有皮囊一付,留在“世上”貌似无用。佛祖以仁爱为厚德,暂且我们不要删除它们。我们要对它们进行“改造”,给它们添加数据,让它们有用武之地。英语中的append是添加的意思,在Python中用它做为列表的添加命令。用法见下面的代码:

>>> three = list()         # 新建空的列表,名为three
>>> three.append(1)        # 给three添加1
>>> three.append(2)        # 给three添加2
>>>three.append(3)         # 给three添加3
>>> three
[1, 2, 3]

通过append命令,我们给列表添加了三个数据。append的用法是不是非常简单呢?这三个数据在列表中以逗号为分隔,它们从左数到右有一个“编号”,这个“编号”正式的名称叫索引(index),也可以称之为下标。索引是从0开始的。在这个列表中索引为0的数据是1,索引为1的数据是2,索引为2的数据是3。新建列表的时候,我们可以直接在中括号是写入数据,由于在列表中不仅可以存储数字,还能存储字符串,以下列表存储了一些水果的英文名称。

>>> fruit = ['apple','banana','peach','watermelon']
>>> 
>>> fruit.append('pear')
>>> fruit
['apple', 'banana', 'peach', 'watermelon', 'pear']
>>>

如果要引用列表中的数据或者修改列表中的数据要如何书写?首先,需要指定索引号,这样就能知道对哪个数据进行操作了。接着,把索引号放在中括号中就行了,当然还要指明是取哪个列表的数据,下面的代码修改了索引为0的数据,打印了其它的数据。

>>> fruit[0] = 'pineapple'        # 修改索引为0的数据
>>> print(fruit[1])               # 打印索引为1的数据        
banana
>>> print(fruit[2])               # 打印索引为2的数据
peach
>>> print(fruit[3])               # 打印索引为3的数据
watermelon
>>> print(fruit[4])               # 打印索引为4的数据
pear
>>> print(fruit[5])               # 打印索引为5的数据
Traceback (most recent call last):
  File "<pyshell#17>", line 1, in <module>
    print(fruit[5])
IndexError: list index out of range
>>> fruit
['pineapple', 'banana', 'peach', 'watermelon', 'pear']
>>>

在上面的代码中,fruit列表有5个数据,那么它最大的索引号为4。如果试图访问fruit[5]那就会出现索引错误。上面的英文:IndexError: list index out of range就是索引错误,列表的索引超出范围之意思。

来次小小的总结,在Python列表就是以逗号隔开,以中括号括起来的数据集合,这些数据可以是小数,可以是逻辑数据,也可以是字符串,甚至是另一个列表。要访问或修改列表中的数据都要通过索引号来进行。列表的故事说不完,今天暂且到此结束。

发表在 杂谈 | python随机取整教程randint已关闭评论

Python随机取样教程

“随机”取样(“random” sample)

在Python中有很多模块,其中有一个是模块的名称叫random。它在英文中就是随机的意思。导入这个模块用命令import random即可,import 是导入、输入的意思。在这个模块里有一个命令叫sample,它的意思是取样本。所谓取样就是从一些东西里面抽取一些来,然后进行分析。假设超市进货的时候,卡车拉来一大批苹果,经理可能会随机抽取一些苹果来验证质量,这就是取样本的一个过程。接下来,假设有一个列表中存储了苹果的质量,我们来随机取样。

>>> import random
>>> apple = [32,76,88,10,24,256,32,56,80,40,50]
>>> random.sample(apple,3)
[80, 32, 56]
>>>

上面第一行代码中的apple是一个列表,现在我们只要知道它是用中括号括起来的,以逗号隔开的数据集合就行了。apple里有11个数据,代表11个苹果的质量。第2行的代码是随机抽取3个苹果的质量的意思。我们看到了返回的结果也是一个列表。

简而言之,random.sample命令就是随机从一个序列中出取一些数据,当然,抽取的数据的数量不能大于序列的数据数量。下面的代码从26个英文字母中抽取10个字母。

>>> letters = 'abcdefghijklmnopqrstuvwxyz'
>>> random.sample(letters,10)
['a', 'z', 'y', 'e', 'l', 'p', 't', 'v', 'b', 'w']
>>>

关于random模块,先就叙述到这里。上次我们用open命令打开文件,一次性读取了文件的全部内容,接下来我们一行一行的读取。

按行读取文本文件(Read text files by line)

打开文本文件用open命令,它会返回一个文件对象。这个文件对象是可以用for来迭代的。以下是迭代文件对象的示例:

>>> f = open("D:/test.txt")        # 默认为只读方式打开文件
>>> for line in f:                 # 以行迭代文件对象
        print(line)                # 打印line

静夜思

李白	
>>> f.close()

通过上面迭代f,我们看出来了它是以行来迭代的,每次迭代,line就获取一行的内容。在test.txt文件中,只有紧挨着的两行的内容,由于print打印line完成的时候会默认打印一个换行符号,所以上面的静夜思下面多打印了一个换行符号。当文件的内容都输出了后,不要忘了用close命令关闭文件。

发表在 杂谈 | Python随机取样教程已关闭评论

python教程之全局与局部变量

局部变量(Local Variable)

有句谚语叫盲人摸象,盲人们看不到整体的大象,他们摸到什么就说大象像什么。这里将要说的是一个局部的概念。前面讲了函数的定义,在函数内部也是可以定义变量的。不过,如果想在函数外面使用函数里面的变量,那是无法使用的,就像你在老家讲的方言,到了外地,别人无法听懂,所以老家方言无法使用。接下来,我们“以身试法”,看看在函数外面使用函数内部定义的变量会怎么样,以下是代码示例:

>>> def func1():       # 定义函数,名称为func1
  number = 1           # 定义变量,名称为number
  print(number)

  
>>> print(number)
Traceback (most recent call last):
  File "<pyshell#61>", line 1, in <module>
    print(number)
NameError: name 'number' is not defined
>>>

上面的代码“强行”打印曾经在函数内部定义的变量number的值,然而并没有什么用处。Python给你提示了一个叫NameError的错误。在第10行,提示了名字‘number’没有定义。

由于number这个变量,它是在函数内部定义的,它只是局限于在函数内使用,所以它叫局部变量,也叫本地变量。既然有局部变量,那相对而言,是不是有全局变量呢?答案是肯定的,它能贯穿全局,可“厉害”着呢。

全局变量(Global Variable)

当你爬上一座高峰,或许能看到一座小城市的整体面貌。这叫一览众山小,说的是一个全局的概念。相对于在函数内定义的变量,在函数外部定义的变量叫全局变量。如果不需要修改这个全局变量的值,那么可以直接引用这个全局变量的值。以下是一个例子:

>>> number2 = 10                  #  定义全局变量
>>> def func2():                  # 定义函数
  number3 = number2 + 10    # 定义局部变量,同时赋值
  print(number3)

  
>>> number2
10
>>> number3

在上面的func2中有两个变量,一个number3是局部变量,一个number2是函数外部的变量,由于不需要修改它的值,所以可以直接引用它的值。如果我们要在函数内部修改number2的值,则要用global申明一下它是全局变量。global 在英文中就是全局的意思,在Python中用它来申明一个变量为全局变量。以下示例修改了number2的值。

>>> number2 = 10               # 定义全局变量
>>> def double():                # 定义函数
  global number2            # 申明number2为全局变量
  number2 = number2 * 2  

  
>>> double()
>>> number2
20
>>>

在上面的第3行是申明number2为全局变量的语句,如果不申明,将会报错,到底会报什么错误,我们来实践一下:

>>> number3 = 0               # 定义全局变量
>>> def double():               # 定义函数 
  number3 = number3 * 2       # 试图修改变量的值

  
>>> double()
Traceback (most recent call last):
  File "<pyshell#86>", line 1, in <module>
    double()
  File "<pyshell#85>", line 2, in double
    number3 = number3 * 2
UnboundLocalError: local variable 'number3' referenced before assignment
>>>

在上面的代码中,定义函数的时候是不会出错的,但是在调用函数的时候出错了,显示的是未绑定的局部错误(UnboundLocalError)。 我们来假设一下,如果number3是本地变量,使用它时应该先定义,而第3行并没有事先定义number3就直接让它乘以2。如果number3是全局变量,第3行试图修改这个全局变量的值,但并没有申明number3为全局变量。

上面的两种假设说明number3即不是本地变量也不是外地变量,就像你到了外地,即不是外地人,也不是本地人一样,这里就产生了矛盾,所以出错是必然的。其实在第3行代码,Python试图把number3当成本地变量,但在使用它时并未赋值,所以显示了local variable ‘number3’ referenced before assignment这行英文(本地变量在赋值前就被引用)。

还有一种情况,那就是在函数内部定义了和外部同名的变量,那么优先使用函数内部的这个变量。请输入以下代码,体验一下这种情况。

>>> number5 = 10           # 定义全局变量
>>> def test1():           # 定义函数test1
  number5 = 20             # 定义局部变量
  print(number5)

  
>>> test1()
20
>>> number5               # number5的值并没有改变
10

上面第9行试图显示number5的值,结果是10,并不是函数内部那个number5的值。这说明函数内定义的number5的确是局部变量,而外部的number5的值丝毫没有改变。

我们应该尽量减少在函数内部使用全局变量。一般情况下,应该使用返回值让函数和它外层代码建立联系。函数是有返回值的,关于返回值的概念,下次再讲解。

nonlocal变量(nonlocal Variable)

前面说了全局变量和本地变量,还有一种特殊的情况,即在函数中又定义了一个函数这种情况。 如果在内部函数中要修改上层那个函数的值的话,那么申明变量的类型应该为nonlocal。先看看下面的例子:

>>> def zsum(x,y):
  z = x + y
  def func():          # 在函数中又定义了一个函数
    nonlocal z   # 申明z为nonlocal变量
    z = z * 2
  func()               # 调用func函数
  print(z)             # 打印z的值

>>> zsum(3,7)
20

在上面的代码中,func函数是在一个函数中所定义的内部函数。它要修改z的值,但是z并不是全局变量,所以不能申明它为全局变量。Python规定要申明它为nonlocal变量才能修改它的值。nonlocal字面意思是非本地的意思。如果不申明z为nonlocal变量,则运行到z = z * 2时肯定会出错。如果直接让z = 2 ,那么不会出错,这是由于Python把它当成func函数内的局部变量了。

发表在 杂谈 | python教程之全局与局部变量已关闭评论

编程基础之模块与类及函数3D直角坐标系

模块(Module)

有部可爱的动画片叫《万能阿曼》。讲的是热心助人的阿曼,是小镇上的修理高手,带着他爱讲话万能工具们,什么疑难杂症都难不倒他们。你看,下面的小阿曼提着它的工具箱又要出发了。阿曼的工具箱有好几个呢。针对什么电器坏了,他会带上不一样的工具箱。工具箱里面有很多的工具,有电动工具,有手动工具,有各式各样的镙丝刀,有各式各样的钳子,如尖嘴钳、老虎钳、斜口钳。还有各式各样的扳手,用来拧开或拧紧各种大镙丝。想像一下,如果没有这些工具,万能阿曼可就变成万痴阿曼了啊。

万能阿曼工具箱

有句话叫工欲善其事,先必利其器。万能阿曼之所以万能,和他能熟悉地使用各种工具是分不开的。在Python编程中,我们也有很多“工具箱”。如果要下载文件,有一个叫request的工具箱。如果要制作游戏有一个叫pygame的工具箱。如果要画图,有一个叫turtle的工具箱。这些工具箱在Python编程中叫模块。它们是由专业的开发人员开发的。要使用这些模块的话,使用命令“import 模块名”就行了,是不是很简单呢。

类和函数(Class and Function)

前面说了万能阿曼可是有很多不同的工具箱。我们就假设它有电动工具箱,手动工具箱,园艺专用工具箱,电脑维修工具箱吧。这里就是一个分类的概念。在Python编程的较高级阶段,我们要学习“类”这个概念,它和我们现实中分类的概念是一致的。在工具箱里可能会有各式各样的起子,它们也是属于一类。每把起子能拧起和它大小匹配的某种镙丝钉。这些起子是早就生产好了的。万能阿曼只要直接使用即可。在Python编程中,也有很多现成的工具,我们只要直接使用它们就行了。这些现成的工具有一个专业的名称为函数。函数的英文名叫function,直译为功能的意思。要编写程序,离不开熟练地使用各种函数。如果你学过scratch,一种儿童编程语言,那么肯定用scratch的各种积木拼搭过很多小作品。下面的两个命令配合重复执行,就能让角色转圈。

scratch旋转角色

这些命令实现了某种功能,它们其实就是函数,而重复执行10次则是一种控制结构。在课程《我的世界》我们使用的基本都是别人制作好的函数或类,这并没有关系。只要实现了目的就行了。有句话叫拿来主义,前人已经编写了很多优秀的函数和类等,除非特别的必要,我们不必去重复地编写它们。Python之所有高效,这和它有众多的模块及各式各样的函数是分不开的。不过,除了熟练掌握工具或许还不太够,如果我们要进行3D编程,那么掌握3D坐标系那可是必需的。

三维坐标系 (Three-dimensional coordinate system)

要学习三维坐标系,先看下二维坐标系。二维就是有两个维度或两个指标来表示位置的意思。这是怎么样的两个指标呢?下面有一只小黄猫,假设我们是在天上朝下看它,所以看到的是俯视图,还假设单位为米。我们来看下面的图示:

小黄猫扒在一个十字架的中央一动不动的。如果它往前,倒退,左右转弯。它都是在同一个平面上移动。橙色的线条我们称为x轴,蓝色的线条我们称之为z轴。这个时候它在中央,我们称为它在原点。

 

如果小黄猫往右转(90度),前进100,它就到了左边如图所示的位置。这时候我们称它的位置为(100,0),它在z轴右边。

 

如果小黄猫再往左转(90度),再前进100。这时我们称它的位置为(100,100)。它在z轴右边,并且在x轴上边。

 

如果小黄猫再往左拐,前进200,那么它将会到达如左图所示的位置。这个时候它的位置我们记为(-100,100),为什么小括号里的第一个数是负100呢。这是由于它在蓝色线条,也就是z轴的左边。

 

如果小黄猫再往左拐,前进200,那么它将会到达如左图所示的位置。这个时候它的位置我们记为(-100,-100),为什么小括号里的数都是负100呢。这是由于它不仅在蓝色线条左边,也在橙色线条的下边。

 

如果小黄猫再往左拐,前进100,那么它将会到达如左图所示的位置。这个时候它的位置我们记为(0,-100),为什么小括号里的第一数是0呢。这是由于它离蓝色线条的距离是0。如果它再前进50,你能说出它的位置吗?

 

上边我们所记的位置叫做坐标。不过这只是记录了小黄猫在平面上的位置,所以这个坐标是二维坐标。它有两个值,第一个值表示到蓝色线条的最短距离,如果在蓝色线条右边,这个数值就是正数。如果在蓝色线条左边,也就是我们说的z轴,这个值就是负数。

坐标中的第二个数值表示小猫到橙色线条,也就我们说的x轴的最短距离。如果小猫在橙色线条的上面,那第二个数值就是正数。如果它在橙色线条的下面,那么第二个数值就是负数。

当小猫在原点的时候,距离x轴和z轴的距离都是零,所以它的坐标是(0,0)。假设它在原点,方向为左,前进了100,这时候它的坐标就是(-100,0)。如果它再倒退200,这时候它的坐标就变成了(100,0)了。

综上所述,描述位置的两个指标是分别到z轴的最短距离和到x轴的最短距离。现在又来了一只小蓝猫。如下图所示,它距离小黄猫头顶上有100米的距离。 那这只小蓝猫的坐标怎么表示呢?

小黄猫距离地面的距离是0,而蓝猫距离地面的距离是100。这时候我们给坐标增加一个数据用来表示这个距离。那么,小黄猫的坐标就是(0,0,0),而小蓝猫的坐标就是(0,0,100)。最后面的这个100表示是高度,如果它在小黄猫的下面,那么这个值就是负数。我们把这个高度用y来表示,相应的上面的红色线条叫y轴。小括号里面有三个数据了,这就是三维坐标表示法。如果这个时候蓝猫往下降了50米,那么它的坐标是什么呢?如果蓝猫再往前移动100,这时候它的坐标又是多少?

上面的x轴和z轴表示了一个平面,我们把它叫xz平面。在《我的世界》游戏中,史蒂夫就是在这个平面上行走,当然史蒂夫的高度会变化。在游戏中是以z轴正方向为正朝南,x轴正方向为正朝东。当进入游戏后,可以按F3键时,能看到一些信息。如史蒂夫的坐标,它的方向等,如下图所示:

python我的世界编程

发表在 杂谈 | 编程基础之模块与类及函数3D直角坐标系已关闭评论

Python的列表切片(List Slice)教程

  1. 列表切片(List Slice)

    Python中的列表存储的是一系列数据,每个数据都可以通过索引来修改或引用它的值。假设我要取列表中的连续的一片数据,比如索引从1开始到6结束,但不包括索引为6的所有数据,应该怎么操作呢?这可以通过编写代码实现,以下是示例代码:

  2. >>> data =[3,2,7,6,8,10,24,76,8]            # 定义列表 
    >>> start = 1                             #  定义起始索引
    >>> end = 6                             #  定义结束索引
    >>> subdata = [ ]                         # 定义空列表
    >>> for index in range(start,end):           # 从start到end迭代index
      subdata.append(data[index])          # 给列表添加数据
    
               
    >>> subdata
    [2, 7, 6, 8, 10]
    >>>
    

    上面的确是一个不错的方法,但是每次取一序列数据都要编写一段代码吗?答案是否定的。Python早为我们准备好了更简洁的语法来获取列表中的一片数据。这叫做切片,对列表进行切片操作,返回的结果也是列表。显然,我们需要知道起始索引和结束索引,就像上面一样,然后把这两个值放在中括号中以冒号隔开。以下是切片语法示例:

  3. >>> sub = data[start:end]	 # 取data列表中以start开始,end结束,不包括end索引数据的数据       
    >>> sub		       
    [2, 7, 6, 8, 10]
    >>>
    

    我们看到,结果和我们上面编写的程序运行的结果是一模一样的。以下是图示:

  4. 上图起始索引是1,结束索引是6。如果不写start,那么会默认从零开始,如果不写end,那么会把start后面的所有数据都包括。如果两个都不写,相当于拷贝了列表。我们来实践一下:
  5. >>> data =[3,2,7,6,8,10,24,76,8]
    >>> data[:5]                    # 取从索引为0开始到5结束的所有数据(不包括索引为5,下同)
    [3, 2, 7, 6, 8]
    >>> data[5:]                    # 取从索引为5开始的所有数据
    [10, 24, 76, 8]
    >>> data[:]                     # 取从索引为0开始的所有数据
    [3, 2, 7, 6, 8, 10, 24, 76, 8]
    >>>
    

    由于列表中最后一个数据的索引可以写为-1,所以下面的语法也是可以的。

  6. >>> data[5:-1]           # 取从索引为5开始到最后一个数据的所有数据
    [10, 24, 76]
    >>> data[:-4]            # 取从0开始到索引为-4的那一序列数据
    [3, 2, 7, 6, 8]
    >>>
    

    如果要取1,3,5,7索引号的这几个数据应该怎么取呢?这也可以通过编写一个程序来实现,当然Python也为我们准备好了语法,接下来先学习步长。

    步长(Step)

  7. 步长,就是每步的长度之简称。它的英文为step,就是步骤,步子的意思。我们知道,range可以生成一系列整数。它有步长这个参数,如range(1,10,2)中的2就是步长。它能产生1,3,5,7,9这几个数据。 在这里,每步的长度是2,当我们不写第三个参数的时候,步长默认为1。如果要取列表[3,2,7,6,8,10,24,76,8]中的索引号为奇数的所有数据,我们先来编个程序完成这个要求,请看代码:
  8. >>> subdata = []
    >>> data = [3,2,7,6,8,10,24,76,8]
    >>> for index in range(1,8,2):
      subdata.append(data[index])
    
      
    >>> subdata
    [2, 6, 10, 76]
    >>>
    

    当然,Python也为我们准备好了语法,我们只要在切片的时候再加一个参数就行了。这个参数就是步长。上面得出来的结果,我们只要用subdata = data[1:8:2]这句代码就行了。以下是图例:

  9. 上面data[1:8:2]中的2就是步长,像range命令一样,不写它的值它是默认为1的,所以data[1:8:]和data[1:8]的值是一样的。步长一般是正数,它也可以是负数,这时候我们就要倒着取数据,如data[-1:0:-1],表示从最后一个数据开始,倒着取数据,一直取到索引为0的数据,所以返回的列表是:[8, 76, 24, 10, 8, 6, 7, 2]。看下面两种取法,返回的列表是一样的:
  10. >>> data[-1::-1]              # 取从倒数第一个数据开始的所有数据
    [8, 76, 24, 10, 8, 6, 7, 2, 3]
    >>> data[::-1]                # 由于步长为-1,所以也是取从倒数第一个数据开始的所有数据
    [8, 76, 24, 10, 8, 6, 7, 2, 3]
    

    前面说了,如果不写起始索引,那么默认为0,不过那是在步长为正数的情况。如果步长为负数,那么不写起始索引的话,默认是-1。综上所述,列表切片语法图为:

  11. python列表切片
发表在 杂谈 | Python的列表切片(List Slice)教程已关闭评论

python教程之类的继承(Class Inheritance)

  1. 类的继承(Class Inheritance)

  2. 前面我们定义了类,用类生成了对象。对象能接收数据及输出结果。在具体的编程中,主要考虑程序中会有什么对象,如何让对象之间进行数据交互,这是一种叫面向对象编程的方法。要学好这种方法,还要学习另一个非常重要的概念,叫做继承。俗话说,种瓜得瓜,种豆得豆,老鼠儿子会打洞。它们说的都是一种继承的关系。有继承,就会有变异,随着环境的改变,岁月的变迁,老鼠儿孙们可能会不断变异从而形成新的物种。现代计算机语言中,面向对象编程虽然是更加抽象的编程方法,但是我们也没必要想得那么复杂,在海龟画图中我们就不断地和海龟类打交道。由于在Python中类和类之间也会有继承关系,所以通过继承Turtle类,我们可以定义新的类, 让海龟摇身一变成“人”类也是完全有可能的。假设有一个Fruit(水果)类,我们再定义一个Apple类,让它继承自Fruit类,那么Fruit就是它的父类,也称基类或超类,相应的Apple称为Fruit的子类。子类会继承父类的属性和方法,当然也可以定义新的方法,如果子类定义了和父类同名的方法,这叫做重写父类的方法。下面是Fruit类的代码:
  3. >>> class Fruit:                  # 定义名为Fruit的类
         def __init__(self,w,c):      # 初始化方法
             self.weight = w          # 设定初始重量
             self.color = c          # 设定初始颜色
         def addweight(self,w):      
             self.weight += w        # 将重量增加w
         def getweight (self):  
             return self.weight     # 返回self的重量
    

    所有的水果都有重量,有颜色,上面的weight属性代表水果的重量,color属性代表水果的颜色。addweight方法能让水果的重量增加,getweight方法用来返回水果的重量。接下来定义一个叫Apple的类,让它继承自Fruit类。

  4. >>> class Apple(Fruit):                # 定义名为Apple的类,它继承自Fruit
         def __init__(self,w,c,shape):     # 初始化方法
            Fruit.__init__(self,w,c)       # 首先运行父类的初始化方法
            self.shape = shape             # 新增形状属性,并赋值
         def getshape(self):      
           return self.shape               #  返回形状
    

    上面的第1行代码定义了一个名为Apple(苹果)的类,它继承自Fruit类。语法就是在类的名字后面写上小括号,小括号里写上父类的名字即可。在苹果类的初始化方法中,我们调用了父类的初始化方法,注意,这是必需的,一般是写在初始化方法的第一行。父类的初始化方法对重量和颜色进行了赋值,然后就是第4行代码,它对shape(形状)进行了赋值。

    如果对第4行代码:self.shape = shape比较迷惑的话,首先要知道在self的点后面的名字是我们自定义的属性,这个属性的名称叫shape。而在等于号后面的shape是给这个属性赋的值,它是从方法的参数列表中来的。下面是实例化Apple类时的赋值图。

  5. python类的实例化
  6. 第5行代码定义了一个方法,它直接返回对象的形状。由于苹果类继承自水果类,所以它也有addweight方法和getweight方法。注意,实例化苹果类时,它有三个参数。以下是代码:
  7. >>> a = Apple(50,"red","circle")         # 实例化一个苹果
    >>> a.addweight(100)                 # 增重100
    >>> print(a.getweight())                # 打印重量
    >>> print(a.getshape())                # 打印形状
    

    类的继承示例一(Inheritance Example one)

  8.  上面说了类和类之间有继承的关系,我们学了海龟模块,每个海龟都是通过Turtle类来生成的。那么我们定义的类能不能继承自Turtle类呢?这当然是可以的,假设我们有一些海龟对象,我们并不需要它们画画,并且希望它们的形状都是圆形,那么我们应该把它们归为一类,假设叫Ball,以下是Ball的代码。
  9. >>> from turtle import Turtle                          # 从海龟模块导入Turtle类
    >>> class Ball(Turtle):                                # 定义球类,继承自Turtle类
      def __init__(self):
        Turtle.__init__(self,shape='circle')     # 首先调用父类的初始化方法
        self.penup()                        # 由于不需要画画,所以让它抬笔
      def move(self,dx,dy):                       # 定义移动方法
        x = self.xcor() + dx                # 水平坐标增dx
        y = self.ycor() + dy                # 垂直坐标增dy
        self.goto(x,y)                      # 坐标定位
    
        
    >>> ball = Ball()                       #  实例化一个小球
    >>> while True:
      ball.move(1,1)                         # 让小球每次在水平和垂直方向上移动一个单位
    

    由于Ball类是继承自Turtle类,所以它就像Turtle类的亲生儿子一样,继承了海龟所有的方法和属性。在第5 行代码中,由于海龟类的对象默认是落笔的,但我们并不希望它的儿子Ball类画画,所以把它给抬笔了。

    在第6行定义了一个叫move的方法。它的作用是让对象在水平和垂直方向上位移。 第12行代码是生成了一个ball,它不断地调用move方法,每次在水平和垂直方向上都移动1个单位。结果就是运行程序的时候看到一个小球朝右上角移动。通过定义move方法,好像Ball类相对于Turtle类发生了变异一样。

  1. 类的继承示例二(Inheritance Example two)

  2.  上面我们定义了一个Ball类,它有移动的方法,可是球移动一会儿就不见了。接下来我们定义一个弹球类,让它可以“碰到边缘就反弹”。我们让弹球类继承自球类。重新编写它的move方法实现这个功能。代码如下所示:
  3. from turtle import Turtle
    from random import randint
    class Ball(Turtle):    
        def __init__(self):
            Turtle.__init__(self,shape='circle')
            self.penup()
            self.sw = self.screen.window_width()       # 定义sw属性,它的值是屏幕的宽度
            self.sh = self.screen.window_height()       # 定义sh属性,它的值是屏幕的高度        
        def move(self,dx,dy):
            x = self.xcor() + dx
            y = self.ycor() + dy
            self.goto(x,y)	    
    class BounceBall(Ball):                            # 定义BounceBall类,它继承自Ball类  
        def __init__(self):
            Ball.__init__(self)                         # 调用父类的初始化方法
            self.xspeed = randint(-5,5)                 # 设定xspeed属性,代表每次的水平位移 
            self.yspeed = randint(-5,5)                 # 设定yspeed属性,代表每次的垂直位移
        def move(self):        
            x = self.xcor() + self.xspeed                # 对象的x坐标加上水平位移
            y = self.ycor() + self.yspeed                # 对象的y坐标加上垂直位移
            self.goto(x,y)                             # 定位到新的位置
            if x > self.sw//2 or x < -self.sw//2:      # 如果x坐标大于或小于屏幕宽度的一半
                self.xspeed = -self.xspeed              # 水平位移取负
            if y > self.sh//2 or y <  -self.sh//2:      # 如果y坐标大于或小于屏幕高度的一半
                self.yspeed = -self.yspeed              # 垂直位移取负
    ball = BounceBall()
    while True:
        ball.move()       
    

    上面的代码运行的时候,我们能看到一个黑色的小球,它碰到窗口的边框会反弹,这是由于我们在BounceBall类的定义中对move方法进行了重写。我们把小球看成一个点,当小球的坐标大于或等于屏幕宽度的一半的时候,我们让它的xspeed取反,这样它在水平方向上就会朝相反的方向移动了。垂直反弹的原理也是一样的。在这里反弹原理不是重点,重点就是我们可以重新改写父类的方法,并且在有些情况下要先调用父类的同名方法。如果要让一个方法失效,也可以通过改写父类的方法,只要定义同名方法,把它的语句组换成pass就行了。

    通过继承某类,我们不必编写重复的代码,只要把缺少或需要优化的功能重新编写就行了。子类可以重新编写父类的方法,这也叫做方法重载。

发表在 杂谈 | python教程之类的继承(Class Inheritance)已关闭评论

python教程之类的方法method

  1. 类的方法(Class Method)

  2. 在学习类的定义当中,我们学习了__init__,它是初始化函数,并且说了在类中定义的函数也叫方法。在类中还能定义其它的方法。如,哺乳动物有走的行为,我们可以定义相应的走的方法。下面我们定义一个叫Animal的类,它有走的方法。
  3. >>> class Animal:                       # 定义名为Animal的类
      def __init__(self,weight):      # 实始化方法,有参数名为weight
        self.weight = weight    # 给对象的weight属性赋值为weight
      def walk(self):                 # 设定walk方法
        print("走一步")         # walk方法具体执行的代码 
    
        
    >>> pig = Animal(100)                   # 实例化一个Animal
    >>> pig.walk()                          # 调用pig的walk方法
    走一步
    >>>
    

    上面的第4行代码定义了一个名为walk的方法,它有一个参数名为self,这个参数用来表示实例化后的对象。 第9行调用了这个walk方法,就像调用函数一样,只不过在点号前面写上对象的名称。调用时,self参数会收到对象名,然后执行方法的代码。上面定义的walk太简单了,方法就是函数,它能接收很多参数,接下来我们定义有更多参数的方法。

  4. 类的方法示例一(Method Example one)

  5. 下面我们定义一个有些实用价值的类,它的名字叫Point。我们用它来代表平面上的点。它有两个属性,分别表示x和y坐标,以下是示例代码:
  6. >>> class Point:                    # 定义名为Point的类
         def __init__(self,x,y):        # 初始化方法
               self.x = x               # 设定x坐标
               self.y = y               # 设定y坐标
         def move(self,dx,dy):          #  定义move方法
               self.x = self.x + dx     #  x坐标增加dx
               self.y = self.y + dy     #  y坐标增加dy
    
         def distance(self,other):  
            """计算两点的长度"""
            dx = self.x - other.x
            dy = self.y - other.y
            return (dx * dx + dy * dy ) ** 0.5
    
    
    >>> p = Point(20,20)              # 实例化一个点
    >>> p.move(80,80)                 # 把点的x和y坐标各增加80
    >>> print(p.x,p.y)                # 打印点的坐标
    >>> print(p.distance(Point(0,0))  # 打印p点到原点之间的距离
    

    通过move方法把p点的x和y坐标都增加80,就改变了它的坐标。这个点就像左图这样从(20,20)移到了(100,100)的坐标。

    在第9行定义了一个叫distance(距离)的方法,它是用来计算两个点的距离的。具体的计算代码不懂没有关系,重点在于第10行写上了这个方法的说明。它是用三引号括起来的字符串,这叫文档字符串。最后函数返回了两点之间的距离。在实际的编码中,我们还要判断other参数是不是一个Point类的实例,在这里省略了。如果对第19行不太明白,可以看看下面这张图示:

  7. point点实例化距离
  8. Point(0,0)用来实例化一个对象。p点的distance方法用来计算它和另一个对象的距离。这个距离最后用print打印出来。
  9. 类的方法示例二(Method Example two)

    上面我们定义了一个Point类,它有移动的方法,可是我们看不到这个点的移动过程。如果想让这个点真正的移动起来那多好。这是可以实现的,我们学了海龟画图,可以让它来移动。下面Point类中的初始化方法和移动方法都增加了代码,为的就是有这种可视化效果。代码如下所示:

  10. """可移动的点类.py"""
    from turtle import Turtle
    
    class Point:                         # 定义名为Point的类
        def __init__(self,x,y):             # 初始化方法
           self.x = x                    # 设定x坐标
           self.y = y                    # 设定y坐标
           self.t = Turtle(shape='circle')   # 属性t的值是一只海龟
           self.t.color('blue')             # 设定颜色为蓝色
           self.t.penup()                # 抬笔           
               
        def move(self,dx,dy):
           """在水平和垂直方向增加距离"""
           self.x = self.x + dx     #  x坐标增加dx
           self.y = self.y + dy     #  y坐标增加dy
           self.t.goto(self.x,self.y) # 坐标变化后让海龟到达指定位置
    
    p = Point(0,0)
    for i in range(100):
        p.move(1,1)
    

    上面的代码运行的时候,我们能看到一个蓝点慢悠悠地移动。这是由于在初始化函数中给Point类增加了一个属性t,它的值是一个海龟对象。当每次用move方法改变了点的坐标值的时候就用了海龟的goto方法让它到达这个位置。

发表在 杂谈 | python教程之类的方法method已关闭评论

Python之类class教程

  1. 类的概述(Class Introduce)

  2. “小明,去买点水果回来做沙拉吧。”,妈妈对小明说。小明也没有再问,就随便买了些苹果,梨子,桔子之类的水果回来。在这里,水果,就是一个类别。它们有共同的属性,如质量,颜色,价格等。在生活中,很多事物都可以归为一个类别。我们也学过很多数据类型,它们有的是整数,有的是字符串,有的是列表。用type命令就能显示出它们的类别出来。现在让我们复习一下所学过的类别吧。在IDLE里输入type和数据,看看它们是什么类别,下面是示例代码:
  3. >>> x = 5
    >>> type(x)                 # 显示x的类别
    <class 'int'>
    >>> string = "Python"
    >>> type(string)             # 显示string的类别
    <class 'str'>
    >>> f = 32.768
    >>> type(f)                  # 显示f的类别
    <class 'float'>
    >>> type([])                 # 显示[ ]的类别
    <class 'list'>
    >>> type(True)              # 显示True的类别
    <class 'bool'>       
    >>>
    >>> from turtle import Turtle  # 从海龟模块导入Turtle类
    >>> t = Turtle()
    >>> type(t)                 # 显示t的类别
    <class 'turtle.Turtle'>
    

    上面的14行以上的都是Python内置的类型,而第16行则是Python自带的海龟模块里面的一个类型,它叫Turtle类。通过Turtle类,我们可以新建一个海龟对象,所新建的海龟都有共同的属性和命令。那么问题来了,这个Turtle类是怎么“制作”出来的? 当然,它是由一个程序员编写的,以供我们学习编程。要学习编写一个Turtle类超出了我们的学习范围。我们现在学习如何编写一个非常简单的类。

  4. 定义类(Define Class)

  5. 我们学习过定义函数,用的是def 关键词。如果要定义一个类,则用的是class关键词。最简单的类是这样的:class  Test:pass。这就定义了一个类,它的名字是Test,它的内容是pass,也就是没有内容,但它可是真正能使用的类。用Turtle类生成一只小海龟也叫做实例化一只小海龟,这只小海龟就是生成的一个对象。 刚才我们定义了一个叫Test的类,那么也能用它生成一个对象,用Test()这个命令就行了,当然我们一般给它取个名字,也可以把这个名字叫做t,以下是示例代码:
  6. >>> class Test:           #  定义类Test
      pass              #  忽略内容
    
    >>> t = Test()            # 实例化Test
    >>> type(t)               # 查看t的类别
    <class '__main__.Test'>
    >>> 
    

    上面我们用Test类实例化了一个对象,这个对象的名字叫t。用type命令能查看到它的类别。上面的类太简单了,我们可以在类中定义一个叫初始化的函数,当实例化对象的时候,这个函数会马上运行,它会对这个对象进行初始化,这个函数的名字一定要是__init__。下面我们来定义它。

  7. >>> class Test:                  # 定义名叫Test的类
       def __init__(self):          # 定义初始化方法
          print("我诞生了。")
    
          
    >>> t = Test()                    # 实例化Test类
    我诞生了。
    >>>  
    

    上面我们定义了初始化函数。需要说明的是,在类中所定义的函数叫方法,它的第一个参数用来表示实例化后的自己,一般用的名称是self(自己)。当实例化的时候,__init__方法就对自己进行初始化。 当然,既然它是函数,也就会有返回值,不过一般初始化方法不用返回数据。函数可不止一个参数,也可能有几个,接下来,我们新建一个叫Point的类,并且给它的初始化方法加了两个参数。以下是代码示例:

  8. >>> class Point:                            # 定义名叫Point的类
       def __init__(self,x,y):            # 定义初始化方法 
          self.x = x                      # 设定属性x,赋值为x
          self.y = y                      # 设定属性y,赋值为y
         	    
    >>> p = Point(10,10)                        # 实例化一个点,x值是10,y值也是10
    >>> print(p.x)                              # 打印p.x的值              
    10
    >>> print(p.y)                              # 打印p.y的值
    10
    >>> p.z = 20                                # 新增一个属性叫z,并赋值
    >>> print(p.z)
    20
    >>>
    

    point在英文中是点的意思,在这里我们用它来代表一个平面坐标点。所有的坐标点都有共同的属性,如x坐标,y坐标。我们定义的Point类就是用来代表坐标点的,注意它的第一个字母为大写,这是一种约定俗成的写法。 Point类的初始化方法里有三个参数,self代表实例化后的自己,x用来代表x坐标的初始值,y用来代表y坐标的初始值。这是我们的一种设定,这三个参数分别用a,b,c理论上也是没有任何问题的。

    第三句代码是self.x = x,我们用它来表示这个点初始化后的x坐标的值是x。self.y = y设定了这个坐标点的y值。 下面是p点实例化时的赋值图:

  9. point python class
  10. 上面在初始化方法中用点号给对象增加了两个变量,它们叫做属性。如果要修改它们的值的话,直接用点号操作符,让它等于某个值就可以了。我们在类之外也可以直接给对象增加属性,如可以写p.z = 20,这样p点又增加了一个属性了。综上所述,定义类的语法是首先用关键词class,然后加空格,接着写上类的名字,这个名字的第一个字母应该用大写,最后就是冒号。通常情况下,我们会定义__init__方法。以下是类的定义示例图:
  11. python类的定义示意图
  12. 定义类,和定义函数相似之处在于,这都是我们的一种设计。类就相当于对象的蓝图或模版,它就像一座工厂,不过它能实例化很多对象。现在我们编写程序,或许先要考虑一下,在程序中会出现什么对象,然后这些对象会有什么共同的性质或行为,然后思考如何把它们定义成一个类。
  13. 练习

  14. 下列代码在IDLE中是什么操作?有什么问题吗?
  15. >>> class fruit
            pass
    

    说说下列IDLE中每行代码的意思。

  16. >>> class Python:
          def __init__(self,length):
            self.length = length
            print("我的长度是:",self.length)
      
        
    >>> snake = Python(100)
    我的长度是: 100
    >>> snake.length = 200
    >>> snake.weight = 300
    >>>
    
    
    • 阅读下列代码,说出每行代码的意思,它的运行结果是什么,代码有什么问题?
    • >>> import random
      >>> class random:
        def __init__(self,x):
          self.x = x * 2
          
      >>> r = random(10)
      >>> print(r.x)
      >>> random.randint(10,20)
      

       

发表在 杂谈 | Python之类class教程已关闭评论