精华内容
下载资源
问答
  • 用Python的Flask框架写微信小程序及其管理网页后台(测试篇)-附件资源
  • 小程序的开发过程中,会存在模板消息的发送,具体文档见 这里,模板消息的发送是和语言无关的,这里将简要一下怎么 Python 给用户发送模板消息。 通过文档可以知道,发送的时候,需要使用小程序的 access_...

        在小程序的开发过程中,会存在模板消息的发送,具体文档见 这里,模板消息的发送是和语言无关的,这里将简要写一下怎么用 Python 给用户发送模板消息。
         通过文档可以知道,发送的时候,需要使用小程序的 access_token 以及用户提交的 form_id,这里实现小程序的发送也就主要分为三部分:

        1. 获取小程序的 access_token;
               2. 获取用户提交的 form_id;
         3. 给用户发送模板消息。

     

    1. 获取小程序的 access_token,由于失效期为 2 小时,为了避免每次发送的时候都要去请求接口获取,这里可以使用一个定时任务,定时的时间只需要少于两个小时就可以,获取到 access_token 后,存储在 Redis 中,这样在小程序中包括发送模板消息在内,只需要直接读取 Redis 的值就可以了。示例代码如下:

     1 def get_access_token():
     2 payload = {
     3 'grant_type': 'client_credential',
     4 'appid': 'appid',
     5 'secret': 'secret'
     6 }
     7 
     8 req = requests.get('https://api.weixin.qq.com/cgi-bin/token', params=payload, timeout=3, verify=False)
     9 access_token = req.json().get('access_token')
    10 redis.set('ACCESS_TOKEN', access_token)

     

    2. 获取用户提交的 form_id,这里只需要提供一个接口给小程序就可以了,代码示例如下:

    1 class FormHandler(RequestHandler):
    2 
    3     def post(self):
    4         req_data = self.request.body
    5         req_data = json.loads(req_data)
    6         form_id = req_data.get('form_id')
    7         template_push(form_id)  # 使用消息进行模板推送

     

    3. 发送模板消息

     1 def template_push(form_id):
     2     data = {
     3         "touser": 'openid',
     4         "template_id": 'template_id',
     5         "page": 'pages/index/index',
     6         "form_id": form_id,
     7         "data": {
     8             'keyword1': {
     9                 'value': 'value1'
    10             }
    11         },
    12         "emphasis_keyword": ''
    13     }
    14     access_token = redis.get('ACCESS_TOKEN')
    15     push_url = 'https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token={}'.format(access_token)
    16     requests.post(push_url, json=data, timeout=3, verify=False)

    至此,用户就会收到消息了。

    转载于:https://www.cnblogs.com/qiaojushuang/p/9195583.html

    展开全文
  • 教你Py来玩跳一跳小程序教程+项目地址2017 年 12 月 28 日下午,微信发布了 6.6.1 版本,加入了「小游戏」功能,并提供了官方 DEMO「跳一跳」。这是一个 2.5D 插画风格的益智游戏,玩家可以通过按压屏幕时间的长短...

    教你用Py来玩跳一跳小程序教程+项目地址

    2017 年 12 月 28 日下午,微信发布了 6.6.1 版本,加入了「小游戏」功能,并提供了官方 DEMO「跳一跳」。

    这是一个 2.5D 插画风格的益智游戏,玩家可以通过按压屏幕时间的长短来控制这个「小人」跳跃的距离。可能刚开始上手的时候,因为时间距离之间的关系把握不恰当,只能跳出几个就掉到了台子下面。 玩法类似于《Flappy Bird》

    />

    如果能精确测量出起始和目标点之间测距离,就可以估计按压的时间来精确跳跃?所以花 2 个小时写了一个 Python 脚本进行验证

    希望不要把分数刷太高,容易没朋友的。。。

    操作规范

    考虑到生产环境的规范性,实验与项目之间不受干扰,请尽量用新的虚拟环境来完成实验

    MacOS/Win,请使用如下操作开辟新的虚拟环境(不强调表示MacOS/Win相同操作)下载Anaconda. MacOS:默认安装/Win:注意安装时候勾选配置路径或者之后手动配置,直至cmd后conda关键字有效

    查看所有的虚拟环境 conda info --envs

    使用命令: conda create -n wechat_env python=3 ,创建名为 wechat_env 的虚拟环境,且配置python版本为python3

    激活虚拟环境:MacOS: source activate wechat_env /Win: activate wechat_env

    安装所需要的包,比如 matplotlib 等,建议使用 conda install package_name 来避免虚拟环境包的路径问题

    接下来的操作非必须,仅当实验完成后可操作,试验阶段全程在虚拟环境中操作,进入虚拟环境会有前置符号表示如:

    (wechat_env) ~/Desktop/wechat_jump_game-master>退出虚拟环境:MacOS: source deactivate wechat_env / Win: deactivate wecha_env

    删除虚拟环境: conda remove -n wechat_env --all

    工具介绍Python

    手机或模拟器

    ADB 驱动,可以到 这里 下载

    相关依赖

    如果你是 iOS + MacOS,请参考下面的配置:

    如果你是 Android + MacOS,请参考下面的配置:Python 3

    使用brew进行安装 brew cask install android-platform-tools

    安装完后插入安卓设备且安卓已打开usb调试模式(部分新机型可能需要再另外勾上 允许模拟点击 权限),终端输入 adb devices ,显示如下表明设备已连接

    List of devices attached

    6934dc33device

    如果你是 Android + Windows,请参考下面的配置:Python 3

    安装 ADB 后,请在 环境变量 里将 adb 的安装路径保存到 PATH 变量里,确保 adb 命令可以被识别到。

    同 Android + MacOS 测试连接

    关于Win+Android的adb调试添加路径等问题,可以尝试使用Tools文件夹中adb文件夹进行调试,详见adb中readme文件

    依赖安装

    pip install -r requirements.txt

    原理说明将手机点击到《跳一跳》小程序界面;

    用 ADB 工具获取当前手机截图,并用 ADB 将截图 pull 上来

    adb shell screencap -p /sdcard/autojump.png

    adb pull /sdcard/autojump.png .计算按压时间手动版:用 Matplotlib 显示截图,用鼠标点击起始点和目标位置,计算像素距离;

    自动版:靠棋子的颜色来识别棋子,靠底色和方块的色差来识别棋盘;用 ADB 工具点击屏幕蓄力一跳;

    adb shell input swipe x y x y time(ms)

    安卓手机操作步骤安卓手机打开 USB 调试,设置》开发者选项》USB 调试

    电脑与手机 USB 线连接,确保执行 adb devices 可以找到设备 ID

    界面转至微信跳一跳游戏,点击开始游戏

    运行 python wechat_jump_auto.py ,如果手机界面显示 USB 授权,请点击确认

    请按照你的手机分辨率从 ./config/ 文件夹找到相应的配置,拷贝到 *.py 同级目录 ./config.json (如果屏幕分辨率能成功探测,会直接调用 config 目录的配置,不需要复制)

    iOS 手机操作步骤运行安装好的 WebDriverAgentRunner

    将手机点击到《跳一跳》小程序界面

    运行脚本。有两种模式可供选择:手动辅助跳 和 自动连续跳手动辅助跳命令行运行 python3 wechat_jump_iOS_py3.py

    依次点击弹出的窗口中的起始位置和目标位置,会自动计算距离后起跳

    根据起跳的精准情况更改 python3 wechat_jump_iOS_py3.py 中的 time_coefficient参数,直到获得最佳取值

    自动连续跳拷贝 ./config/iPhone 目录下对应的设备配置文件,重命名并替换到 ./config.json

    命令行运行 python3 wechat_jump_auto_iOS.py

    会自动计算坐标并连续起跳,根据起跳的精准情况更改 ./config.json 中的 press_coefficient 参数,直到获得最佳取值

    实验结果

    />

    TODO可以对拉上来的图片进行颜色分割,识别小人和目标中心,这样就不需要手动点击自动弹跳。

    事实证明,机器人比人更会玩儿游戏。

    展开全文
  • Python Flask 数据库 微信小程序后台 网页后台

    代码实现篇

    创建数据库

    • 利用命令提示符登录数据库(方法在准备篇,这里不做阐述)
    • 创建一个名为db_info的数据库(SQL语句)
      create database db_info charset utf8;
      

    代码框架

    在这里插入图片描述

    主程序(app.py

    • app.py

      from flask import Flask, render_template, request, make_response, send_file
      from models import Admin, Student, Project
      from exts import db
      import config, os
      from methods import get_Info, to_Data, to_List, to_Json, new_avatar_name, create_xlsx
      from flask_cors import *
      
      app = Flask(__name__)
      CORS(app, supports_credentials = True) # 解决跨域问题
      
      app.config.from_object(config)
      db.init_app(app)
      
      url = "http://127.0.0.1:5000/"
      
      @app.route('/')
      def index():
          #return render_template('index.html')
          return ("首页")
      
      @app.route('/login', methods=['POST']) # 登录
      def login():
          data = to_Data()
          account = data['account']
          password = data['password']
          if account and password:
              admin = Admin.query.filter(Admin.Adminaccount == account, Admin.Password == password).first()
              if admin:
                  return ("1")
          return ("0")	
      
      @app.route('/by_input', methods = ['POST']) # 按输入查询
      def by_input():
          data = to_Data() # 将json转为字典
          input = data['input']
          page = data['page']
          if input and page:
              info = get_Info(input = input) #从数据库获取成员信息
              list = to_List(info, page) #将数据转为列表
              data = to_Json(list) #将列表数据转为json
              return data
          return ("0")
      
      
      @app.route('/by_name', methods = ['POST']) # 按姓名查询
      def by_name():
          data = to_Data()
          sname = data['name']
          page = data['page']
          if sname and page:
              info = get_Info(sname = sname)
              list = to_List(info, page)
              data = to_Json(list)
              return data
          return ("0")
      
      @app.route('/by_group', methods = ['POST']) # 按组别查询
      def by_group():
          data = to_Data()
          group = data['group']
          page = data['page']
          if group and page:
              info = get_Info(group = group)
              list = to_List(info, page)
              data = to_Json(list)
              return data
          return ("0")
      
      @app.route('/by_grade', methods = ['POST']) # 按年级查询
      def by_grade():
          data = to_Data()
          grade = data['grade']
          page = data['page']
          if grade and page:
              info = get_Info(grade = grade)
              list = to_List(info, page)
              data = to_Json(list)
              return data
          return ("0")
      
      @app.route('/by_name_group', methods=['POST']) # 按姓名、组别查询
      def by_name_group():
          data = to_Data()
          sname = data['name']
          group = data['group']
          page = data['page']
          if sname and group and page:
              info = get_Info(sname = sname, group = group)
              list = to_List(info, page)
              data = to_Json(list)
              return data
          return ("0")
      
      @app.route('/by_name_grade', methods=['POST']) # 按姓名、年级
      def by_name_grade():
          data = to_Data()
          sname = data['name']
          grade = data['grade']
          page = data['page']
          if sname and grade and page:
              info = get_Info(sname = sname, grade = grade)
              list = to_List(info, page)
              data = to_Json(list)
              return data
          return ("0")
      
      @app.route('/by_group_grade', methods=['POST']) # 按组别、年级
      def by_group_grade():
          data = to_Data()
          group = data['group']
          grade = data['grade']
          page = data['page']
          if group and grade and page:
              info = get_Info(group = group, grade = grade)
              list = to_List(info, page)
              data = to_Json(list)
              return data
          return ("0")
      
      @app.route('/by_name_group_grade', methods=['POST']) # 按姓名、组别、年级查询
      def by_name_group_grade():
          data = to_Data()
          sname = data['name']
          group = data['group']
          grade = data['grade']
          page = data['page']
          if sname and group and grade and page:
              info = get_Info(sname = sname, group = group, grade = grade)
              list = to_List(info, page)
              data = to_Json(list)
              return data
          return ("0")
      
      @app.route('/up/image', methods=['POST']) # 上传头像
      def up_image():
          sno = request.form.get('sno')
          # sno = "20182109xxxx"
          avatar = request.files['image_data'] # 上传图片数据名
          if sno and avatar:
              student = Student.query.filter(Student.SNo == sno).first()  # 查找相应成员
              if student:
                  basedir = os.path.dirname(__file__) # 运行路径
                  avatar_path = os.path.join(basedir, 'static\image', new_avatar_name(avatar.filename)) # 重命名后合成文件在服务器的路径
                  avatar_path = avatar_path.replace('\\','/') # 若不换成/ Linux服务器会报错  位置:static/image/*.jpg
                  avatar.save(avatar_path) # 保存文件
                  avatar_url = url + avatar_path # 合成头像访问路径
      
                  old_url = student.Avatar
                  if old_url: # 判断是否存在,若存在删除存储的旧头像
                      old_url = old_url.replace(url,'') # 除去路径中的url
                      os.remove(old_url)
      
                  student.Avatar = avatar_url # 将链接存储在数据库
                  db.session.add(student)
                  db.session.commit()
                  return ("1")
          return ("0")
      
      @app.route('/add_change/info', methods=['POST']) # 添加或修改成员数据
      def add_change_info():
          data = to_Data()
          sno = data['sno']
          avatar = url + "static/image/0.png" # 默认头像
          sname = data['name']
          grade = data['grade']
          group = data['group']
          ID = data['ID']  # 从前端获取得需要修改数据项目的ID列表
          state = data['state'] # 添加或修改
          data_pro = data['project_arr']
      
          telephone = data['contact']['phone']
          wechat = data['contact']['wx']
          qq = data['contact']['qq']
          mailbox = data['contact']['email']
          other = data['contact']['other']
      
          occupation = data['graduation']['job']
          workaddress = data['graduation']['address']
          direction = data['graduation']['study']
      
          if sno and sname and grade and group:
              if state == 0: # 修改
                  student = Student.query.filter(Student.SNo == sno).first()
                  # student.SNo = sno # 学号作为主键不可更改
                  student.SName = sname
                  student.Group = group
                  student.Grade = grade
                  student.Telephone = telephone
                  student.WeChat = wechat
                  student.QQ = qq
                  student.MailBox = mailbox
                  student.Other = other
                  student.Occupation = occupation
                  student.WorkAddress = workaddress
                  student.Direction = direction
                  db.session.add(student) # 修改成员数据
                  db.session.commit() # 提交
      
                  for data in data_pro:
                      if data['ID'] == 0:
                          project = data['name']
                          award = data['prize']
                          code = data['code']
                          project = Project(SNo=sno, Project=project, Award=award, Code=code)
                          db.session.add(project)  # 添加项目数据
                          db.session.commit()
                  if ID:
                      for id in ID:
                          project = Project.query.filter(Project.ID == id).first()
                          if project:
                              for data in data_pro:
                                  if data['ID'] == id:
                                      project.Project = data['name']
                                      project.Award = data['prize']
                                      project.Code = data['code']
                                      db.session.add(project) # 修改项目数据
                                      db.session.commit()
                  return ("1")
      
              elif state == 1: # 增加
                  student = Student.query.filter(Student.SNo == sno).first()
                  if not student:
                      student = Student(SNo=sno, Avatar=avatar, SName=sname, Grade=grade, Group=group, Telephone=telephone, WeChat=wechat,
                                        QQ=qq, MailBox=mailbox, Other=other, Occupation=occupation, WorkAddress=workaddress, Direction=direction)
                      db.session.add(student) # 添加成员数据
                      db.session.commit() # 提交
                      for data in data_pro:
                          project = data['name']
                          award = data['prize']
                          code = data['code']
                          project = Project(SNo=sno, Project=project, Award=award, Code=code)
                          db.session.add(project) # 添加项目数据
                          db.session.commit()
                      return ("1")
                  return ("0") # 成员已经存在
          return ("-1") # 学号、姓名不能为空
      
      @app.route('/delete/info', methods = ['POST']) # 删除成员
      def delete_info():
          data = to_Data()
          sno = data['sno']
          if sno:
              student = Student.query.filter(Student.SNo == sno).first()
              if student:
                  old_url = student.Avatar
                  if old_url:  # 删除存储在服务器的头像
                      old_url = old_url.replace(url, '')  # 除去路径中的url
                      os.remove(old_url)
                  Student.query.filter(Student.SNo == sno).delete() # 删除
                  db.session.commit()
                  return ("1")
          return ("0")
      
      @app.route('/delete/pro', methods=['POST']) # 删除项目
      def delete_pro():
          data = to_Data()
          ID = data['ID']
          if ID:
              Project.query.filter(Project.ID == ID).delete()
              db.session.commit()
              return ("1")
          return ("0")
      
      @app.route('/excel')
      def excel():
          info = Student.query.filter().all()
          excel_path = create_xlsx(info)
          if excel_path:
              response = make_response(send_file(excel_path))
              response.headers["Content-Disposition"] = "attachment; filename = {}".format('新思路成员信息一览表.xls'.encode().decode('latin-1'))
              # 将文件名(中文)utf-8编码转成 latin-1 编码
              return response
          return ("0")
      
      if __name__ == '__main__':
          # app.run(host = '0.0.0.0', port = 80) # 若要配置在服务器上
          app.run()
      

    扩展(exts.py

    • exts.py

      from flask_sqlalchemy import SQLAlchemy
      db = SQLAlchemy()
      

    主程序用到的方法(methods.py

    • methods.py

      from flask import request
      import json, re, datetime, random, os
      from models import Student, Project
      from werkzeug.utils import secure_filename
      import xlwt # 向excel表格写数据的库
      
      def get_Info(sname = None, group = None, grade = None, input = None):
          info = None
          if sname:
              sname = re.sub(' ', "", sname) # 除去空格
              sname = re.sub('\d+', "", sname) # 提取姓名
      
          if sname and group and grade:
              info = Student.query.filter(Student.SName == sname, Student.Group == group, Student.Grade == grade).all()
              if not info: # 模糊查询
                  sname = "%" + sname + "%" # 模糊条件
                  info = Student.query.filter(Student.SName.like(sname)).all()
          elif sname and group:
              info = Student.query.filter(Student.SName == sname, Student.Group == group).all()
              if not info: # 模糊查询
                  sname = "%" + sname + "%" # 模糊条件
                  info = Student.query.filter(Student.SName.like(sname)).all()
          elif sname and grade:
              info = Student.query.filter(Student.SName == sname, Student.Grade == grade).all()
              if not info: # 模糊查询
                  sname = "%" + sname + "%" # 模糊条件
                  info = Student.query.filter(Student.SName.like(sname)).all()
          elif group and grade:
              info = Student.query.filter(Student.Group == group, Student.Grade == grade).all()
          elif sname:
              info = Student.query.filter(Student.SName == sname).all()
              if not info: # 模糊查询
                  sname = "%" + sname + "%" # 模糊条件
                  info = Student.query.filter(Student.SName.like(sname)).all()
          elif group:
              info = Student.query.filter(Student.Group == group).all()
          elif grade:
              info = Student.query.filter(Student.Grade == grade).all()
      
          elif input:
              input = re.sub(' ', "", input) # 除去空格
              # 输入条件为学号查询
              input_sno = re.sub('\D', "", input) # 提取数字
              if len(input_sno) > 6:
                  info = Student.query.filter(Student.SNo == input_sno).all()
                  if not info:
                      input_sno = "%" + input_sno + "%"
                      info = Student.query.filter(Student.SNo.like(input_sno)).all()
      
              if not info:
                  # 为姓名查询
                  input_name = re.sub('\d+',"",input) # 提取姓名
                  if len(input_name) >= 1: # 存在
                      info = Student.query.filter(Student.SName == input_name).all()
                      if not info: # 模糊查询
                          input_name = "%" + input_name + "%"
                          info = Student.query.filter(Student.SName.like(input_name)).all()
      
              if not info:
                  # 为组别
                  input_group = re.sub('\d+', "", input)  # 提取组别
                  if len(input_group) >= 1:  # 存在
                      info = Student.query.filter(Student.Group == input_group).all()
                      if not info: # 模糊查询
                          input_group = "%" + input_group +"%"
                          info = Student.query.filter(Student.Group.like(input_group)).all()
      
              if not info:
                  # 为年级查询
                  input_grade = re.sub('\D',"",input) # 提取年级
                  if 4 >= len(input_grade) >= 2:# 存在
                      info = Student.query.filter(Student.Grade == input_grade).all()
                      if not info:
                          input_grade = "%" + input_grade + "%"
                          info = Student.query.filter(Student.Grade.like(input_grade)).all()
              if not info:
                  info = []
          return info
      
      def to_Data():
          # data = request.get_data()  # 获取前端数据
          # data = str(data, 'utf-8')  # 转utf-8
          # data = json.loads(data)  # json转字典
          data = json.loads(request.get_data().decode("utf-8"))
          if data:
              return data
          else:
              return {}
      
      def to_Json(list = None):
          if list:
              data = json.dumps(list, ensure_ascii = False)
          else:
              data = "0"
          return data
      
      def to_List(info, page): # page为页数
          list = []
          limit = 10 # 限制返回数据条数
          index = len(info)  # 行索引
          for row in range(index):
              dic_stu = {
                  'sno': info[row].SNo,
                  'image_url':info[row].Avatar,
                  'name': info[row].SName,
                  'grade': info[row].Grade,
                  'group': info[row].Group,
                  'contact':{
                      'phone': info[row].Telephone,
                      'wx': info[row].WeChat,
                      'qq': info[row].QQ,
                      'email': info[row].MailBox,
                      'other': info[row].Other
                  },
                  'graduation':{
                      'job': info[row].Occupation,
                      'address': info[row].WorkAddress,
                      'study': info[row].Direction
                  },
              }
      
              list_pro = []
              pro_info = Project.query.filter(Project.SNo == info[row].SNo).all()
              for row_ in range(len(pro_info)):
                  dic_pro = {
                      'ID':pro_info[row_].ID,
                      'name': pro_info[row_].Project,
                      'prize': pro_info[row_].Award,
                      'code': pro_info[row_].Code
                  }
                  list_pro.append(dic_pro)
              dic_stu['project_arr'] = list_pro
      
              list.append(dic_stu) # 合并
      
          total = limit * page
      
          list = list[total-limit:total] # 索引,位置
          return list
      
      def new_avatar_name(avatar_name):
          now_time = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
          rand_num = random.randint(10,99) # 随机10到99
          name = secure_filename(avatar_name)
          ext = name.rsplit('.', 1)[1]  # 扩展名
          avatar_name = str(now_time) + str(rand_num) + '.' + ext # 合成
          return avatar_name
      
      def create_xlsx(info):
          workbook = xlwt.Workbook(encoding = 'utf-8')
          worksheet = workbook.add_sheet('新思路成员信息一览表', cell_overwrite_ok = True)
      
          alignment = xlwt.Alignment()  # 对齐格式
          alignment.horz = xlwt.Alignment.HORZ_CENTER  # 水平居中
          alignment.vert = xlwt.Alignment.VERT_CENTER  #
      
          font = xlwt.Font() # 字体
          font.bold = True # 设置黑体
      
          pattern = xlwt.Pattern()
          pattern.pattern = xlwt.Pattern.SOLID_PATTERN
          pattern.pattern_fore_colour = 27 # 浅色
      
          borders = xlwt.Borders()
          borders.left = xlwt.Borders.THIN # THIN:实线  NO_LINE:无  DASHED:虚线
          borders.right = xlwt.Borders.THIN
          borders.top = xlwt.Borders.THIN
          borders.bottom = xlwt.Borders.THIN
      
          borders_ = xlwt.Borders()
          borders_.bottom = xlwt.Borders.THIN
      
          tall = xlwt.easyxf('font:height 700;')
          worksheet.row(0).set_style(tall)
          tall = xlwt.easyxf('font:height 360;')
          worksheet.row(1).set_style(tall)
          tall = xlwt.easyxf('font:height 360;')
          worksheet.row(2).set_style(tall)
      
          worksheet.col(0).width = 256*13 # 学号
          worksheet.col(4).width = 256*12 # 电话
          worksheet.col(5).width = 256*12 # 微信
          worksheet.col(6).width = 256*12 # QQ
          worksheet.col(7).width = 256*18 # 邮箱
          worksheet.col(10).width = 256*15 # 地址
          worksheet.col(11).width = 256*27 # 方向
          worksheet.col(13).width = 256*25
          worksheet.col(14).width = 256*25
          worksheet.col(15).width = 256*25
          worksheet.col(16).width = 256*25
          worksheet.col(17).width = 256*25
      
          style0 = xlwt.XFStyle()
          style0.alignment = alignment
          style0.font = font
          style0.pattern = pattern
          style0.borders = borders
          worksheet.write_merge(0, 0, 0, 17, 'New-Thread成员信息一览表', style0)
      
          style1 = xlwt.XFStyle()
          style1.alignment = alignment
          style1.font = font
          style1.borders = borders
          worksheet.write_merge(1, 1, 0, 3, '个人信息', style1)
          worksheet.write_merge(1, 1, 4, 8, '联系方式', style1)
          worksheet.write_merge(1, 1, 9, 11, '毕业去向(工作/研究生/留学生)', style1)
          worksheet.write_merge(1, 1, 12, 17, '参与项目', style1)
      
          style2 = xlwt.XFStyle()
          style2.alignment = alignment
          style2.borders = borders
          a = ['学号','姓名','年级','组别','电话','微信','QQ','邮箱','其它','职业','地址(工作单位)','研究方向(岗位/研究生技术方向)','-','项目1','项目2','项目3','项目4','项目5']
          for i in range(18):
              worksheet.write(2, i, a[i], style2)
      
          style3 = xlwt.XFStyle()
          style3.alignment = alignment
          style3.borders = borders
          if info:
              i = 3 # 控制行
              pi = 3
              for row in range(len(info)):
                  stu_info = [info[row].SNo, info[row].SName, info[row].Grade, info[row].Group, info[row].Telephone, info[row].WeChat, info[row].QQ,
                          info[row].MailBox, info[row].Other, info[row].Occupation, info[row].WorkAddress, info[row].Direction]
                  j = 0 # 控制信息列
                  pj = 13 # 工程列
                  for content in stu_info:
                      worksheet.write_merge(i, i+2, j, j, content, style3) # 合并单元格参数(从0开始): 1-3行,0-0列,内容,格式
                      j = j+1
                      if j == 12:
                          break
      
                  style4 = xlwt.XFStyle()
                  style4.borders = borders_
                  worksheet.write(i, 12, '项目名称')
                  worksheet.write(i+1, 12, '获奖情况')
                  worksheet.write(i+2, 12, '源码', style4)
      
                  project = Project.query.filter(Project.SNo == info[row].SNo).all()
                  for row in range(len(project)):
                      pro_info = [project[row].Project, project[row].Award, project[row].Code]
                      for content in pro_info:
                          worksheet.write(pi, pj, content, style3)
                          pi = pi+1 # 加行
                      pj = pj + 1 # 加列
                      pi = pi - 3 # 还是一个学生,所以回到这一次的初始行
      
                  i = i + 3 # 隔行输出
                  pi = pi + 3 # 下一初始行
      
              basedir = os.path.dirname(__file__)  # 运行路径
              excel_path = os.path.join(basedir, 'static', '成员信息一览表.xls')  # 重命名后合成文件在服务器的路径
              excel_path = excel_path.replace('\\', '/')  # 若不换成/ Linux服务器会报错  位置:static/*.xls
              workbook.save(excel_path)  # 写入
      
              return excel_path
          return ("0")
      

    数据库配置信息(config.py

    • config.py
      DIALECT ='mysql'
      DRIVER = 'mysqldb'
      USERNAME = 'root'
      PASSWORD = 'password' # 此处填写你的数据库密码
      HOST = 'localhost' # 部署到服务器不能用127.0.0.1 得用localhost
      PORT = '3306'
      DATABSE = 'db_info' # 此处为你建的数据库的名称
      SQLALCHEMY_DATABASE_URI ="{}+{}://{}:{}@{}:{}/{}?charset=utf8".format(DIALECT,DRIVER,USERNAME,PASSWORD,HOST,PORT,DATABSE)
      
      SQLALCHEMY_TRACK_MODIFICATIONS = False
      

    创建相应数据库模型(models.py

    • models.py
      from exts import db
      
      class Admin(db.Model):
          __tablename__ = 'admin'
          Adminaccount = db.Column(db.String(255, 'utf8_general_ci'), primary_key=True)
          Password = db.Column(db.String(255, 'utf8_general_ci'), nullable=False)
      
      class Project(db.Model):
          __tablename__ = 'project'
          ID = db.Column(db.Integer, primary_key=True)
          SNo = db.Column(db.ForeignKey('student.SNo', ondelete='CASCADE', onupdate='CASCADE'), nullable=False, index=True)
          Project = db.Column(db.String(255))
          Award = db.Column(db.String(255))
          Code = db.Column(db.String(255))
          student = db.relationship('Student', primaryjoin='Project.SNo == Student.SNo', backref='projects')
      
      class Student(db.Model):
          __tablename__ = 'student'
          SNo = db.Column(db.String(255, 'utf8_general_ci'), primary_key=True, index=True)
          Avatar = db.Column(db.String(255, 'utf8_general_ci'), index=True)
          SName = db.Column(db.String(255, 'utf8_general_ci'), nullable=False)
          Grade = db.Column(db.String(255, 'utf8_general_ci'), nullable=False)
          Group = db.Column(db.String(255, 'utf8_general_ci'), nullable=False)
          Telephone = db.Column(db.String(255, 'utf8_general_ci'))
          WeChat = db.Column(db.String(255, 'utf8_general_ci'))
          QQ = db.Column(db.String(255, 'utf8_general_ci'))
          MailBox = db.Column(db.String(255, 'utf8_general_ci'))
          Other = db.Column(db.String(255, 'utf8_general_ci'))
          Occupation = db.Column(db.String(255, 'utf8_general_ci'))
          WorkAddress = db.Column(db.String(255, 'utf8_general_ci'))
          Direction = db.Column(db.String(255, 'utf8_general_ci'))
      

    将models中所写模型映射到数据库中(manager.py

    • manager.py

      from flask_script import Manager
      from flask_migrate import Migrate, MigrateCommand
      from app import app
      from exts import db
      
      manager = Manager(app)
      migrate = Migrate(app,db) # 使用Migrate绑定app和db
      manager.add_command('db',MigrateCommand) #添加迁移脚本的命令到manager中
      
      if __name__ == '__main__':
          manager.run()
      
    • 映射
      打开命令提示符,切换到项目文件目录

      cd /d D:\Flask\成员信息管理系统

      执行以下命令

      python manager.py db init
      python manager.py db migrate
      python manager.py db upgrade

    上一篇(准备篇):https://blog.csdn.net/qq_42766994/article/details/89401754
    下一篇(测试篇):https://blog.csdn.net/qq_42766994/article/details/89437977

    展开全文
  • 在前面: 主要运用python进行简单的图像处理,不得不说python用起来是真的爽,各种库的学习使得开发变得越来越简单... 其实玩过这个小程序的应该知道实现起来也不是很难,很适合新手练手。第一次到了500多题不...

    写在前面:

          主要运用python进行简单的图像处理,不得不说python用起来是真的爽,各种库的学习使得开发变得越来越简单...


         其实玩过这个小程序的应该知道实现起来也不是很难,很适合新手练手。第一次到了500多题不知道是因为被检测了还是网掉了分数没提交。。。结果以后到200分就手动停了,发现提交是正常的......

       话不多说先上效果:(gif太麻烦了将就着看吧......)



    首先说一下思路:

           1.运用投屏软件将手机屏幕投屏到电脑。(实际上也可以运用adb截图再处理,但是adb太慢到200题后速度会变得相对很快,所以运用投屏,我这里用的是:vysor,自行下载安装就好了)

           2.图片处理。截图+识别(图像处理这里用的是PIL库,运用感知哈希算法、汉明距离进行图片匹配)

           3.得到结果并点击。


    **-***---**-**-*-**-*-*乱而华丽的分割线*--*--**-*--*--*****--*-

    那就开始我们的代码吧:

           1. 首先安装PIL库:https://www.cnblogs.com/mrgavin/p/8177841.html

            ok很快!我们安装好了PIL。

            我这这里主要用了其中的Image:

    from PIL import Image

           官方文档:http://effbot.org/imagingbook/image.htm

           这里有个中文的自己写的:https://blog.csdn.net/icamera0/article/details/50706615(感谢大佬)

            2.图片处理,我们需要得到图片的哈希值(dHash值),并运用汉明距离在我们自己做的列表中匹配最接近的。

    截图:
    from PIL import ImageGrab
    img = ImageGrab.grab((left,top, right, bottom))#截屏幕

            介绍一下我们这里用的感知哈希算法

                    一张图片有很多个像素点构成,每个像素点都是一个rgb,例如:


                    是一个440*300的图片,其中的像素点达到了13万...都计算的话显然有点吃力,所以我们缩小他的大小,把它缩小到15*20(当然你可以缩到其他的数字...主要是让他足够小并能比较准确的被识别)。然后的得到他的rgb,当然这里我们可以先对其进行二值化,然后在得到他的黑白图片,这样我们可以直接得到它的一个有 1,0组成的数组。那这个数组对于这个图片来说就是他的dHash。

                     这里又有一个问题就是每个图片都是不同的,不过这似乎很简单就可以解决,我们可以裁剪出其中每个数字并将其dHash然后对我们预先处理(首先得到一遍1-9以及'-','+',='的dHash存储数组)的dHash值进行比较就可以了。

             再来介绍一下我们的汉明距离

                    实际上很简单,对象a变成对象b需要改变几个元素,例如:字符串"1235"变成"1257"需要改变的是2,2就是它们的汉明距离。我们可以运用其匹配两个dHash,一般两个相同数字图片的汉明距离在5以内。


            开始我们的主要函数:

    img = Image.open(path)  # 打开一张图片
    img = img.convert('L')  # 灰度转化
    re_img = img.point(table, mode)  # table可以为数组 在将灰度图像转换为位图图像(模式”1“)时,所有非零值都设置为255(白色)
    newimg = img.crop(left, up, right, bottom)  # 裁剪
    small_img = re_img.resize((width, height), mode)  # 缩小图片这里用 mode=Image.LANCZOS
    
            我们可以运用上面的某些函数将普通的img,转换为黑白图片。当然这里point中的table可能有点问题,我们直接上代码:

    table = []
    for i in range(256):
        if i > threshold:
            table.append(0)
        else:
            table.append(1)
    bin_img = img.point(table, '1')

            

            然后我们要对其进行裁剪,分为两部分:横向,纵向。我们不难看出上面图片中每个数字之间是背景色的,转为黑白图片后就是白色的。

            我们调用:

    import numpy
    num_img = numpy.array(re_img)#将其转换为二维数组形式,其黑为1,白为0。

    当然这还不足以让方便我们识别我们该剪切那一部分,我们需要将其每一列每一行求和分别得到两个一维数组。

    list(numpy.sum(numpy.array(img) == 0, axis=1)) #axis为0为列求和,1为行求和 返回一维数组。(我也不太确定到底是0,1对应的是谁)

    得到了他们求和的数组之后我们判断一下那一块是大于零的并用crop裁减出来就可以了。


    别忘记将其缩小!别忘记将其缩小!别忘记将其缩小!


    横竖裁剪完成后我们的到了每一个数字的缩小版,下面我们就要对其进汉明距离的匹配了。这里也很简单我们只要判断一下两个的dHash有哪些不同就好了,这里的dHash很明显就是我们转换每个缩小版数字的数组。找出最小的汉明距离然后返回它对应的值(这个应该是你已经初始化完成的,我们先找几个样例然后得到其dHash,手动输入他对应的数字是多少并储存)。

    #如果有问题可以去下面代码借鉴一下。

    运算:

           上面我们终于就完成了,下面的是运算,这个其实对于学过算法的其实不难,但是python好就好在给你提供了你意想不到的库。比如说得到字符串中运算结果,例如

    eval("2+5")==7

    我们可以直接调用eval运算出结果并于结果对比。


    3.点击:

            点击还是比较容易实现的,python库如此强大!

    import win32api, win32gui, win32con
    win32gui.GetCursorPos()#得到鼠标位置
    win32api.SetCursorPos(x, y)#改变鼠标位置到x,y
    win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN | win32con.MOUSEEVENTF_LEFTUP, 0, 0)#点击。0,0为偏移量具体百度
    

     


    ------------------------------------------不乱但是不华丽的分割线-------------------------------------------------

    注意点:我们还需要初始化获取'44'这两个数字的dHash,因为44之间是连着的所以不会被我们程序分开然后就会得到错误结果。算是个坑点吧。

    这一只有图像处理与匹配的函数,具体的其他的还是蛮简单的。

    项目自取:https://github.com/goodtimep/python

    展开全文
  • 因此感觉目前工作已经快走到尽头,必须寻找饭碗,所以开始瞄准了微信小程序一...作为个人业余开发者,程序的前端后端都必须要能,然而微信小程序的前端都是CSS语言完成的,跟python基本不沾边。后端可能会用到
  • 这两天刚刚入门学习微信小程序,有一个问题想请教。我之前用python写了一个从视频截取图片并筛选的程序。想在小程序里实现它,请问有什么方法呢?从教学里学习到这种功能一般是用API接口实现的。如果API可以实现的话...
  • 手上有个微信小程序项目,因为对Python相对熟悉一些,打算后端用python写,具体采用python 轻量级的flask框架。在做的过程中,有些问题需要考虑,记录在下边.1. 开发的小程序后端怎么区分不同的小程序用户?或者说有...
  • Python 3安装 PyCharm安装 MySQL 8.0安装 Flask框架安装 flask-sqlalchemy安装 微信小程序后台 网页后台
  • 教你Py来玩跳一跳小程序教程+项目地址2017 年 12 月 28 日下午,微信发布了 6.6.1 版本,加入了「小游戏」功能,并提供了官方 DEMO「跳一跳」。这是一个 2.5D 插画风格的益智游戏,玩家可以通过按压屏幕时间的长短...
  • 教你Py来玩跳一跳小程序教程+项目地址2017 年 12 月 28 日下午,微信发布了 6.6.1 版本,加入了「小游戏」功能,并提供了官方 DEMO「跳一跳」。这是一个 2.5D 插画风格的益智游戏,玩家可以通过按压屏幕时间的长短...
  • 本人大四,现在正在准备毕业设计,不想做一般的web项目(所有人都在做没有什么新意),思来想去最后决定用python写个爬虫(这个是毕设的核心功能),然后想联系当下的较流行的微信小程序,把爬虫放到微信小程序上...
  • 逢年过节发新年祝福成为新时代的新习俗,近年来微信的出现令人们从传统的电话祝福、短信祝福升级为微信祝福,文字,图片,视频...python有专门调用微信接口的包,利用这个就能有比较好的功能。本文参考了下面三...
  • 2017年的尾巴上,微信推出了游戏,其中跳一跳火遍大江南北,咱们可爱的程序猿哥哥直接用Python写了个自动跳一跳的程序,github地址:https://github.com/wangshub/wechat_jump_game因为跳一跳实在是太火了,在...
  • 测试工具Postman安装 POST方式向后台(接口网址)发送json数据
  • SQL Alchemy对数据库的增删改查 相似查询 flask-sqlacodegen 将数据库结构转换成SQL Alchemy的ORM模型 json数据转换

空空如也

空空如也

1 2 3 4 5 ... 13
收藏数 258
精华内容 103
关键字:

用python写微信小程序

python 订阅
微信小程序 订阅