基于51单片机的简易密码锁

基于51单片机的简易密码锁

基于51单片机的密码锁
前言
一、密码锁所含有的功能
二、所实现功能模块的代码
1.储存功能
2.读取外部温度功能
3.用LCD1602实现的显示功能
4.主程序
三、总结
前言
在翻之前的项目中,找到了一个学习完51单片机时候的拿来练手的一个小项目,因为时间隔着有点长,自己尽力回忆记录下来,这个小项目是用51开发板来进行的,主要用到的材料包含51开发板,LCD1602液晶显示屏,继电器,淘宝上买的一个5v驱动锁,注意我定义的引脚与大家的是否相同。

一、密码锁所含有的功能
1、可以通过矩阵按键进行输入和修改密码并储存所修改的密码
2、可以通过LCD1602液晶显示屏对输入密码提示
3、可以在LCD1602液晶显示屏上显示此时的温度
4、通过继电器进行解锁和上锁

二、所实现功能模块的代码
1.储存功能
使用I2C总线进行存储

#include<I2C.h>
/*
typedef unsigned int u16;
typedef unsigned char u8;
*/
void delay10us() //误差 0us
{
unsigned char a,b;
for(b=1;b>0;b–)
for(a=2;a>0;a–);
}

void IICstart()
{

SCL=1;
SDA=1;
delay10us();
SDA=0;
SCL=1;
delay10us();
SCL=0;
delay10us();

/* SDA=1;
delay10us();
SCL=1;
delay10us();//建立时间是SDA保持时间>4.7us
SDA=0;
delay10us();//保持时间是>4us
SCL=0;
delay10us();
*/
}
void IICstop()
{

SDA=0;
SCL=1;
delay10us();
SDA=1;
SCL=1;
delay10us();

/*
SDA=0;
delay10us();
SCL=1;
delay10us();//建立时间大于4.7us
SDA=1;
delay10us();
*/
}
uchar IICsend(uchar dat)
{
uint m=0,n=0;
for(n=0;n<8;n++)
{
SDA=dat>>7;
dat=dat<<1;
delay10us();
SCL=1;
delay10us();
SCL=0;
delay10us();
}
SDA=1;
delay10us();
SCL=1;
delay10us();
while(SDA)
{
m++;
if(m>200)
{
SCL=0;
// SDA=0;
delay10us();
return 1;
}
}
SCL=0;
delay10us();
return 0;
}
uchar IICreceive()
{
uint a=0,dat=0;
SDA=1;
delay10us();
for(a=0;a<8;a++)
{
// SCL=1;
delay10us();
dat<<=1;
dat|=SDA;
SCL=1;
delay10us();
SCL=0;
delay10us();
}
return dat;
}
void AT24C02send(uchar arr,uchar dat)
{
IICstart();
IICsend(0xa0);
IICsend(arr);
IICsend(dat);
IICstop();
}
uchar AT24C02receive(uchar arr)
{
uchar num;
IICstart();
IICsend(0xa0);
IICsend(arr);
IICstart();
IICsend(0xa1);
num=IICreceive();
IICstop();
return num;
}

2.读取外部温度功能
使用的是DS18B20,DS18B20是常用的数字温度传感器,其输出的是数字信号,具有体积小,硬件开销低,抗干扰能力强,精度高的特点。DS18B20数字温度传感器接线方便,封装成后可应用于多种场合

#include”ds18b20.h”

void Delay1ms() //误差 0us
{
unsigned char a,b,c;
for(c=1;c>0;c–)
for(b=142;b>0;b–)
for(a=2;a>0;a–);
}

void Delay80us(void) //误差 0us
{
unsigned char a,b;
for(b=11;b>0;b–)
for(a=2;a>0;a–);
}
void Delay15us(void) //误差 0us
{
unsigned char a;
for(a=6;a>0;a–);
}
void Delay60us(void) //误差 0us
{
unsigned char a,b;
for(b=3;b>0;b–)
for(a=8;a>0;a–);
}
void delay480us(void) //误差 0us
{
unsigned char a,b;
for(b=53;b>0;b–)
for(a=3;a>0;a–);
}

uchar DS18B20start()
{
uint i;
DSPORT=0;
delay480us();
DSPORT=1;
Delay80us();
while(DSPORT)
{
Delay1ms();
i++;
if(i>5)
{
return 0;
}
}
return 1;
}

void DS18B20write(uchar dat)
{
uint j;
for(j=0;j<8;j++)
{
DSPORT=0;
Delay15us();
DSPORT=dat&0x01;
Delay60us();
DSPORT=1;
dat>>=1;
}
}

uchar DS18B20read()
{
uint i,j;
uchar bi,byte;
for(i=0;i<8;i++)
{
DSPORT=0;
j++;
DSPORT=1;
Delay15us();
bi=DSPORT;
byte=(byte>>1)|(bi<<7);
Delay60us();
}
return byte;
}

void DS18B20change()
{
DS18B20start();
Delay1ms();
DS18B20write(0xcc);
DS18B20write(0x44);
// Delay1ms(100);
}
void DS18B20get()
{
DS18B20start();
Delay1ms();
DS18B20write(0xcc);
DS18B20write(0xbe);
}

int DS18B20readtemp()
{
uint temp=0;
uchar tml,tmh;
DS18B20change();
DS18B20get();
tml=DS18B20read();
tmh=DS18B20read();
temp=tmh;
temp<<=8;
temp|=tml;
return temp;
}

3.用LCD1602实现的显示功能
关于LCD1602的详细中文手册
链接:https://pan.baidu.com/s/1uFq66_MQEsx0fI2qJy5yXg
提取码:fuel

#include “lsd1602.h”

#define RS_CLR RS=0
#define RS_SET RS=1

#define RW_CLR RW=0
#define RW_SET RW=1

#define EN_CLR EN=0
#define EN_SET EN=1

#define DataPort P0

void delay1ms(unsigned char c) //误差 0us
{
unsigned char a,b;
for(;c>0;c–)
for(b=142;b>0;b–)
for(a=2;a>0;a–);
}

/*————————————————
写入命令函数
————————————————*/
void LCD_Write_Com(unsigned char com)
{
RS_CLR;
RW_CLR;
DataPort= com;
EN_SET;
delay1ms(1);
EN_CLR;
}
/*————————————————
写入数据函数
————————————————*/
void LCD_Write_Data(unsigned char Data)
{
RS_SET;
RW_CLR;
DataPort= Data;
EN_SET;
delay1ms(1);
EN_CLR;
}

/*————————————————
清屏函数
*/
void LCD_Clear(void)
{
LCD_Write_Com(0x01);
delay1ms(5);
}
/*————————————————
写入字符串函数
———————————————–
void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s)
{
while (*s)
{
LCD_Write_Char(x,y,*s);
s++;
x++;
}
}
/*————————————————
写入字符函数
————————————————*/
void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data)
{
if (y == 0)
{
LCD_Write_Com(0x80 + x);
}
else
{
LCD_Write_Com(0xC0 + x);
}
LCD_Write_Data( Data);
}
/*————————————————
写入字符串函数
————————————————*/
void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s)
{
while(*s)
{
if(y==0)
{
LCD_Write_Com(0x80+x);
}
else
{
LCD_Write_Com(0xC0+x);
}
LCD_Write_Data(*s);
s++;
x++;
}
}
//初始化函数
void LCD_Init(void)
{
LCD_Write_Com(0x38);
LCD_Write_Com(0x0c);
LCD_Write_Com(0x06);
LCD_Write_Com(0x01);
// LCD_Write_Com(0x18);
LCD_Write_Com(0x80);
delay1ms(5);
}

4.主程序
部分主程序,还有一部分自定义子函数在百度网盘中,大家自取。注意连接继电器的引脚。

void final()//检验密码是否正确
{
unsigned char num,i=0,j;
unsigned char passwordtemp[16]; //*大输入16个
unsigned char inputtimes; //密码输入错误次数
unsigned char passwordlength,PLEN; //输入密码长度,实际密码长度
bit Flag;

PLEN=sizeof(pass)/sizeof(pass[0]);
//用于计算出实际密码长度
relay=0;
while(1)
{
num=KeyPro();
if(num!=0xff) //如果扫描是按键有效值则进行处理
{
if(num==12)
{
LCD_Write_String(0,1,”again!”);
delay1ms(1000);
delay1ms(1000);
delay1ms(1000);
delay1ms(1000);
delay1ms(1000);
LCD_Write_String(0,1,” “);
i=0;
}

else if(num==14)
{
uint ppp,qqq=0,rrr=1;
if(rrr==1)
{
temp(DS18B20readtemp());
delay1ms(100);
for(ppp=0;ppp<7;ppp++)
{
LCD_Write_Com(0x88+qqq);
LCD_Write_Data(duan[ppp]);
qqq++;
}

}
}
else
{
if(i==0) //输入是*个字符的时候需要把改行清空,方便观看密码
LCD_Write_String(0,1,” “); //清除该行
if(i<16)
{
if(num==13)
{
passwordtemp[i]=passwordtemp[i-1];
LCD_Write_String(i-1,1,” “);
i=i-2;
}
else
{
passwordtemp[i]=num;
LCD_Write_Char(i,1,’*’);
} //输入的密码用”*”代替
}
i++; //输入数值累加
if(i==PLEN) //输入按键值15或者密码输入到*大值16,表示输入结束,需要进行比对
{
passwordlength=i; //计算输入密码长度
i=0; //计数器复位
if(passwordlength==PLEN) //长度相等则比较,否则直接输出错误
{
Flag=1; //先把比较位置1
for(j=0;j<PLEN;j++) //循环比较8个数值,如果有一个不等 则*终Flag值为0
Flag=Flag&&(passwordtemp[j]==pass[j]); //比较输入值和已有密码
}
if(Flag) //如果比较全部相同,标志位置1
{
LCD_Write_String(0,1,” “); //清除该行
LCD_Write_String(0,1,”Right Open!>>>>”); //密码正确显示的信息
inputtimes=0; //输入正确则次数清零,重新计数
Flag=0;
delay1ms(100);
relay=1; //清除正确标志
}
else
{
LCD_Write_String(0,1,” “); //清除该行
LCD_Write_String(0,1,”Wrong! Retry!”); //密码错误,提示重新输入
inputtimes++; //连续输入错误,则次数累加
if(inputtimes==3)
{
LCD_Write_String(0,1,” “); //清除该行
LCD_Write_String(0,1,”Wrong 3 times!”); //密码错误,提示重新输入
while(1); //停止该位置,重启电源后才能输入,实际实用中则需要等到一定时间后才能再次输入。
}
delay1ms(100);
relay=0;
}
}
}
}
}
}

void main()
{
// relay=0;
LCD_Init(); //初始化液晶屏
delay1ms(10); //延时用于稳定,可以去掉
LCD_Clear(); //清屏
LCD_Write_String(0,0,”Welcome!”); //写入*行信息,主循环中不再更改此信息,所以在while之前写入
LCD_Write_String(0,1,”Input password!”); //写入第二行信息,提示输入密码
fourkey();
final();//对密码输入进行检测的函数
}

 

BeautifulSoup的基本用法

BeautifulSoup的基本用法

BeautifulSoup的基本用法
from bs4 import BeautifulSoup
from urllib import request
import requests

web = ‘https://www.csdn.net/’
html = request.urlopen(web)
soup = BeautifulSoup(html,’lxml’)
print(soup.title) #<title>CSDN – 专业开发者社区</title>
print(soup.title.string) #CSDN – 专业开发者社区
print(soup.meta) #<meta content=”CSDN博客,CSDN学院,CSDN论坛,CSDN直播” name=”keywords”/>

解析一个网址,获取其内部的节点,使用BeautifulSoup去得到需要的节点信息(当有多个节点是,这种选择方法置换选择匹配到*个匹配的节点,后面的其他节点都会忽略)。

提取信息的方法
from bs4 import BeautifulSoup
from urllib import request
import requests

web = ‘https://www.csdn.net/’
html = request.urlopen(web)
soup = BeautifulSoup(html,’lxml’)

print(soup.title.string) #CSDN – 专业开发者社区
print(soup.title.name) #title
print(soup.meta.attrs) #{‘name’: ‘keywords’, ‘content’: ‘CSDN博客,CSDN学院,CSDN论坛,CSDN直播’}
print(soup.meta.attrs[‘name’]) #keywords
print(soup.meta[‘content’]) #CSDN博客,CSDN学院,CSDN论坛,CSDN直播

string属性获取节点元素包含的文本内容。
name属性获取节点的名称。
attrs获取所有属性(返回的是字典形式,可以使用字典的索引方式[‘xx’]),也可以直接传入属性名获取而不用添加attrs。
要注意收的返回结果是字符串,有的返回结果是列表,这个根据不同的属性去判断,如name属性的值是唯一的,就返回字符串。

嵌套选择
from bs4 import BeautifulSoup
from urllib import request
import requests

web = ‘https://www.csdn.net/’
html = request.urlopen(web)
# net = requests.get(web)
soup = BeautifulSoup(html,’lxml’)
# print(net.text)
print(soup.head.meta) #<meta content=”CSDN博客,CSDN学院,CSDN论坛,CSDN直播” name=”keywords”/>
print(soup.head.meta[‘name’]) #keywords

可以调用节点中的节点去获取内部元素信息。

print(soup.head.meta) #<meta content=”CSDN博客,CSDN学院,CSDN论坛,CSDN直播” name=”keywords”/>
print(soup.head.meta[‘name’]) #keywords
print(soup.head.contents) #[<title>CSDN – 专业开发者社区</title>, ‘ ‘, <meta content=”CSDN博客,CSDN学院,CSDN论坛,CSDN直播” name=”keywords”/>, ‘ ‘, <meta content=”CSDN是全球知名中文IT技术交流平台,创建于1999年,包含原创博客、精品问答、职业培训、技术论坛、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区.” name=”description”/>, ‘ ‘, <meta content=”text/html;charset=utf-8″ http-equiv=”content-type”/>, ‘ ‘, <meta content=”initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui” name=”viewport”/>, ‘ ‘, <meta content=”always” name=”referrer”/>, ‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘\n’, <script src=”https://g.csdnimg.cn/tingyun/1.8.5/www-index.js”></script>, ‘\n’, <link href=”https://g.csdnimg.cn/static/logo/favicon32.ico” rel=”shortcut icon” type=”image/x-icon”/>, ‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘\n’, <meta content=”{}” name=”toolbar”/>, ‘\n’, <meta content='{“spm”:”1000.2115″}’ name=”report”/>, ‘\n’, <script src=”https://g.csdnimg.cn/??lib/jquery/1.12.4/jquery.min.js,user-tooltip/2.2/user-tooltip.js,lib/qrcode/1.0.0/qrcode.min.js”></script>, ‘ ‘, <script src=”//g.csdnimg.cn/common/csdn-report/report.js” type=”text/javascript”></script>, ‘\n’, <script src=”https://g.csdnimg.cn/user-ordercart/2.0.1/user-ordercart.js?ts=2.0.1″></script>, ‘\n’, <script src=”https://g.csdnimg.cn/login-box/1.1.4/login-box.js”></script>, ‘\n’, <script src=”https://g.csdnimg.cn/user-ordertip/3.0.2/user-ordertip.js?t=3.0.2″></script>, ‘\n’, ‘ ‘, <link href=”https://csdnimg.cn/release/cmsfe/public/css/common.2cf061fe.css” rel=”stylesheet”/>, <link href=”https://csdnimg.cn/release/cmsfe/public/css/tpl/www-index/index.dd2d557d.css” rel=”stylesheet”/>]
print(soup.head.children) #<list_iterator object at 0x000001BDE78637B8>
for i,child in enumerate(soup.head.children):
print(i,child)

利用contents或者children的方式可以获取节点的子节点,区别的返回的值类型不同,同样也可以用enumerate方式去获取每个子节点的内容,利用descendants(soup.head.descendants)方式可以得到所有的子孙节点内容。

print(soup.title.parent)
print(soup.title.parents) #<generator object PageElement.parents at 0x000001386CE28048> 使用列表来输出信息,单纯parents则输出的是一个生成器类型
1
2
使用parent和parents获取直接父节点与祖父节点(关于兄弟节点,此处不多做叙述,考虑各个网站的结构不同,需要进行适当地调整)。

方式选择器
import re
# find_all(name,attrs,recursive,text,**kwargs) find_all()的API
print(soup.find_all(name = ‘title’)) #[<title>CSDN – 专业开发者社区</title>]
print(soup.find_all(name = ‘head’))
print(soup.find_all(attrs = {‘name’:’keywords’})) #[<meta content=”CSDN博客,CSDN学院,CSDN论坛,CSDN直播” name=”keywords”/>]
print(soup.find_all(text = re.compile(‘CSDN’))) #[‘CSDN – 专业开发者社区’, ‘CSDN技术公开课’, ‘CSDN资讯’, ‘CSDN资讯’, ‘CSDN资讯’, ‘CSDN资讯’, ‘CSDN资讯’……]
print(soup.find(name = ‘head’))

find_all()可以查询符合条件的元素,传入基本的属性就可,attrs可以根据属性去查询,text可以用文本传入来匹配,find()与find_all()不同的地方在于,前者返回单个元素,后者返回一个列表。
此外还有:
find_parents()和find_parent() :前者返回所有祖先节点,后者返回直接父节点。
find_next_siblings()和find_next_sibling() :前者返回所有祖先节点,后者直接返回父节点。
find_previous_siblings()和find_previous_sibling() :前者返回所有的兄弟节点,后者返回*个兄弟节点。
find_all_next()和find_next() :前者返回节点后所有符合条件的节点,后者返回*个符合条件的节点。
find_all_previous()和find_previous() :前者返回节点前所有符合条件的节点,后者返回*个符合条件的节点。

 

Python单元测试之Unittest

Python单元测试之Unittest

Python中有很多可以做单元测试的package,能力有限聊聊对unittest的使用。
话不多说,直接上代码,详情见注释。

import unittest #导入unittest模块
import HTMLTestRunner
from mock import patch
import webbrower

def mycluster():
return “cluster”

class Mytest(unittest.TestCase):#继承unit test.TestCase的测试类
def setUp(self):#每个测试用例执行之前要做的操作
print(“Starting test”)
def tearDown(self):#每个测试用例执行之后要做的操作
print(“Test is done!”)

@classmethod
def setUpClass(self):#必须使用@classmethod装饰器,所有测试用例执行前运行一次
pass
def tearDownClass(self):#必须使用@classmethod装饰器,所有测试用例执行后运行一次
pass

#下面是测试用例(测试方法)以test开头,unittest会将test开头的方法放入测试用例集中
def test_a_run(self):
self.assertEqual(2,1) #assertEqual校验方法是判断a == b
def test_b_run(self):
self.assertEqual(2,2) #assertEqual校验方法是判断a == b

#调用unittest.main()启动测试
if __name__ == ‘__main__’:
test_suite = unittest.TestSuite()
test_suite.addTest(unittest.makeSuite(Mytest))
fp = open(‘res.html’,’wb’)
runner = HTMLTestRunner.HTMLTestRunner(stream = fp,title = ‘test report’,description = ‘test status’)
runner.run(test_suite)
webbrower.open(‘res.html’)
unittest.main() #运行所有测试用例

测试效果如下,

%title插图%num

selenium的入门使用

selenium的入门使用

一、环境准备:
使用chrome需要安装chrome浏览器和chromedriver,并且需要把chromedriver放入到PATH环境变量中;
使用phantomjs需要安装phantomjs,并且需要把phantomjs加入到PATH环境变量中;

二、示例代码:
# coding = utf-8
from selenium import webdriver
import time

# 实例化一个浏览器
driver = webdriver.Chrome()
# driver = webdriver.PhantomJS()

# 设置窗口大小
# driver.set_window_size(1920,1080)
# *大化窗口
driver.maximize_window()

driver.get(“https://www.baidu.com”)

# 页面定位方法
driver.find_element_by_id(“kw”).send_keys(“python”)
driver.find_element_by_id(“su”).click()

# 获取html字符串
# print(driver.page_source)

print(driver.current_url)

# driver 获取 cookie
cookies = driver.get_cookies()
print(cookies)
print(“*” * 100)
cookies = {i[“name”]:i[“value”] for i in cookies}
print(cookies)

# 进行页面截屏
time.sleep(3)
# driver.save_screenshot(“./baidu.png”)
driver.quit()

三、获取元素常用方法:
获取一个 超找不到元素时 抛异常:
*
driver.find_element_by_id()
*
driver.find_element_by_name()
*
driver.find_element_by_xpath()
*
driver.find_element_by_link_text()
*
driver.find_element_by_partial_link_text()
*
driver.find_element_by_tag_name()
*
driver.find_element_by_class_name()
*
driver.find_element_by_css_selector()

获取多个 超找不到元素时 返回空列表:
*
driver.find_elements_by_name()
*
driver.find_elements_by_xpath()
*
driver.find_elements_by_link_text()
*
driver.find_elements_by_partial_link_text()
*
driver.find_elements_by_tag_name()
*
driver.find_elements_by_class_name()
*
driver.find_elements_by_css_selector()

简易计算器

 

简易计算器

℡不畏将来,不念过往。 2021-04-25 19:49:55 2 收藏
文章标签: python tkinter
版权
初入Python

使用tkinter制作简易计算器(代码BUG较多)

import tkinter
import tkinter.messagebox
# 创建窗口
window = tkinter.Tk()

# 设置窗口大小
window.geometry(‘300×600’)

# 窗口标题
window.title(‘计算器’)

# 定义变量接受字符
char = ”

# 定义变量获取点的个数
point = 1

def info(num):
global char,point
if num == ‘clear’:
text_var.set(”)
sum_var.set(”)
char = ”
elif num == ‘=’:
sum_var.set(eval(char))
# elif num == ‘X’:
# old_num = text_var.get()
# text_var.set(old_num[:-1])
# char

else:
if num == ‘.’:
if point>1:
tkinter.messagebox.askokcancel(‘提示’, ‘输入错误请重新输入’)
sum_var.set(”)
char = ”
text_var.set(”)
else:
pass
char += num
text_var.set(char)
# print(num)
# 创建列表
num_list = [
[‘%’, ‘**’, ‘ ‘, ‘X’],
[‘clear’, ‘(‘, ‘)’, ‘+’],
[‘7’, ‘8’, ‘9’, ‘-‘],
[‘4’, ‘5’, ‘6’, ‘*’],
[‘1’, ‘2’, ‘3’, ‘/’],
[‘.’, ‘0’, ‘//’, ‘=’]
]

# 创建按钮
for i in range(6):
for j in range(4):
num_button = tkinter.Button(window, text=num_list[i][j], font=(‘楷体’, 14),
command=lambda num=num_list[i][j]: info(num))
num_button.place(x=j * 75, y=240 + 60 * i, width=75, height=60)

# 创建输出框
text_var = tkinter.StringVar()
text_label = tkinter.Label(window, textvariable=text_var, font=(‘楷体’, 20))
text_label.place(x=0, y=40, width=300, height=70)

# 创建结果框
sum_var = tkinter.StringVar()
sum_label = tkinter.Label(window, textvariable=sum_var, font=(‘楷体’, 20))
sum_label.place(x=150, y=120, width=150, height=70)

# 显示窗口
window.mainloop()

成品图入下:
%title插图%num

python在图上画出射线及平行线

python在图上画出射线及平行线

import math
import numpy as np
import cv2 as cv

def Polar2Cartesian(theata):
“””
*坐标转直角坐标系
:return: 斜率
“””
pi = 3.14
radian = pi * theata / 180
return math.tan(radian)

def Painter(ori,theta):
“””
painter a picture
:param ori: origin image
:param theta: θ
:return: img
“””
width, height = ori.shape[0], ori.shape[1]
img = np.zeros((height,width))
slope = Polar2Cartesian(theta)
if theta < 90:
min_offset = int(0 – slope * width)
max_offset = height – 1
else:
min_offset = 1
max_offset = 2 * height – int(slope * width)
for offset in range(min_offset, max_offset, 50):
if theta < 45:
for i in range(0, width):
y = int(slope * i) + offset
if y >= height:
break
# idx += 1
img[y, i] = 255
elif theta <= 90:
“””
x = 1/slop
“””
for i in range(0, height):
x = int((i – offset) / slope)
if x >= width or x < 0:
continue
# idx += 1
img[i, x] = 255
elif theta <= 135:
for i in range(0, height):
x = int((i – offset) / slope)
if x >= width or x < 0:
continue
# idx += 1
img[i, x] = 255
else:
for i in range(0, width):
y = int(slope * i) + offset
if (y >= height or y < 0) and offset < height:
break
if (y >= height or y < 0) and offset >= height:
continue
# idx += 1
img[y, i] = 255
return img

if __name__ == “__main__”:
width, height = 1000, 1000
img = np.zeros((height,width))
tmp = Painter(img,50)
cv.imshow(“test”,tmp)
cv.waitKey()
%title插图%num