-
Python是一门高级编程语言,其拥有多种循环方式,如for循环、while循环、do-while循环等。在编写程序时,需要根据不同的场景和效率要求选择合适的循环方式。下面将逐个分析Python所有的循环执行效率和适用场景。1.for 循环for循环通常用于遍历序列(如列表、元组、字符串)或其他可迭代对象,效率较高。for循环的执行时间与序列长度成正比,因此在处理较大的数据集时,for循环的效率较高。例如,遍历一个包含100万个元素的列表,for循环的执行时间仅需几秒钟。for循环的基本语法为:for value in sequence: statement(s)其中,value为序列中的每一个元素,sequence为需要遍历的序列,statement(s)为循环体中需要执行的语句。for循环适用于需要遍历序列或其他可迭代对象的场景,例如:遍历列表、元组、字符串等序列;遍历字典、集合等其他可迭代对象;遍历文件中的每一行数据;遍历网络数据等。2.while 循环while循环适用于需要反复执行某个操作,但不知道具体执行次数的场景。while循环的执行效率与循环次数有关,因此在循环次数较少的情况下,while循环的效率比较高。但是,如果循环次数太多,会导致性能下降。while循环的基本语法为:while condition: statement(s)其中,condition为循环条件,statement(s)为循环体中需要执行的语句。while循环适用于需要反复执行某个操作,但不知道具体执行次数的场景,例如:读取用户输入,直到输入正确为止;模拟游戏等需要不断循环的场景;处理需要反复执行的任务等。需要注意的是,如果循环条件一直为True,会导致无限循环,因此需要在循环体中加入break语句来跳出循环。3.do-while 循环do-while循环是Python中没有原生支持的循环方式,但可以通过while循环和break语句来实现。do-while循环适用于需要至少执行一次循环的场景。do-while循环的执行效率与while循环类似,取决于循环次数。do-while循环的基本语法为:while True: statement(s) if not condition: break其中,True表示循环至少执行一次,statement(s)为循环体中需要执行的语句,condition为循环条件。do-while循环适用于需要至少执行一次循环的场景,例如:读取文件中的数据,并对数据进行处理;处理需要至少执行一次的任务等。需要注意的是,在循环体中需要加入break语句来跳出循环。4.for-else 循环for-else循环在Python中也是比较常用的一种循环方式,它可以在for循环结束后执行一些额外的代码。for-else循环的执行效率与for循环类似,取决于序列的长度。for-else循环的基本语法为:for value in sequence: statement(s) else: statement(s)其中,value为序列中的每一个元素,sequence为需要遍历的序列,statement(s)为循环体中需要执行的语句。for-else循环适用于在for循环结束后需要执行一些额外的代码的场景,例如:遍历完列表后对数据进行汇总、统计等操作;遍历完文件中的数据后关闭文件等。需要注意的是,只有当for循环正常结束时,才会执行else语句中的代码。如果在for循环中使用了break语句跳出循环,则不会执行else语句中的代码。5.while-else 循环while-else循环与for-else循环类似,也是用来在循环结束后执行一些额外的代码的。while-else循环的执行效率与while循环类似,取决于循环次数。while-else循环的基本语法为:while condition: statement(s) else: statement(s)其中,condition为循环条件,statement(s)为循环体中需要执行的语句。while-else循环适用于在while循环结束后需要执行一些额外的代码的场景,例如:处理需要反复执行的任务,直到任务完成;处理需要不断重试的任务,直到任务成功为止。需要注意的是,只有当while循环正常结束时,才会执行else语句中的代码。如果在while循环中使用了break语句跳出循环,则不会执行else语句中的代码。综上所述,不同的循环方式适用于不同的场景和效率要求。在编程时,需要根据具体的需求选择适当的循环方式。如果需要遍历一个序列,应该使用for循环;如果需要反复执行某个操作,但不知道具体执行次数,可以使用while循环;如果需要至少执行一次循环,可以使用do-while循环(通过while循环和break语句实现);如果需要在循环结束后执行一些额外的代码,可以使用for-else循环或while-else循环。
-
1. re.findall()re.findall():函数返回包含所有匹配项的列表。返回string中所有与pattern相匹配的全部字串,返回形式为list / 数组。由函数原型代码可知,findall() 函数存在三个参数:1. pattern:正则表达式中的 ‘模式字符串’ ;2. string:当前需要处理(查找替换)的原始字符串;3. flags:可选参数,表示编译时用的匹配模式(如忽略大小写、多行模式等),数字形式,默认为0# 示例代码 import re text1 = '北京市海淀区不存在的38街区不想工作大厦99号' res = re.findall(r'\d+', text1) print(type(res)) print(res) # output # <class 'list'> # ['38', '99']2. re.sub()re.sub():函数将所有匹配项,替换为选择的文本,并返回结果。由函数原型代码可知,re.sub() 函数存在五个参数:1. pattern:正则表达式中的 ‘模式字符串’ ;2. repl:需要被替换成的字符串,即将匹配到的pattern替换为repl;可以是函数;3. string:当前需要处理(查找替换)的原始字符串; 4. count:可选参数,表示需要替换的最大次数,必须是非负整数;默认值为0,即匹配到的所有子串都进行替换操作;5. flags:可选参数,表示编译时用的匹配模式(如忽略大小写、多行模式等),数字形式,默认为0# 将所有匹配到的‘数字串' 替换为 '520‘ text1 = '北京市海淀区不存在的38街区不想工作大厦99号' res = re.re(r'\d+', 520) print(type(res)) print(res) # output,返回值res结果是str # <class 'str'> # 北京市海淀区不存在的520街区不想工作大厦520号3. set() set():python内置函数的其中一个,创建一个无序不重复元素集。支持计算交集、差集、并并集。# 为list数组l1 去重 l1 = [1, 1, 2, 2, 2, 3, 4] s1 = set(l1) print(type(s1)) print(s1) # output,返回类型是 set # <class 'set'> # {1, 2, 3, 4}
-
前言五一放假了,今天还要继续内卷。我们今天来给大家写一个小游戏,无聊的时候可以玩一玩摸摸鱼。基本框架from tkinter import * import tkinter.messagebox as msg root = Tk() root.title('井字棋') # labels Label(root, text="player1 : X", font="times 15").grid(row=0, column=1) Label(root, text="player2 : O", font="times 15").grid(row=0, column=2) 我们在这段代码中,我们首先导入了 tkinter 模块和 tkinter.messagebox 模块。然后,我们创建了一个名为 root 的 Tk 对象,并设置了它的标题。我们这里命名为井字棋。接着,我们创建了两个 Label 对象,并将它们放置在根窗口中的第一行和第二列。Label 对象的文本分别是 player1 : X 和 player2 : O,它们的字体大小为 15 像素。最后,我们创建了一个名为 msg 的 messagebox 对象,并将其显示在根窗口中。当用户单击消息框中的按钮时,消息框将显示在用户的主窗口中,以便用户可以看到它。在这个例子中,我们只是简单地显示了一个消息框。定义buttonbutton1 = Button(root, width=15, font=('Times 16 bold'), height=7, command=lambda: checker(1)) button1.grid(row=1, column=1) button2 = Button(root, width=15, height=7, font=('Times 16 bold'), command=lambda: checker(2)) button2.grid(row=1, column=2) button3 = Button(root, width=15, height=7, font=('Times 16 bold'), command=lambda: checker(3)) button3.grid(row=1, column=3) button4 = Button(root, width=15, height=7, font=('Times 16 bold'), command=lambda: checker(4)) button4.grid(row=2, column=1) 我们这段代码是Python中的Tkinter模块中的Button组件的代码。Button组件是Tkinter中的一个小部件,用于创建按钮,可以响应用户的单击事件。我们这里定义了9个Button组件,并为每个Button组件设置了一些属性和方法。每个Button组件的代码片段都与之前的Button组件略有不同,因为这段代码是一个完整的Tkinter应用程序,包括了窗口、标签、按钮等小部件。在我们这个示例中,我们使用了Tkinter中的布局管理器Grid,将9个Button组件按照列进行排列,每个按钮的宽度都设置为15个像素。这个宽度是指Button组件在Tkinter窗口中的宽度,可以根据需要进行调整。最后,我们为每个Button组件设置了一个lambda函数,该函数用于执行特定的操作。这个lambda函数是一个匿名函数,可以接受一个参数,该参数表示Button组件的编号。在这个示例中,我们为每个Button组件设置了一个lambda函数,用于调用Checker组件,该组件是一个递归函数,用于检查指定的编号。Checker组件的实现是一个单独的函数,具体的实现细节大家可以参考Tkinter官方文档。总之,这段代码演示了如何使用Tkinter中的Button组件和Grid布局管理器来创建一个简单的应用程序,并实现了一些基本的交互功能。功能实现我们这里代码就展示一部分,剩下的写法都是一样的。if digit == 1 and digit in digits: digits.remove(digit) ##player1 will play if the value of count is even and for odd player2 will play if count % 2 == 0: mark = 'X' panels[digit] = mark elif count % 2 != 0: mark = 'O' panels[digit] = mark button1.config(text=mark) count = count + 1 sign = mark if (win(panels, sign) and sign == 'X'): msg.showinfo("Result", "Player1 wins") root.destroy() elif (win(panels, sign) and sign == 'O'): msg.showinfo("Result", "Player2 wins") root.destroy() 我们这段代码定义了一个计数器和两个标记digit和mark。计数器count表示要在多少次循环中判断并执行相应的操作。如果digit等于1并且digit在digits中,则从digits中删除digit,并且根据count的奇偶性来决定玩家1或2的操作。如果count是偶数,则玩家1将玩游戏,否则玩家2将玩游戏。在每次循环中,如果count除以2的余数是0,则mark等于X,将panel[digit]设置为mark。否则,mark等于O,将panel[digit]设置为mark。然后,将mark设置为按钮组件button1的文本,将count加1,将sign设置为mark,并将根据sign的值来决定游戏的胜者。如果玩家1赢得游戏,则显示“Result”消息,并关闭窗口。如果玩家2赢得游戏,则显示“Result”消息,并关闭窗口。
-
前言需求背景来源于AI算法通信接口编写…采用python flask框架 解决flask不是生产环境问题一、flask框架1.1,简介.Flask是一个使用 Python 编写的轻量级 Web 应用框架。其 WSGI 工具箱采用 Werkzeug ,模板引擎则使用 Jinja2 。Flask使用 BSD 授权。Flask也被称为 “microframework” ,因为它使用简单的核心,用 extension 增加其他功能。Flask没有默认使用的数据库、窗体验证工具。Flask是一个轻量级的可定制框架,使用Python语言编写,较其他同类型框架更为灵活、轻便、安全且容易上手。它可以很好地结合MVC模式进行开发,开发人员分工合作,小型团队在短时间内就可以完成功能丰富的中小型网站或Web服务的实现。另外,Flask还有很强的定制性,用户可以根据自己的需求来添加相应的功能,在保持核心功能简单的同时实现功能的丰富与扩展,其强大的插件库可以让用户实现个性化的网站定制,开发出功能强大的网站。Flask的基本模式为在程序里将一个视图函数分配给一个URL,每当用户访问这个URL时,系统就会执行给该URL分配好的视图函数,获取函数的返回值并将其显示到浏览器上,其工作过程见图。from flask import Flask, request, jsonify import json from gevent import pywsgi # from settings import APP_PORT # 创建一个服务 app = Flask(__name__) # 创建一个接口 指定路由和请求方法 定义处理请求的函数 @app.route(rule='/analysis/alarm_push/', methods=['POST']) def everything(): # 1.获取 JSON 格式的请求体 并解析拿到数据 # if not request.data: # 检测是否有数据 # return 'fail' request_body = request.get_json() print('request_body:', request_body) print('request.data:', request.data) print(request.headers) return request.data if __name__ == '__main__': # 启动服务 指定主机和端口 server = pywsgi.WSGIServer(('127.0.0.1', 8807), app) print('server is running...') server.serve_forever()
-
初步认识对于熟悉matplotlib三维画图的人来说,最常用的应该是plot_surface,但这个函数的绘图逻辑是,将xy平面映射到z轴,所以没法一次性绘制球,只能把球分成两半,上半球和下半球分别绘制。如果想一次性绘制封闭图形,则可通过tri_surface,其绘图逻辑便是将图形拆分成一个个三角面,然后在对这些三角面进行绘制。所以,将一个曲面拆分成三角面,便构成了一个非常现实的问题,德劳内三角剖分便是建立在这个问题背景之下的。scipy.spatial中提供了Delaunay类,下面以二维散点为例,来初步认识一下。 import numpy as np import matplotlib.pyplot as plt from scipy.spatial import Delaunay pts = np.array([[0, 0], [0, 1], [2, 0], [2, 1]]) tri = Delaunay(pts) plt.triplot(pts[:,0], pts[:,1], tri.simplices) plt.plot(pts[:,0], pts[:,1], 'o') plt.show() 构造函数和属性Delaunay的构造函数如下Delaunay(points, furthest_site=False, incremental=False, qhull_options=None)各参数含义为points 输入散点furthest_site 为True时,计算最远点incremental 为True时,允许增量添加点qhull_options 为qhull参数,具体可参考qhull在Delaunay对象中,有下面几个必须知道的常用属性points 即输入的点集simplices 三角面顶点在点集中的序号neighbors 三角面相邻三角面的序号equations 三角面方程实战-画个球想要画个球,第一步是要得到一个球# N为点数 def getBall(N): pts = [] while len(pts) < N: while True: u = np.random.uniform(-1, 1) v = np.random.uniform(-1, 1) r2 = u**2 + v**2 if r2 < 1: break x = 2*u*np.sqrt(1-r2) y = 2*v*np.sqrt(1-r2) z = 1 - 2*r2 pts.append((x,y,z)) return np.vstack(pts)接下来将这些随机点生成三角面,并进行绘图 tri = Delaunay(pts) ax = plt.subplot(projection='3d') for i in tri.simplices: ax.plot_trisurf(pts[i, 0], pts[i, 1], pts[i,2]) plt.show()
-
根据实验要求完成了对应考试,但是考试显示分数只有50分,请核对。
-
前言 Python模拟星空,你值得拥有!uu们一周不见啦,本周博主参考网上大佬们的星空,给大家带来了属于自己的星空,快来看看吧~ Turtle基础 小海龟(Turtle)是Python中画图的一个重要的包(内置包),里面包含丰富的画图工具以及画图的各种功能,当你学会了用Turtle画图后,你可以画任何你想画的图案哦 1.1 Turtle画板 Turtle的画板大小可以用turtle.screensize()函数来设置 turtle.screensize(width,height,bg):设置画板的大小,包含长和宽,width为宽,height为高,bg为画布颜色 1.2 Turtle画笔 Turtle的画笔有几个常用的函数 ①turtle.penup():抬起画笔,此时移动画笔不会在画布上留下痕迹哦 ②turtle.pendown():放下画笔,与turtle.penup相对应,放下画笔后就可以继续画画了(放下画笔后画画会在画布上留下痕迹) ③turtle.pensize():控制画笔的大小(可以根据需求自行定义画笔的大小哦) ④turtle.pencolor():控制画笔的颜色(可以自己在网上查阅所有python可以使用的颜色,python里面可以用的颜色有很多的哦) ⑤turtle.hideturtle():隐藏画笔(隐藏画笔以后画图时画笔就看不到了) 1.3 Turtle画图 在画图的过程中,我们经常要使用一些简单的移动函数 ①turtle.forward(x):将画笔向前移动x个像素(x可以理解为距离) ②turtle.backward(x):将画笔向后退x个像素(x可以理解为距离) ③turtle.left(n):将画笔向左旋转n度 ④turtle.right(n):将画笔向右旋转n度 ⑤turtle.speed():设置画笔画图的速度(1~10递增,0最快) 1.4 Turtle填色 在画好图后,我们经常需要对其进行填色,这里可以用turtle.fillcolor()函数,括号里写入你想填充的颜色即可。 在使用turtle.fillcolor()函数要注意其基本格式 turtle.beginfill() #开始填充 turtle.fillcolor() #输入填充的颜色 turtle.endfill() #结束填充 1.5 Turtle写字 在完成整个画图后,我们可以使用turtle.write()函数进行写字 turtle.write(" ",move,align,font) ① 第一个位置双引号内填入要写的字 ② move(可选):在默认情况下,move为false。如果move为true,则笔将移动到右下角 ③ align(可选):可取值是left即左、center即中、right即右之一,是字符串格式 ④ font(可选):字体三元组(fontname、fontsize、fonttype),fontname即字体名称(字符串格式,如“宋体”),fontsize即字体大小),fonttype即字体类型如:normal(普通)、bold(粗体)、italic(斜体) 模拟星空 简单了解turtle小海龟后,让我们一起来模拟星空吧! 模拟星球 我们将每一个星球看成一个质点,每一个质点用小海龟表示,通过克隆小海龟生成一个个星球 t=tu.Turtle(visible=False,shape='circle') t.pencolor("white") t.fillcolor("white") t.penup() t.goto(ra.randint(width/2,width),ra.randint(-height/2,height/2)) for i in range(99): star=t.clone() s=ra.uniform(0,1)/3 star.shapesize(s,s) star.speed(ra.randint(2,5)) star.setx(ra.randint(width/2,width)) star.sety(ra.randint(-height/2,height/2)) star.showturtle() stars.append(star) 浪漫星空 通过循环来模拟星空 当每个星球从左边消失时,我们将他从新加入右侧,继续循环 while True: for star in stars: star.setx(star.xcor()-star.speed()) if star.xcor()<-width/2: star.hideturtle() star.setx(ra.randint(width/2,width)) star.sety(ra.randint(-height/2,height/2)) star.showturtle()尾声 友友们下期见! ———————————————— 版权声明:本文为CSDN博主「Want595」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/m0_68111267/article/details/129948882
-
继续编写魂斗罗 在上次的博客学习 Python 之 Pygame 开发魂斗罗(十二)中,我们解决了一些问题,这次我们新加入一个敌人,那我们就开始吧 下面是图片的素材 链接:https://pan.baidu.com/s/1X7tESkes_O6nbPxfpHD6hQ?pwd=hdly 提取码:hdly 1. 创建敌人2类 这次新加入一个敌人,首先创建敌人2的类 class Enemy2(pygame.sprite.Sprite): def __init__(self, x, y, direction, currentTime): pygame.sprite.Sprite.__init__(self) self.r = 0.0 self.bulletPosition = 0 self.rightImage = loadImage('../Image/Enemy/Enemy2/right.png') self.rightUpImage = loadImage('../Image/Enemy/Enemy2/rightUp.png') self.rightDownImage = loadImage('../Image/Enemy/Enemy2/rightDown.png') self.leftImage = loadImage('../Image/Enemy/Enemy2/right.png', True) self.leftUpImage = loadImage('../Image/Enemy/Enemy2/rightUp.png', True) self.leftDownImage = loadImage('../Image/Enemy/Enemy2/rightDown.png', True) self.type = 2 if direction == Direction.RIGHT: self.image = self.rightImage else: self.image = self.leftImage self.rect = self.image.get_rect() self.rect.x = x self.rect.y = y self.center = self.rect.x + self.rect.width / 2, self.rect.y + self.rect.height / 2 self.isDestroy = False self.isFiring = False self.life = 1 self.lastTime = currentTime self.n = 0 # 计算时间 self.t = 0 这里设置了一下加载的图片,还有一些必要的属性 下面是这个敌人的图片 这个敌人发射子弹的放心是玩家的中心,所以我们要计算出玩家的中心,也要计算出敌人的中心,这样可以计算出玩家与敌人相距的x方向的距离和y方向的距离 所以我们要有一个计算敌人中心的函数 def getCenter(self): return self.rect.x + self.rect.width / 2, self.rect.y + self.rect.height / 2 有了计算中心的函数,现在就可以写draw()函数了 2. 编写敌人2类的draw()函数 这个敌人一共有6种状态,下面是示意图 这六个姿势就是6个图片 敌人的枪口始终对着我们的中心位置,因为在魂斗罗游戏中,这个敌人发射的子弹是一直跟着玩家的,玩家移动,它就移动枪口的位置,因此就有这6中姿势 下面我们首先计算出敌人和玩家的距离 我们通过图,可以看出x和y分别都是用人物的中心进行计算而得来的 ∠1是玩家与敌人中心连线与水平方向的夹角,这个交的大小决定着敌人的姿势 这张图片中的蓝色线,是45度的线,所以我们把姿势定下来 当玩家在敌人左边时,计算玩家与敌人的夹角,如果大于45度,敌人就是姿势6,如果小于-45度,敌人状态就是姿势5,其他敌人的姿势就是通过这样的方法计算出来的 下面我们写代码 def draw(self, window: pygame.Surface, player: PlayerOne, currentTime): # 获取玩家中心 playerCenter = player.getCenter() # 获取敌人中心 center = self.getCenter() # 计算距离 y = playerCenter[1] - center[1] x = playerCenter[0] - center[0] # 设置存放夹角的变量 r = 0 # 当 x = 0时,此时玩家在敌人的正上方,我们不做任何操作 if x != 0: # 如果玩家在敌人的正上方,计算角度 r = math.atan(y / x) * 180 / math.pi # 设置变量,用来记录敌人的姿势,敌人的姿势就是发射子弹时的样子 self.bulletPosition = 1 # 根据距离的正负关系判断玩家在敌人的左边还是右边 if x >= 0: if -45 < r < 45: self.bulletPosition = 2 self.image = self.rightImage elif r >= 45: self.bulletPosition = 3 self.image = self.rightDownImage elif r <= -45: self.bulletPosition = 1 self.image = self.rightUpImage else: if -45 < r < 45: self.bulletPosition = 5 self.image = self.leftImage elif r <= -45: self.bulletPosition = 4 self.image = self.leftDownImage elif r >= 45: self.bulletPosition = 6 self.image = self.leftUpImage self.r = r window.blit(self.image, self.rect) 代码中我写了注释,这段代码的意思上面也说明明白了,大概就是计算出玩家和敌人的x方向距离和y方向距离,然后计算夹角,根据夹角的度数设置敌人的姿势 现在关键的一步来了,发射子弹的位置有了,下面就是要思考:如何让敌人对着玩家中心发射? 我们来想一下,在高中我们学过 路程 = 时间×速度,现在我们知道了路程,就是敌人和玩家中心的距离差,要计算速度,那么需要知道时间,那么如何计算时间呢?有了时间,我们通过公式 速度 = 路程 / 时间 计算出速度了 我们可以把调用draw()函数的时间间隔记录下来,把这个的平均值设置为时间 于是我们在构造函数中,就有了这两个变量 self.n = 0 # 时间 self.t = 0 1 2 3 n记录总的间隔数,t记录当前间隔的平均值 下面是计算思路:把每次调用该函数的时间间隔记录下来,根据调用的次数,计算出平均调用该函数的时间间隔,这个时间间隔就作为子弹的发射速度 self.n += 1 # 计算速度 total = self.t * self.n total = total + abs(currentTime - self.lastTime) self.lastTime = currentTime self.t = total * 1.0 / (self.n + 1) 1 2 3 4 5 6 首先我们把上次调用该函数的时间记录到lastTime中,这次调用函数时的时间记录在currentTime 中,通过函数参数把currentTime值传进来 total = self.t * self.n 这句代码来计算总的时间间隔,因为最后我们要求两次调用该函数间隔的平均值 其次,我们使用下面的代码,把总的时间间隔和求出来 total = total + abs(currentTime - self.lastTime) 之后 self.lastTime = currentTime 记录当前的时间,准备进行下一次计算 最后,计算间隔的平均值 self.t = total * 1.0 / (self.n + 1) 举一个例子: 第一次计算出调用该函数的时间间隔是7ms,此时n = 1,t = 7,子弹的速度就设置为7 第二次计算出调用该函数的时间间隔是8ms,此时我们要计算8和7的平均值,此时 n = 2, t = (1 * 7 + 8) / 2= 7.5,所以此时的子弹速度为7.5 第二次计算出调用该函数的时间间隔是8ms,此时我们还是要计算平均值,于是有t = (7.5 * 2 + 8)/ 3,这个结果还是记录为子弹的速度 以此类推,每次都会更新这个间隔时间,这个间隔时间就是子弹的速度 所以,我们最后就计算出来了子弹的速度了 把代码写到draw()函数中,就完成了draw()函数 def draw(self, window: pygame.Surface, player: PlayerOne, currentTime): self.n += 1 # 计算时间 total = self.t * self.n total = total + abs(currentTime - self.lastTime) self.lastTime = currentTime self.t = total * 1.0 / (self.n + 1) # 获取玩家中心 playerCenter = player.getCenter() # 获取敌人中心 center = self.getCenter() # 计算距离 y = playerCenter[1] - center[1] x = playerCenter[0] - center[0] # 设置存放夹角的变量 r = 0 # 当 x = 0时,此时玩家在敌人的正上方,我们不做任何操作 if x != 0: # 如果玩家在敌人的正上方,计算角度 r = math.atan(y / x) * 180 / math.pi # 设置变量,用来记录敌人的姿势,敌人的姿势就是发射子弹时的样子 self.bulletPosition = 1 # 根据距离的正负关系判断玩家在敌人的左边还是右边 if x >= 0: if -45 < r < 45: self.bulletPosition = 2 self.image = self.rightImage elif r >= 45: self.bulletPosition = 3 self.image = self.rightDownImage elif r <= -45: self.bulletPosition = 1 self.image = self.rightUpImage else: if -45 < r < 45: self.bulletPosition = 5 self.image = self.leftImage elif r <= -45: self.bulletPosition = 4 self.image = self.leftDownImage elif r >= 45: self.bulletPosition = 6 self.image = self.leftUpImage self.r = r window.blit(self.image, self.rect) 3. 编写敌人越界消失函数 当敌人创建出来后,我们没有消灭,他就会随着玩家向右移动消失在玩家的窗口中,为了方式程序中存在大量的无效的敌人数据,我们要检查程序,让那些离开窗口的敌人自动销毁 编写检查函数 def checkPosition(self, x, y): if abs(self.rect.x - x) > 2000: self.isDestroy = True elif abs(self.rect.y - y) > 600: self.isDestroy = True 当然,敌人1类也有该函数 4. 编写敌人开火函数 由于敌人2发射的子弹要对着玩家的方向发射,这里我们要修改子弹类 把子弹的初始速度变为0 修改构造函数参数 enemyType 是敌人的类型,类型不一样,发射位置不一样 parameter是一些额外的参数,敌人2发射子弹时,这里面就是传入一些必要的信息,用来计算 接下来将原来的逻辑进行修改 大部分代码没有改变,加了一个if-else语句 下面我们来写敌人2的子弹逻辑代码 elif enemyType == 2: self.index = 0 bulletPosition = parameter[0] player = parameter[1] playerCenter = player.getCenter() if player.isDown or player.isSquating: # 下蹲、蹲下、在水中时,让人物中心下移动,下移动代表y坐标的值相加 playerCenter = (playerCenter[0], playerCenter[1] + 8) elif player.isInWater: playerCenter = (playerCenter[0], playerCenter[1] + 15) t = parameter[2] # t *= 15 r = parameter[3] if bulletPosition == 1: self.rect.x += 19 * PLAYER_SCALE self.rect.y += -1 * PLAYER_SCALE self.ySpeed = - abs(self.rect.y - playerCenter[1]) * 1.0 / t self.xSpeed = abs(self.rect.x - playerCenter[0]) * 1.0 / t elif bulletPosition == 2: self.rect.x += 25 * PLAYER_SCALE self.rect.y += 10 * PLAYER_SCALE s = -1 if r > 0: s = 1 self.ySpeed = s * abs(self.rect.y - playerCenter[1]) * 1.0 / t self.xSpeed = abs(self.rect.x - playerCenter[0]) * 1.0 / t elif bulletPosition == 3: self.rect.x += 25 * PLAYER_SCALE self.rect.y += 25 * PLAYER_SCALE self.ySpeed = abs(self.rect.y - playerCenter[1]) * 1.0 / t self.xSpeed = abs(self.rect.x - playerCenter[0]) * 1.0 / t elif bulletPosition == 4: self.rect.x += -1 * PLAYER_SCALE self.rect.y += 25 * PLAYER_SCALE self.ySpeed = abs(self.rect.y - playerCenter[1]) * 1.0 / t self.xSpeed = - abs(self.rect.x - playerCenter[0]) * 1.0 / t elif bulletPosition == 5: self.rect.x += -1 * PLAYER_SCALE self.rect.y += 10 * PLAYER_SCALE s = 1 if r > 0: s = -1 self.ySpeed = s * abs(self.rect.y - playerCenter[1]) * 1.0 / t self.xSpeed = - abs(self.rect.x - playerCenter[0]) * 1.0 / t elif bulletPosition == 6: self.rect.x += -1 * PLAYER_SCALE self.rect.y += -1 * PLAYER_SCALE self.ySpeed = - abs(self.rect.y - playerCenter[1]) * 1.0 / t self.xSpeed = - abs(self.rect.x - playerCenter[0]) * 1.0 / t self.xSpeed /= 5 self.ySpeed /= 5 self.image = self.images[self.index] 完整的子弹类构造函数 def __init__(self, person, enemyType = 0, parameter = None): pygame.sprite.Sprite.__init__(self) self.images = [ loadImage('../Image/Bullet/bullet1.png') ] self.index = 0 # 速度 self.xSpeed = 1 self.ySpeed = 1 self.rect = pygame.Rect(person.rect) # 类型0表示不是敌人 if enemyType == 0: if person.isInWater: self.waterPosition(person) else: self.landPosition(person) # 敌人1 elif enemyType == 1: self.index = 0 if person.direction == Direction.RIGHT: self.rect.x += 27 * PLAYER_SCALE self.rect.y += 7 * PLAYER_SCALE self.ySpeed = 0 self.xSpeed = 7 else: self.rect.x += -1 * PLAYER_SCALE self.rect.y += 7 * PLAYER_SCALE self.ySpeed = 0 self.xSpeed = -7 # 敌人2 elif enemyType == 2: self.index = 0 # 从额外参数中获取敌人的姿势,即子弹的发射位置 bulletPosition = parameter[0] # 获取玩家对象 player = parameter[1] # 获取玩家中心 playerCenter = player.getCenter() # 让人物中心下移 if player.isDown or player.isSquating: # 下蹲、蹲下、在水中时,让人物中心下移动,下移动代表y坐标的值相加 playerCenter = (playerCenter[0], playerCenter[1] + 8) elif player.isInWater: playerCenter = (playerCenter[0], playerCenter[1] + 15) # 获取子弹移动的时间 t = parameter[2] # t *= 15 # 获取敌人与玩家连线与水平方向的夹角 r = parameter[3] # 根据子弹的发射位置(敌人的姿势)计算敌人的发射子弹的位置和子弹的速度 if bulletPosition == 1: self.rect.x += 19 * PLAYER_SCALE self.rect.y += -1 * PLAYER_SCALE # 计算公式,|x0 - x1| / t = v self.ySpeed = - abs(self.rect.y - playerCenter[1]) * 1.0 / t self.xSpeed = abs(self.rect.x - playerCenter[0]) * 1.0 / t elif bulletPosition == 2: self.rect.x += 25 * PLAYER_SCALE self.rect.y += 10 * PLAYER_SCALE # s 表示方向这里可以直接根据r的大小,计算出子弹的速度是减少还是增加 # 减少表示向负方向移动 s = -1 if r > 0: s = 1 self.ySpeed = s * abs(self.rect.y - playerCenter[1]) * 1.0 / t self.xSpeed = abs(self.rect.x - playerCenter[0]) * 1.0 / t elif bulletPosition == 3: self.rect.x += 25 * PLAYER_SCALE self.rect.y += 25 * PLAYER_SCALE self.ySpeed = abs(self.rect.y - playerCenter[1]) * 1.0 / t self.xSpeed = abs(self.rect.x - playerCenter[0]) * 1.0 / t elif bulletPosition == 4: self.rect.x += -1 * PLAYER_SCALE self.rect.y += 25 * PLAYER_SCALE self.ySpeed = abs(self.rect.y - playerCenter[1]) * 1.0 / t self.xSpeed = - abs(self.rect.x - playerCenter[0]) * 1.0 / t elif bulletPosition == 5: self.rect.x += -1 * PLAYER_SCALE self.rect.y += 10 * PLAYER_SCALE s = 1 if r > 0: s = -1 self.ySpeed = s * abs(self.rect.y - playerCenter[1]) * 1.0 / t self.xSpeed = - abs(self.rect.x - playerCenter[0]) * 1.0 / t elif bulletPosition == 6: self.rect.x += -1 * PLAYER_SCALE self.rect.y += -1 * PLAYER_SCALE self.ySpeed = - abs(self.rect.y - playerCenter[1]) * 1.0 / t self.xSpeed = - abs(self.rect.x - playerCenter[0]) * 1.0 / t self.xSpeed /= 5 self.ySpeed /= 5 self.image = self.images[self.index] # 销毁开关 self.isDestroy = False 之后我们来写玩家2类的开火函数了 def fire(self, enemyBulletList, player): i = random.randint(0, 30) if i == 5: self.isFiring = True enemyBulletList.append(Bullet(self, 2, (self.bulletPosition, player, self.t, self.r))) 设置开火的频率,开火就创建一个子弹对象,把相应的额外参数传入 好,至此就完成了敌人2类 5. 把敌人2加入地图进行测试 来到主类,编写全局函数,用来创建敌人2 def generateEnemy2(x, y): enemy = Enemy2(x, y, MainGame.player1, pygame.time.get_ticks()) MainGame.enemyList.append(enemy) MainGame.allSprites.add(enemy) MainGame.enemyGroup.add(enemy) 之后在generateEnemy()函数中调用 这个代码就是在指定的位置上创建一个敌人2 if -2005 < self.backRect.x < -2000: if self.enemyBoolList[2]: self.enemyBoolList[2] = False generateEnemy2(MainGame.player1.rect.x + 540, 465) 接下来运行一下游戏,看看效果 出现了报错信息,应该是子弹类的构造函数进行了修改,所有创建子弹的函数都要修改,我们下面一一进行修改 首先进入enemyUpdate()函数,由于我们加入了敌人2,所以调用draw()函数的时候要进行判断了,因为敌人1和敌人2的draw()函数参数不一样 将代码进行修改 def enemyUpdate(enemyList, enemyBulletList): # 遍历整个敌人列表 for enemy in enemyList: if enemy.type == 1: if enemy.isDestroy: enemyList.remove(enemy) MainGame.allSprites.remove(enemy) MainGame.enemyGroup.remove(enemy) else: enemy.checkPosition(MainGame.player1.rect.x, MainGame.player1.rect.y) enemy.draw(pygame.time.get_ticks()) enemy.move(pygame.time.get_ticks()) enemy.fire(enemyBulletList) elif enemy.type == 2: if enemy.isDestroy: enemyList.remove(enemy) MainGame.allSprites.remove(enemy) MainGame.enemyGroup.remove(enemy) else: enemy.checkPosition(MainGame.player1.rect.x, MainGame.player1.rect.y) enemy.draw(MainGame.window, MainGame.player1, pygame.time.get_ticks()) enemy.fire(enemyBulletList, MainGame.player1) 变化的地方就是敌人2的draw()函数和fire()函数多了一个参数 之后给敌人1类加入成员变量type self.type = 1 1 我们再运行游戏,看看问题 可以看到敌人发射子弹的方向一直向着玩家 但是还有个问题,就是玩家屏幕向右移动的时候,子弹会停下来 这应该是窗口移动时,没让子弹也一起移动 我们修改一下mapObjectMove()函数,加入下面的代码 理论上,爆炸也应该加入进去,我们没有加入,我们把爆炸也一同加入 def mapObjectMove(self): for sprite in MainGame.allSprites: sprite.rect.x -= self.cameraAdaption for collider in MainGame.playerColliderGroup: collider.rect.x -= self.cameraAdaption for collider in MainGame.colliderStack: collider.rect.x -= self.cameraAdaption for collider in MainGame.enemyColliderGroup: collider.rect.x -= self.cameraAdaption for bullet in MainGame.enemyBulletList: bullet.rect.x -= self.cameraAdaption for explode in MainGame.explodeList: explode.rect.x -= self.cameraAdaption 好,接下来我们再运行一下游戏,看看效果 可以看到,子弹也会随着窗口移动而移动啦 我们现在就完了敌人2了,下面就是加入其他敌人和BOSS了 完整的主类代码 ———————————————— 版权声明:本文为CSDN博主「_DiMinisH」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/qq_37354060/article/details/129756649
-
1. 首先登陆谷歌云盘,上传自己的项目 左上角+号,可以上传整个文件夹、单个文件,选择自己的项目代码,上传到自定义目录 2. 新建Colab 还是左上角的new,找到Google Colaboratory,会新建一个Colab笔记,如下,可自行修改名字 目前就和jupyter notebook差不多的使用方法,可以新建代码段,并运行 3. 配置GPU 按如下,修改->笔记本设置(我的是中文的) 选择GPU ,保存,等待分配GPU 4. 挂载谷歌云盘 输入命令 from google.colab import drive drive.mount('/content/drive/') 会提示登录谷歌账号,登录即可 5. 切换到自己的项目目录下 import os os.chdir('/content/drive/My Drive/项目目录/') 6. 运行python文件 .py后可根据需要加参数 %run demo.py ———————————————— 版权声明:本文为CSDN博主「biu piu biu piu」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/MISS_XDY/article/details/127729000
-
环境准备 Python3.5以上 Appium Server服务器 Android SDK,需要用到adb服务 需要依赖Appium-Python-Client组件库 真机或者模拟器,推荐模拟器(真机一般安卓8版本以上了,appium对安卓8以上版本元素获取的兼容性不太好) JDK8环境 实现 确保adb服务和appium服务及真机/模拟器正常打开,然后在真机/模拟器上将抖音打开。 确定需要的参数 参数基本上都是固定的,只需要确定抖音的包名和活动页即可。 adb shell dumpsys window | findstr mCurrentFocus获取到抖音的包名数据,最后代码里的参数: desired_caps = { "platformName": "Android", # 平台是安卓的 "deviceName": "127.0.0.1:62001", # 通过 adb devices命令获取 "appPackage": "com.ss.android.ugc.aweme", # 抖音包名 "appActivity": ".splash.SplashActivity", # 活动页 "platformVersion":"7.1" # 7.1.2 } 参数整完记得项目跑起来测试一下。 控制模拟器进入抖音后 我们需要去获取页面上的元素或坐标,来实现滑动视频等其他操作。 到我们的Android SDK的tools目录下使用uiautomatoviewer.bat取页面快照。 操作的过程其实相对简单,就是实现页面滑动即可;可能会遇到弹框、点击授权之类的,处理一下即可。然后还需要注意的就是元素的加载时间问题,尽量考虑好网络、设备等其他因素,将等待时间放长些。 # @creator by wlh # @date 2023/3/15 19:43 import time from appium import webdriver from appium.webdriver.common.touch_action import TouchAction from selenium.webdriver.common.by import By from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support import expected_conditions as ec desired_caps = { "platformName": "Android", "deviceName": "127.0.0.1:62001", # 通过 adb devices命令获取 "appPackage": "com.ss.android.ugc.aweme", "appActivity": ".splash.SplashActivity", "platformVersion": "7.1" # 7.1.2 } driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", desired_capabilities=desired_caps) driver.implicitly_wait(20) # 等待弹框元素 driver.find_element(By.XPATH, "//*[@text='同意']").click() driver.implicitly_wait(20) # 等待弹框元素 driver.find_element(By.XPATH, "//*[@text='允许']").click() time.sleep(1.5) size = driver.get_window_size() width, height = size['width'], size['height'] # 获取屏幕宽高 action = TouchAction(driver) for i in range(5): # 实现滑动 action.press(x=width / 2, y=height / 3 * 2).wait(500).move_to(x=width / 2, y=height / 3).release() action.perform() try: # 3s后 弹框元素不出现,直接跳过继续执行 WebDriverWait(driver, 3).until(ec.presence_of_element_located((By.XPATH, "//*[@text='允许']"))) driver.find_element(By.XPATH, "//*[@text='允许']").click() except: pass time.sleep(5) driver.close_app() driver.quit() ———————————————— 版权声明:本文为CSDN博主「鸢尾の」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/weixin_45248492/article/details/129584410
-
环境使用: Python 3.8 Pycharm mou歌浏览器 mou歌驱动 —> 驱动版本要和浏览器版本最相近 <大版本一样, 小版本最相近> 模块使用: requests >>> pip install requests selenium >>> pip install selenium==3.141.0 <需要浏览器和浏览器驱动> 默认安装 4.0版本 语法上面有点区别 re json 卸载模块: pip uninstall selenium 卸载模块 安装python第三方模块: win + R 输入 cmd 点击确定, 输入安装命令 pip install 模块名 (pip install requests) 回车 在pycharm中点击Terminal(终端) 输入安装命令 基本思路流程: <通用> 一. 数据来源分析: 明确需求: 采集什么数据内容 I. 视频播放链接 II. 视频标题 通过浏览器自带工具: 开发者工具, 进行抓包分析 打开开发者工具: F12 / 鼠标右键点击检查选择network 刷新网页: 让本网页数据内容重新加载一遍 分析/找到 视频播放链接在哪里 选择 media <媒体文件> 可以直接看到 视频播放链接 通过搜索分析可以直接找到 视频播放链接/ 视频标题 二. 代码实现步骤: 发送请求, 模拟浏览器对于url地址发送请求 获取数据, 获取服务器返回响应数据 开发者工具: response <网页源代码> 解析数据, 提取我们想要的数据内容 视频标题 视频播放链接 保存数据, 把视频内容保存本地文件夹 代码展示 导入模块 导入数据请求模块 import requests import re import json from pprint import pprint from selenium import webdriver import time 创建浏览器对象, 实例化对象 自动打开浏览器 driver = webdriver.Chrome() 1 访问网址【需要网址的私我吧这不给放】 执行页面滚动的操作 def drop_down(): for x in range(1, 40, 4): time.sleep(1) j = x / 9 js = 'document.documentElement.scrollTop = document.documentElement.scrollHeight * %f' % j driver.execute_script(js) 可以直接定位元素提取内容 lis = driver.find_elements_by_css_selector('.Eie04v01') for li in lis: url = li.find_element_by_css_selector('a').get_attribute('href') 1 2 3 1. 发送请求, 模拟浏览器对于url地址发送请求 <Response [200]> 响应对象, 表示请求成功 仅表示请求成功, 但是不代表一定得到数据<你想要的数据> 没有得到我们想要的数据内容: 原因: 是因为代码被服务器识别出来了, 是pachong程序 解决:把代码伪装成浏览器去发送请求 —> headers 请求头 print(url) time.sleep(1) 确定请求链接 <视频播放页面> 模拟伪装 headers = { 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36' } 发送请求 response = requests.get(url=url, headers=headers) 获取数据, 获取服务器返回响应数据 开发者工具: response <网页源代码> 解析数据, 提取我们想要的数据内容 视频标题 视频播放链接 正则表达式, 你要获取什么数据, 直接复制过来, 然后要的数据内容用 (.*?) 表示, 会直接给返回相应的内容 .*? 表示可以匹配任意字符串, 除了\n换行符以外 提取标题 title = re.findall('<title data-react-helmet="true">(.*?)</title>', response.text, re.S)[0] 1 替换一下特殊字符 title = re.sub(r'[\/:*?"<>|\n]', '', title) 1 提取视频信息 video_info = re.findall('<script id="RENDER_DATA" type="application/json">(.*?)</script', response.text)[0] 数据进行解码 html_data = requests.utils.unquote(video_info) 转换数据类型 json_data = json.loads(html_data) 键值对取值, 根据冒号左边的内容[键], 提取冒号右边的内容[值] video_url = 'https:' + json_data['41']['aweme']['detail']['video']['bitRateList'][0]['playAddr'][0]['src'] print(title) print(video_url) 4. 保存数据 video_content = requests.get(url=video_url, headers=headers).content with open('video\\' + title + '.mp4', mode='wb') as f: f.write(video_content) 1 2 3 我是爱学python的蚂蚁,咱下篇文章再见啦(✿◡‿◡) 有更多建议或问题可以评论区或私信我哦!一起加油努力叭(ง •_•)ง 喜欢就关注一下博主,或点赞收藏评论一下我的文章叭!!! ———————————————— 版权声明:本文为CSDN博主「蚂蚁爱Python」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/xff123456_/article/details/129287579
-
Jetson NX 配置pytorch备注:参考博客最后安装的pytorch无法使用cuda-----目前没找到原因,不知如何解决。但是官方的教程没问题!环境情况: 系统JetPack 5.0.2 --ubuntu20.04 配置流程 安装miniconda(流程省略)conda create -n pytorch python=3.8 安装pytorchsudo apt-get -y update;sudo apt-get -y install autoconf bc build-essential g++-8 gcc-8 clang-8 lld-8 gettext-base gfortran-8 iputils-ping libbz2-dev libc++-dev libcgal-dev libffi-dev libfreetype6-dev libhdf5-dev libjpeg-dev liblzma-dev libncurses5-dev libncursesw5-dev libpng-dev libreadline-dev libssl-dev libsqlite3-dev libxml2-dev libxslt-dev locales moreutils openssl python-openssl rsync scons python3-pip libopenblas-dev;sudo apt-get install python3-pip libopenblas-base libopenmpi-devconda activate pytorchpip3 install Cython添加环境变量export PATH=/usr/local/cuda/bin:$PATHexport LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATHexport CUDA_ROOT=/usr/local/cudaexport TORCH_INSTALL=https://developer.download.nvidia.cn/compute/redist/jp/v51/pytorch/torch-1.14.0a0+44dac51c.nv23.02-cp38-cp38-linux_aarch64.whlpython3 -m pip install --upgrade pip; python3 -m pip install aiohttp numpy=='1.19.4' scipy=='1.5.3'; python3 -m pip install --upgrade protobuf; python3 -m pip install --no-cache $TORCH_INSTALLtorchvision pip install torchvision测试结果>>> import torch >>> print(torch.__version__) >>> print('CUDA available: ' + str(torch.cuda.is_available())) >>> print('cuDNN version: ' + str(torch.backends.cudnn.version())) >>> a = torch.cuda.FloatTensor(2).zero_() >>> print('Tensor a = ' + str(a)) >>> b = torch.randn(2).cuda() >>> print('Tensor b = ' + str(b)) >>> c = a + b >>> print('Tensor c = ' + str(c)) >>> import torchvision >>> print(torchvision.__version__)配合repvgg的部署 pip install opencv-contrib-pythonpip install matplotlibpip install torchvision 其他问题报错:ImportError: cannot import name ‘PILLOW_VERSION’ from ‘PIL’ (/home/jiajie/anaconda3/envs/py35/lib/python3.7/site-packages/PIL/init.py)解决:pip index versions pillow or conda search pillowpip3 install pillow==6.2.0警告:UserWarning: Failed to load image Python extension:warn(f"Failed to load image Python extension: {e}")解决:没解决,据说是pytorch版本太高,或者是pytorch与torchvision版本不契合pytorch版本与jetpack的选择安装pytorch 中第7步,不同版本的jetpack需要根据情况修改版本,
-
Swin Transformer是一种用于图像处理的深度学习模型,它可以用于各种计算机视觉任务,如图像分类、目标检测和语义分割等。它的主要特点是采用了分层的窗口机制,可以处理比较大的图像,同时也减少了模型参数的数量,提高了计算效率。Swin Transformer在图像处理领域取得了很好的表现,成为了最先进的模型之一。Swin Transformer通过从小尺寸的图像块(用灰色轮廓线框出)开始,并逐渐合并相邻块,构建了一个分层的表示形式,在更深层的Transformer中实现。Swin Transformer 模块Swin Transformer模块是基于Transformer块中标准的多头自注意力模块(MSA)进行替换构建的,用的是一种基于滑动窗口的模块(在后面细说),而其他层保持不变。如上图所示,Swin Transformer模块由基于滑动窗口的多头注意力模块组成,后跟一个2层MLP,在中间使用GELU非线性激活函数。在每个MSA模块和每个MLP之前都应用了LayerNorm(LN)层,并在每个模块之后应用了残差连接。滑动窗口机制Cyclic ShiftCyclic Shift是Swin Transformer中一种有效的处理局部特征的方法。在Swin Transformer中,为了处理高分辨率的输入特征图,需要将输入特征图分割成小块(一个patch可能有多个像素)进行处理。然而,这样会导致局部特征在不同块之间被分割开来,影响了局部特征的提取。Cyclic Shift将输入特征图沿着宽度和高度方向分别平移一个固定的距离,使得每个块的局部特征可以与相邻块的局部特征进行交互,从而增强了局部特征的表达能力。另外,Cyclic Shift还可以通过多次平移来增加块之间的交互,进一步提升了模型的性能。需要注意的是,Cyclic Shift只在训练过程中使用,因为它会改变输入特征图的分布。在测试过程中,输入特征图的大小和分布与训练时相同,因此不需要使用Cyclic Shift操作。Efficient batch computation for shifted configurationCyclic Shift会将输入特征图沿着宽度和高度方向进行平移操作,以便让不同块之间的局部特征进行交互。这样的操作会导致每个块的特征值的位置发生改变,从而需要在每个块上重新计算注意力机制。为了加速计算过程,Swin Transformer中引入了"Efficient batch computation for shifted configuration"这一技巧。该技巧首先将每个块的特征值复制多次,分别放置在Cyclic Shift平移后的不同位置上,使得每个块都可以在平移后的不同的位置上参与到注意力机制的计算中。然后,将这些位置不同的块的特征值进行合并拼接,计算注意力。需要注意的是,这种技巧只在训练时使用,因为它会增加计算量,而在测试时,可以将每个块的特征值计算一次,然后在不同位置上进行拼接,以得到最终的输出。Relative position bias在传统的Transformer模型中,为了考虑单词之间的位置关系,通常采用绝对位置编码(Absolute Positional Encoding)的方式。这种方法是在每个单词的embedding中添加位置编码向量,以表示该单词在序列中的绝对位置。但是,当序列长度很长时,绝对位置编码会面临两个问题:编码向量的大小会随着序列长度的增加而增加,导致模型参数量增大,训练难度加大;当序列长度超过一定限制时,模型的性能会下降。为了解决这些问题,Swin Transformer采用了Relative Positional Encoding,它通过编码单词之间的相对位置信息来代替绝对位置编码。相对位置编码是由每个单词对其它单词的相对位置关系计算得出的。在计算相对位置时,Swin Transformer引入了Relative Position Bias,即相对位置偏置,它是一个可学习的参数矩阵,用于调整不同位置之间的相对位置关系。这样做可以有效地减少相对位置编码的参数量,同时提高模型的性能和效率。相对位置编码可以通过以下公式计算:最终,相对位置编码和相对位置偏置的结果会被加到点积注意力机制中,用于计算不同位置之间的相关性,从而实现序列的建模。代码实现:下面是一个用PyTorch实现Swin B模型的示例代码,其中包含了相对位置编码和相对位置偏置的实现:
-
使用背景逛社区发现许多人在解决删除文件夹中非图片文件,删除文件夹中图片等问题的时候,都写了很多代码取实现这一功能,我当时就纳闷了,能几行代码解决的事,为什么要写那么多的代码?解决下述问题解决的问题是:删除文件夹中具有相同后缀类型文件。如删除文件夹下所有的JPG文件或者PNG文件核心函数str.endswith(suffix[, start[, end]])函数用法: endswith() 方法用于判断字符串是否以指定后缀结尾,如果以指定后缀结尾返回True,否则返回False。可选参数"start"与"end"为检索字符串的开始与结束位置。suffix – 该参数可以是一个字符串或者是一个元素。start – 字符串中的开始位置。end – 字符中结束位置。注:返回值为bool类型实战演练现在文件夹中有TXT文件(后缀为.txt),CSV文件(后缀为.csv)和PNG文件(后缀为.png),需要删除PNG文件,只保留TXT和CSV文件。代码如下所示:import os file=os.listdir(r'C:\Users\ZFG\Desktop\test') for i in file: if i.endswith('.png'): os.remove(r'C:\Users\ZFG\Desktop\test/'+i)#i保存的只是文件夹中的一个相对路径,绝对路径还需要加上文件夹的路径+‘/' 附:以下代码是删除指定目录下的jpg图片 # 删除文件夹下面的图片 #先导入所需的包 import os #指定路径 path = '/content/drive/My Drive' filenames = os.listdir(path) for filename in filenames: print(filename) #判断是否是文件而非文件夹 if(os.path.isfile(filename)): # print('it is a file') #判断文件后缀名是否是‘.jpg' if(os.path.splitext(filename)[1] == '.jpg'): #执行删除 os.remove(filename)
上滑加载中
推荐直播
-
华为云码道Agent集成与鸿蒙实战2026/08/11 周二 19:00-21:00
王一男-华为云码道产品规划专家;李炎-华为云码道产品专家;彭江敏-华为云鸿蒙端云一体化开发专家
本次直播带你解读华为云码道7月份产品新特性、新功能。更有专家演示码道Agent Space × 钉钉机器集成实战,从0到1打通消息通道;码道鸿蒙端云一体化实战,快速搭建员工签到系统。
回顾中 -
华为云开发者AI素养直播课·第五期2026/09/04 周五 16:00-18:00
林华鼎-华为云AI开发者运营负责人;蒋春阳-华为云AI开发者案例开发专家
本期直播内容: AI工具体验营 · 第5-8课连讲。Agent-Team 多智能体协作完成毕业设计实践
回顾中 -
华为云开发者AI素养ClassRoom·第六期2026/09/08 周二 19:00-20:00
樊渊-2026华为软件挑战赛冠军
高手来了:看软挑高手解析二维排样问题—从工业难题到算法突破
回顾中
热门标签