精华内容
下载资源
问答
  • 联邦学习和中心训练--知识记录

    千次阅读 2021-11-16 20:25:05
    联邦学习机理如下:设备下载云端最新的共享模型,本地改进和训练,个性后的模型被抽取为一个更新文件,将差异部分加密上传云端,在云端和其它设备上传的最新模型差异做平均更新,以改善共享模型。 网络的上传

    一、知识点:

    1、原子操作(atomic operation)指的是由多步操作组成的一个操作。如果该操作不能原子地执行,则要么执行完所有步骤,要么一步也不执行,不可能只执行所有步骤的一个子集。

    2、联邦学习为移动设备上的模型共享创造可能,模型训练与云端存储解耦,移动端存储训练数据,并进行模型训练和进化。

    联邦学习机理如下:设备下载云端最新的共享模型,本地改进和训练,个性化后的模型被抽取为一个更新文件,将差异部分加密上传云端,在云端和其它设备上传的最新模型差异做平均化更新,以改善共享模型。

    网络的上传速度通常比下载速度慢,谷歌开发出一种新颖的算法:“random rotations and quantization”,将上传更新的通信速度提升为原来的100倍。这些算法都聚焦在深度学习的训练上,还针对点击率预测的问题设计出了“high-dimensional sparse convex"模型。

    3、差分隐私

    差分隐私是用来防范差分攻击的,我们对加入新样本后的结果查询中加入噪声,使得攻击者无法辨别某一样本是否在数据集中,即达到双兔傍地走安能辨我是雄雌的境地。

    4、智能合约,类似于实际合同效力,在计算机语言描述和实现,在没有第三方参与的情况下进行合约的触发和执行。

    智能合约区别于传统合约:

    1)合约的触发与执行合二为一次原子操作

    2)去中心化和自动化地合约流程,无须第三方中心机构的介入。

    5、横向和纵向联邦学习

    横向联邦学习适用于联邦学习的参与方的数据有重叠的数据特征,即数据特征在参与方之间是对齐的,参与方数据样本不同。纵向联邦学习 适用于联邦学习参与方的训练数据有重叠的数据样本,即参与方之间的数据样本对齐的,但数据特征上不同。

    二、钱学海团队的研究成果:

    1、钱学海认为,分布式训练系统的核心问题是不同计算设备的通信以及由于计算和通讯性能的差异带来的异构性,具体可以看做面临三个方面的挑战,分别是:通信(Communication)、异构性(Heterogeneity)和多因素交互的复杂性 (Complex Trade-offs )。

    (1)通信:早期分布式训练是一个中心化结构,每一个worker会把自己计算得到的梯度上传到中心节点,中心节点对all worker 的梯度平均化处理,再传回各个worker。存在中心节点通信瓶颈问题;第二代分布式训练系统结构是Ring-All-Reduce,节点同步环+并行流水线工作机制,通信更加高效,但当每个worker的运行性能差距较大时,系统性能受限于运行效率最低的worker。

    Ring All-Reduce系统结构

    (2)异构性:确定异构性(Deterministic heterogeneity)和 动态异构性(Dynamic heterogeneity )。确定异构性是指不同的设备通常有不同的计算能力(比如:采用不同的GPU或 TPU系列),并且设备或节点具有不同的网络通信性能。动态异构性是由资源共享造成的,即同一个设备对不同的应用提供的计算性能不同。分布式训练系统下会产生Slow Worker,被称为Straggler。Straggler问题亦称之为异构性问题,即平台上Worker具有不同的运行性能时,整个系统的性能受限于运行效率最低的Worker。

    (3)复杂性:全局考量系统设计,如考虑并行性与通信之间的关系,一般采用Data Parallelism 和 Model Parallelism

            Data Parallelism      

                  Model Parallelism

    2、去中心化的分布式训练

    去中心化方法下,可定义任意模式的通信图。提供了一个更灵活的通讯方式。每一个节点的运行过程如下:

    根据Min-batch数据和当前的模型进行梯度计算,并更新模型;

    把参数发送给“邻居”Worker;

    接收其他Worker的参数,并进行Reduce操作;

    更新模型参数,进入下一个Iteration。

    此训练中的同步是指每个Worker在做Reduce操作时,所有的参数应该出自同一个Iteration。这是在构建去中心化分布式训练系统中独特的一个问题,在PS和Ring All-Reduce中都不存在这样的问题,因为它们有一个非常自然的中心节点或者有一个同步的操作去划分Iteration。

    PS和Ring All-Reduce

    3、 基于同步算法的去中心化分布式训练

    基于队列的同步算法(Queue-based Synchronization),该算法应用于同步算法系统设计中,主要解决两个问题:(1)系统应该能够自适应按需分配资源,而不是持续分配资源(2)Backup Worker是解决异构问题的一种技术,它能够控制同步的松紧程度(Bounding Iteration Gap),但会造成无穷大的Iteration gap

    基于队列的同步是指每个Worker有两个队列:Update Queue(UQ), 用来存储邻居发送来的信息,Token Queue(TQ), 用来控制同步。假设在部署协议时,设定Iteration Gap的最大容忍是2,则TQ的Token数最大为2。协议开始执行以后,每一个Worker都可以向其他Worker发送参数更新。Worker要想进入下一个Iteration,必须要从邻居的TQ中获取Token放入自己的TQ当中。如果C要进入下一个Iteration,必须先从TQ_A->C和TQ_B->C中获取token,分别放入TQ_C->A和TQ_C->B中。

    解释上述提到的Backup技术控制Bounding Iteration Gap,设Number of backup = 1,若A出现Slowdown,B和C仍然可继续进行。当B和C进入Iteration(2)之后,由于A仍然在Iteration(0)且A的TQ中已经没有token了,所以B和C也会停止。这样就确定了Iteration gap的边界。这个边界值是由TQ的长度决定的

    Queue-based Synchronization with backup Worker

    4、基于异步算法的去中心化分布式训练

    去中心化异步训练算法的代表:深度学习异步去中心化随机梯度下降算法Asynchronous Decentralized Parallel SGD(AD-PSGD),其核心思想是通信的随机性(worker的迭代是随机选择的)以及worker之间进行原子性操作。

    原子性操作的两个作用:(1)两个串行操作执行完以后,w(2)的模型更新中也包含w(1)的模型更新,(2)模型的收敛速度会大大提高。

    原子性操作也存在弊端,参数大量同步成本,训练过程中,AD-PSGD在不同的数据集上训练的同步开销都比Ring All-Reduce要大。在异构环境下,AD-PSGD的收敛速度比Ring All-Reduce要快;在同构环境下,则相反。

    鉴于上述挑战,Partial All-Reduce算法应用于异步算法系统设计中,应运而生,它主要解决两个问题:1)如何让同步操作本身更快;2)如何减少冲突,降低由于串行操作带来的延迟。

    概算法的核心思想是worker Group 代替worker 同步,首先,Group Generator 产生不冲突的分组,每个节点一个分组,每个分组内部有一个Head worker进行节点之间的同步,组内同步不需要进行节点之间的通信,避免了网络拥堵的问题。

    展开全文
  • 中心中心

    千次阅读 2021-01-04 10:47:25
    相反,外部开来中心单工作机制采用了中心设计思想的分布式系统正在不断涌出。在这种架构下,集群中的领导是被动态选择出来的,而不是认为预先置顶的,而且集群发生故障的情况下,集群的成员会自发的举行“会议...

    中心化和去中心化:

    分布式的架构中,同一个服务会部署若干服务节点,在面对具体服务请求时,怎么决定由哪个节点来提供服务,根据实现方案分为中心化和去中心化两种方式。

    中心化
    在开源中间件codis的集群组网中,应用对缓存节点的访问都通过codis的proxy代理,由代理来决定数据存储到哪个节点上:
    在这里插入图片描述
    这种分布式的组网架构就是中心化的组网,由统一的中心codis-proxy进行调度。我司使用的zk/dubbo架构也属于中心化的组网,zk作为服务的注册中心。
    去中心化
    开源中间件redis的集群模式组网中(非我司使用的哨兵模式),没有中心节点,所有节点处于对等地位:
    在这里插入图片描述
    这种分布式的组网架构中,由节点间两两相互进行状态确认,根据算法集体决策出服务的提供方。

    节点规模的因素
    去中心化中,每个节点需要与其它所有节点进行状态确认,节点部署规模小的情况下,整个过程还算快捷。但当节点规模超大时,节点间交互过程会随节点数指数增长,整个过程会复杂漫长而不可控。

    中心化的组网架构中,服务统一进行管理,管理逻辑相对简单和稳定,特别适用于大规模节点部署的情况。

    中心节点单点故障的风险
    中心化的设计存在的最大问题是中心节点的安危问题,如果中心节点出了问题,整个集群就奔溃了。为了解决这个问题,大多数中心化系统都采用了主备两个“中心节点”的设计方案,例如图3中两台codis-proxy本身采用的是负荷分担方式;

    中心化带来的性能影响
    中心化的设计中,对服务的访问往往需要先经过中心节点,会带来额外的该问路径,造成额外的性能开销,例如codis和redis底层存储节点都一样,但是不同组网架构中,coides性能明显差于redis的集群模式。

    换存类型Value长度SET速率(条/s)GET速率(条/s)
    redis1003244938013
    5002974336855
    10002424533395
    codis1001852418709
    5001748118368
    10001552316981

    没有绝对的去中心化
    实际上,完全意义的真正去中心化的分布式系统并不多见。相反,外部开来去中心化单工作机制采用了中心化设计思想的分布式系统正在不断涌出。在这种架构下,集群中的领导是被动态选择出来的,而不是认为预先置顶的,而且集群发生故障的情况下,集群的成员会自发的举行“会议”选举新的“领导”主持工作。最典型的案例就是ZooKeeper。

    脑裂问题
    去中心化设计里最难解决的一个问题是“脑裂”问题,这种情况的发生概率很低,但影响很大。脑裂指一个集群犹豫网络的故障,被分为至少两个彼此无法通信的单独集群,此时如果两个集群都各自工作,则可能会产生严重的数据冲突何错误。一般的设计思路是,当集群半段发生了脑裂问题是,规模较小的集群就“自杀”或者拒绝服务。

    展开全文
  • 最近在编写UI自动框架,现在将一些碎片东西进行梳理,便于记忆 这里是根据PO模型编写框架用到的所有分层,梳理一下每个包的用途 .pytest_cache 这个是使用pytest框架系统默认导入的 commom公共管理方法 ...

    最近在编写UI自动化框架,现在将一些碎片化东西进行梳理,便于记忆
    在这里插入图片描述
    同时,为了方便于各个模块的独立管理,以及秉承高复用,低耦合的思想,这里是根据PO模型编写,同时将所有的模块进行了独立,页面和元素,以及用例和操作
    框架用到的所有分层,梳理一下每个包的用途

    1.  .pytest_cache 这个是使用pytest框架系统默认导入的
      
    2.  commom公共管理方法
      
      在这里插入图片描述
      common_handle: 这里可以理解为base_page,这里对selenium里的方法进行了二次封装,同时对于一些操作,会在代码段里做注释,就不过多叙述
    # encoding: utf-8
    """
    @author:辉辉
    @email: 372148872@qq.com
    @Wechat: 不要静音
    @time: 2020/12/14 15:15
    """
    from selenium.webdriver.remote.webdriver import WebDriver
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.webdriver.support.wait import WebDriverWait
    
    from JPT_UITEST.Config.path_name import PathName
    from JPT_UITEST.common import time
    from JPT_UITEST.common.log_handle import logger
    
    
    class BasePage:
        #  初始化,传入一个driver
        def __init__(self, driver: WebDriver):
            self.driver = driver
    
        #  二次封装元素等待,如果错误,记录日志,并截图保存
        def wait(self, loc, filename):
            """
            元素等待
            :param loc: 等待的元素
            :param filename: 截图名字
            :return:
            这里使用的是隐式等待,同时将隐式等待和元素是否可见的判断进行了结合,这样更加稳定!
            """
            logger.info('{}正待等待元素{}'.format(filename, loc))
            try:
                WebDriverWait(self.driver, timeout=30).until(EC.visibility_of_element_located(loc))
                #首先是隐式等待表达式(driver对象,等待时长)
                #同时每0.5秒会查看一次,查看元素是否出现,如果超过30s未出现,则报错timeout
                #until()是等待元素可见,这里加入了元素是否可见的判断
            except Exception as e:
                self.error_screenshots(filename)
                logger.exception('元素等待错误发生:{}元素为{}'.format(e, loc))
                raise
    
        def error_screenshots(self, name):
            """
            保存截图
            :param name:根据被调用传入的名字,生成png的图片
            :return:
            """
    
            try:
                file_path = PathName.screenshots_path
                times = time.time_sj()
                filename = file_path + times + '{}.png'.format(name)
    
                self.driver.get_screenshot_as_file(filename)
                logger.info("正在保存图片:{}".format(filename))
    
            except Exception as e:
                logger.error('图片报存错误:{}'.format(e))
                raise
    
        def get_ele(self, loc, filename):
            """
            查找元素
            :param loc:
            :param filename:
            :return:
            """
            logger.info('{}正在查找元素:{}'.format(filename, loc))
            try:
            	#  这里使用的是find_element查找单个元素,这里需要传入的是一个表达式,需要告诉driver对象使用的是什么定位方法,以及元素定位!
            	# By是继承了selenium里面的8大定位方法,所以框架里操作元素的皆是By.XPATH或者By.id等等
            	# 同时因为需要传入的是一个表达式,而By.XPATH是一个元组,这里做了解包处理
                ele = self.driver.find_element(*loc)
            except Exception as e:
                logger.exception('查找元素失败:')
                self.error_screenshots(filename)
                raise
            else:
                return ele
    
        def send_key(self, loc, name, filename):
            """
            输入文本
            :param loc:元素
            :param filename:截图名字
            :param name: 输入的名字
            :return:
            """
            logger.info('{}正在操作元素{},输入文本{}'.format(filename, loc, name))
            self.wait(loc, filename)
            try:
    
                self.get_ele(loc, filename).send_keys(name)
            except:
                logger.exception('元素错误 {}:')
                self.error_screenshots(filename)
                raise
    
        def click_key(self, loc, filename):
            """
            元素点击
            :param loc:
            :param filename:
            :return:
            """
            logger.info('{}正在操作元素{}'.format(filename, loc))
            self.wait(loc, filename)
            try:
                self.get_ele(loc, filename).click()
            except Exception as e:
                logger.exception('点击元素错误:{}'.format(e))
                self.error_screenshots(filename)
                raise
    
        def get_ele_text(self, loc, filename):
            """
            获取元素文本
            :param loc: 
            :param filename: 
            :return: 
            """""
            logger.info('{}正在获取文本{}'.format(filename, loc))
            self.wait(loc, filename)
            ele = self.get_ele(loc, filename)
            try:
    
                text = ele.text
                logger.info('获取文本成功{}'.format(text))
                return text
            except:
                logger.exception('获取文本错误:')
                self.error_screenshots(filename)
    
        def get_ele_attribute(self, loc, attribute_name, filename):
            """
            获取元素属性
            :param loc:
            :param attribute_name:
            :param filename:
            :return:
            """
            logger.info('{}正在获取元素{}的属性'.format(filename, loc))
            self.wait(loc, filename)
            ele = self.get_ele(loc, filename)
            try:
                value = ele.get_attribute(attribute_name)
                logger.info('获取属性成功{}'.format(value))
                return value
            except:
                logger.exception('获取属性失败')
                self.error_screenshots(filename)
    
        def wait_ele_click(self, loc, filename):
    
            logger.info('{}正待等待可点击元素{}'.format(filename, loc))
            try:
                WebDriverWait(self.driver, timeout=20).until(EC.element_to_be_clickable(loc))
                # logger.info('等待可点击元素{}'.format(loc))
            except:
                self.error_screenshots(filename)
                logger.exception('等待可点击元素错误:元素为{}'.format(loc))
                raise
    
        def switch_to_iframe(self, loc, filename):
            try:
                WebDriverWait(self.driver, 20).until(EC.frame_to_be_available_and_switch_to_it(loc))
                logger.info('正在进入嵌套页面:{}'.format(loc))
            except:
                logger.exception('进入嵌套页面失败{}'.format(loc))
                self.error_screenshots(filename)
    
        def click_wait_ele(self, loc, filename):
            logger.info('正在等待{}中的可点击元素出现{}'.format(filename, loc))
            self.wait_ele_click(loc, filename)
            try:
                self.get_ele(loc, filename).click()
                logger.info('正在{}中点击元素{}'.format(filename, loc))
            except:
                logger.info('在{}当中点击{}元素失败'.format(filename, loc))
                self.error_screenshots(filename)
    
    

    这里应该有部分同学会对初始化时的位置参数比较疑惑,为什么是 driver: WebDriver这种写法!

    这里的写法,是因为我们在封装时,不能在这里去实例driver会话对象!不然所有页面使用的就全部是一个会话对象了
    但是如果不实例呢,pycharm就不知道driver是什么,就无法使用后续的一些操作,比如driver.find_element.by.id()这种方法!
    所以我们就在初始化时,声明告诉了编译器,driver是一个webdriver对象

    同时,这里二次封装的主要思想为:要做什么->日志打印->等待元素->判断->截图这样可以清晰的知道,那个地方出了问题,有日志,有截图

    2.common_mysql:
    这里是预留封装mysql的文件,因为暂时用不到,就没使用
    3.log_handle:
    这里封装的是log日志模块

    # encoding: utf-8
    """
    @author:辉辉
    @email: 372148872@qq.com
    @Wechat: 不要静音
    @time: 2020/11/23 17:19
    """
    import logging
    import os
    
    from JPT_UITEST.Config.common_data import Context
    from JPT_UITEST.Config.path_name import PathName
    
    log_path_name = os.path.join(PathName.logs_path, Context.log_name)
    # print(log_path_name)
    
    
    class LogHandel(logging.Logger):
        """定义日志类"""
    
        def __init__(self, name, file, level='DEBUG',
                     fmt="%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s"):
            super().__init__(name)
            self.setLevel(level)
    
            file_headers = logging.FileHandler(file)
            file_headers.setLevel(level)
            self.addHandler(file_headers)
            fmt = logging.Formatter(fmt)
            file_headers.setFormatter(fmt)
    
    
    logger = LogHandel(Context.log_name, log_path_name, level=Context.level)
    
    if __name__ == '__main__':
        log = logger
        log.warning('测试1')
    
    

    这里是通用模板,不多说
    4. time.py
    这里是生成时间

    # encoding: utf-8
    """
    @author:辉辉
    @email: 372148872@qq.com
    @Wechat: 不要静音
    @time: 2020/12/15 14:56
    """
    
    import datetime
    
    
    
    def time_sj():
    
        sj = datetime.datetime.now().strftime('%m-%d-%H-%M-%S')
        return sj
    
    
    

    在这里插入图片描述

    Config 这里我存放的是路径,以及公共操作里会用到的数据
    common_data.py
    这里就放了一些关于日志的等级和level

    # encoding: utf-8
    """
    @author:辉辉
    @email: 372148872@qq.com
    @Wechat: 不要静音
    @time: 2020/12/15 13:47
    """
    
    
    class Context:
        log_name = 'Ui自动化.txt'
        level = 'DEBUG'
    
    

    path_name.py
    这里是存放了所有会用到的存放路径,以及读取数据路径

    # encoding: utf-8
    """
    @author:辉辉
    @email: 372148872@qq.com
    @Wechat: 不要静音
    @time: 2020/12/15 13:47
    """
    import os
    
    
    class PathName:
        # 初始路径F:\jintie\JPT_UITEST
        dir_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
        # F:\jintie\JPT_UITEST\Options\
        options_path = os.path.join(dir_path, 'Options')
        # Logs文件目录地址
        logs_path = os.path.join(options_path, 'Logs/')
        # report测试报告路径
        report_path = os.path.join(options_path, 'report/')
    
        screenshots_path = os.path.join(options_path, 'error_screenshots/')
    
        case_name = os.path.join(dir_path, 'testcases/')
    
    

    data文件包中存放的是项目相关的全局数据,和测试数据
    Global_Data:存放了所有全局数据

    # encoding: utf-8
    """
    @author:辉辉
    @email: 372148872@qq.com
    @Wechat: 不要静音
    @time: 2020/12/14 15:21
    """
    
    
    class GlobalData:
    
        # 域名
        host = ''
    
        # url
        BackGround = host + '/login'
    
    
    
    

    Test_data:
    test_data.py: 存放的测试数据
    数据分离的好处在于,如果数据发生改变,我只需要在这个文件中将数据做修改即可,不需要去做其他的代码改动

    # encoding: utf-8
    """
    @author:辉辉
    @email: 372148872@qq.com
    @Wechat: 不要静音
    @time: 2020/12/14 15:56
    """
    
    
    class TestData:
        # 正确账号密码
        just_data = {
            'username': '',
            'pwd': ''
        }
    	# 错误测试数据
        test_data = [{'username': '', 'pwd': ''},
                     {'username': '', 'pwd': ''},
                     {'username': '', 'pwd': ''}]
    
    

    lib的包中原本存放的是一些修改过源码的三方库,比如HTMLTestRunner.py和ddt.py
    但是后续将unittest改为了pytest所以这里的数据驱动模块,和测试报告模块变弃用了,不多做叙述

    在这里插入图片描述
    Options:这里存放的为输出的日志,报告,以及错误截图

    在这里插入图片描述
    因为使用了PO模型, PO模型是指在UI自动化中,将页面、操作、元素、和测试用例全部独立,减少耦合性,所以这里我存放的为xpath元素方法

    """
    @author:辉辉
    @email: 372148872@qq.com
    @Wechat: 不要静音
    @time: 2020/12/14 15:13
    """
    “”“涉及了实际项目,所以部分数据做脱敏处理”“”
    from selenium.webdriver.common.by import By
    
    
    class BackGroundLoc:
        # 登陆窗口
        input_user = (By.XPATH, '//input[@id="name"]')
        # 输入密码
        input_pwd = (By.XPATH, '//input[@id="password"]')
    
        # 选择平台下拉框
        select_platform_input = (By.XPATH, '//div[@unselectable="on"]')
    
        # 选择子平台
        select_platform = (By.XPATH, '//span[text()=""]')
        # 记住用户名
        Re_user_name = (By.XPATH, '//span[@class="ant-checkbox ant-checkbox-checked"]')
        # 用户登录
        user_login = (By.XPATH, '//button[@class="ant-btn login-form-button ant-btn-primary ant-btn-lg"]')
    
        title_name = 'XX管理系统'
    
        # error_msg
        error_msg = (By.XPATH, '//div[@class="ant-form-explain"]')
    
    

    这里是首页页面所有的元素定位!这样做的好处为,后续如果元素发生了改变,只需要去修改元素即可,不需要对其他地方做出修改!同时,改了这里,所有用到此元素的地方,都会发生改变

    在这里插入图片描述
    PageObject: 这里是所有关于页面操作的封装
    background_home.py是关于后台首页的操作

    # encoding: utf-8
    """
    @author:辉辉
    @email: 372148872@qq.com
    @Wechat: 不要静音
    @time: 2020/12/14 14:49
    """
    import time
    
    from JPT_UITEST.PageLocation.background_home_loc import BackGroundLoc as BLC
    from JPT_UITEST.common.common_handle import BasePage
    
    
    class PlatformLogin(BasePage):
    
        #  输入账号密码
        def platform_login_succeed(self, username, pwd):
            self.send_key(BLC.input_user, username, '登陆页_输入用户名')
    
            self.send_key(BLC.input_pwd, pwd, '登陆页_输入密码')
            time.sleep(2)
    
        # 选择平台
        def select_platform(self):
            self.click_key(BLC.select_platform_input, '登陆页_选择下拉框')
    
            self.click_key(BLC.select_platform, '登陆页_选择平台')
    
        #  登陆
        def login(self):
            self.click_key(BLC.user_login, '登陆页_点击登陆')
    
        # 记录用户名
        def Res_users_name(self):
            self.click_key(BLC.Re_user_name, '登陆页_记录用户名')
    
        # 登陆后的首页
        def login_home(self):
            self.driver.title(BLC.title_name)
    
    # if __name__ == '__main__':
    #
    #     driver = webdriver.Chrome()
    #     driver.get()
    
    

    在这里插入图片描述
    testcases: 这里存放的是所有测试用例
    conftest.py:这里是pytest的前后置条件,固定名字!不需要导入到用例中,pytest会自动遍历
    这里因为我暂时只用到了一个function用例级别的前后置条件,所以只封装了一个

    # encoding: utf-8
    """
    @author:辉辉
    @email: 372148872@qq.com
    @Wechat: 不要静音
    @time: 2020/12/23 14:26
    """
    from JPT_UITEST.data.Global_Data.global_data import GlobalData as GD
    from JPT_UITEST.common.log_handle import logger
    import pytest
    from selenium import webdriver
    
    # @pytest.fixture装饰器,是表示接下来的函数为测试用例的前后置条件
    #fixture一共4个级别,默认scope=function(用例,对标为unittest中的setup以及tearDown)
    #同时,fixture中包含了前置条件,以及后置条件
    #function是每个用例开始和结束执行
    #class是类等级,每个测试类执行一次
    #modules 是模块级别,也就是当前.py文件执行一次
    #session  是会话级别, 指测试会话中所有用例只执行一次
    #pytest中区分前置后置是用关键字yield来区分的,  yield之前,是前置!yield之后,是后置 yield同行,是返回数据
    
    @pytest.fixture()
    def open_browser():
        logger.info('-----------正在执行测试用例开始的准备工作,打开浏览器,请求后台-----------')
        driver = webdriver.Chrome()
        driver.get(GD.BackGround)
        driver.maximize_window()
        yield driver
        driver.quit()
    

    test_login.py 测试用例

    # encoding: utf-8
    """
    @author:辉辉
    @email: 372148872@qq.com
    @Wechat: 不要静音
    @time: 2020/12/14 14:44
    """
    import time
    
    import pytest
    
    from JPT_UITEST.PageObject.background_home import PlatformLogin
    from JPT_UITEST.PageObject.jinpantao_home import JinpantaoHome
    from JPT_UITEST.common.log_handle import logger
    from JPT_UITEST.data.Test_Data.test_data import TestData as TD
    
    data = TD.test_data
    
    #pytest.mark.usefixtures()是使用前置条件,括号中填写要使用的前置条件函数名称
    #因为封装前置条件的py文件名称固定,所以这里不需要导入,是由pytest自动遍历查找
    #放在类方法上,是表示测试类下所有测试方法,都会使用这个前置条件
    @pytest.mark.usefixtures('open_browser')
    class TestLogin:
        # @pytest.mark.parametrize('su_data', TD.just_data)
        def test_login_01_succeed(self, open_browser, ):
            """
            #正向场景
            3.输入账号密码,点击登陆
            4.选择对应子平台
            6.判断首页元素是否可见
            :return:
            """
            logger.info('+++++正在执行正向登陆测试用例+++++')
            try:
                pf = PlatformLogin(open_browser)
                pf.platform_login_succeed(TD.just_data['username'], TD.just_data['pwd'])
                pf.select_platform()
                pf.login()
                JT = JinpantaoHome(open_browser)
                JT.context_operation()
                JT.tag_mg()
                JT.money_mg()
                JT.article_list()
                JT.article_stat()
                JT.article_decry()
                logger.info('正在执行测试用例:账号{},密码{}'.format(TD.just_data['username'], TD.just_data['pwd']))
            except Exception as e:
                logger.error('用例执行错误:{}'.format(e))
                raise AssertionError
    	“”“@pytest.mark.parametrize()装饰器是用来执行数据驱动的,需要传入两个值
    		1.数据名称,不固定,自由填写
    		2.数据
    		但是数据名称要在使用数据驱动的方法里当作参数传入,对标ddt当中的传值接收
    	”“”
        @pytest.mark.parametrize('test_data', TD.test_data)
        
        def test_login_02_fail(self, open_browser, test_data):
            """
            3.输入账号密码
            4.选择对应平台
            5.点击登陆
            6.查看失败提示
            :return:
            """
            logger.info('+++++正在执行逆向向登陆测试用例+++++')
            try:
                pf = PlatformLogin(open_browser)
                pf.platform_login_succeed(test_data['username'], test_data['pwd'])
                # time.sleep(1)
                # pf.Res_users_name()
                time.sleep(1)
                pf.select_platform()
                pf.login()
                logger.info('正在执行逆向场景用例用户名{},密码{}'.format(test_data['username'], test_data['pwd']))
            except Exception as e:
    
                logger.error('逆向场景用件执行失败{}'.format(e))
    
    

    同时pytest当中,更加灵活的是断言,如果在unittest中,需要使用self.assert.断言方式(实际结果,预期结果)
    但是pytest当中,只需要使用assert 表达式 例如:assert 1+1=2 这种方式即可,如果结果为true,则代表断言成功!
    最后一个文件是出于习惯使用了一个加载所有用例的.run_all.py

    # encoding: utf-8
    """
    @author:辉辉
    @email: 372148872@qq.com
    @Wechat: 不要静音
    @time: 2020/12/17 20:13
    """
    import datetime
    import os
    
    import pytest
    
    from JPT_UITEST.Config.path_name import PathName
    from JPT_UITEST.common.log_handle import logger
    
    
    def run_all():
        times = datetime.datetime.now().strftime('%Y-%m-%d %H-%M-%S')
        report_name = os.path.join(PathName.report_path, (times + 'report.html'))
        logger.info('生成测试用例,存放为{}'.format(report_name))
    
        pytest.main(['-s', '-v', '--html={}'.format(report_name)])
    
    
    if __name__ == '__main__':
        run_all()
    
    

    pytest执行用例有几种方法,我这里使用的是pytest.main()这个方法,实际上就是和在cmd命令符里使用
    pytest -s -v的效果一样! '–html=xxx.html’是生成html测试用例!
    到这里,就是一个完整的框架,剩下的就是根据项目的不同,去做一些定制化的操作!

    展开全文
  • 数学四大思想方法

    千次阅读 2021-01-17 13:46:43
    数学思想方法数学思想是指人们对...函数与方程函数思想,是指用函数的概念和性质分析问题、转化问题和解决问题。方程思想,是从问题的数量关系入手,运用数学语言将问题中的条件转化为数学模型(方程、不等式、或方...

    数学思想方法

    数学思想是指人们对数学理论和内容的本质的认识,数学方法是数学思想的具体化形式,实际上两者的本质是相同的,差别只是站在不同的角度看问题。通常混称为“数学思想方法”。

    数学四大思想:函数与方程、转化与化归、分类讨论、数形结合;

    函数与方程

    函数思想,是指用函数的概念和性质去分析问题、转化问题和解决问题。方程思想,是从问题的数量关系入手,运用数学语言将问题中的条件转化为数学模型(方程、不等式、或方程与不等式的混合组),然后通过解方程(组)或不等式(组)来使问题获解。有时,还实现函数与方程的互相转化、接轨,达到解决问题的目的。

    笛卡尔的方程思想是:实际问题→数学问题→代数问题→方程问题。宇宙世界,充斥着等式和不等式。我们知道,哪里有等式,哪里就有方程;哪里有公式,哪里就有方程;求值问题是通过解方程来实现的……等等;不等式问题也与方程是近亲,密切相关。列方程、解方程和研究方程的特性,都是应用方程思想时需要重点考虑的。

    函数描述了自然界中数量之间的关系,函数思想通过提出问题的数学特征,建立函数关系型的数学模型,从而进行研究。它体现了“联系和变化”的辩证唯物主义观点。一般地,函数思想是构造函数从而利用函数的性质解题,经常利用的性质是:f(x)、f (x)的单调性、奇偶性、周期性、最大值和最小值、图像变换等,要求我们熟练掌握的是一次函数、二次函数、幂函数、指数函数、对数函数、三角函数的具体特性。在解题中,善于挖掘题目中的隐含条件,构造出函数解析式和妙用函数的性质,是应用函数思想的关键。对所给的问题观察、分析、判断比较深入、充分、全面时,才能产生由此及彼的联系,构造出函数原型。另外,方程问题、不等式问题和某些代数问题也可以转化为与其相关的函数问题,即用函数思想解答非函数问题。

    函数知识涉及的知识点多、面广,在概念性、应用性、理解性都有一定的要求,所以是高考中考查的重点。我们应用函数思想的几种常见题型是:遇到变量,构造函数关系解题;有关的不等式、方程、最小值和最大值之类的问题,利用函数观点加以分析;含有多个变量的数学问题中,选定合适的主变量,从而揭示其中的函数关系;实际应用问题,翻译成数学语言,建立数学模型和函数关系式,应用函数性质或不等式等知识解答;等差、等比数列中,通项公式、前n项和的公式,都可以看成n的函数,数列问题也可以用函数方法解决。

    等价转化

    等价转化是把未知解的问题转化到在已有知识范围内可解的问题的一种重要的思想方法。通过不断的转化,把不熟悉、不规范、复杂的问题转化为熟悉、规范甚至模式法、简单的问题。历年高考,等价转化思想无处不见,我们要不断培养和训练自觉的转化意识,将有利于强化解决数学问题中的应变能力,提高思维能力和技能、技巧。转化有等价转化与非等价转化。等价转化要求转化过程中前因后果是充分必要的,才保证转化后的结果仍为原问题的结果。非等价转化其过程是充分或必要的,要对结论进行必要的修正(如无理方程化有理方程要求验根),它能给人带来思维的闪光点,找到解决问题的突破口。我们在应用时一定要注意转化的等价性与非等价性的不同要求,实施等价转化时确保其等价性,保证逻辑上的正确。

    著名的数学家,莫斯科大学教授C.A.雅洁卡娅曾在一次向数学奥林匹克参赛者发表《什么叫解题》的演讲时提出:“解题就是把要解题转化为已经解过的题”。数学的解题过程,就是从未知向已知、从复杂到简单的化归转换过程。

    等价转化思想方法的特点是具有灵活性和多样性。在应用等价转化的思想方法去解决数学问题时,没有一个统一的模式去进行。它可以在数与数、形与形、数与形之间进行转换;它可以在宏观上进行等价转化,如在分析和解决实际问题的过程中,普通语言向数学语言的翻译;它可以在符号系统内部实施转换,即所说的恒等变形。消去法、换元法、数形结合法、求值求范围问题等等,都体现了等价转化思想,我们更是经常在函数、方程、不等式之间进行等价转化。可以说,等价转化是将恒等变形在代数式方面的形变上升到保持命题的真假不变。由于其多样性和灵活性,我们要合理地设计好转化的途径和方法,避免死搬硬套题型。

    在数学操作中实施等价转化时,我们要遵循熟悉化、简单化、直观化、标准化的原则,即把我们遇到的问题,通过转化变成我们比较熟悉的问题来处理;或者将较为繁琐、复杂的问题,变成比较简单的问题,比如从超越式到代数式、从无理式到有理式、从分式到整式…等;或者比较难以解决、比较抽象的问题,转化为比较直观的问题,以便准确把握问题的求解过程,比如数形结合法;或者从非标准型向标准型进行转化。按照这些原则进行数学操作,转化过程省时省力,有如顺水推舟,经常渗透等价转化思想,可以提高解题的水平和能力。

    分类讨论

    在解答某些数学问题时,有时会遇到多种情况,需要对各种情况加以分类,并逐类求解,然后综合得解,这就是分类讨论法。分类讨论是一种逻辑方法,是一种重要的数学思想,同时也是一种重要的解题策略,它体现了化整为零、积零为整的思想与归类整理的方法。有关分类讨论思想的数学问题具有明显的逻辑性、综合性、探索性,能训练人的思维条理性和概括性,所以在高考试题中占有重要的位置。

    引起分类讨论的原因主要是以下几个方面:

    ①问题所涉及到的数学概念是分类进行定义的。如|a|的定义分a>0、a=0、a<0三种情况。这种分类讨论题型可以称为概念型。

    ②问题中涉及到的数学定理、公式和运算性质、法则有范围或者条件限制,或者是分类给出的。如等比数列的前n项和的公式,分q=1和q≠1两种情况。这种分类讨论题型可以称为性质型。

    ③解含有参数的题目时,必须根据参数的不同取值范围进行讨论。如解不等式ax>2时分a>0、a=0和a<0三种情况讨论。这称为含参型。

    另外,某些不确定的数量、不确定的图形的形状或位置、不确定的结论等,都主要通过分类讨论,保证其完整性,使之具有确定性。

    进行分类讨论时,我们要遵循的原则是:分类的对象是确定的,标准是统一的,不遗漏、不重复,科学地划分,分清主次,不越级讨论。其中最重要的一条是“不漏不重”。

    解答分类讨论问题时,我们的基本方法和步骤是:首先要确定讨论对象以及所讨论对象的全体的范围;其次确定分类标准,正确进行合理分类,即标准统一、不漏不重、分类互斥(没有重复);再对所分类逐步进行讨论,分级进行,获取阶段性结果;最后进行归纳小结,综合得出结论。

    数形结合

    中学数学的基本知识分三类:一类是纯粹数的知识,如实数、代数式、方程(组)、不等式(组)、函数等;一类是关于纯粹形的知识,如平面几何、立体几何等;一类是关于数形结合的知识,主要体现是解析几何。

    数形结合是一个数学思想方法,包含“以形助数”和“以数辅形”两个方面,其应用大致可以分为两种情形:或者是借助形的生动和直观性来阐明数之间的联系,即以形作为手段,数为目的,比如应用函数的图像来直观地说明函数的性质;或者是借助于数的精确性和规范严密性来阐明形的某些属性,即以数作为手段,形作为目的,如应用曲线的方程来精确地阐明曲线的几何性质。

    恩格斯曾说过:“数学是研究现实世界的量的关系与空间形式的科学。”数形结合就是根据数学问题的条件和结论之间的内在联系,既分析其代数意义,又揭示其几何直观,使数量关的精确刻划与空间形式的直观形象巧妙、和谐地结合在一起,充分利用这种结合,寻找解题思路,使问题化难为易、化繁为简,从而得到解决。“数”与“形”是一对矛盾,宇宙间万物无不是“数”和“形”的矛盾的统一。华罗庚先生说过:数缺形时少直观,形少数时难入微,数形结合百般好,隔裂分家万事休。

    数形结合的思想,其实质是将抽象的数学语言与直观的图像结合起来,关键是代数问题与图形之间的相互转化,它可以使代数问题几何化,几何问题代数化。在运用数形结合思想分析和解决问题时,要注意三点:第一要彻底明白一些概念和运算的几何意义以及曲线的代数特征,对数学题目中的条件和结论既分析其几何意义又分析其代数意义;第二是恰当设参、合理用参,建立关系,由数思形,以形想数,做好数形转化;第三是正确确定参数的取值范围。

    数学中的知识,有的本身就可以看作是数形的结合。如:锐角三角函数的定义是借助于直角三角形来定义的;任意角的三角函数是借助于直角坐标系或单位圆来定义的。

    展开全文
  • 什么是中心做市机器人

    千次阅读 2021-07-13 09:54:57
    中心做市机器人 币圈的朋友对交易所做市机器人应该都不陌生,简单来说就是可以代替人工交易或者说植入了人工的做市思想来实现某种做市策略。 做市,通俗的说就是刺激交易。 因为有时某些小币种交易量太少,...
  • 中心结构的相关理解

    千次阅读 2021-03-23 12:18:02
    中心结构前言一、C/S架构二、中心架构总结 前言 中心结构可以与C/S(Client/Server)架构,客户机与服务器这种衣服武器为中心的架构进行对比学习。 一、C/S架构 C/S架构如下图所示: 将整个应用托辊...
  • 四大数学思想

    千次阅读 2021-01-17 13:46:41
    主流的说法,数学思想有四大:函数与方程思想、分类讨论思想、数形结合思想归与转化思想.咦,好像什么行业都有四大?四大名捕,四大天王,四大会计师事务所,四大名著......额,可能四个好记吧.一、函数与方程...
  • 读《Java编程思想第五版》心得体会

    千次阅读 多人点赞 2021-09-20 13:20:58
    而且,日渐网络的今天,转行培训的人也比比皆是,这里不是说转行者不好,而是,转行者在经过培训班速成之后,他们只学到了如何应用Java,如何在一个项目中胜任一个角色,但大多数人都不了解代码的来龙去脉,为...
  • 结构开发方法

    千次阅读 2021-03-15 15:08:47
    目录 一、概述 二、结构分析 1、结构分析步骤 (1)研究“物质环境” (2)建立系统逻辑模型 ...三、结构设计 ...1、抽象 ...结构方法由结构分析、结构设计、结构程序设计构成,它是
  • 点击蓝字关注我们AI TIME欢迎每一位AI爱好者的加入!神经元或卷积核之间的强相关性会大幅削弱神经网络的泛化能力。本文提出使归一后的权重向量在单位超球面上尽可能分布均匀,从而减弱其相...
  • 你不可不知的数学四大思想方法

    千次阅读 2021-01-17 13:46:48
    名师指导合肥一中 高级教师 杜明成数学在培养和提高考生的思维能力方面有着其他学科不可代替的独特作用,这是因为数学不仅是一种重要的“工具”和“方法”,而且是一种思维模式,这表现为数学思想.高考试题十分重视对...
  • 三字棋的实现以及模块思想

    千次阅读 多人点赞 2021-11-08 17:52:38
    文章目录模块思维:...因此许多的软件开发企业提出了模块思想,用来减少维护成本低增加,增加程序的可读性,和可维护性 本小编用模块思维量实现三字棋的实现 首先进行主函数的书写 void test(void); int main
  • 学习一门知识,究其核心,主要是学其思想和方法,这是学习的精髓。学数学亦如此,分学数学思想和数学方法。数学思想是指客观世界的空间形式和数量关系反映到人们的意识之中,经过思维活动而产生的结果。数学思想是对...
  • 一、简介 从前一篇下来,有一段时间没有更新了,那是因为在界面自动伸缩中,我遇到了自动伸缩的功能。本文的目的就是帮助大家如何实现当我们自动拖拉tk窗口时,GUI可以自动伸缩。 我们的目的很简单,就是类似...
  • 组件学习(1)思想及实现方式

    千次阅读 2021-12-01 09:39:53
    1.组件的介绍 我认为组件,就是整个项目由app外壳,若干业务组件,以及公共基础组件构成。如图所示 我认为组件最明显的特点就是:各个业务模块之间没有直接的横向依赖。 意义:不相互依赖,但是可以相互交互...
  • 文章目录为什么要进行数据归一什么是数据归一最值归一(Normalization)最值归一的适用性均值方差归一(Standardization)为什么要这么归一呢?参考文献 为什么要进行数据归一 我们来考虑这样一个场景...
  • 1冯诺依曼体制中最核心的思想是计算机采用 (14页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦!14.9 积分一、填空题1. 冯?诺依曼体制屮最核心的思想是计算机采川 工作...
  • 1、冯·诺依曼计算机工作原理的设计思想是 (???? )。A.程序设计B.程序存储C.程序编制D.算法设计【】【】语言是用来编程计算机程序的工具,有高级语言(如VB、VFP)和低级语言(汇编语言、机器语言)之分。程序是...
  • 甚至因为开发人员编写的代码的问题从而提升 了自动脚本编写的难度,需要花费大量的时间解决一些脚本编写过程中遇到 的一些未知的问题,那么这种情况下,手工测试往往要比自动测试要更有效率。 1.3 手工测试与...
  • 一文带你了解 Spark 架构设计与原理思想

    千次阅读 多人点赞 2021-11-04 12:42:21
    Spark 架构设计与原理思想,性能调优与故障处理 ...
  • 一、背景 图像分类是深度学习中常见的任务,在进行模型的训练时,经常需要对图片进行一些预处理后... 中心是将每个像素减去图像中所有像素的均值,使得变换后的图像的所有像素的均值变为0,因此有时候也称作0均...
  • 冯诺依曼的设计思想是什么冯.诺依曼计算机的工作原理冯.诺依曼计算机结构的基本思想是冯.诺依曼计算机结构的基本思想是冯.诺依曼计算机体系结构的基本思想是什么冯诺依曼结构计算机工作原理的核心哈佛结构 哈佛结构...
  • 数据聚焦于数据的采集、清理、预处理、分析和挖掘,图形聚焦于解决对光学图像进行接收、提取信息、加工变换、模式识别及存储显示,可视聚焦于解决将数据转换成图形,并进行交互处理。 信息:是数据的内涵,信息是...
  • 什么是模块 简单说就是把系统分成各个独立的部分,每个部分单独实现功能,将系统分割成可独立的功能部分。 随着MVC等框架、微服务等技术的兴起,模块开发已经称为必须。web前端也已经演变称为大前端。 模块...
  • 这种库存管理策略打破了各自为政的库存管理模式,有效地控制了供应链的库存风险,是一种新的有代表性的库存管理思想。联合库存管理(Jointly Managed Inventory,JMI),是一种在VMI的基础上发展起来的上游企业和下游...
  • 版权声明1. 本站文章和资源均来自互联网收集和整理,本站不承担任何责任及版权问题。2. 相关版权归作者及其公司所有,仅供学习研究用途,请勿用于...​内容简介······本书是《《Spring Boot编程思想(核心篇...
  • 前端 vue 在可视大屏领域的工作实践

    千次阅读 多人点赞 2021-06-08 01:13:33
    导读:最近入职了一家互联网公司,主要是做物联网及互联网解决方案方向,我上来就接手了这个项目,是一个可视管理地图,主要用于某国企物业的安全预警的职能,说来也比较倒霉,刚来这公司,公司做这个...
  • 深度学习中的9种归一方法概述

    千次阅读 2021-01-29 10:27:06
    9 种 归一(Normalization)方法概述
  • “收缩”就是“软阈值”,是许多信号降噪方法的核心步骤。 深度残差收缩网络也是一种“注意力机制”下的深度学习算法。其软阈值所需要的阈值,本质上是在注意力机制下设置的。 在本文中,我们首先对残差网络、...
  • 什么是模块代码?如何写?

    千次阅读 2020-12-24 12:26:20
    关注、星标公众号,直达精彩内容ID:技术让梦想更伟大作者:李肖遥随着我们工程经验的增加,不知不觉的我们就会关心到这个问题,模块,模块设计就显现出来,那到底什么是模块呢?这不叫模块...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 903,132
精华内容 361,252
关键字:

去思想化