CAM自动化助力PCB智能制造

该文章已生成可运行项目,

CAM智能化助力PCB智能制造

文章目录


前言

古语云:路漫漫其修远兮,吾将上下而求索!

  • 二十一世纪二十年代了,科技发展日新月异,所有的事物都在快速发展,人类的文明也得到了极大的繁荣,唯一不变的是美帝国主义亡我之心不死,作为红旗下茁壮成长的我终于不再是早上八九点钟的太阳,我现在至少是中午的太阳.我有一个梦想,我希望世界和平,梦想太大风浪大,我没出过海经不起什么大风大浪,这个梦想我肯定实现不了,人贵要有自知之明,踏着梦想砥砺前行我肯定说得到,做不做得到我不知道,但是我坚信还是要先做,怕死不死不成立,我们追求稳步前进但是一定心怀远大梦想,梦想一定是我们前进道路的方向,失去梦想的人注定只能行尸走肉.
    正所谓敢想敢干,说干就干.首先,我介绍一下我自己,本人生于红旗下,成长于天地间,自呱呱坠地就使得我家倾家荡产,没有错,我就是计划生育的非计划人口,30年前的国家负担,30年后生育的主力,生我嫌多,我生嫌少,我的成长过程自然而又充满变革,时代的红利都完美的避开,我就是悲催的80后,成长在大变革大发展的30年,如今新的30年已经重新开启,我们的国家已经走完由穷到富的历史征程,接下来将进入由富到强新的发展阶段,新的变革潮流已经形成,墨守成规者必定会在新潮流新趋势下被淘汰,敢于革新者必将成为下一阶段的领头羊,各行各业无所不一,做为一名合格的搬砖人员或者行业沙子能拿3K还是30K每月考验的不光是你的智慧,更是眼界与胆识.
    PCB制造业在国内已经取得长足的进步及发展,随着产品种类的丰富多样及生产工艺能力的不断提升,对工程前端生产指示及工具设计都提出了更高的要求,如何提高效率,品质将是制前工程永恒的课题,作为PCB制前工程自动化资深从业人员,我无时无刻不在思考这个课题,以我之浅见,完成课题核心在于“解放思想,开拓眼界,大胆实施,强力执行”!解放何种思想?1.效率不够人来凑,人手不够加班凑;2.改变工程部门在工厂处于辅助部门的认知,改变系统开发人员在工程处于辅助人员甚至服务员的认知;以我为主,坚持系统化,自动化,智能化!

一、系统化

1.定义

  • 将工作分割细化,以点带面,使复杂的笼统的工作分割为有组织有结构的具体的工作细则,简而言之,化繁为简,以量变产生质变,以质变产出奇效.

2.思考

  • 如何系统化?
    答:首先将工作按职责划分并分类,然后将分类后的工作分割成单元模块,再次将单元模块具体操作步骤化,最后将每步执行脚本化.

  • 能否详细说明?
    答:举例说明,CAM自动化系统,单凭字面仅能泛化理解,并不能直观的感受及认识什么是自动化系统,接下来用思维导图的方式给大家展示:
    在这里插入图片描述

    • 如上图所示,我们看到的所有模块汇总就叫CAM自动化系统,样例中又包含三大子系统或者子模块,子系统又包含更小的颗粒系统或者模块,以此不停的细化分割直至到最小的分支或者颗粒,如果以人为例,我们就可以称之为"人类生物系统",所以CAM自动化系统并不是简单的脚本程式汇总,而是一个相对庞大的需要统一协调的达成一至执行的框架性执行合集,从来就不是所谓"系统人员"一个人的事,而是一整个部门甚至全公司更甚至全行业同行的事情,我们将这个系统分拆组合,细化分类的整个过程就做系统化,系统化是自动化实施的基石,没有经过系统化的自动化我们称之为形式自动化,并不能真正解决根本问题,没有有效组织及规范要求的自动化程式,功能再强大也仅仅只是功能强大,就如一堆无组织无纪律的散兵游勇,再勇敢也只是散兵游勇,并不能发挥出团队合作的效能.

3.方法

  • 学会使用工具,使用何种工具?
    首先人与动物最大的区别在于人会使用工具及易于沟通交流,21世纪的工具是相当丰富的,掌握更多的资源及工具就能掌握先机,就能实现利益最大化,所有人在社会的阶层地位都是由个人掌握的资源和能力来决定的,我们说的能力就是对各类工具的使用能力及与任何对象的沟通能力,任何一种能力都能使我们获取更多的资源,所以任何时候都要对自己的能力有清晰的认知.
    综上所述,我们在工作中学会使用各类工具,掌握更多工具使用技巧,学会沟通交流就会让你在同行中抢得先机.
    回到正题,我们在系统化的过程中使用何种工具,本人极力推荐思维导图软件XMind,
    这是一款功能强大且易掌握使用的多平台国产软件,当然还有许多类似的功能软件大家可以自行搜索选择合适自己的即可.
    下面我们看看用思维导图软件整理后的CAM系统人员工作及管理事项,会不会将我们的思维具象化,让所有人都能懂你在做什么,你要做什么,你要怎么做.
    在这里插入图片描述
    • 以上我们讲到了思维导图工具的使用及思维具象化的方法,接下来我们学习使用工具将我们要做的事情变成有组织有结构有计划的可执行的任务(维护计划和项目开发计划),使用企业微信的公司我强烈推荐直接在企业微信中搞定一切,没有企业微信也不用慌,我们可以使用WPS,方法是一样的,企业微信集成了我们制作项目的所需的一切软件功能,如思维导图,流程图,excel,工作群组搭建,线上会议及任务追踪等.
    • 如下图,我们制作一个需求的处理的周工作任务计划,任务计划包含了周制作项目及时间计划,同时我们还可以添加所有需要关注周计划的相关人员,真正做到信息实时共享,进度全盘掌握.
      在这里插入图片描述

二、标准化

1.人员的标准化管理

  • 团队的搭建及分工

    工程PIE开发维护
    提出,测试,执行需求整理规范及标准方案制定,项目开发及文档编写项目维护升级及培训
  • 建立项目开发标准流程图
    在这里插入图片描述

  • 1.3.团队的管理
    自动化的实施分为开发和维护两个过程,团队的建立并不是传统的某个专门部门,一般实施会建立项目部门,这样做的好处在于,统一协调,统一行动,让各职能部门真正发挥各自领域的专业性,团队核心能力说明:

    • (1).工程部门熟悉运作流程及制作要求,部分优秀人员的操作经验就是良好的自动化实施基础,但是并不是所有的人员能力及经验都是全面的,均衡的,工程负责人也并不是全能,建立项目组的目的就是让优秀的人员及良好的经验都能参与到实施的过程中来,让优秀的个人经验变成优秀的团队经验,既能提升团队协作能力,也能让的用户全程参与实施,做一名参与者而不是机械的执行人员或者旁观者,总而言之就是充分挖掘工程人员的潜力及充分利用良好的经验;
    • (2).PIE部门作为成本管控及标准制定的担当可以为团队的标准化管理及规范管理提供专业的助力,从体系端规范自动化实施的管理标准,让一切项目的执行都是有据可查,有规可依,避免项目制作规则混乱及不成文靠嘴上说的问题出现;
    • (3).软件部开发组,作为实际的实施部门,根据需求及规则制定详细的实施及开发计划,让所有的需求及规范都能变为实际可操作的程式代码,这个过程控制一般会要求制定专业的项目制作甘特图,以便大家都是能实时的掌控项目的进度;
    • (4).软件部维护组,任何项目的开发完结并不能代表整个项目的完结,所有的需求及规则都是动态的,需要专业的系统维护人员根据需求部门的反馈,及时完善,优化及导入新的规则.
    • 综上所述,自动化项目的实施都会分为两个阶段,开发阶段及维护阶段,项目的团队管理并不是以固定部门职责来定义,而是以项目负责人为核心来管理运行,如何选定项目负责人自然是以对项目的理解,掌控及实施能力来定义,这样能有效避免一言堂及屁股指挥大脑的情况发生.
  • 1.4.系统人员的培训(以Centos7/InCAMPro/Python3/PyQt5环境为主)
    专业的人做专业的事,专业的人员培养必不可少,任何时候掌握人才培养的能力永远比找寻人才更能抢占先机,培训课程及计划必须安排上:

    前章.专业人员培训

    人员培训课程表
    章节课程小节关键点课时
    第一章.Linux系统学习第1课.系统安装1.虚拟机安装(Windows)掌握虚拟机基本配置60min
    2.Centos7系统镜像下载安装分区只做引导分区,内存交换分区,根分区60min
    第2课.系统配置1.网络配置了解网络配置10min
    2.SMB共享服务配置掌握SMB服务配置10min
    3.NFS共享服务配置掌握NFS服务配置10min
    4.VNCSERVER服务配置掌握vncservers服务配置30min
    5.自动任务配置掌握crontab配置及原理30min
    第3课.常用命令1.Centos7常用终端指令cd,df,ps,ls,ln,su,cp,mv,scp,ssh,rm,touch,mkdir60min
    第4课.vim编辑器1.vim基础操作掌握vim基本操作30min
    第二章.开发环境配置第5课.安装Anaconda3(Python3)1.Anaconda安装了解为什么选择Anaconda30min
    2.Python3环境配置不能覆盖系统原有Python环境,会影响系统10min
    第6课.常用的Python模块安装1.PyQt5图像界面模块安装conda安装和pip安装10min
    2.pymysql/pymssql数据库操作模块安装掌握常用数据库操作模块的安装10min
    3.xlrd/xlwt库安装掌握常用excel处理模块的安装10min
    4.其他常用库安装掌握常用处理模块的安装10min
    第7课.安装集成开发工具(PyCharm)1.PyCharm安装掌握集成开发软件的安装配置10min
    2.PyCharm常规设置一些常用的插件及AI插件,集成环境的配置20min
    3.PyCharm配置Python环境虚拟环境及本地环境10min
    4.PyCharm下安装Python第三方模块掌握集成开发环境下常用模块的安装方法10min
    第8课.安装数据库(MySQL/SQLServer)1.安装CentOS时自动安装装MySQL数据库服务掌握系统安装时的一些必要服务同步安装10min
    2.MySQL数据库服务常规安装配置掌握Linux下的MySQL数据库安装20min
    3.SqlServer数据库服务安装配置掌握Windows下Sql Server数据库的安装20min
    第9课.安装navicat(数据库操作客户端)1.数据库操作客户端navicat安装掌握数据库客户端软件navict的安装及激活10min
    2.navicat配置数据库连接掌握客户端连接数据库的基本操作10min
    3.navicat常规操作掌握通过客户端对数据库的查改增删基本操作10min
    第10课.CAM软件脚本语言环境配置1.解释型语言脚本运行配置文件讲解掌握奥宝CAM软件脚本运行机制10min
    2.编译型型语言脚本运行配置文件讲解/10min
    第11课.Git安装配置1.下载安装Git程序了解git的作用,掌握基本的代码托管操作10min
    2.配置Git用户信息/10min
    3.上传并提交代码(gitee代码托管平台)/10min
    4.下载托管的代码(gitee代码托管平台)/10min
    第12课.Svn安装配置1.下载安装Svn程序了解Svn的作用,掌握基本的代码托管操作10min
    2.配置Svn用户信息/10min
    3.上传并提交代码(本地服务器)/10min
    4.下载托管的代码(本地服务器)/10min
    第三章.工程软件学习第13课.Genesis2000/InCAM/InCAMPro安装配置1.Genesis2000安装(Windows)理解各个模块的基本功能和配置方法10min
    2.Genesis2000安装(CentOS)掌握Linux下genesis服务配置30min
    3.InCAM/InCAMPro安装(CentOS)掌握Linux下incam服务配置及License配置30min
    4.CAM软件服务端配置理解服务端与客户端的异同30min
    第14课.Genesis2000/InCAM/InCAMPro操作基础1.操作界面及功能模块介绍了解软件基本操作(功能模块对照)10min
    2.基本操作演示掌握最基本的操作功能30min
    3.进阶操作演示掌握一些技巧性的操作30min
    第15课.Genesis2000/InCAM/InCAMPro系统参数1.系统参数设置掌握系统常规参数设置15min
    2.自定义功能及界面设置掌握快捷键及自定义功能的添加设置15min
    3.软件Library管理及配置掌握系统常规参数设置15min
    4.系统管理员模块配置掌握系统管理员模块参数设置15min
    第16课.Genesis2000/InCAM/InCAMPro基础命令1.常用LMC的录制掌握原始代码基本获取方式及转化方式30min
    2.完整的LMC参数查询掌握完整原始代码获取方式及查询官方文档10min
    3.LMC及Line_Hooks防呆指令掌握软件防呆设计原理及使用时机20min
    第四章.系统维护学习第17课.Linux系统常见异常问题汇总1.操作系统相关掌握常规的系统维护事项10min
    2.CAM软件掌握CAM软件常用的维护事项20min
    3.系统磁盘空间容量异常掌握磁盘空间自动监控及管理方法30min
    第五章.脚本开发学习第18课.Python3基础1.Python3环境搭建掌握Python3语言环境的搭建10min
    2.PyCharm开发环境配置掌握Python3开发环境的搭建10min
    3.Python3基础语法掌握Python3基础语法30min
    4.Python3数据类型理解字符串,数值,元组,列表,集合,字典类型20min
    5.Python3数据类型转换掌握数据类型之间的相互转换方法10min
    6.Python3注释掌握Python3的注解方式并灵活应用10min
    7.Python3运算符掌握Python3的常用运算符10min
    8.Python3条件控制掌握Python3的条件控制语句10min
    9.Python3循环语句掌握Python3的循环控制语句10min
    10.Python3推导式理解并能灵活应用推导式10min
    11.Python3函数理解函数的基本结构10min
    12.Python lambda(匿名函数)理解lambda函数并掌握一些常见的应用场景10min
    13.Python3数据结构理解Python3数据结构的基本操作10min
    14.Python3模块掌握模块的导入及基本调用方法10min
    15.Python3输入和输出掌握常用的格式化方法(%, ‘{0}’.fomat(a)等)10min
    16.Python3文本处理掌握文本处理的基本操作及异常处理10min
    17.Python3模块之OS(文件/目录方法)掌握最常用的OS模块基本操作10min
    18.Python3错误和异常掌握程式异常处理机制10min
    第19课.Python3进阶1.Python3面向对象理解面向对象思想及面向对象编程的好处20min
    2.Python3命名空间和作用域了解Python3关键字,掌握命名规则及作用域10min
    3.Python3标准库了解Python3标准库及熟练使用常见标准库10min
    4.Python3实例掌握Python3编程基本技能30min
    5.Python测验检验Python3编程基本技能水平30min
    第20课.Python3高阶1.Python3正则表达式掌握常用的正则表达式写法基本检验方法30min
    2.Python数据库连接驱动之MySQL掌握Pyhton3对MySQL数据库的驱动及操作20min
    3.Python数据库连接驱动之Sql Server掌握Pyhton3对Sql Server数据库的驱动及操作10min
    4.Python3邮件发送之SMTP掌握Pyhton3自动发送邮件的处理方式30min
    5.Python3多线程掌握Pyhton3多线程编程10min
    6.Python3数据解析之XML掌握Pyhton3对XML的解析10min
    7.Python3数据解析之JSON掌握Pyhton3对JSON的解析10min
    8.Python3日期和时间处理掌握Pyhton3对日期及时间的处理10min
    9.Python3内置函数了解Python3常用内置函数10min
    10.Python3模块安装工具之pip掌握pip工具的操作10min
    11.Python3模块之urllib了解Python3网页URL操作及网页内容处理30min
    12.Python3模块之operator了解operator模块基本应用场景10min
    13.Python3模块之math了解math模块基本数学运算函数10min
    14.Python3模块之requests掌握requests模块调用WebApi10min
    15.Python3模块之random理解模块主要用于生成随机数10min
    16.Python3模块之PyQt5掌握模块并能灵活的开发出各种交互界面60min
    17.Python3模块之pymysql/pymssql掌握模块并能轻松的通过模块操作数据库30min
    第21课.Python3编程实战开发(CAM脚本开发)1.自定义基础接口包IncamClasses.py理解Python3连接CAM软件的基础命令模块30min
    2.自定义基础接口包InfoClasses.py掌握模块基本结构及扩展方法,灵活应用与开发30min
    3.自定义基础接口包LcmClasses.py掌握模块基本结构及扩展方法,灵活应用与开发30min
    4.自定义基础接口包MainClasses.py掌握模块基本结构及扩展方法,灵活应用与开发10min
    5.自定义基础接口包JobClasses.py掌握模块基本结构及扩展方法,灵活应用与开发30min
    6.自定义基础接口包sendMail.py掌握模块基本结构及扩展方法,灵活应用与开发30min
    7.自定义基础接口包GuiClasses.py掌握模块基本结构及扩展方法,灵活应用与开发30min
    8.自定义基础接口包SqlClasses.py掌握模块基本结构及扩展方法,灵活应用与开发30min
    9.自定义基础接口包TextClasses.py掌握模块基本结构及扩展方法,灵活应用与开发30min
    10.自定义基础接口包FileClasses.py掌握模块基本结构及扩展方法,灵活应用与开发30min
    11.自定义基础接口包gatewayClasses.py理解模块与IncamClasses.py的异同10min
    12.牛刀小试(切换InCAMPro系统单位)掌握基本的脚本开发能力10min
    13.往前一步(自动添加Pad脚本)进一步掌握脚本开发能力10min
    14.加快脚步(有交互的添加Pad脚本)掌握基本的交互界面脚本开发能力10min
    15.奔跑向前(自动交互的添加Pad脚本)掌握基本的自动界面交互脚本开发能力30min
    16.破风而行(模块化的系统开发)掌握脚本开发能力的同时掌握脚本的扩展能力10min
    17.顺势而上(面向AI编程)了解新的科技所带来的效率提升20min
    第22课.Python3编程实战开发(Line_Hooks开发)1.如何用Python3来开发Line_Hooks脚本理解奥宝CAM软件的脚本运行机制及防呆机制10min
    2.实战操作(新建料号防呆脚本开发)掌握前置,后置防呆脚本的开发20min
    3.实战操作(用户操作记录)理解奥宝CAM软件的保存机制及日志存储方式20min
    4.实战操作(建立料号履历)理解软件机制,利用Line_Hooks做一些灵活操作30min
    5.实战操作(让用户无法犯错)掌握主动防呆,过程防呆,替用户把住易错点30min
    6.实战操作(让用户无感操作)掌握主动防呆,过程防呆,替用户做一些常用操作30min
    7.实战操作(让用户只做该做的事)掌握主动防呆,过程防呆,替用户规划好操作权限30min
    第23课.Python3编程实战开发(脚本全自动执行)1.奥宝CAM软件的无界面模式了解奥宝CAM软件无界面模式及常用场景10min
    2.实战操作(无界面输出tgz资料)掌握常用的无界面执行指令及脚本开发30min
    3.实战操作(无人值守输出tgz资料)掌握无人值守脚本的开发及应用30min
    第24课.Python3编程实战开发(外挂脚本执行)1.奥宝CAM软件的gateway执行模式了解奥宝CAM软件gateway指令及常用场景30min
    2.实战操作(通过外挂管理料号库)掌握通过外挂执行CAM脚本指令30min
    3.实战操作(通过外挂实现camguide)深入理解并充分利用gateway模式开发脚本60min
    第六章.项目开发学习第25课.快板系统项目详解1.项目建立及需求分析了解项目的概念及如何做需求分析20min
    2.项目小组建立及任务分解了解项目成员划分及任务分解规则20min
    3.项目计划制作及执行掌握项目计划甘特图及项目推进进度追踪方法20min
    4.了解项目整体架构及编程思想/10min
    5.外挂主体程式讲解掌握主体程式开发及功能架构10min
    6.外挂功能模块组成掌握功能模块开发方法10min
    7.外挂的扩展及维护掌握扩展方法及功能模块维护方法10min
    8.一切皆可外挂理解集成化界面带来的效率提升核心点10min

    第一章.Linux系统学习

    第1课.系统安装
    第1节.虚拟机安装(Windows)
    • 步骤1.VMware Workstation Pro下载: 下载地址

    • 步骤2.安装虚拟机软件(安装演示):

      注意事项:
      1.虚拟机硬件配置不能超过本机实际硬件配置;
      2.根据实际的需求选择硬件配置;
      3.新建虚拟机时可以先不装载ISO文件,待完成所有配置后在执行加载系统ISO文件安装.

      课后作业:

      • 下载VMware WorkStation Pro安装包。
      • 运行VMware WorkStation Pro安装包。
      • 安装VMware WorkStation Pro。
      • 输入许可证密钥(如果有)。
      • 完成安装并启动VMware WorkStation Pro。
      • 配置网络和虚拟机设置。
      • 开始使用VMware WorkStation Pro。
    第2节.Centos7系统镜像下载安装
    • 步骤1.CentOS7系统ISO镜像下载: 网易163镜像源下载地址

    • 步骤2.虚拟机安装CentOS7系统镜像(安装演示):

      • (1).选择配置好的虚拟机并添加下载好的操作系统镜像:

      • (2).启动虚拟机并安装CentOS7镜像文件:

      • (3).安装完成后进入CentOS 7系统的图形界面,默认使用kde桌面模式:

      注意事项:
      1.分区选择手动新建分区,只分(boot分区,内存交换swap分区及"/"根分区);
      2.安装时选择"带GUI的服务器"模式并且直接勾选全部服务模块安装;
      3.在安装过程中配置好普通用户及网络服务

      课后作业:

      • 下载CentOS 7系统ISO镜像安装包。
      • 安装CentOS 7系统ISO镜像。
      • 在安装过程中按要求完成系统配置。
      • 完成安装CentOS 7系统ISO镜像后进入KDE桌面。
    第2课.系统配置
    第1节.网络配置

    网络配置参考: 超详细CentOS7 NAT模式(有图形化界面)网络配置

    • 步骤1.查看网络状态
      首先,我们需要查看当前 CentOS 系统的网络状态。我们可以通过运行以下命令来检查网络状态:

      ip addr show
      

      该命令会列出所有网络接口及其配置信息。我们可以看到每个接口的 IP 地址、MAC 地址和状态等信息。如果系统上有多个网络接口,则需要查看每个接口的状态和配置。

    • 步骤2.配置网络接口
      如果您需要手动配置网络接口,则可以编辑 /etc/sysconfig/network-scripts/ifcfg- 文件。该文件包含系统的网络配置信息。其中 是网络接口的名称,例如 eth0。
      例如,如果您要配置 eth0 接口,可以使用以下命令编辑 /etc/sysconfig/network-scripts/ifcfg-eth0 文件:

      sudo nano /etc/sysconfig/network-scripts/ifcfg-eth0
      

      在该文件中,您可以设置 IP 地址、子网掩码、网关和 DNS 等信息。以下是一个样例配置文件:

      DEVICE=eth0
      TYPE=Ethernet
      ONBOOT=yes
      BOOTPROTO=static
      IPADDR=192.168.1.100
      NETMASK=255.255.255.0
      GATEWAY=192.168.1.1
      DNS1=8.8.8.8
      DNS2=8.8.4.4
      

      在该配置文件中,
      DEVICE 表示网络接口的名称,
      ONBOOT 设置为 yes 表示开机自动启用该接口,
      BOOTPROTO 设置为 static 表示手动配置 IP 地址,
      IPADDR 表示 IP 地址,
      NETMASK 表示子网掩码,
      GATEWAY 表示默认网关,
      DNS1 和 DNS2 表示 DNS 服务器地址。
      可以根据需要修改这些值。

    • 步骤3. 重启网络服务
      完成配置后,您需要重启网络服务以使更改生效。可以使用以下命令重启网络服务:

      sudo systemctl restart network
      

      该命令将会将新的配置文件写入系统,并重启网络服务以使更改生效。

    • 步骤4. 检查网络连接
      完成配置和重启后,您应该能够使用 ping 命令检查网络连接。例如,您可以使用以下命令 ping 网关 IP 地址:

      ping 192.168.1.1
      

      如果 ping 命令能够成功响应,则表示网络连接正常。

      注意事项:
      1.设置静态IP地址时确保IP没有被分配;
      2.网络设置时IPv6默认设置为忽略;
      3.IPv4设置网络默认设置为静态IP,具体的配置参数需由IT提供.

      课后作业:

      • 完成通过终端操作配置好CentOS7网络。
      • 完成通过操作界面配置好CentOS7网络。
    第2节.SMB共享服务配置
    • 步骤1.使用root权限登录到CentOS 7服务器:在这里插入图片描述在这里插入图片描述

      在普通用户终端输入"su"后回车;
      输入root密码后回车切换到root用户
      
    • 步骤2.使用root权限登录到CentOS 7服务器安装共享服务:
      使用命令yum install samba -y安装Samba软件包。

      yum  -y  install  samba
      

      结果截图如下:
      在这里插入图片描述

    • 步骤3.在Samba配置文件中定义共享目录:

      • (1).打开文件/etc/samba/smb.conf并添加以下行:
        其中,[share]为共享名称,comment为共享描述,path为共享目录的路径,browseable表示是否可浏览,writable表示是否可写入,guest ok表示是否允许匿名用户访问。
        vim  /etc/samba/smb.conf
        [centos7]
         comment = Centos7 DVD directory.  
         path = /media  
         public = yes  
         read only = yes
        
      • (2).输入上述内容,定义一个新的只读共享centos7:
        设置物理目录为 /media
        mkdir  /media
        mkdir  /media/cdrom/
        mount  /dev/cdrom  /media/cdrom/
        
    • 步骤4.挂载光盘到/meda/cdrom,以方便用户远程访问:
      使用命令systemctl start smb启动Samba服务,并使用systemctl enable smb设置开机自启。

      systemctl start smb (启动共享)
      testparm (确认参数没问题)
      

      完成上述结果截图如下:
      在这里插入图片描述

    • 步骤5.以账号(用户)访问共享:

      • (1).设置账号:
        useradd  vina
        pdbedit  -a  –u  vina
        (密码)
        (再输入密码)
        
        其中,vina是你自己定义的Samba用户名。你会被要求输入密码。
        结果截图如下:
        在这里插入图片描述
      • (2).设置安全访问:
        (防火墙配置:如果启用了防火墙,需要开放Samba服务的相关端口,包括TCP端口139和445,以及UDP端口137和138)
        systemctl  stop  firewalld
        setenforce  0
        sestatus  -b  | grep  samba (用命令可了解当前安全访问状态)
        
        结果截图如下:
        在这里插入图片描述
      • (3).测试访问:在另一台Windows客户端电脑上,使用Windows资源管理器访问该共享目录,输入Samba用户账号和密码,即可访问共享目录。
        在客户机访问共享打开一个窗口
        在地址栏输入\192.168. 168.129 (这里为自己虚拟机IP地址)
        在登录窗口输入用户名:vina(这里也为你自己设置的用户名,不可用中文),输入密码。
        打开光碟的共享名,看到文件后结果截图如下:在这里插入图片描述

      课后作业:

      • 下载并安装samba服务
      • 配置SMB服务并成功共享Linux系统目录到本机
    第3节.NFS共享服务配置
    • NFS共享服务配置:详细参考链接
    • NFS 网络文件系统,是一种使用于分布式文件系统的协议,功能是通过网络让不同的机器,不同的操作系统能够彼此分享各自的数据,让应用程序在客户端通过网络访问位于服务器磁盘中的数据,是在类Unix系统间实现磁盘文件共享的一种方法。
    • NFS服务器可以允许NFS客户端将远端NFS服务器端的共享目录挂载到本地的NFS客户端中,在本地的NFS客户端的机器看来,NFS服务器端共享的目录就好像自己的磁盘分区和目录一样。
    • NFS服务器是通过读取/etc/exports配置文件设定那个客户端可以访问那些NFS共享文件系统,如下我们提供了NFS的基本配置写法。
      [共享目录]    [允许谁来访问][权限]    [可用主机名][权限]    [其他主机权限]
      /nfs        192.168.1.1(rw)             localhost(rw)        *(ro,sync)
      /nfs        192.168.1.0/24(rw)       localhost(rw)        *(ro,sync)
      /nfs        192.168.1.1(rw)        192.168.1.2(ro)  192.168.1.3(ro,sync)
      
    • 步骤1.NFS服务端配置
      • (1).在配置NFS共享文件之前,我们先来放行NFS的几个常用服务,并将防火墙默认设置为拒绝状态.

        [root@localhost ~]# firewall-cmd --add-service=nfs
        [root@localhost ~]# firewall-cmd --add-service=mountd
        [root@localhost ~]# firewall-cmd --add-service=rpc-bind
        [root@localhost ~]# firewall-cmd --add-service=nfs --permanent
        [root@localhost ~]# firewall-cmd --add-service=mountd --permanent
        [root@localhost ~]# firewall-cmd --add-service=rpc-bind --permanent
        
      • (2).通过YUM仓库快速安装NFS相关的软件包.

        [root@localhost ~]# yum install -y rpcbind nfs-utils*
        Package rpcbind-0.2.0-47.el7.x86_64 already installed and latest version
        Package 1:nfs-utils-1.3.0-0.61.el7.x86_64 already installed and latest version
        Nothing to do
        
      • (3).创建需要共享的文件,并拷贝相关的文件内容,并设置SeLinux规则.

        [root@localhost ~]# mkdir -p /public
        [root@localhost ~]# chmod o+rw /public/
        [root@localhost ~]# chcon -R -t public_content_t /public/
        
      • (4).修改NFS主配置文件,并写入要访问的主机列表.

        [root@localhost ~]# vim /etc/exports
        /public 192.168.1.0/24(rw,sync)
        #[共享目录]    [允许谁来访问][权限]    [可用主机名][权限]    [其他主机权限]
        #/nfs        192.168.1.1(rw)        localhost(rw)        *(ro,sync)
        #/nfs        192.168.1.0/24(rw)    localhost(rw)        *(ro,sync)
        
      • (5).重启NFS服务,和守护进程,并设置开机自启动.

        [root@localhost ~]# systemctl restart nfs
        [root@localhost ~]# systemctl restart rpcbind
        [root@localhost ~]# systemctl enable nfs
        [root@localhost ~]# systemctl enable rpcbind
        [root@localhost ~]# systemctl restart nfs-server
        [root@localhost ~]# systemctl enable nfs-server
        
    • 步骤2.NFS客户端配置
      • (1).通过YUM仓库快速安装NFS相关的软件包.

        [root@localhost ~]# yum install -y rpcbind nfs-utils*
        Package rpcbind-0.2.0-47.el7.x86_64 already installed and latest version
        Package 1:nfs-utils-1.3.0-0.61.el7.x86_64 already installed and latest version
        Nothing to do
        
      • (2).创建挂载点,并设置SeLinux规则.

        [root@localhost ~]# mkdir -p /mnt/nfsmount
        [root@localhost ~]# chcon -R -t public_content_t /mnt/nfsmount
        
      • (3).手动挂载目录,可通过mount命令来实现,并将配置文件写入到开机自启动列表.

        # mount -t nfs -o 选项 服务主机:/服务器共享目录  /本地挂载没记录
        [root@localhost ~]# mount -t nfs -o rw,sync 192.168.1.5:/public /mnt/nfsmount
        [root@localhost ~]# df -hT |grep "public"
        
        Filesystem              Type      Size  Used Avail Use% Mounted on
        192.168.1.5:/public     nfs4       17G  1.9G   16G  12% /mnt/nfsmount
        
        [root@localhost ~]# vim /etc/fstab
        192.168.1.1:/public /mnt/nfsmount  nfs  default  0 0
        
      • (4).NFS提供了查看NFS共享状态的一系列命令.

        [root@localhost ~]# nfsstat        #显示服务端与客户端状态
        [root@localhost ~]# nfsstat -s     #只显示服务端状态
        [root@localhost ~]# nfsstat -c     #只显示客户端状态
        [root@localhost ~]# nfsstat -n     #仅显示NFS与RPC信息
        [root@localhost ~]# nfsstat -m     #显示挂载信息
        [root@localhost ~]# nfsstat -l     #以列表信息显示信息
        
        [root@localhost ~]# rpcinfo -m 127.0.0.1   #显示指定主机rpcbind操作列表
        [root@localhost ~]# rpcinfo -p 127.0.0.1   #显示指定主机RPC注册信息 
        [root@localhost ~]# rpcinfo -s             #显示所有RPC注册信息
        
        [root@localhost ~]# showmount -e 127.0.0.1  #显示服务器可用资源
        [root@localhost ~]# showmount -a 127.0.0.1  #查看所有客户链接信息
        [root@localhost ~]# showmount -d 127.0.0.1  #只显示客户输出信息
        
        [root@localhost ~]# exportfs -a   #全部挂载或卸载配置文件中的内容
        [root@localhost ~]# exportfs -r   #重新加载配置文件中的信息
        [root@localhost ~]# exportfs -u   #停止单一目录的共享
        [root@localhost ~]# exportfs -au  #停止所有服务端的共享
        [root@localhost ~]# exportfs -ra  #重新共享所有目录
        
      课后作业:
      • 下载并安装NFS服务
      • 配置NFS服务并成功共享Linux系统目录
    第4节.VNCSERVER服务配置

    原文链接

    • 步骤1.VNC 简介
      VNC(Virtual Network Computing) 是使用网络建立连接的一个虚拟桌面,用来远程操作计算机的一种技术,日常会有很多中场景需要远程来控制和操作服务器等计算机。

    • 步骤2. CentOS 安装 VNC Server
      在root用户下使用 yum 安装 tigervnc-server。

      # yum install tigervnc-server
      

      看到“完毕”则表示安装成功!

    • 步骤3. 配置 VNC Server
      拷贝一份 VNC 配置文件模板到如下目录。

      # cp /lib/systemd/system/vncserver@.service /etc/systemd/system/vncserver@:1.service
      
      • (1). 指定用户
        CentOS 7 需要编辑配置文件,修改 user 关键字为实际用户名;其它版本不需要进行该步骤。

        # sudo vim /etc/systemd/system/vncserver@:1.service
        

        在这里插入图片描述
        [例]:这里笔者的用户名为 imaginemiracle,该位置修改为对应的用户名即可。

      • (2). 启动对应配置文件的服务
        重新加载系统服务

        # systemctl daemon-reload
        

        开启该服务

        # systemctl start vncserver@:1
        

        开启自启动该服务

        # systemctl enable vncserver@:1
        
    • 步骤4. 开启 VNC Server
      切换到对应用户

      # su imaginemiracle
      

      执行 vncpasswd 配置 VNC 连接密码,这里不设置仅查看模式的密码,因为一般用不到仅查看的方式。
      在这里插入图片描述
      执行如下命令启动对应的 VNC Server

      $ vncserver :1
      

      注意:后面的 id 号即表示哪个桌面 id,其使用的端口号为 5900+id,如此处使用的端口号则为 5901,若使用防火墙则需要开放该端口,才可以连接。
      在这里插入图片描述

    • 步骤5. 连接使用

      • (1).新建连接
        在这里插入图片描述

      • (2).这里在 VNC Server 处填写 IP:ID,Name 处随意写。
        在这里插入图片描述

        注意:这里笔者使用的是之前的配置,若按照本文配置来,则这里的 id 需要改为 1。

      • (3).配置完成后,双击连接,若出现如下弹窗则说明 VNC Server 启动成功,其后面的 590X 表示该服务所使用的端口号。(5900 + ID)
        在这里插入图片描述

      • (4).点击继续并输入密码即可进入远程虚拟桌面
        在这里插入图片描述
        OK,连接成功!
        在这里插入图片描述

      日常处理:
      1.如何规避vnc密码限制必须6位字符及客户端免密登录vnc?
      答:进入用户终端,输入"vncpasswd -f 你的密码或者空字符 > /home/username/.vnc/passwd"后回车两次
      2.批量终止vnc窗口服务?
      答:进入用户终端,输入"pkill Xvnc"或者"pkill vncserver"
      $ vncpasswd -f incam > /home/incam/.vnc/passwd
      $ pkill Xvnc

      课后作业:

      • 下载并安装VNCSERVER服务
      • 配置VNCSERVER服务并成功共享Linux系统桌面
    第5节.自动任务配置
    • 在 centos7上使用crontab定时任务,自动定时执行脚本
      添加/编辑 Crontab

      crontab -e                        
      crontab [-u username] -e       
      默认情况下,系统会编辑当前用户的crontab命令集合
      

      查看Crontab

      crontab -l                        
      crontab [-u username] -l
      

      删除Crontab

      crontab -r                        
      crontab [-u username] -r   
      慎用。可以直接crontab -e 进行编辑
      

      载入

      crontab [-u user] file     
      将file做为crontab的任务列表文件并载入crontab                        
      如果在命令行中没有指定这个文件,crontab命令将接受标准输入(键盘)上键入的命令,并将它们载入crontab。
      

      配置路径

      /var/spool/cron/root (以用户命名的文件) 是所有默认存放定时任务的文件            
      /etc/cron.deny 该文件中所列出用户不允许使用crontab命令
      /etc/cron.allow 该文件中所列出用户允许使用crontab命令,且优先级高于/etc/cron.deny/var/log/cron    该文件存放cron服务的日志
      

      示例

      每五分钟执行  */5 * * * *        
      每105分钟执行一次        */105 * * * *            
      每小时执行     0 * * * *                        
      每天执行        0 0 * * *                        
      每周执行       0 0 * * 0                        
      每月执行        0 0 1 * *                        
      每年执行       0 0 1 1 *    
                        
      1.每天 02:00 执行任务                            
          0 2 * * * /bin/sh backup.sh                        
                            
      2.每天 5:00和17:00执行任务                            
          0 5,17 * * * sh /a.sh
                                  
      3.每分钟执行一次任务                            
          * * * * *  sh /a.sh
                                  
      4.每周日 17:00 执行任务                            
          0 17 * * sun  sh /a.sh
                                  
      5.每 10min 执行一次任务                            
          */10 * * * * sh /a.sh
                                  
      6.在特定的某几个月执行任务                            
          * * * jan,may,aug * /script/script.sh                        
                                  
      7.在特定的某几天执行任务                            
          0 17 * * sun,fri /script/scripy.sh                        
          在每周五、周日的17点执行任务                        
                                  
      8.在某个月的第一个周日执行任务                            
          0 2 * * sun  [ $(date +%d) -le 07 ] && /script/script.sh                            
                                  
      9.每四个小时执行一个任务                            
          0 */4 * * * sh /a.sh
                                  
      10.每周一、周日执行任务                            
          0 4,17 * * sun,mon sh /a.sh
                                  
      11.每30秒执行一次任务                                                
          * * * * * sh /a.sh
          * * * * *  sleep 30; sh /a.sh
                                  
      12.多个任务在一条命令中配置                            
          * * * * * sh /a.sh sh /b.sh
                                  
      13.每年执行一次任务                            
          @yearly sh /a.sh
          @yearly 类似于“0 0 1 1 *”。它会在每年的第一分钟内执行,通常我们可以用这个发送新年的问候。 
                                                     
      14.系统重启时执行                            
          @reboot sh /a.sh
                                  
      15.将 Cron 结果重定向的特定的账户                            
          默认情况下,cron 只会将结果详情发送给 cron     被制定的用户。如果需要发送给其他用户,可以通过如下的方式:                    
            # crontab -l                        
            MAIL=bob                        
            0 2 * * * /script/backup.sh       
      
    • 实战演练:

      • 项目需求:自动备份CAM资料库近三天有修改保存的料号(增量备份)
      • 执行时间:午夜00:30,中午12:30,下午18:00(每天三次)
      • 执行权限:root管理员用户
      • 执行模式:全自动执行
      • 信息推送:邮件&企业微信消息推送
      • 参考项目<PCB制前工程CAM资料日备份项目制作>

      课后作业:

      • 编写一个获取系统当前日期的脚本并自动发送邮件到指定邮箱
    第3课.常用命令
    • Centos7常用终端指令:
      CentOS7命令合集:查看网络博客1
      CentOS7命令合集:查看网络博客2
      示例

      cd
      #用法:
      cd    路径    
      #含义:(change directory,改变目录)
      #作用:用于切换当前的工作目录的
      
      ls
      #用法:
      ls    路径    
      #含义:(打开目录)
      #作用:用于打开当前的工作目录或者指定目录
              
      df        
      #用法:
      df -h
      #含义:查看磁盘分区空间使用情况
      #作用:检测磁盘空间使用情况
      #案例:益阳磁盘空间检测报警(当被监控空间容量达到80%时自动发送邮件报警,达到98%时自动锁死CAM资料制作保存功能,避免爆盘)
      
      ps
      #用法
      ps -ef | grep python3
      #含义:查看包含python3字符的进程信息
      #作用:清除死进程
      #案例:清除后台僵死的python3脚本(根据进程信息,kill相关的进程PID)        
      
      ln        
      #用法
      ln -s /opt/python/bin/python /usr/bin/mypython
      #含义:将/opt/python/bin/python解释器软链接为/usr/bin/mypython
      #作用:在不改变本身真实目录的情况下虚拟一个可用的路径或文件
      #案例:将自己的anaconda虚拟的python3解释器做为系统下的python3使用(ln -s /opt/anaconda/envs/python3.7.5/bin/python /usr/bin/python3)
      
      su
      #用法
      su incam
      #含义:切换到incam用户,当su后面不带任何参数时默认切换到root用户
      #作用:在一个终端下进入不同的用户并进行相关操作
      #案例:切换到普通用户incam
      
      cp
      #用法
      cp 指定文件 新文件
      cp /tmp/aaa /tmp/bbb
      #含义:将/tmp/aaa文件复制出一个/tmp/bbb文件
      #作用:复制文件或路径
      #案例:/
      
      mv
      #用法
      mv 指定文件 新文件
      mv /tmp/aaa /tmp/bbb
      #含义:将/tmp下的aaa文件改名为bbb文件
      #作用:修改文件(夹)名称,移动文件(夹)
      #案例:/
      
      scp
      #用法
      scp 服务器:目录文件 复制过来后存放的文件路径
      scp 172.20.7.19:/tmp/aaa /tmp
      #含义:将172.20.7.19/tmp下的aaa文件复制到本机/tmp下
      #作用:远程复制文件(夹)到本地
      #案例:/
      
      ssh
      #用法
      ssh root@服务器IP地址
      ssh root@172.20.7.19
      #含义:以root用户远程访问172.20.7.19服务器终端
      #作用:远程操作指定服务器终端
      #案例:以X模式进入172.20.7.19远端服务器启动genesis(ssh incam@172.20.7.19 -X; get启动Genesis2000)
      
      rm
      #用法
      rm 文件
      rm -rf /tmp/aaa
      #含义:直接删除/tmp下aaa文件或者文件夹
      #作用:删除指定文件(夹)
      #案例:/
      
      touch
      #用法
      touch 文件
      touch /tmp/aaa
      #含义:在/tmp下新建一个aaa文件
      #作用:新建文件
      #案例:/
      
      mkdir
      #用法
      mkdir 文件夹
      mkdir -p /tmp/aaa
      #含义:递归创建/tmp/aaa文件夹
      #作用:新建文件夹
      #案例:/
      
      source
      #用法
      source shell脚本文件
      source /tmp/aaa.csh
      #含义:在当前环境直接获取/tmp/aaa.csh中定义的变量等
      #作用:不执行脚本但能获取脚本中设定的变量
      #案例:/
      
      xdg-open
      #用法
      xdg-open 软件启动文件
      xdg-open aaa.pdf
      #含义:自动调用系统默认pdf软件打开aaa.pdf文件
      #作用:自动打开不确定文件
      #案例:/
      
    • 实战演练:

      课后作业:

      • 自行收集更多的常用命令并按示例记录好常用案例
    第4课.Vim编辑器
      1. vim基础操作
        网络参数教程:VIM操作基础命令
      • A.文件操作
        • (1).打开文件
          VIM 使用 –o 或 –O 选项打开多个文件,其中 –o 表示垂直并排,例如 vim -o lesson4 lesson5 lesson6。大O表示水平排列
          对于垂直并排的文件:使用 ctrl + w + 上、下方向,表示上、下切换文件;
          对于水平并排的文件:使用 ctrl + w + 左、右方向,表示左、右切换文件。
          退出动作是针对所有的(ALL):qa、qa!、wqa

        • (2).退出、保存文件

          按键含义
          :w filename保存为filename文件名,filename为空保存当前文件
          :q退出编辑
          :q!放弃修改直接退出
          :qa、qa!、wqa退出所以文件
        • (3). vim键入shell命令
          输入 :!ls / ,可以在切换到shell命令ls,查看root目录下文件列表

      1. 光标操作
      按键含义
      h
      j
      k
      l
      1. 插入模式
      按键含义
      i在光标的前边进入插入模式
      I在光标所在行的行首进入插入模式
      a在光标的后边进入插入模式
      A在光标所在行的行尾进入插入模式
      o在光标所在行的下方插入空行并进入插入模式
      O在光标所在行的上方插入空行并进入插入模式
      s删除光标指定的字符并进入插入模式
      S将光标所在行清除并进入插入模式
      1. 普通模式
      • (1). 通用操作

        按键含义
        0将光标定位到行首的位置
        ^同上
        $将光标定位到行尾的位置
        b将光标定位到光标所在单词的起始处
        e将光标定位到光标所在单词的结尾处
        w将光标定位到下一个单词的起始处(注意,是光标所在单词的下一个单词)
        gg将光标定位到文件的开头
        G将光标定位到文件的末尾
        u撤销最后一次修改
        U撤销对整行的修改
        Ctrl + r恢复撤销的内容
        Ctrl + g查看文件名等状态
        %匹配(),[],{}的另一部分
      • (2).删除操作

        按键含义
        d0删除光标从当前位置(不包含)到该行行首的所有字符
        d^同上
        d$删除从光标当前位置(包含)到该行行尾的所有字符
        db删除从光标当前位置(不包含)到单词起始处的所有字符
        de删除从光标当前位置(包含)到单词结尾处的所有字符
        dw删除从光标当前位置(包含)到下个单词起始处的所有字符
        dh删除光标前面一个字符dl删除光标指定的字符
        dj删除光标所在行以及下一行的所有字符
        dk删除光标所在行以及上一行的所有字符
        dd删除光标所在行的所有字符
        dgg删除光标所在行(包含)到文件开头的所有字符
        dG删除光标所在行(包含)到文件末尾的所有字符
        x删除单个字符
        可与数字进行组合,如3dj,表示删除光标下面3行
      • (3).复制、粘贴

        按键含义
        y复制命令
        yy复制当前行
        p将粘贴板内容粘贴到光标前
        P将粘贴板内容粘贴到光标后
        r替换命令,单个字符

        可与数字进行组合,如3k向上移动3行

      • (4).查找、替换

        按键含义
        /findcontent光标将定位到光标开始时至查找到的第一个内容处。如需查找下一个,则按下enter键,按下n键查找下一个,按下N查找上一个
        :行号光标跳转到某行
        :/s/old/new将光标所在行的第一个 old 替换为 new
        :%s/old/new/g替换整个文件中每个匹配的字符串
        :%s/old/new/gc在替换时vim咨询弹出 (y/n/a/q/l/E/Y) 确认信息:
        y 表示替换
        n 表示不替换
        a 表示替换所有
        q 表示放弃替换
        l 表示替换第一个并进入插入模式
        ^E 表示用 Ctrl+e 来滚动屏幕
        ^Y 表示用 Ctrl+y 来滚动屏幕
        :5,13s/old/new/g替换第 5 行到第 13 行之间的所有old为new
        :行号光标跳转到某行

        删除空格行:非编辑状态下输入:   g/^$/d
        删除行首空格:非编辑状态下输入:  %s/^\s*//g
        删除行尾空格:非编辑状态下输入:  %s/\s*$//g
        VIM删除空白行: 在命令状态下输入: :g/^\s*$/d
        :g 代表在全文档范围内 ^代表行的开始 \s*代表空白字符 &代表行的结束 d代表删除 用//将3段代码隔开

      1. 可视模式
        普通模式下按v键进入可视模式
        可视模式下使用hjkl选中行,使用“数字 + >”,向右缩进数次。其中,>表示右缩进,<表示左缩进

      课后作业:

      • 使用VIM编辑器新建一个"/tmp/test"文件,分别执行写入,修改,复制,返回,重做,删除行操作并保存文本
      • 在终端实际操作练习vim基本操作,熟练掌握最常用的vim操作指令

    第二章.开发环境配置

    第5课.安装Anaconda3(Python3)
    第1节.Windows下安装配置Anaconda3
    • 1.Anaconda简介
      Anaconda,一个开源的Python发行版本,可用于管理Python及其相关包,包含了conda、Python等180多个科学包及其依赖项。
      网络教程地址:原文链接

    • 2.运行环境
      Windows11 (Window10用户亦可参考,仅环境变量打开位置不同)。

    • 3.安装Anaconda

      • (1).百度“Anaconda”或者输入网址“https://www.anaconda.com/”进入Anaconda官网。
        在这里插入图片描述

        默认版本为Windows,点击“Download”即可下载 。

      • (2).下载完成后双击“Anaconda3-2022.10-Windows-x86_64.exe”进行安装。
        在这里插入图片描述

      • (3).点击“Next”。
        在这里插入图片描述

      • (4).点击“I Agree”。
        在这里插入图片描述

      • (5).点击“Just Me” 之后点击“Next”。(如果电脑有多个用户,选择“All User”)。
        在这里插入图片描述

      • (6).设置安装路径,最好为全英文且文件夹需为空,之后点击“Next”。
        在这里插入图片描述

      • (7).选择手动安装路径,之后点击“Install”。(因为上一个Anaconda也是手动添加路径,本次依然选择手动添加,大家有兴趣的也可尝试上面的自动添加路径。)
        在这里插入图片描述

      • (8).点击“Next”。
        在这里插入图片描述

      • (9).点击“Next” 。
        在这里插入图片描述

      • (10).点击“Finish”。
        在这里插入图片描述
        到这里Anaconda已经安装完成了,接下来到配置环境变量。

    • 4.手动配置环境变量(重点)

      • (1).打开“此电脑”,右键点击“属性”,选择“高级系统设置”,点击“环境变量”。
        在这里插入图片描述
        在这里插入图片描述
      • (2).在系统变量中找到“Path”(注意是区分是系统变量,不是环境变量;个别电脑“Path”可能大小写不同,但都是一样的,只是书写方式不同。)
        在这里插入图片描述
      • (3).双击“Path”,新建环境变量。
        分三次输入以下信息(按自己实际安装路径输入):
        Anaconda安装路径
        Anaconda安装路径\Scripts
        Anaconda安装路径\Library\bin
        在这里插入图片描述
        上图所示为个人安装路径,三条变量信息新建完成后点击“确定”。
    • 5.测试Anaconda环境是否配置成功

      • (1).WIN+R打开cmd。
        在这里插入图片描述
      • (2).输入“conda --version”。(查看conda版本)
        在这里插入图片描述
      • (3).输入“conda info”。
        在这里插入图片描述
      • (4).输入“activate”,回车。之后输入“python”。
        在这里插入图片描述
        如果输出内容与上图类似(可能版本号不同),则说明环境变量配置成功。
        至此,Anaconda安装已全部完成。
    第2节.CentOS 7下安装配置Anaconda3

    网络教程地址:原文链接

    • 1.Anaconda下载
      进入anaconda官方网站下载个人免费版本,网站链接,点击download,选择Linux平台的安装包
      在这里插入图片描述

    • 2.Anaconda安装

      • (1).执行如下指令,安装anaconda

        # 进入当保存文件的目录,执行此指令, 后期由于版本更新,可能会与此文件命名有所不同
        bash Anaconda3-2020.11-Linux-x86_64.sh
        
      • (2).按照安装提示,键入回车

        Please, press ENTER  to continue
        >>> ENTER
        
      • (3).安装此版本时,会强制用户看完整个协议,直接一路回车就行,直到看到确认信息

        # 输入yes,表示同意安装协议
        Do you accept the license terms? [yes|no][no] 
        >>> yes
        

        在这里插入图片描述

      • (4).确认安装路径(可修改,也可以使用自定义)

        # 使用默认路径,直接键入回车,使用自定义路径,直接输入安装路径
        # 此处使用 /opt/anaconda3作为安装路径
        Anaconda3 will now be installed into this location:
        /root/anaconda3  
        - Press ENTER to confirm the location  
        - Press CTRL-C to abort the installation  
        - Or specify a different location below
        
        [/root/anaconda3] >>> /opt/anaconda3
        

        在这里插入图片描述

        注:安装位置可以在执行安装脚本的时候直接指定,可以这样修改执行内容:

        bash Anaconda3-2020.11-Linux-x86_64.sh -p /opt/anaconda3
        

        这样可跳过软件安装路径确认阶段,直接安装到指定目录下。

      • (5).环境变量初始化

        # 此处询问是否初始化conda的环境,直接输入yes
        Do you wish the installer to initialize Anaconda3
        by running conda init? 
        [yes|no][no] >>> yes
        

        在这里插入图片描述
        安装完成
        在这里插入图片描述

      • (6).初始化时,anaconda将配置写入了~/.bashrc 文件,直接执行

        source ~/.bashrc
        

        后即可正常使用了。

      • (7).配置多用户使用
        将anaconda初始化时,写入到 ~/.bashrc 文件中的内容复制到 /etc/bashrc 文件中,内容如下(此处仅为示例,请复制本机对应文件中的相应内容)

        # >>> conda initialize >>>
        # !! Contents within this block are managed by 'conda init' !!
        __conda_setup="$('/opt/anaconda3/bin/conda' 'shell.bash' 'hook' 2> /dev/null)"
        if [ $? -eq 0 ]; then
            eval "$__conda_setup"
        else
            if [ -f "/opt/anaconda3/etc/profile.d/conda.sh" ]; then
                . "/opt/anaconda3/etc/profile.d/conda.sh"
            else
                export PATH="/opt/anaconda3/bin:$PATH"
            fi
        fi
        unset __conda_setup
        # <<< conda initialize <<<
        

        在这里插入图片描述

        再执行 source /etc/bashrc 指令即可。

    • 3.配置镜像源

      • 3.1.conda配置镜像源:
        使用conda进行安装时,访问的是国外的网络,所以下载和安装包时会特别慢。我们需要更换到国内镜像源地址,这里我更换到国内的清华大学地址。(永久添加镜像)
        Windows和Linux 对于conda修改镜像源的方法一样

        • (1).查看anaconda中已经存在的镜像源

          conda config --show channels
          

          在这里插入图片描述

        • (2).添加镜像源(永久添加)

          conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
          conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/
          conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/
          

          在这里插入图片描述

        • (3).设置搜索时显示通道地址

          conda config --set show_channel_urls yes
          
        • (4).若不想按照上述步骤添加镜像,可使用以下命令直接指定安装时使用的镜像地址(以opencv为例):

          conda install opencv -c https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/
          

          在这里插入图片描述

        • (5).添加完后查看

          conda config --show channels
          
      • 3.2.pip使用国内镜像源:
        一般在使用conda install安装时会出现包无法找到或者安装失败的情况,此时可以使用pip install来尝试安装(以opencv为例):

        pip install opencv
        

        若安装速度过慢可单独指定安装镜像加快安装:

        pip install opencv -i https://mirrors.aliyun.com/pypi/simple/
        

        此处列举国内常用pip安装镜像:
        清华:https://pypi.tuna.tsinghua.edu.cn/simple
        阿里云:https://mirrors.aliyun.com/pypi/simple
        中国科技大学: https://pypi.mirrors.ustc.edu.cn/simple
        华中理工大学:https://pypi.hustunique.com
        山东理工大学:https://pypi.sdutlinux.org
        豆瓣:https://pypi.douban.com/simple

        channels:
          - defaults
        show_channel_urls: true
        default_channels:
          - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main
          - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free
          - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r
          - https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/Paddle/
        custom_channels:
          conda-forge: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
          msys2: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
          bioconda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
          menpo: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
          pytorch: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
          simpleitk: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
        
    • 4.root用户安装的anaconda如何给普通用户使用
      服务器里安装了anaconda,结果发现只有root用户才能使用,其他的用户都无法使用conda命令!
      【解决方案】
      首先,root用户安装anaconda的时候,需要安装在普通用户可以访问的目录下,比如/usr/local、/opt、/home之类的
      其次,普通用户登陆后,需要执行以下conda init 使conda的路径等系统环境变量信息写入当前用户的bashrc下
      例:
      anaconda 装在了 (需要查看anaconda3安装路径)

      /opt/anaconda3
      

      普通用户 需要执行

      /opt/anaconda3/bin/conda init bash
      

      在这里插入图片描述

      你需要根据自己的实际情况修改bin之前的目录
      普通用户再执行启用配置命令

      source ~/.bashrc
      

      然后重新连接SSH (推荐)
      或者
      即使你没有重新连接ssh也可以通过(没试过)

      source activate base
      

      conda activate base
      

      能正常使用conda后,你就可以创建你自己的环境了,例

      conda create -n xxx python=3.7
      

      环境会装在home中你的用户文件夹下,可以通过

      conda env list
      

      查看对应的地址
      以上操作的问题是,那个用户需要使用conda,就需要按以上步骤执行一遍,并没有设置成所有用户都可以调用的方式。

    课后作业:

    • 在Windows上安装并配置好Anaconda3,虚拟出Python3.7.5环境
    • 在Centos 7上安装并配置好Anaconda3,虚拟出Python3.7.5环境
    第6课.常用的Python模块安装
    • 1.安装python模块
      • PyQt5图像界面模块安装
        使用conda安装
        (1).激活环境(例如:需要在已虚拟好的python3.7.5下安装)

        conda activate python3.7.5
        

        退出虚拟环境可以使用conda deactivate命令
        (2).安装PyQt5模块

        conda install PyQt5
        

        (3).验证PyQt5模块是否安装成功(如下:进入python解释器,导入安装的PyQt5模块,没有任何提示信息表示安装成功)

        python3.7.5
        >>> import PyQt5
        >>>
        

        使用pip安装

        pip install PyQt5
        
      • pymysql/pymssql数据库操作模块安装
        使用conda安装
        (1).激活环境(例如:需要在已虚拟好的python3.7.5下安装)

        conda activate python3.7.5
        

        退出虚拟环境可以使用conda deactivate命令
        (2).安装pymysql/pymssql模块

        conda install pymysql
        

        (3).验证pymysql/pymssql模块是否安装成功(如下:进入python解释器,导入安装的pymysql模块,没有任何提示信息表示安装成功)

        python3.7.5
        >>> import pymysql
        >>>
        
      • xlrd/xlwt/xlutils库安装
        (1).激活环境(例如:需要在已虚拟好的python3.7.5下安装)

        conda activate python3.7.5
        

        退出虚拟环境可以使用conda deactivate命令
        (2).安装xlrd/xlwt/xlutils模块

        conda install xlrd
        

        (3).验证xlrd/xlwt/xlutils模块是否安装成功(如下:进入python解释器,导入安装的xlrd模块,没有任何提示信息表示安装成功)

        python3.7.5
        >>> import xlrd
        >>>
        

    课后作业:

    • 使用conda自行安装一款python第三方库
    • 使用pip安装python开发需要的第三方库
    第7课.安装集成开发工具(PyCharm)
    • 系统要求
      在安装 Pycharm 之前,请确保您的计算机满足以下系统要求:

      • Windows:Windows 7 或更高版本(64 位)。
      • macOS:macOS 10.13 或更高版本。
      • Linux:GNOME、KDE 或 XFCE(64 位)。
    • 下载 Pycharm

        1. 打开浏览器,访问 JetBrains 官方网站
        1. 在页面上找到“Download”按钮,点击进入下载页面。
          在这里插入图片描述
        1. 根据您的操作系统,选择相应的版本进行下载。Pycharm 提供了专业版(Professional)和社区版(Community),专业版功能更丰富,但需要付费订阅,社区版则是免费开源的,对于大多数初学者和普通开发者来说,社区版已经足够使用。
          在这里插入图片描述
    • 安装 Pycharm(以 Windows 为例)

        1. 找到下载好的 Pycharm 安装程序(.exe 文件),双击运行。
        1. 在欢迎界面中,点击“Next”。
        1. 选择安装路径。建议您选择非系统盘(如 D 盘)的目录进行安装,以避免占用系统盘过多空间。点击“Browse”选择安装目录后,点击“Next”。
        1. 选择安装选项。您可以根据自己的需求选择创建桌面快捷方式、关联文件类型等选项。一般情况下,保持默认设置即可。点击“Next”。
        1. 选择开始菜单文件夹。默认情况下,Pycharm 会在开始菜单中创建一个文件夹,您也可以修改文件夹名称或选择不创建。点击“Install”开始安装。
        1. 安装过程可能需要一些时间,请耐心等待。安装完成后,点击“Finish”。
    • 首次运行 Pycharm

        1. 安装完成后,如果您在安装过程中选择了创建桌面快捷方式,可以直接双击桌面上的 Pycharm 图标启动;否则,可以在开始菜单中找到 Pycharm 并点击启动。
        1. 首次运行 Pycharm 时,会弹出一个对话框,询问您是否要导入之前的设置。如果您是首次使用 Pycharm,可以选择“Do not import settings”,然后点击“OK”。
        1. 接下来,会弹出一个许可证激活对话框。如果您使用的是社区版,直接点击“Evaluate for free”即可开始免费试用;如果您有专业版的许可证,可以点击“Activate”并输入许可证信息进行激活。
    • 配置 Pycharm

        1. 项目设置
          点击“Create New Project”创建一个新项目。在弹出的对话框中,选择项目的存储路径、Python 解释器等信息。如果您已经安装了 Python,可以在“Python Interpreter”下拉列表中选择对应的解释器;如果没有安装,Pycharm 会提示您安装。点击“Create”创建项目。
        1. 界面设置
          Pycharm 的界面可以根据您的喜好进行定制。您可以通过“View”菜单中的选项来显示或隐藏各种工具窗口,如项目窗口(Project)、代码编辑器(Editor)、终端(Terminal)等。
          在“Settings”(Windows 下为“File”->“Settings”,macOS 下为“Pycharm”->“Preferences”)中,您可以进一步配置 Pycharm 的各种功能,如代码风格、编辑器字体、快捷键等。
    • 至此,Pycharm 已经安装并配置完成,您可以开始使用它进行 Python 项目的开发了。

    第8课.安装数据库(MySQL/SQLServer)
    • 本人开发数据库主要使用MySQL8,以此为例(CentOS7安装配置MySQL8)
      原文参考链接
      • 下载mysql安装包,复制安装包到CentOS7共享目录
        在这里插入图片描述在这里插入图片描述
        在这里插入图片描述
        下载哪个版本,首先需要确定一下系统的glibc版本,使用如下命令:

        rpm -qa | grep glibc
        

        在这里插入图片描述
        在这里插入图片描述
        在这里插入图片描述

        cp /你的下载文件目录/mysql-8.0.39-linux-glibc2.17-x86_64.tar /opt
        
      • 检查是否安装mysql

        ps:因为以前用yum安装过,所以先用yum卸载。如果不是此方式或者没安装过则跳过

        [root@localhost ~]# yum remove mysql
        # 已加载插件:fastestmirror
        # 参数 mysql 没有匹配
        # 不删除任何软件包
        

        查看是否有mysql依赖

        [root@localhost ~]# rpm -qa | grep mysql
        

        如果有则卸载

        # 普通删除模式
        rpm -e xxx(mysql_libs)
        # 强力删除模式,如果上述命令删除时,提示有依赖其他文件,则可以用该命令对其进行强力删除
        rpm -e --nodeps xxx(mysql_libs)
        
      • 检查是否有mariadb

        [root@localhost ~]# rpm -qa | grep mariadb
        mariadb-libs-5.5.68-1.el7.x86_64
        

        如果有则卸载

        [root@localhost ~]# rpm -e --nodeps mariadb-libs
        [root@localhost ~]# rpm -e --nodeps mariadb-libs-5.5.68-1.el7.x86_64
        错误:未安装软件包 mariadb-libs-5.5.68-1.el7.x86_64 
        
      • 安装mysql依赖包

        [root@localhost home]# yum install libaio
        
      • 解压
        进入/opt目录下将mysql文件解压

        [root@localhost home]# cd /opt
        [root@localhost opt]# tar -xvf mysql-8.0.36-linux-glibc2.17-x86_64.tar
        mysql-test-8.0.36-linux-glibc2.17-x86_64.tar.xz
        mysql-8.0.36-linux-glibc2.17-x86_64.tar.xz
        mysql-router-8.0.36-linux-glibc2.17-x86_64.tar.xz
        [root@localhost opt]# tar -Jxvf mysql-8.0.36-linux-glibc2.17-x86_64.tar.xz
        [root@localhost opt]# mv mysql-8.0.36-linux-glibc2.17-x86_64 mysql
        

        按照习惯,我们将文件移动到/usr/local目录下

        [root@localhost opt]# mv /opt/mysql/ /usr/local/
        

        我们切换到usr/local/目录下查看mysql是否存在

        [root@localhost opt]# cd /usr/local/
        [root@localhost local]# ll
        总用量 0
        drwxr-xr-x.  2 root root   6 411 2018 bin
        drwxr-xr-x.  2 root root   6 411 2018 etc
        drwxr-xr-x.  2 root root   6 411 2018 games
        drwxr-xr-x.  2 root root   6 411 2018 include
        drwxr-xr-x.  2 root root   6 411 2018 lib
        drwxr-xr-x.  2 root root   6 411 2018 lib64
        drwxr-xr-x.  2 root root   6 411 2018 libexec
        drwxr-xr-x.  9 root root 129 42 21:20 mysql
        drwxr-xr-x. 11 root root 151 828 2023 nginx
        drwxr-xr-x.  2 root root   6 411 2018 sbin
        drwxr-xr-x.  5 root root  49 829 2023 share
        drwxr-xr-x.  2 root root   6 411 2018 src
        

        创建数据库文件存放的文件夹。这个文件夹将来存放每个数据库的库文件

        [root@localhost local]# cd mysql
        [root@localhost mysql]# ls
        bin  docs  include  lib  LICENSE  man  README  share  support-files
        [root@localhost mysql]# mkdir mysqldb
        
      • mysql安装目录赋予权限

        [root@localhost mysql]# chmod -R 777 /usr/local/mysql/
        
      • 创建mysql组和用户
        创建组

        [root@localhost mysql]# groupadd mysql
        

        创建用户(-s /bin/false参数指定mysql用户仅拥有所有权,而没有登录权限)

        [root@localhost mysql]# useradd -r -g mysql -s /bin/false mysql
        

        将用户添加到组中

        [root@localhost mysql]# chown -R mysql:mysql ./
        
      • 修改mysql配置文件

        [root@localhost mysql]# vi /etc/my.cnf
        

        将里面的命令都删除掉,然后添加以下命令,保存并退出(如果有一定经验,可以在里面添加一些其他的配置)

        [mysqld]
        # 设置3306端口
        port=3306
        # 设置mysql的安装目录
        basedir=/usr/local/mysql
        # 设置mysql数据库的数据的存放目录
        datadir=/usr/local/mysql/mysqldb
        # 允许最大连接数
        max_connections=10000
        # 允许连接失败的次数。这是为了防止有人从该主机试图攻击数据库系统
        max_connect_errors=10
        # 服务端使用的字符集默认为UTF8
        character-set-server=utf8
        # 创建新表时将使用的默认存储引擎
        default-storage-engine=INNODB
        # 默认使用“mysql_native_password”插件认证
        default_authentication_plugin=mysql_native_password
        [mysql]
        # 设置mysql客户端默认字符集
        default-character-set=utf8
        [client]
        # 设置mysql客户端连接服务端时默认使用的端口
        port=3306
        default-character-set=utf8
        
      • 安装mysql
        进入mysql 安装目录下:

        [root@localhost mysql]# cd /usr/local/mysql/bin/
        

        安装mysql,并记住初始化随机密码

        	[root@localhost bin]# ./mysqld --initialize --console
        	2024-04-02T13:25:55.133890Z 0 [Warning] [MY-010918] [Server] 'default_authentication_plugin' is deprecated and will be removed in a future release. Please use authentication_policy instead.
        	2024-04-02T13:25:55.133913Z 0 [System] [MY-013169] [Server] /usr/local/mysql/bin/mysqld (mysqld 8.0.36) initializing of server in progress as process 2186
        	2024-04-02T13:25:55.139191Z 0 [Warning] [MY-013242] [Server] --character-set-server: 'utf8' is currently an alias for the character set UTF8MB3, but will be an alias for UTF8MB4 in a future release. Please consider using UTF8MB4 in order to be unambiguous.
        	2024-04-02T13:25:55.154304Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
        	2024-04-02T13:25:55.706150Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
        	2024-04-02T13:25:57.058187Z 6 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: <;cdUJXy!91b
        	2024-04-02T13:25:57.159383Z 6 [Warning] [MY-013360] [Server] Plugin mysql_native_password reported: ''mysql_native_password' is deprecated and will be removed in a future release. Please use caching_sha2_password instead'
        

        在这里插入图片描述

      • 启动mysql服务
        进入mysql.server服务目录下并启动服务

        [root@localhost bin]# cd /usr/local/mysql/support-files
        [root@localhost support-files]# ./mysql.server start
        Starting MySQL.Logging to '/usr/local/mysql/mysqldb/localhost.localdomain.err'.
         ERROR! The server quit without updating PID file (/usr/local/mysql/mysqldb/localhost.localdomain.pid).
        

        如果第一次启动,当初始化执行会有报错
        此时不要担心,重新给mysql安装目录赋予一下权限后,再次执行。

        [root@localhost support-files]# chmod -R 777 /usr/local/mysql
        [root@localhost support-files]# ./mysql.server start
        Starting MySQL. SUCCESS!
        
      • 将mysql添加到系统进程中

        [root@localhost support-files]# cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
        

        此时我们就可以使用服务进程操作mysql了

      • 设置mysql自启动

        [root@localhost support-files]# chmod +x /etc/init.d/mysqld
        [root@localhost support-files]# systemctl enable mysqld
        mysqld.service is not a native service, redirecting to /sbin/chkconfig.
        Executing /sbin/chkconfig mysqld on
        

        此时mysql自启动就已经设置好了

      • 修改root用户登录密码
        登录mysql

        [root@localhost support-files]# cd /usr/local/mysql/bin/
        [root@localhost bin]# ./mysql -u root -p
        

        执行后,输入我们初始化时记录下的随机密码,就会进入mysql。
        修改密码:

        mysql> alter user 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '123456';
        Query OK, 0 rows affected (0.01 sec)
        
      • 设置允许远程登录

        mysql> use mysql
        Reading table information for completion of table and column names
        You can turn off this feature to get a quicker startup with -A
        Database changed
        mysql> update user set user.Host='%'where user.User='root';
        Query OK, 1 row affected (0.01 sec)
        Rows matched: 1  Changed: 1  Warnings: 0
        mysql> flush privileges;
        Query OK, 0 rows affected (0.00 sec)
        mysql> quit
        Bye
        
      • 重启服务且测试
        centos6与centos7的服务命令都支持

        [root@localhost bin]# systemctl restart mysql
        [root@localhost bin]# service mysql restart
        Redirecting to /bin/systemctl restart mysql.service
        

        查看mysql是否启动

        systemctl status mysql
        

        查看防火墙开放端口

        [root@localhost bin]# firewall-cmd --list-all
        

        在防火墙中将3306端口开放

        [root@localhost bin]# firewall-cmd --zone=public --add-port=3306/tcp --permanent
        success
        //--permanent为永久生效,没有此参数 服务器重启后配置失效
        [root@localhost bin]# firewall-cmd --reload
        success
        

        在Navicat上测试连接
        在这里插入图片描述
        重启linux后测试自启动(可选)

        [root@localhost bin]# reboot
        

        测试mysql服务是否自启动
        在这里插入图片描述

        测试远程访问
        在这里插入图片描述

    第9课.安装navicat(数据库操作客户端)
    • 下载安装包
      官网下载
    • 安装
      除了更改安装路径和生成桌面快捷方式外,其余按照默认步骤安装即可,建议安装在 D 盘,如下图:
      在这里插入图片描述
      询问是否生成桌面安装方式时,选上,如下图:
      在这里插入图片描述

      注意:安装完成先不要打开运行navicat

    • 激活
      由于版权原因,此处不便复述,请购买正版软件或者
      参考博文1
      参考博文2
      自行处理
    第10课.CAM软件脚本语言环境配置
    • 步骤1. 找到InCAMPro编程语言环境配置脚本:
      配置脚本路径:/incam/release/app_data/scr_start.csh,release根据自己公司绑定的版本目录
      在这里插入图片描述
      脚本代码:
      #!/bin/csh
      #
      #  Date    : 12 Jan 1994
      #  Version : 1        MK
      #
      #  11/09/2005 IL: Modified to suit InCAM variables
      #    Some of the 'if's are no longer relevant, but kept anyway,
      #    perhaps they will be relevant for Unix installations.
      #
      #  24/05/2007 Mikets: Added support for Python scripts
      #
      if($?INCAM_SERVER)then
        set _incam_root="$INCAM_SERVER"
      else
        set _incam_root=/incam
      endif
      
      if($?INCAM_PRODUCT)then
        set __incam_prod="$INCAM_PRODUCT"
      else
        set __incam_prod="$_incam_root/release"
      endif
      
      if ($?windir) then
        set sep=";"
      else
        set sep=":"
      endif
      
      if("$__incam_prod" =~ /* || "$__incam_prod" =~ ?:*)then
        setenv PATH "$__incam_prod/utils$sep$PATH"
      else
        setenv PATH "$_incam_root/$__incam_prod/utils$sep$PATH"
      endif
      
      set STATUS=0
      set PROG=$1
      if(! -e $PROG)then
        set PROG_STATUS=1
        goto end
      endif
      
      # define aliases
      set DIR_PREFIX='@%#%@'
      
      alias VON 'echo "${DIR_PREFIX}VON";'
      alias VOF 'echo "${DIR_PREFIX}VOF";'
      
      alias SU_ON  'echo "${DIR_PREFIX}SU_ON";'
      alias SU_OFF 'echo "${DIR_PREFIX}SU_OFF";'
      
      alias PAUSE 'echo "${DIR_PREFIX}PAUSE \!:*"; \\
         set STATUS=$<; set READANS=$<; set PAUSANS=$<; \\
         if ($PAUSANS != "OK") exit'
      alias MOUSE 'echo "${DIR_PREFIX}MOUSE \!:*"; \\
         set STATUS=$<; set READANS=$<; set MOUSEANS="$<"'
      alias COM 'echo "${DIR_PREFIX}COM \!:*"; \\
         set STATUS=$<; set READANS="$<"; set COMANS=($READANS)'
      alias AUX 'echo "${DIR_PREFIX}AUX \!:*"; \\
         set STATUS=$<; set READANS="$<"; set COMANS=($READANS)'
      
      set argv = ($2)
      
      set IFILE = $INCAM_TMP/info.$$
      alias DO_INFO 'COM info,out_file=$IFILE,write_mode=replace,args= \!:* ; source $IFILE; rm $IFILE'
      
      #executing hook script
      set _user_done=0
      if($?INCAM_USER_DIR)then
        if(-e $INCAM_USER_DIR/hooks/script_start.csh)then
          source $INCAM_USER_DIR/hooks/script_start.csh
          set _user_done=1
        endif
      endif
      if($_user_done != "1")then
        if(-e $_incam_root/site_data/hooks/script_start.csh)then
          source $_incam_root/site_data/hooks/script_start.csh
        endif
      endif
      
      # check first line of program
      #set _HEAD=`head -1 $PROG`    Yefim 02.06.04
      set _HEAD=`sed -n 1p $PROG`
      set _END = `echo $PROG:e`
      
      if ("$_HEAD" =~ *perl*) then                    # 当用perl编写脚本程式时,首行包含"perl"将调用perl解释器执行代码
         echo "Executing Perl Program $PROG $argv"
         perl $PROG $argv
         set PROG_STATUS=$status
      else if ("$_HEAD" =~ *python*) then            # 当用Python编写脚本程式时,首行包含"python"将调用python解释器执行代码
         echo "Executing Python Program $PROG $argv"
         /usr/bin/python3 $PROG $argv
         set PROG_STATUS=$status
      else if ("$_HEAD" =~ *py3k*) then              # 当用自定义的Python版本或者环境编写脚本程式时,首行包含"py3k"将调用自定义环境下的python解释器执行代码
         echo "Executing Python Program $PROG $argv"
         /usr/bin/py3k $PROG $argv
         set PROG_STATUS=$status
      else if ("$_HEAD" =~ *wish*) then              # 当用tcl编写脚本程式时,首行包含"wish"将调用tcl解释器执行代码
         setenv TCSHONLYSTARTEXES 1
         echo "Executing TCL Program $PROG $argv"
         $_incam_root/site_data/hooks/wish_start.tcl $PROG $argv
         set PROG_STATUS=$status
      else if ("$_END" =~ [Pp][Yy][Cc]) then        # 当用python编写脚本程式并使用生成的pyc执行时,文件后缀包含"pyc"将调用python解释器执行pyc文件
         echo "Executing Python PYC Program $PROG $argv"
         /usr/bin/python3 $PROG $argv
         set PROG_STATUS=$status
      else                                          # 默认执行C SHell代码
         echo "Executing C Shell Program $PROG"
         source $PROG
         set PROG_STATUS=$status
      endif
      
      end:
      exit($PROG_STATUS)
      
    • 步骤2. 编写InCAMPro软件Python脚本接口(最新版的InCAMPro已经自带python接口):
      python接口路径:/incam/release/app_data/python/incam.py(没有接口也没关系这个是可以自己写的,参考perl的代码直接转写为python代码,效果是一样的,也可以参考我提供给大家的源码!在这里插入图片描述
      接口代码:
      #!/usr/bin/env python
      
      '''Package for running Python programs in a InCAM/InCAMPro environment.
      '''
      
      import sys, re
      import time
      import os
      import socket
      import io
      import string
      
      
      # In order to support both python2 and python3 
      
      if sys.version_info[0] < 3:
          input = raw_input
          python_version = 2
          # reload(sys)
          # sys.setdefaultencoding('utf-8')
      else:
          python_version = 3
          sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='utf-8')
      
      
      class InCAM:
          def __init__(self, remote='127.0.0.1'):
              """ 
              Initialize the class
              """
              self.prefix = '@%#%@'
              self.blank()
              self.pid = os.getpid()
              tmp = 'incam_'+ str(self.pid)+'.'+str(time.time())
              if 'TMP' in os.environ.keys():
                  self.tmpfile = os.path.join(os.environ['TMP'], tmp)
                  self.tmpdir = os.environ['TMP']
              else:
                  self.tmpfile = os.path.join('/tmp', tmp)
                  self.tmpdir = '/tmp'
              self.comms = 'pipe'
              self.port = 'flsport'
              self.socketOpen = 0
              self.remote = remote
              try:
                  if sys.stdin.isatty() or 'INCAM_USER' not in os.environ.keys():
                      self.comms = 'socket'
                      self.openSocket()
                      self.socketOpen = 1
                      self.inheritEnvironment()
              except:
                  pass
      
          def closeDown(self):
              self.sendCmd("CLOSEDOWN", "")
              
          def inheritEnvironment(self):
              self.sendCmd("GETENVIRONMENT", "")
              while 1:
                  reply = self.getReply().strip()
                  if reply == 'END':
                      break
                  var,value = reply.split('=',1)
                  os.environ[var]=value
              
          def openSocket(self):
              self.socketOpen += 1
              if self.socketOpen != 1:
                  return
              port = self.port
              remote = self.remote
              try:
                  if re.match(r'\D+',port):
                      port = socket.getservbyname(port, 'tcp')
              except:
                  port = 56753
              
              self.SOCK = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
              self.SOCK.connect((remote,port))
              self.sf = self.SOCK.makefile('rw')
              
          def sendCmd(self, cmd, args=''):
              self.blank()
              if self.comms == 'pipe':
                  self.sendCommandToPipe(cmd, args)
              if self.comms == 'socket':
                  self.sendCommandToSocket(cmd, args)
      
          def sendCommandToPipe(self,cmd, args=''):
              '''
              Send the commands to stdout
              '''
              wsp = ' '*(len(args)>0)
              cmd = self.prefix + cmd + wsp + args + '\n'
              # sys.stdout.write(cmd.encode('utf8'))
              # if python_version == 2:
              sys.stdout.write(cmd)
              sys.stdout.flush()
              return 0
          
          def sendCommandToSocket(self, cmd, args=''):
              '''
              Send the commands to Socket
              '''
              wsp = ' '*(len(args)>0)
              cmd = self.prefix + cmd + wsp + args + '\n'
              self.sf.write(cmd)
              self.sf.flush()
              
          def getReply(self):
              if self.comms == 'pipe':
                  reply = input()
              if self.comms == 'socket':
                  reply = self.sf.readline()
              return reply
      
          def __del__(self):
              '''
              Called when class is cleaned up by python
              '''
              if os.path.isfile(self.tmpfile):
                  os.unlink(self.tmpfile)
              if (self.socketOpen == 0):
                  return
              self.sf.write(self.prefix + 'CLOSEDOWN\n')
              self.sf.flush()
              self.sf.close()
              self.SOCK.close()
      
          def blank(self):
              '''
              Initiate the return values
              '''
              self.STATUS   = 0
              self.READANS  = ''
              self.COMANS   = ''
              self.PAUSANS  = ''
              self.MOUSEANS = ''    
      
          def SU_ON(self):
              print("")
              return self.sendCmd('SU_ON')
              
          def SU_OFF(self):
              print("")
              return self.sendCmd('SU_OFF')
              
          def VON(self):
              print("")
              return self.sendCmd('VON')
              
          def VOF(self):
              print("")
              return self.sendCmd('VOF')
              
          def PAUSE(self, msg):
              self.sendCmd('PAUSE', msg)
              self.STATUS = int(self.getReply())
              self.READANS = self.getReply()
              self.PAUSANS = self.getReply()
              #solve the print message to terminal issues: some message can't be printed.
              print("")
              return self.STATUS
              
          def MOUSE(self, msg, mode='p'):
      
              self.sendCmd('MOUSE ' + mode, msg)
              self.STATUS = int(self.getReply())
              self.READANS = self.getReply()
              self.MOUSEANS = self.getReply()
              return self.STATUS
              
          def COM(self, args):
      
              self.sendCmd('COM', args)
              self.STATUS = int(self.getReply())
              self.READANS = self.getReply()
              self.COMANS = self.READANS[:]
              # self.COMANS = self.COMANS.strip()
              #solve the print message to terminal issues: some message can't be printed.
              print("")
              return self.STATUS
              
          def AUX(self, args):
      
              self.sendCmd('AUX', args)
              self.STATUS = int(self.getReply())
              self.READANS = self.getReply()
              self.COMANS = self.READANS[:]
              # self.COMANS = self.COMANS.strip()
              #solve the print message to terminal issues: some message can't be printed.
              print("")
              return self.STATUS
          
          # --- INFO methods ---
          # Get some basic info
          # It is received in the form of a csh script, so the information needs parsed to suit for python
          def INFO(self, args):
      
              self.COM('info,out_file=%s,write_mode=replace,args=%s' % (self.tmpfile, args))
              lineList = open(self.tmpfile, 'r').readlines()
              os.unlink(self.tmpfile)
              return lineList
          
          #Get InCAMPro info in imperial unit 
          def DO_INFO(self, args):
      
              self.COM('info,out_file=%s,write_mode=replace,args=%s' % (self.tmpfile, args))
              lineList = open(self.tmpfile, 'r').readlines()
              os.unlink(self.tmpfile)
              infoDict = self.parseInfo(lineList)
              return infoDict
      
          #Get InCAMPro info in metric unit 
          def DO_INFO_MM(self, args):
      
              self.COM('info,out_file=%s,write_mode=replace,units=mm,args=%s' % (self.tmpfile, args))
              lineList = open(self.tmpfile, 'r').readlines()
              os.unlink(self.tmpfile)
              infoDict = self.parseInfo(lineList)
              return infoDict      
      
          def convertToNumber(self, value):
              try:
                  return string.atoi(value)
              except:
                  try:
                      return string.atof(value)
                  except:
                      return value
      
          def parseInfo(self, infoList):
              parseDict = {}
              for line in infoList:
                  line=line.strip()
                  keywithval = line.split(' = ', 1)
                  if len(keywithval) == 2:
                      key = keywithval[0].strip()[4:]
                      val = keywithval[1]
                      allValList = val.split("'")
                      valList = []
                      if allValList[0] == '(':
                          allValList = allValList[1:-1]
                          for i in range(allValList.__len__()):
                              if allValList[i] == '':
                                  valList.append('')
                              elif re.match(r'^\s+$',allValList[i]):
                                  continue
                              else:
                                  valList.append(allValList[i])
                      elif allValList[0] =='()':
                          valList=[]
                      else:
                          if allValList.__len__() == 1:
                              valList=self.convertToNumber(allValList[0])
                          if allValList.__len__() == 3:
                              valList=self.convertToNumber(allValList[1])
                      parseDict[key] = valList
              return parseDict
      
      有了这些就可以用python自由编写InCAMPro的脚本代码了,当然,我们实际的工作中去实现我们的脚本逻辑一般会在这个基础的接口上进行更加个性化及抽象化的封装,尽可能的让我们的脚本逻辑清晰代码简洁,此处不做过多复述,后续课程我们会着重讲解自定义接口包的封装!
      使用案例代码:
      #!/usr/bin/python
      
      import os
      import re
      import sys
      
      #add python lib path to search path, so that incam class can be imported
      sys.path.append(os.environ['INCAM_PRODUCT']+'/app_data/python')
      import incam
      
      # get JOB, STEP variable
      f = incam.InCAM()
      job=os.environ['JOB']
      step=os.environ['STEP']
      #DO_INFO example
      info = f.DO_INFO('-t matrix -e ' + job + '/matrix')
      
      #INFO example, used only when the output is not in cshell format,
      #for example, get measures result from one checklist
      #info = f.INFO("-t check -e "+ job + "/" + step + "/checklist -d MEAS")
      
      for lay in info['gROWname']:
          #do some regulation express filter
          if re.search('\+{3}$',lay):
              f.COM('delete_layer, layer=' + lay)
              #PAUSE command
              f.PAUSE("layer "+lay+"is deleted, please check!")
      
      exit()
      
    第11课.Git安装配置
    第1节. 安装 Git
    • Windows

      • 访问 Git 官方下载页面:https://git-scm.com/download/win
      • 下载适合您的 Windows 版本的 Git 安装包(32 位或 64 位)。
      • 运行安装程序,按照提示完成安装,推荐使用默认设置。
    • macOS

      • 使用 Homebrew 安装 Git(如果尚未安装 Homebrew):
        brew install git
        
      • 或者访问 Git 官方下载页面:https://git-scm.com/download/mac,下载安装包进行安装。
    • Linux
      在终端中运行以下命令安装 Git:
      Ubuntu / Debian:

      sudo apt update
      sudo apt install git
      

      CentOS / RHEL:

      sudo yum install git
      

      Fedora:

      sudo dnf install git
      
    第2节. 配置 Git

    安装完成后,进行一些基本配置。

    • 配置用户名:

      git config --global user.name "Your Name"
      
    • 配置用户邮箱:

      git config --global user.email "youremail@example.com"
      
    • 设置默认编辑器(如使用 Vim):

      git config --global core.editor vim
      
    • 检查配置:

      git config --list
      
    第3节. Git 基本命令
    • 创建仓库

      • 创建一个新的 Git 仓库:
        git init
        
      • 克隆一个远程仓库:
        git clone <repository-url>
        
    • 工作区与暂存区

      • 查看文件状态:
        git status
        
      • 将文件添加到暂存区:
        git add <file>
        
    • 提交更改:

      git commit -m "Commit message"
      
    • 查看提交历史:

      git log
      
    • 分支操作

      • 创建新分支:
        git branch <branch-name>
        
      • 切换分支:
        git checkout <branch-name>
        
      • 创建并切换到新分支:
        git checkout -b <branch-name>
        
      • 删除分支:
        git branch -d <branch-name>
        
      • 合并分支:
        git merge <branch-name>
        
      • 查看分支:
        git branch
        
    • 远程仓库操作

      • 添加远程仓库

        • 添加远程仓库:
          git remote add origin <repository-url>
          
        • 查看远程仓库:
          git remote -v
          
      • 推送与拉取

        • 推送代码到远程仓库:
          git push origin <branch-name>
          
        • 从远程仓库拉取代码:
          git pull origin <branch-name>
          
        • 推送所有标签:
          git push --tags
          
      • 拉取最新代码

        • 拉取最新的代码并合并:
          git pull origin master
          
    • Git 进阶命令

      • Git Rebase
        git rebase 命令用于将一个分支的变更合并到另一个分支上,与 git merge 的区别在于,rebase 会将提交的历史改写为线性。

        • 切换到需要变基的分支:
          git checkout feature-branch
          
        • 执行变基操作:
          git rebase master
          
        • 如果发生冲突,解决冲突后继续变基:
          git add 冲突文件
          git rebase --continue
          
        • 完成后,将变基后的分支推送到远程仓库:
          git push origin feature-branch --force
          
      • Git Stash
        git stash 可以暂时保存当前工作目录的改动,以便切换到其他分支。

        • 保存当前修改:
          git stash
          
        • 查看当前的 stash:
          git stash list
          
        • 恢复最近保存的 stash:
          git stash pop
          
        • 如果不再需要某个 stash,可以删除它:
          git stash drop stash@{0}
          
      • Git 标签(Tag)
        标签用于标记特定的提交,常用于发布版本。

        • 创建标签:
          git tag v1.0.0
          
        • 推送标签到远程仓库:
          git push origin v1.0.0
          
        • 查看所有标签:
          git tag
          
        • 删除本地标签:
          git tag -d v1.0.0
          
      • Git Submodule
        Git 子模块用于在一个 Git 仓库中嵌套另一个 Git 仓库。

        • 添加子模块:
          git submodule add <repository-url> <path>
          
        • 初始化子模块:
          git submodule init
          
        • 更新子模块:
          git submodule update
          
    • 参考资料

    第12课.Svn安装配置
      1. 安装 SVN 程序
      • Windows

        • 访问 SVN 官方下载页面:https://subversion.apache.org/packages.html
        • 下载适用于 Windows 的安装程序(例如:TortoiseSVN)。
        • 运行安装程序,按照提示完成安装,推荐使用默认设置。
      • macOS

      • Linux
        在终端中运行以下命令安装 SVN:

        • Ubuntu / Debian:
          sudo apt update
          sudo apt install subversion
          
        • CentOS / RHEL:
          sudo yum install subversion
          
        • Fedora:
          sudo dnf install subversion
          
      1. 配置 SVN 用户信息
        安装完成后,需要配置 SVN 用户信息。
      • 配置用户名:
        svn propset svn:username "Your Name" <repository-path>
        
      • 配置用户邮箱:
        svn propset svn:email "youremail@example.com" <repository-path>
        
      • 配置提交日志:
        svn propset svn:log "Your commit message" <repository-path>
        
      • 检查配置:
        svn info
        
      1. 上传并提交代码(SVN 代码托管平台)
      • 上传本地代码到 SVN 仓库
        • 创建本地工作副本:
          svn checkout <repository-url>
          
        • 将代码添加到工作副本:
          svn add <file-or-directory>
          
        • 提交更改到 SVN 仓库:
          svn commit -m "Your commit message"
          
      • 提交特定文件
        • 如果只提交某些文件,可以指定文件名:
          svn commit <file1> <file2> -m "Commit message for specific files"
          
      1. 下载托管的代码(SVN 代码托管平台)
      • 获取 SVN 仓库代码
        • 从远程 SVN 仓库检出代码:
          svn checkout <repository-url>
          
        • 更新本地工作副本以获取最新的代码:
          svn update
          
        • 检出指定的分支或标签:
          svn checkout <repository-url>/branches/<branch-name>
          
      • 查看文件的历史记录
        • 查看文件的修改历史:
          svn log <file>
          
        • 查看目录的修改历史:
          svn log <directory>
          
      1. 参考资料

    第三章.工程软件学习

    第13课.Genesis2000/InCAM/InCAMPro安装配置
    第1节.CentOS 7安装配置Genesis2000
    • 步骤1.安装前准备工作(root用户):

      • CentOS7安装wine工具:
        yum install epel-release
        yum install wine
        
      • CentOS7安装依赖包:
        yum install libX11.so.6 --setopt=protected_multilib=false
        
      • CentOS7字体安装:
        yum install -y *org*font*
        
    • 步骤2.安装Genesis2000:

      • 复制安装文件到/opt/linux_genesis目录:在这里插入图片描述

      • 启动Genesis2000安装脚本install.csh安装程式:

        cd /opt/linux_genesis/Genesis-Linux
        ls
        

        如图找到install.csh安装脚本文件
        在这里插入图片描述
        执行csh install.csh命令启动安装脚本

        csh install.csh
        

        如下图启动程式安装界面
        在这里插入图片描述
        如下图配置安装参数,单击"Load Installation Plug-in"
        在这里插入图片描述
        如下图单击"Server"进入下一步
        在这里插入图片描述
        如下图设置安装路径为"/frontline/app_gen",单击"Copy product files"进入下一步
        在这里插入图片描述
        如下分别在弹窗窗口依次点击"Yes,OK, YES, Genesis"等待当前步骤执行完成
        在这里插入图片描述在这里插入图片描述
        在这里插入图片描述
        在这里插入图片描述
        当"Copy product files"完成后如下图显示
        在这里插入图片描述
        如下图单击"Set file permissions"进入下一步,完成后显示"Done"
        在这里插入图片描述
        如下图单击"Update license"进入下一步,完成后显示"Error"
        在这里插入图片描述

        注意:此步报错不必理会

        如下图单击"Update startup files"进入下一步,弹出窗口单击"YES",然后在单击"OK"完成此步
        在这里插入图片描述
        在这里插入图片描述
        完成后如下图显示
        在这里插入图片描述
        如下图单击"Set users/group"配置初始管理员用户及用户组
        在这里插入图片描述
        完成后如下图显示
        在这里插入图片描述
        单击"Set logical databases"设置库文件路径
        在这里插入图片描述
        在这里插入图片描述
        完成后如下图显示
        在这里插入图片描述
        单击"Update O.S. Kernel"后进入下一步
        在这里插入图片描述
        单击"check installation"检查安装状况
        在这里插入图片描述
        完成后如下图显示
        在这里插入图片描述

      • 替换安装目录下的get及gnd程序及配置license文件:

        • 替换get文件
          cd /opt/linux_genesis
          ls
          cp get /frontline/app_gen/e100/get
          cp: 是否覆盖"/frontline/app_gen/e100/get/get" y
          
        • 替换gnd文件
          cd /opt/linux_genesis
          ls
          cp gnd /frontline/app_gen/e100/gnd
          cp: 是否覆盖"/frontline/app_gen/e100/gnd/gnd" y
          
        • 配置license文件
          cd /opt/linux_genesis
          ls
          cp GN00-9281-A8F9-CF68 /frontline/app_gen/share/license
          
        • 配置Genesis2000启动及运行环境:
          创建/genesis软链接
          ln -s /frontline/app_gen /genesis
          
          配置genesis服务启动:
          安装依赖包
          yum install libz.so.1 --setopt=protected_multilib=false
          yum install libfreetype.so.6
          
          启动genesis服务:
          systemctl start genesis
          systemctl status genesis  (查看服务状态)
          ps -ef|grep gnd (查看gnd进程是否已经启动")
          
          看到如下图所示表示gnd进程已启动:
          在这里插入图片描述
        • 启动Genesis2000,验证安装是否成功:
          安装依赖包
          yum install libXp.so.6 -y
          yum install libXt.so.6 -y
          
          root用户下验证启动Genesis2000:
          cd /genesis/e100/get
          ./get
          
          输入账户密码成功后登入软件,如下图所示:
          在这里插入图片描述
        • 配置普通用户启动Genesis2000:
          配置/genesis/init.csh初始化文件
          vim /genesis/init.csh
          
          如下图编辑init.csh文件内容后保存退出
          在这里插入图片描述
          配置普通用户(例:incam) .cshrc环境变量加载文本
          vim /home/incam/.cshrc
          
          如下图编辑.cshrc文件内容
          在这里插入图片描述
          配置普通用户(incam)默认使用csh
          vim /etc/passwd
          
          如下图编辑文本最后一行shell为/bin/csh
          在这里插入图片描述
          配置.Xmodmap文档激活Genesis2000快捷键模式
          vim /home/incam/.Xmodmap
          
          如下图编辑.Xmodmap文本
          在这里插入图片描述
          如下图注销普通用户后打开终端按提示启动Genesis2000
          在这里插入图片描述
          打开终端输入"get"后回车启动并登录Genesis2000
          get
          
          成功后如下图进入Genesis2000
          在这里插入图片描述

    课后作业:

    • 安装完成Linux版Genesis2000软件
    • 配置普通用户登录Genesis2000
    • 启动Genesis2000并创建一个料号
    第2节.华为欧拉安装配置InCAMPro
    • 安装InCAMPro:
      • 复制安装文件到"/root/桌面"目录:
        在这里插入图片描述

      • 启动InCAMPro安装程式:

        cd /root/桌面
        ls
        

        如图找到InCAMPro-5.0SP4.364587-linux-x64-installer.run安装文件

        执行修改安装文件权限命令并执行安装文件

        chmod 777 InCAMPro-5.0SP4.364587-linux-x64-installer.run
        ./InCAMPro-5.0SP4.364587-linux-x64-installer.run
        

        如下图安装程序启动,单击"Next"进入下一步
        在这里插入图片描述

        如下图配置安装参数,单击"Next"
        在这里插入图片描述
        如下图选择要安装的类型,单击"Next"进入下一步,我们这里仅安装客户端及InLink模块
        在这里插入图片描述

        如下图设置安装路径为"/incampro",单击"Next"进入下一步
        在这里插入图片描述

        如下设置"/tmp"为临时目录,单击"Next"继续
        在这里插入图片描述
        如下设置"/incampro/server"为server目录,单击"Next"继续

        注意:需要先挂载服务端的server路径在设置的路径下,假设服务端IP是172.16.8.1,服务端的server目录在/opt/server目录,我们将服务端的server挂载到/incampro/server即可,没有成功挂载服务端server是无法继续往下安装客户端的

        mount 172.16.8.1:/opt/server /incampro/server
        

        在这里插入图片描述

        如下图单击"Next"进入下一步
        在这里插入图片描述

        如下图需按Inplan的Oracle相关配置参数填写后单击"Install"进入下一步
        在这里插入图片描述

        注意:没有InPlan的不用安装InLink

        如下图配置tnsnames.ora单击"Install"进入下一步
        在这里插入图片描述

        如下图单击"Install"等待安装程序执行
        在这里插入图片描述
        在这里插入图片描述
        在这里插入图片描述
        如下图单击"Finish"完成安装
        在这里插入图片描述

      • 配置InCAMPro:

        • 将版本目录链接成release目录

          cd /incampro
          ls
          ln -s /incampro/5.1SP2 /incampro/release
          
        • 配置普通用户(incam)目录.cshrc文件

          cd /home/incam
          vim .cshrc
          

          输入以下内容,根据自身实际路径调整

          	# .cshrc
          	rm -rf /home/incam/.history >& /dev/null
          	source /incampro/server/init.csh
          	
          	setenv GTK_IM_MODULE ibus
          	setenv QT_IM_MODULE ibus
          	setenv XMODIFIERS @im=ibus
          	setenv QT_NO_SESSION_MANAGEMENT 1
          	setenv INCAM_DIR /incampro
          	setenv INCAM_TMP /incampro/tmp
          	alias mesbox "python3 /incampro/server/site_data/scripts/CAM_public_system/mesbox.py"
          	alias incam "/incampro/release/bin/incampro.csh"
          
        • 配置普通用户默认SHELL为csh

          # 进入root用户
          vim /etc/passwd
          # 找到"incam:x:1000:1000:incam:/home/incam"......这一行,
          # 改为"incam:x:1000:1000:incam:/home/incam:/bin/csh"后reboot重启系统,
          # 进入普通用户incam后"ECHO $SHELL"查看默认的SHELL是否修改ok
          

          在这里插入图片描述

        • 安装依赖包

          yum install libXaw
          
        • 配置加密狗客户端:

          # 启动配置页面
          firefox
          

          如下图先选择中文环境后单击配置进入配置页面:
          在这里插入图片描述
          如下图配置用户页面
          在这里插入图片描述
          如下图配置访问远程授权管理器页面
          在这里插入图片描述
          如下图配置从客户端访问页面
          在这里插入图片描述

        • 重启系统并进入普通用户(incam),启动终端并输入incam回车,输入账号密码进入InCAMPro:
          桌面右键->打开终端->输入incam->回车->输入账户/口令->进入InCAMPro
          启动终端并输入incam回车启动在这里插入图片描述
          如下图输入账户/口令后回车启动InCAMPro在这里插入图片描述
          如下图进入InCAMPro
          在这里插入图片描述

    课后作业:

    • 安装完成Linux版InCAMPro软件
    • 配置普通用户登录InCAMPro
    第14课.Genesis2000/InCAM/InCAMPro操作基础
    第1节.Genesis2000操作基础
    第2节.InCAM操作基础
    第3节.InCAMPro操作基础
    第15课.Genesis2000/InCAM/InCAMPro系统参数
    • 1.Genesis2000的主要系统参数及管理目录说明:

      • Genesis2000软件目录图示:
        在这里插入图片描述

      • 系统结构及主要文件程式释义:

        |e100
        |---all
        |------errs
        |---------ALL_ERRS (软件所有报错弹窗信息分类汇总文档)
        |------fonts (软件自带字体存放目录)
        |---------canned_57 
        |---------canned_67
        !---------......
        |------helps
        |---------line (LMC文档<开发文档>存放目录)
        |------inlink (当MI使用inplan/inflow设计工程资料时可以通过inlink直接同步MI做好的特定资料到CAM料号下)
        |------markers (分孔图样式文件存放目录,允许自定义分孔图刀序样式)
        |------perl (perl语言接口存放位置,我们可以参照这些接口自定义其他开发语言的接口)
        |------pixmaps (一些软件用到的图片文件存放目录)
        |------scr_start.csh (脚本语言配置程式,我们在这里配置自己的脚本语言环境)
        |------sysattr (系统属性文件,我们一般不在这里自定义属性,因为这个文件会跟随版本一起升级)
        |---get
        |------get.exe (软件主程式)
        |---gfb
        |------gfb.exe (form窗口编辑主程式,已过时)
        |---gfl
        |------gfl.exe (flow流程配置主程式,已过时)
        |---gnd
        |------gnd.exe (软件主服务程式,如果当前程序不能运行将无法正常执行软件)
        |---misc
        |---prog(erf参数文档主目录,当系统sys下没有frontline_prog时软件默认读此路径)
        |------dfm (软件优化功能配置文件目录)
        |------cleanup(软件cleanup配置文件目录)
        |------analysis (软件分析功能配置文件目录)
        |fw
        |---jobs (odb++料号文件存放位置)
        |---lib (系统公共资源存放位置)
        |------flows (存放所有flows文件,已过时)
        |------forms (存放所有forms文件,已过时)
        |------fonts (字体存放目录, 优先读取库中的字体)
        |------fonts_ex (自定义的cad字体存放目录, 优先读取库中的字体)
        |---------shx (存放shx格式字体)
        |------------......
        |---------ttf (存放ttf格式字体)
        |------------......
        |------misc
        |---------userattr (自定义属性文件)
        |------symbols (系统symbol库)
        |------steps (存放一些公共的step,例如常用的coupon等)
        |------wheels (存放一些自定义的wheel文件)
        |logs (存放日志文件)
        |share
        |---.comms (存放加密狗相关的一些文件)
        |------gend_global (IP需指向加密狗服务器)
        |------gend_local  (IP需指向加密狗服务器)
        |---license (存放授权文件)
        |---groups (用户组配置文件)
        |---joblist (料号清单文件)
        |---privs (权组配置文件)
        |---rcs (料号上锁清单文件)
        |---users (用户账户/明码配置文件)
        |---users97 ( 用户账户/密码配置文件)
        |sys
        |---frontline_prog (erf参数文档主目录,当系统sys下有frontline_prog时软件默认优先读此路径)
        |------dfm (软件优化功能配置文件目录)
        |------cleanup(软件cleanup配置文件目录)
        |------analysis (软件分析功能配置文件目录)
        |---hooks (软件钩子脚本目录汇总)
        |------ffilters (软件过滤器脚本配置目录)
        |---------names (过滤器功能清单)
        |---------script 过滤器功能配置脚本)
        |------line_hooks (软件lmc指令钩子脚本目录)
        |---------指令.pre (指令前置钩子脚本, 执行指令前先做什么)
        |---------指令.post (指令后置钩子脚本, 执行指令后再做什么)
        |------ncd (自动钻孔输出管理器钩子脚本及配置文件路径)
        |------ncr (自动锣带输出管理器钩子脚本及配置文件路径)
        |------acquire (自动备份导入配置脚本,较少使用)
        |------secure (自动备份导出配置脚本,较少使用)
        |------drill_size (自动补偿钻孔管理器钩子脚本)
        |------drill_size.tab (钻头配置文件)
        |------film_sizes (奥宝光绘机底片尺寸配置文件)
        |------lyr_rule (按厂内层别命名自动定义属性及排序配置文件)
        |------orbotech_plot_spool.config (奥宝光绘机输出配置文件)
        |------userdef_stamp_formats (奥宝LDI输出自动参数配置文件)
        |------rout_tools (锣带刀具参数配置文件)
        |------script_start.csh (脚本运行起始程序)
        |---scripts (脚本存放目录)
        |---bindings (脚本快捷键绑定文件)
        |---colors (图层颜色配置文件)
        |---dblist (料号库配置文件)
        |tmp (临时文件存储目录)
        |Xmanager(Xmanager软件目录,Windows平台必须依赖此软件才能执行Genesis2000)
        |Genesis.bat (软件启动批处理文件)
        
    • 2.InCAM/InCAMPro的主要系统参数及管理目录说明:

      • InCAM/InCAMPro软件目录图示
        在这里插入图片描述

      • 系统结构及主要文件程式释义:

        |tmp (临时文件存储目录)
        |release (软件版本主程序)
        |---app_data
        |------errs
        |---------ALL_ERRS (软件所有报错弹窗信息分类汇总文档)
        |------img (软件图片资源目录)
        |------markers (分孔图样式文件存放目录,允许自定义分孔图刀序样式)
        |------perl (perl语言接口存放位置,我们可以参照这些接口自定义其他开发语言的接口)
        |------python (python语言接口存放位置,新版本的InCAMPro中已提供官方版本的python接口)
        |------sysattr (系统属性文件,我们一般不在这里自定义属性,因为这个文件会跟随版本一起升级)
        |---bin
        |------admin_tools (系统管理软件目录)
        |------inlink (inlink安装路径)
        |------incampro.csh (InCAMPro启动脚本)
        |------dbutil (dbutil程式)
        |------gateway (gateway程式,外挂实现的主程式)
        |------incamd (InCAMPro主服务程式)
        |---def_data (软件的一些默认配置文件及系统路径)
        |---help (帮助文档存放目录)
        |---incamgv (料号web浏览主程序,需要单独的license)
        |---utils (存放一些系统的依赖包或者一些常用的系统程式)
        |incamd (软件主服务程序目录)
        |---app_data
        |---bin
        |---utils
        |server (软件配置服务目录)
        |---config (一些诶主要的配置文件及license文件存放路径)
        |------license (存放授权文件目录)
        |------groups.xml (用户组配置文件)
        |------joblist.xml  (料号清单文件)
        |------privs (权组配置文件)
        |------rcs (料号上锁清单文件)
        |------users.xml  (用户账户/明码配置文件)
        |---logs (存放日志文件)
        |---site_data (系统配置及脚本主目录)
        |------frontline_prog (erf参数文档主目录,当前路径下有frontline_prog时软件默认优先读此路径)
        |---------dfm (软件优化功能配置文件目录)
        |---------cleanup(软件cleanup配置文件目录)
        |---------analysis (软件分析功能配置文件目录)
        |------hooks (软件钩子脚本目录汇总)
        |---------ffilters (软件过滤器脚本配置目录)
        |------------names (过滤器功能清单)
        |------------script 过滤器功能配置脚本)
        |---------line_hooks (软件lmc指令钩子脚本目录)
        |------------指令.pre (指令前置钩子脚本, 执行指令前先做什么)
        |------------指令.post (指令后置钩子脚本, 执行指令后再做什么)
        |---------ncd (自动钻孔输出管理器钩子脚本及配置文件路径)
        |---------ncr (自动锣带输出管理器钩子脚本及配置文件路径)
        |---------acquire (自动备份导入配置脚本,较少使用)
        |---------secure (自动备份导出配置脚本,较少使用)
        |---------drill_size (自动补偿钻孔管理器钩子脚本)
        |---------drill_size.tab (钻头配置文件)
        |---------film_sizes (奥宝光绘机底片尺寸配置文件)
        |---------lyr_rule (按厂内层别命名自动定义属性及排序配置文件)
        |---------orbotech_plot_spool.config (奥宝光绘机输出配置文件)
        |---------userdef_stamp_formats (奥宝LDI输出自动参数配置文件)
        |---------rout_tools (锣带刀具参数配置文件)
        |---------script_start.csh (脚本运行起始程序)
        |------scripts (脚本存放目录)
        |---library
        |------cam_guides (camguide文件主目录)
        |------chk (用户自定义参数主目录)
        |------fonts (字体存放目录, 优先读取库中的字体)
        |------fonts_ex (自定义的cad字体存放目录, 优先读取库中的字体)
        |------forms (存放所有forms文件,已过时)
        |------symbols (系统symbol库)
        |------whltemps (wheel库)
        |---users (用户目录)
        |---init.csh (环境变量配置脚本)
        |---init.gen (环境变量配置脚本)
        |idb (软件料号库,路径可以自定义)
        |---jobs (料号资料目录)
        |CamConnector (InPlan/Inflow同步服务程序目录)
        |tnsnames.ora (Inlink TNS配置文件)
        |network_config.xml (server目录及tmp临时目录指向配置文档)
        
    • 以上只是列举的部分维护过程中必须了解的系统路径及文件,在InCAMPro的维护中基本上已实现了通过软件界面或者管理员工具实现了前台管理,在非必要的情况下我们尽量不去修改后台文件来维护系统!

    第16课.Genesis2000/InCAM/InCAMPro基础命令
    • 1.Genesis2000的开发文档路径"你的安装路径\e100\all\helps\line":
      在此我们主要是学会看懂开发文件的的指令释义
      我们以最常见的add_pad为例:
      首先找到开发文档路径下的editor文件,用写字板打开并找到"add_pad",如下图:
      在这里插入图片描述
      释义:
      Command: add_pad ------>指令:添加pad
      Description: 描述----------->描述: 为受影响的层别添加pad功能…
      Parameter: 参数------------>指令有哪些参数:

      • attributes : yes/no----------> 是否为添加的pad添加属性,"yes"是,"no"否;
      • x, y: 添加的坐标哪里,x->x方向坐标值,y->y方向坐标值;
      • symbol: 添加的物件名字,在Genesis2000中symbol是某个物件的统称;
      • polarity:添加symbol的极性,"positive"正极性,"negative"负极性;
      • angle:添加的symbol角度;
      • mirror:是否镜像添加,"yes"是,"no"否;
      • nx:x方向添加的个数;
      • ny:y方向添加的个数;
      • dx:x方向添加的间距;
      • dy:y方向添加的间距;
      • xscale:x方向的涨缩比例值;
      • yscale:y方向的涨缩比例值
      • 那么我们添加一个pad的完整指令就是:
        add_pad,attributes=no,x=0,y=0,symbol=r100,polarity=positive,angle=0,mirror=no,nx=1,ny=1,dx=0,dy=0,xscale=1,yscale=1
        释义:在0,0坐标处添加一个大小为100的圆pad,极性为正,角度为0度,不镜像,x,y方向只有一个,x,y方向的间距为零,涨缩系数x,y为1:1不涨缩
        软件中添加效果:
        在这里插入图片描述
        如图,我们在软件界面的操作实际上就是再执行一条条的软件内置指令,脚本实际上就是让软件按照我们编制好的指令集有逻辑有计划的执行软件的内置指令,到这里我们就要理解了,不是用户做不到写个脚本就好了,能写脚本的前提是软件支持我们需要的指令或者指令集,与软件开发不是在一个维度的工作,我们称为软件二次开发或者脚本开发,与软件开发不同的是,一个是软件功能或者指令从无到有的过程,一个是在现有的指令或者指令集基础上开发出用户便捷高效且客制化的功能,理解到这一点大家就应该能对我们现在的脚本工作有个基本的了解了!
    • 2.InCAM/InCAMPro从本质上来说它就是Genesis2000的升级版本,所以我们学习理解这两款软件如果是建立在已经掌握Genesis2000/GenFlex的基础上会相当容易上手,以我个人经验来说完全不会有任何难度,最大的不适应仅仅是初期操作习惯养成问题而已,以相同的add_pad指令为例,我们看看操作和开发文档有多大差异:

      • 首先我们打开开发文档,如下图直接在软件界面即可开启:
        在这里插入图片描述
      • 我们在看看InCAM/InCAMPro的指令:
        在这里插入图片描述
        如图此条指令在InCAMPro中与Genesis2000的指令并无太大的差异,仅仅是新增了"direction",“resize"这两个参数,具体的释义不做复述,这就是为什么我们的Genesis2000脚本代码为什么能直接在InCAM/InCAMPro上直接运行的原因,因为它们的底层指令是差不多的,当然反过来也就是为什么Genesis2000很多时候不能运行InCAM/InCAMPro代码的原因了,总结下来就是一句话"向下兼容,高版本兼容低版本”,我们再看看用户操作,如下图:
        在这里插入图片描述
        如上图,对于用户操作基本大同小异,对于已经掌握Genesis2000操作的人员并不会有太高的学习成本,对于脚本工程师更是没有任何难度可言!
        综上所述,我们开发脚本时,最重要的是了解软件的功能,熟练掌握基础开发指令,很多同行可能会有个疑问,软件是自带基础指令录制功能的,我们直接使用录制的代码修改不一样的可以完成脚本编辑,这里要特别强调,录制的代码并不是包含所有指令参数的,部分指令也是不支持录制的,所以,看官方提供的文档永远是最准确可靠的!

    第四章.系统维护学习

    第17课.Linux系统维护汇总(PCB制造业制前工程CAM系统相关)

    CentOS7系统维护汇总

    • 操作系统相关:

      • 1.配置CentOS7国内镜像源
        打开终端,备份原有源文件:

        mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
        

        下载阿里云镜像源(适用于CentOS 7):

        wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
        

        清理缓存并生成新缓存:

        yum clean all && yum makecache
        
      • 2.安装必要的工具包
        以下为常用工具包安装命令:

        yum install -y epel-release  # 安装EPEL扩展源  
        yum install -y vim wget curl net-tools lsof telnet zip unzip  
        yum groupinstall -y "Development Tools"  # 开发工具组  
        
      • 3.系统时间同步异常
        检查并启用NTP服务:

        yum install -y ntp  
        systemctl start ntpd  
        systemctl enable ntpd  
        timedatectl set-timezone Asia/Shanghai  # 设置时区  
        
      • 4.防火墙与SELinux配置
        临时关闭防火墙(生产环境慎用):

        systemctl stop firewalld  
        systemctl disable firewalld  
        

        临时禁用SELinux:

        setenforce 0  
        sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config  
        
      • 5.磁盘空间不足处理
        查看磁盘使用情况:

        df -h  
        

        清理旧内核及日志文件:

        yum autoremove  # 移除旧内核  
        journalctl --vacuum-size=50M  # 限制日志大小  
        
      • 6.SSH连接超时问题
        修改/etc/ssh/sshd_config,调整以下参数:

        ClientAliveInterval 60  
        ClientAliveCountMax 3  
        

        重启SSH服务生效:

        systemctl restart sshd  
        
      • 7.网络接口启动失败
        检查网卡配置文件(如ifcfg-eth0):

        vi /etc/sysconfig/network-scripts/ifcfg-eth0  
        

        确保ONBOOT=yes,重启网络服务:

        systemctl restart network  
        
      • 8.系统语言乱码问题
        安装中文语言包并设置环境:

        yum install -y glibc-common zh-CN  
        localectl set-locale LANG=zh_CN.UTF-8  
        
      • 9.Yum安装报错“Could not resolve host”
        检查DNS配置:

        vi /etc/resolv.conf  
        

        添加可靠DNS服务器(如nameserver 8.8.8.8),重启网络服务。

      • 10.内核参数优化
        修改/etc/sysctl.conf,追加以下内容:

        net.ipv4.tcp_fin_timeout = 30  
        fs.file-max = 65535  
        

        使配置生效:

        sysctl -p  
        
      • 11.配置自定义的系统服务(自定义启动程序以名为askpcbvnc的程式为例)
        1.编写自动执行脚本askpcbvnc.sh:

        #!/bin/sh
        
        export ASK_PCB_VNC_DIR=/home/incam			# 设置程式安装目录环境变量
        export LANG=en_US.UTF-8						# 设置语言环境
        export LC_ALL=en_US.UTF-8					# 覆盖所有其他区域设置变量
        
        case "$1" in
        'start')
            if [ -x $ASK_PCB_VNC_DIR ]; then
                cd $ASK_PCB_VNC_DIR
                echo '启动askpcbvnc服务中...'
                for i in {10..30}; do
                    ./askpro5new $i &
                done
                wait
            fi
            ;;
        'stop')
                echo '终止askpcbvnc服务中...'
                pkill -f askpro5new
                ps -ef | grep 'Xvnc -depth 24' | grep -v grep | awk '{print $2}' | xargs kill -9
                ;;
        'restart')
                $0 stop
                $0 start
                ;;
        'status')
            if pgrep -f askpcbvnc.sh > /dev/null; then
              echo "askpcbvnc服务正在运行中."
            else
              echo "askpcbvnc服务异常."
            fi
            ;;
          *)
            echo "例句: /etc/init.d/askpcbvnc {start|stop|restart|status}"
            exit 1
            ;;
        esac
        exit 0
        

        2.保存脚本文件到"/etc/init.d"目录并赋予执行权限:

        cd /etc/init.d
        chmod +x askpcbvnc.sh
        

        注意事项:
        1.代码主要调用askpro5new可执行文件,文件路径:/home/incam/askpro5new


        3.创建systemd服务文件(/etc/systemd/system/askpcbvnc.service):
        直接在root用户终端执行以下指令

        vim /etc/systemd/system/askpcbvnc.service
        

        将以下代码写入"/etc/systemd/system/askpcbvnc.service"文件并保存

        [Unit]
        Description=Ask PCB VNC Service
        After=network.target
        
        [Service]
        # User=incam
        Environment="HOME=/home/incam"
        
        Type=simple
        ExecStart=/bin/sh /etc/init.d/askpcbvnc.sh start
        ExecStop=/bin/sh /etc/init.d/askpcbvnc.sh stop
        User=incam
        Group=incam
        WorkingDirectory=/home/incam
        Restart=on-failure
        
        [Install]
        WantedBy=multi-user.target
        

        4.配置Centos7系统服务askpcbvnc.service
        启用服务
        运行以下命令以启用并启动服务:

        # 重新加载 systemd 管理器配置
        sudo systemctl daemon-reload
        
        # 启动服务
        sudo systemctl start askpcbvnc.service
        
        # 设置开机自启
        sudo systemctl enable askpcbvnc.service
        

        5.管理服务

        • 查看状态:
          systemctl status askpcbvnc.service
          
        • 停止服务:
          systemctl stop askpcbvnc.service
          
        • 重启服务:
          systemctl restart askpcbvnc.service
          
      • 12.直接禁用 usb0 且不影响其他 USB 设备的简明方案
        直接禁用 usb0 且不影响其他 USB 设备的简明方案:

        bash复制# 1. 立即禁用接口
        sudo ip link set dev usb0 down
        
        # 2. 阻止接口自动启动
        sudo tee /etc/sysconfig/network-scripts/ifcfg-usb0 >/dev/null <<'EOF'
        DEVICE=usb0
        ONBOOT=no
        NM_CONTROLLED=no
        EOF
        
        # 3. 创建强效 UDEV 规则(匹配物理设备特征)
        USB_VENDOR=$(cat /sys/class/net/usb0/device/idVendor 2>/dev/null)
        USB_PRODUCT=$(cat /sys/class/net/usb0/device/idProduct 2>/dev/null)
        
        sudo tee /etc/udev/rules.d/99-kill-usb0.rules >/dev/null <<EOF
        # 物理级禁用USB网卡
        ACTION=="add", SUBSYSTEM=="usb", ENV{ID_VENDOR_ID}=="$USB_VENDOR", ENV{ID_MODEL_ID}=="$USB_PRODUCT", RUN+="/bin/sh -c 'echo 1 > /sys\$DEVPATH/remove'"
        EOF
        
        # 4. 立即触发规则
        sudo udevadm control --reload-rules
        sudo udevadm trigger
        sleep 2  # 等待规则执行
        
        # 5. 物理移除设备(模拟拔插)
        echo "1" | sudo tee /sys/bus/usb/devices/*/remove >/dev/null 2>&1
        

        最终验证命令:

        bash复制# 检查接口状态(应不存在)
        ip link show usb0 2>&1 | grep "not exist"
        
        # 检查设备连接(无输出表示成功)
        lsusb | grep "$USB_VENDOR:$USB_PRODUCT"
        

        永久禁用原理:

        组件作用效果
        ip link set down立即关闭接口临时停止网络通信
        ifcfg-usb0(配置文件)禁止系统启动防止重启后自动启用
        UDEV 物理移除规则拦截设备注册阻止内核识别设备
        sysfs remove(操作)模拟设备拔除强制断开物理连接

        恢复方法:

        bash复制sudo rm -f /etc/sysconfig/network-scripts/ifcfg-usb0
        sudo rm -f /etc/udev/rules.d/99-kill-usb0.rules
        sudo udevadm control --reload-rules
        # 重新连接物理设备或重启系统
        
      • 13.CentOS 7保留最新2个版本内核

        # root用户下
        package-cleanup --oldkernels --count=2
        
    • CAM软件系统相关:

      • 1.Centos7下的InCAMPro导出odb++需安装依赖包

        经验分享:解决InCAMPro导出odb++卡死的问题

        yum install -y glibc.i686
        yum install -y libSM-1.2.1-7.el7.i686.rpm
        yum install -y libXext-1.3.2-2.1.el7.i686.rpm
        yum install -y zlib-1.2.7-13.el7.i686.rpm
        yum install -y freetype-2.4.11-9.el7.i686.rpm
        yum install -y libstdc++-4.8.3-9.el7.i686.rpm
        yum install -y libpng12-1.2.50-6.el7.i686.rpm
        yum install -y libXrender-0.9.8-2.1.el7.i686.rpm
        yum install -y libxft.i686
        yum install -y dos2unix
        yum install -y tcsh-6.20.00-12.el8.x86 64.rpm
        yum install -y libXaw-1.0.13-10.el8.x86 64.rpm
        yum install -y libxcrypt-4.1.1-4.el8.i686.rpm
        
      • 2.远程保存

        经验分享:解决Genesis2000/InCAM/InCAMPro远程保存的问题

        首先了解什么是PID:PID字面理解就是唯一进程码的意思,每开启一个软件窗口系统都会产生一个唯一的进程码,在Genesis2000/InCAM/InCAMPro中,界面直接可以看到进程码,如下图:
        在这里插入图片描述

        # 1.执行"/incam/incamd/bin/gateway WHO"获取用户地址
        [incam@incampro-yy-server ~/Desktop]$ /incam/incamd/bin/gateway WHO
        a1@incampro-yy-server.incampro-yy-server:90 lyk@incampro-yy-server.incampro-yy-server:90 jwz@incampro-yy-server.incampro-yy-server:90
        # 释义: 主机incampro-yy-server 5990端口登录了三个InCAMPro账号(a1, lyk, jwz)
        
        # 2.执行"/incam/incamd/bin/gateway lyk@incampro-yy-server.incampro-yy-server:90 'COM save_job,job=me10n99519a0,override=no'"料号保存指令
        /incam/incamd/bin/gateway lyk@incampro-yy-server.incampro-yy-server:90 'COM save_job,job=me10n99519a0,override=no'
        # 释义: 使用gateway工具远程保存lyk用户正在操作的me10n99519a0料号
        
        # 3.执行"/incam/incamd/bin/gateway %PID@incampro-yy-server.incampro-yy-server 'COM script_run,name=/incam/server/site_data/scripts/CAM_output_system/MDM_data_output/get_mdm_info-t.py,env1=JOB=m06a0786a00,env2=STEP=panel,params=1'"运行脚本
        /incam/incamd/bin/gateway %PID(假设编码为123)@incampro-yy-server.incampro-yy-server:90 'COM script_run,name=/incam/server/site_data/scripts/CAM_output_system/MDM_data_output/get_mdm_info-t.py,env1=JOB=m06a0786a00,env2=STEP=panel,params=1'
        #  释义: 使用gateway工具远程在incampro-yy-server主机的5992端口调用PID为123的InCAMPro软件运行脚本/incam/server/site_data/scripts/CAM_output_system/MDM_data_output/get_mdm_info-t.py,env1=JOB=m06a0786a00,env2=STEP=panel,params=1
        
      • 3.批量杀进程(以InCAMPro为例)

        经验分享:解决类似InCAMPro软件批量退出的问题

        # 搜索所有的InCAMPro进程并获取进程号后批量终止
        ps -e | grep InCAMPro | awk '{print $1}' | xargs kill -9
        
      • 4.系统网络不稳定监测(当使用服务器版软件时会影响软件运行)

        经验分享:监测网络对软件运行的影响

        # 监测并存储网络丢包数据
        ping incampro-yy-server| awk '{print $0"\t" strftime("%Y-%m-%d %H:%M:%S", systime()); fflush()}' >> /home/incam/桌面/test.txt
        # 释义: ping 主机incampro-yy-server 同时将监测的数据存储到指定路径以便后续数据分析或者留存证据
        
      • 5.清除InCAMPro产生的大量日志数据

        经验分享: CAM软件运行过程中会自动产生大量的日志数据,当我们不需要的时候应该及时清理

        # 清除指定的临时文件
        # 案例1:
        cd /incam/tmp
        find ../statistics -mtime +60 -name "statistics-*" -exec rm -Rf {} ;
        # 释义: 删除指定时间前的文件(以删除60天前当前路径statistics目录statistics-开头的文件)
        
        # 案例2:
        find ./ -maxdepth 1 -type f -newermt "Jan 13" -delete
        # 释义: 删除当前文件夹下指定时间(Jan 13)的文件
        
    • 系统磁盘空间容量异常(案例):
      参考博文:Centos7下用Python写一个磁盘空间自动预警脚本

    第五章.脚本开发学习

    第18课.Python3基础
    • Python简介
      Python是一种高级、解释型的编程语言,以简洁易读的语法著称。

      • 特点
        • 简单易学
        • 开源免费
        • 跨平台
        • 丰富的库支持
    • 环境搭建

      • 安装Python
        # Windows
        下载官网安装包:https://www.python.org/downloads/
        
        # Mac
        brew install python
        
        # Linux(CentOS 7)
        sudo yum install python3 -y
        
    • 开发工具推荐

      • VS Code
      • PyCharm
      • Jupyter Notebook
    • 基础语法
      第一个Python程序

      print("Hello, World!")
      
      • 变量和数据类型
        # 基本数据类型
        name = "Python"          # 字符串
        age = 30                 # 整数
        price = 19.99           # 浮点数
        is_active = True        # 布尔值
        
        print(f"语言: {name}, 年龄: {age}年")
        
      • 运算符
        # 算术运算符
        a = 10
        b = 3
        print(a + b)  # 13
        print(a - b)  # 7
        print(a * b)  # 30
        print(a / b)  # 3.333...
        print(a // b) # 3 (整除)
        print(a % b)  # 1 (取余)
        
    • 数据结构

      • 列表(List)

        # 创建列表
        fruits = ['apple', 'banana', 'orange']
        numbers = [1, 2, 3, 4, 5]
        
        # 列表操作
        fruits.append('grape')      # 添加元素
        fruits.remove('banana')     # 删除元素
        print(fruits[0])           # 访问元素
        print(len(fruits))         # 列表长度
        
      • 字典(Dictionary)

        # 创建字典
        person = {
            'name': 'Alice',
            'age': 25,
            'city': 'Beijing'
        }
        
        # 字典操作
        print(person['name'])      # 访问值
        person['job'] = 'Engineer' # 添加键值对
        del person['age']          # 删除键值对
        
        # 遍历字典
        for key, value in person.items():
            print(f"{key}: {value}")
        
      • 元组和集合

        # 元组(不可变)
        coordinates = (10, 20)
        print(coordinates[0])
        
        # 集合(不重复)
        unique_numbers = {1, 2, 3, 3, 4}
        print(unique_numbers)  # {1, 2, 3, 4}
        
    • 控制流程

      • 条件语句
        # if-elif-else
        score = 85
        
        if score >= 90:
            grade = 'A'
        elif score >= 80:
            grade = 'B'
        elif score >= 70:
            grade = 'C'
        else:
            grade = 'D'
        
        print(f"分数: {score}, 等级: {grade}")
        
      • 循环语句
        # for循环
        for i in range(5):
            print(f"循环次数: {i}")
        
        # while循环
        count = 0
        while count < 3:
            print(f"计数: {count}")
            count += 1
        
        # 列表推导式
        squares = [x**2 for x in range(1, 6)]
        print(squares)  # [1, 4, 9, 16, 25]
        
    • 函数编程

      • 函数定义
        def greet(name, message="Hello"):
            """打招呼的函数"""
            return f"{message}, {name}!"
        
        # 调用函数
        result = greet("World")
        print(result)
        
        # 带返回值的函数
        def calculate_area(length, width):
            """计算矩形面积"""
            return length * width
        
        area = calculate_area(5, 3)
        print(f"面积: {area}")
        
      • 高阶函数
        # lambda表达式
        square = lambda x: x ** 2
        print(square(5))  # 25
        
        # map函数
        numbers = [1, 2, 3, 4, 5]
        squared = list(map(lambda x: x**2, numbers))
        print(squared)  # [1, 4, 9, 16, 25]
        
    • 面向对象编程

      • 类和对象
        class Dog:
            """狗类"""
            
            def __init__(self, name, breed):
                self.name = name
                self.breed = breed
            
            def bark(self):
                return f"{self.name}在汪汪叫!"
            
            def get_info(self):
                return f"名字: {self.name}, 品种: {self.breed}"
        
        # 创建对象
        my_dog = Dog("旺财", "金毛")
        print(my_dog.bark())
        print(my_dog.get_info())
        
      • 继承和多态
        class Animal:
            def __init__(self, name):
                self.name = name
            
            def speak(self):
                pass
        
        class Cat(Animal):
            def speak(self):
                return "喵喵喵"
        
        class Dog(Animal):
            def speak(self):
                return "汪汪汪"
        
        # 多态示例
        animals = [Cat("咪咪"), Dog("小黑")]
        for animal in animals:
            print(f"{animal.name}: {animal.speak()}")
        
    • 文件操作

      • 读写文件
        # 写入文件
        with open('example.txt', 'w', encoding='utf-8') as file:
            file.write("Hello, Python!\n")
            file.write("这是第二行内容")
        
        # 读取文件
        with open('example.txt', 'r', encoding='utf-8') as file:
            content = file.read()
            print(content)
        
        # 逐行读取
        with open('example.txt', 'r', encoding='utf-8') as file:
            for line in file:
                print(line.strip())
        
    • 异常处理

      • try-except语句
        try:
            num = int(input("请输入一个数字: "))
            result = 10 / num
            print(f"结果是: {result}")
        except ValueError:
            print("输入的不是有效数字!")
        except ZeroDivisionError:
            print("不能除以零!")
        except Exception as e:
            print(f"发生错误: {e}")
        else:
            print("计算成功!")
        finally:
            print("程序执行完毕")
        
    • 模块和包

      • 导入模块
        # 导入标准库
        import math
        import random
        from datetime import datetime
        
        # 使用模块
        print(math.sqrt(16))  # 4.0
        print(random.randint(1, 100))
        
        # 创建自定义模块
        # mymodule.py
        def say_hello():
            return "Hello from my module!"
        
    • 高级特性

      • 装饰器
        def timer_decorator(func):
            def wrapper(*args, **kwargs):
                import time
                start = time.time()
                result = func(*args, **kwargs)
                end = time.time()
                print(f"函数 {func.__name__} 执行时间: {end - start:.2f}秒")
                return result
            return wrapper
        
        @timer_decorator
        def slow_function():
            import time
            time.sleep(1)
            return "完成"
        
        slow_function()
        
      • 生成器
        def fibonacci_generator(n):
            """生成斐波那契数列"""
            a, b = 0, 1
            for _ in range(n):
                yield a
                a, b = b, a + b
        
        # 使用生成器
        for num in fibonacci_generator(10):
            print(num, end=' ')
        
    • 项目实战

      • 简易待办事项应用
        class TodoList:
            def __init__(self):
                self.tasks = []
            
            def add_task(self, task):
                self.tasks.append({"task": task, "completed": False})
                print(f"添加任务: {task}")
            
            def complete_task(self, task_index):
                if 0 <= task_index < len(self.tasks):
                    self.tasks[task_index]["completed"] = True
                    print(f"完成任务: {self.tasks[task_index]['task']}")
                else:
                    print("任务索引无效")
            
            def show_tasks(self):
                print("\n=== 待办事项 ===")
                for i, task in enumerate(self.tasks):
                    status = "✓" if task["completed"] else "○"
                    print(f"{i}. [{status}] {task['task']}")
        
        # 使用示例
        todo = TodoList()
        todo.add_task("学习Python")
        todo.add_task("写项目")
        todo.show_tasks()
        todo.complete_task(0)
        todo.show_tasks()
        
      • 数据分析示例
        import pandas as pd
        import numpy as np
        
        # 创建示例数据
        data = {
            'Name': ['Alice', 'Bob', 'Charlie', 'David'],
            'Age': [25, 30, 35, 28],
            'Salary': [50000, 60000, 70000, 55000]
        }
        
        df = pd.DataFrame(data)
        print("原始数据:")
        print(df)
        
        # 基本数据分析
        print(f"\n数据形状: {df.shape}")
        print(f"\n描述性统计:")
        print(df.describe())
        
        # 数据筛选
        high_salary = df[df['Salary'] > 55000]
        print(f"\n高薪人员:")
        print(high_salary)
        
    • 总结
      Python是一门功能强大且易于学习的编程语言,适用于Web开发、数据分析、人工智能等多个领域。

      • 学习建议
        1. 多写代码,多练习
        2. 阅读优秀的开源代码
        3. 参与实际项目开发
        4. 持续学习新特性
      • 进阶方向
        - Web开发:Django、Flask
        - 数据分析:Pandas、NumPy
        - 机器学习:Scikit-learn、TensorFlow
        - 自动化脚本

    第19课.Python3进阶
    • Python编程进阶
      • 高级数据结构

        命名元组

        from collections import namedtuple
        
        # 定义命名元组
        Point = namedtuple('Point', ['x', 'y'])
        p = Point(10, 20)
        print(p.x, p.y)  # 10 20
        
        # 支持所有元组操作
        print(p[0])  # 10
        
        

        默认字典

        # 自动初始化缺失的键
        word_count = defaultdict(int)
        words = ['apple', 'banana', 'apple', 'orange']
        
        for word in words:
            word_count[word] += 1
        
        print(word_count)  # {'apple': 2, 'banana': 1, 'orange': 1}
        
        

        计数器

        from collections import Counter
        
        # 快速计数
        data = ['red', 'blue', 'red', 'green', 'blue', 'blue']
        counter = Counter(data)
        print(counter.most_common(2))  # [('blue', 3), ('red', 2)]
        
        

        双端队列

        from collections import deque
        
        # 高效的双端操作
        dq = deque([1, 2, 3])
        dq.appendleft(0)    # 左端添加
        dq.append(4)        # 右端添加
        print(dq)           # deque([0, 1, 2, 3, 4])
        
        
      • 并发编程

        多线程

        import threading
        import time
        
        def worker(num):
            """工作线程函数"""
            print(f'线程 {num} 开始工作')
            time.sleep(2)
            print(f'线程 {num} 完成工作')
        
        # 创建并启动线程
        threads = []
        for i in range(3):
            t = threading.Thread(target=worker, args=(i,))
            threads.append(t)
            t.start()
        
        # 等待所有线程完成
        for t in threads:
            t.join()
        
        

        线程池

        from concurrent.futures import ThreadPoolExecutor
        import requests
        
        def download_url(url):
            """下载URL内容"""
            response = requests.get(url)
            return f'{url}: {len(response.content)} bytes'
        
        urls = [
            'https://httpbin.org/get',
            'https://httpbin.org/post',
            'https://httpbin.org/put'
        ]
        
        # 使用线程池执行
        with ThreadPoolExecutor(max_workers=3) as executor:
            results = executor.map(download_url, urls)
            for result in results:
                print(result)
        
        

        多进程

        import multiprocessing
        import os
        
        def square_number(n):
            """计算数字的平方"""
            print(f'进程 {os.getpid()} 计算 {n} 的平方')
            return n * n
        
        if __name__ == '__main__':
            numbers = [1, 2, 3, 4, 5]
            
            # 使用进程池
            with multiprocessing.Pool(processes=2) as pool:
                results = pool.map(square_number, numbers)
                print(f'结果: {results}')
        
        
      • 异步编程

        异步函数

        import asyncio
        import aiohttp
        
        async def fetch_url(session, url):
            """异步获取URL"""
            async with session.get(url) as response:
                return await response.text()
        
        async def main():
            """主异步函数"""
            async with aiohttp.ClientSession() as session:
                tasks = [
                    fetch_url(session, 'https://httpbin.org/get'),
                    fetch_url(session, 'https://httpbin.org/post')
                ]
                results = await asyncio.gather(*tasks)
                for result in results:
                    print(f'获取到 {len(result)} 字符')
        
        # 运行异步程序
        asyncio.run(main())
        
        

        异步生成器

        import asyncio
        
        async def async_counter(limit):
            """异步计数器"""
            for i in range(limit):
                yield i
                await asyncio.sleep(0.1)
        
        async def main():
            async for number in async_counter(5):
                print(f'当前数字: {number}')
        
        asyncio.run(main())
        
        
      • 元编程
        装饰器进阶

        from functools import wraps
        import time
        
        def retry(max_attempts=3, delay=1):
            """重试装饰器"""
            def decorator(func):
                @wraps(func)
                def wrapper(*args, **kwargs):
                    for attempt in range(max_attempts):
                        try:
                            return func(*args, **kwargs)
                        except Exception as e:
                            if attempt == max_attempts - 1:
                                raise e
                            print(f'第 {attempt + 1} 次尝试失败,{delay}秒后重试')
                            time.sleep(delay)
                    return None
                return wrapper
            return decorator
        
        @retry(max_attempts=3, delay=2)
        def unreliable_function():
            """不可靠的函数"""
            import random
            if random.random() < 0.7:
                raise ValueError('随机失败')
            return '成功'
        
        print(unreliable_function())
        
        

        元类

        class SingletonMeta(type):
            """单例元类"""
            _instances = {}
            
            def __call__(cls, *args, **kwargs):
                if cls not in cls._instances:
                    cls._instances[cls] = super().__call__(*args, **kwargs)
                return cls._instances[cls]
        
        class DatabaseConnection(metaclass=SingletonMeta):
            """数据库连接类"""
            def __init__(self, connection_string):
                self.connection_string = connection_string
                print(f'创建数据库连接: {connection_string}')
        
        # 测试单例
        conn1 = DatabaseConnection('mysql://localhost:3306')
        conn2 = DatabaseConnection('mysql://localhost:3306')
        print(conn1 is conn2)  # True
        
        

        描述符

        class PositiveNumber:
            """正数描述符"""
            def __set_name__(self, owner, name):
                self.name = name
            
            def __get__(self, instance, owner):
                return instance.__dict__.get(self.name)
            
            def __set__(self, instance, value):
                if value <= 0:
                    raise ValueError('必须是正数')
                instance.__dict__[self.name] = value
        
        class Product:
            price = PositiveNumber()
            quantity = PositiveNumber()
            
            def __init__(self, price, quantity):
                self.price = price
                self.quantity = quantity
        
        # 使用描述符
        try:
            product = Product(-10, 5)
        except ValueError as e:
            print(f'错误: {e}')
        
        
      • 性能优化
        内存分析

        import sys
        import tracemalloc
        
        def process_data():
            """处理数据的函数"""
            data = [i**2 for i in range(10000)]
            return sum(data)
        
        # 跟踪内存使用
        tracemalloc.start()
        result = process_data()
        snapshot = tracemalloc.take_snapshot()
        tracemalloc.stop()
        
        # 显示内存使用情况
        for stat in snapshot.statistics('lineno')[:5]:
            print(stat)
        
        

        性能分析

        import cProfile
        import pstats
        
        def slow_function():
            """慢速函数"""
            total = 0
            for i in range(100000):
                total += i
            return total
        
        # 性能分析
        profiler = cProfile.Profile()
        profiler.enable()
        result = slow_function()
        profiler.disable()
        
        stats = pstats.Stats(profiler)
        stats.sort_stats('cumulative')
        stats.print_stats(10)
        
        

        缓存优化

        from functools import lru_cache
        
        @lru_cache(maxsize=128)
        def fibonacci(n):
            """带缓存的斐波那契函数"""
            if n < 2:
                return n
            return fibonacci(n-1) + fibonacci(n-2)
        
        # 测试缓存效果
        import time
        
        start = time.time()
        result = fibonacci(35)
        end = time.time()
        print(f'斐波那契(35) = {result}, 耗时: {end-start:.2f}秒')
        
        
      • 设计模式
        工厂模式

        from abc import ABC, abstractmethod
        
        class Animal(ABC):
            """动物抽象类"""
            @abstractmethod
            def speak(self):
                pass
        
        class Dog(Animal):
            def speak(self):
                return "汪汪汪"
        
        class Cat(Animal):
            def speak(self):
                return "喵喵喵"
        
        class AnimalFactory:
            """动物工厂"""
            @staticmethod
            def create_animal(animal_type):
                if animal_type == 'dog':
                    return Dog()
                elif animal_type == 'cat':
                    return Cat()
                else:
                    raise ValueError(f'未知动物类型: {animal_type}')
        
        # 使用工厂
        dog = AnimalFactory.create_animal('dog')
        cat = AnimalFactory.create_animal('cat')
        print(dog.speak(), cat.speak())
        
        

        观察者模式

        class Subject:
            """主题类"""
            def __init__(self):
                self._observers = []
            
            def attach(self, observer):
                self._observers.append(observer)
            
            def detach(self, observer):
                self._observers.remove(observer)
            
            def notify(self, message):
                for observer in self._observers:
                    observer.update(message)
        
        class Observer:
            """观察者类"""
            def update(self, message):
                print(f'收到消息: {message}')
        
        # 使用观察者模式
        subject = Subject()
        observer1 = Observer()
        observer2 = Observer()
        
        subject.attach(observer1)
        subject.attach(observer2)
        subject.notify('状态已更新')
        
        

        策略模式

        from abc import ABC, abstractmethod
        
        class PaymentStrategy(ABC):
            """支付策略接口"""
            @abstractmethod
            def pay(self, amount):
                pass
        
        class CreditCardPayment(PaymentStrategy):
            def pay(self, amount):
                return f'信用卡支付 {amount} 元'
        
        class AlipayPayment(PaymentStrategy):
            def pay(self, amount):
                return f'支付宝支付 {amount}class PaymentContext:
            """支付上下文"""
            def __init__(self, strategy: PaymentStrategy):
                self._strategy = strategy
            
            def execute_payment(self, amount):
                return self._strategy.pay(amount)
        
        # 使用策略模式
        credit_payment = PaymentContext(CreditCardPayment())
        alipay_payment = PaymentContext(AlipayPayment())
        
        print(credit_payment.execute_payment(100))
        print(alipay_payment.execute_payment(200))
        
        
      • 网络编程
        Socket编程

        import socket
        
        def start_server():
            """启动服务器"""
            server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            server_socket.bind(('localhost', 8888))
            server_socket.listen(1)
            
            print('服务器启动,等待连接...')
            client_socket, addr = server_socket.accept()
            print(f'客户端连接来自: {addr}')
            
            # 接收数据
            data = client_socket.recv(1024)
            print(f'收到数据: {data.decode()}')
            
            # 发送响应
            client_socket.send(b'Hello from server!')
            client_socket.close()
            server_socket.close()
        
        def start_client():
            """启动客户端"""
            client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            client_socket.connect(('localhost', 8888))
            client_socket.send(b'Hello from client!')
            response = client_socket.recv(1024)
            print(f'服务器响应: {response.decode()}')
            client_socket.close()
        
        # 在实际应用中,服务器和客户端应该在不同的进程中运行
        
        

        HTTP客户端

        import requests
        import json
        
        class APIClient:
            """API客户端"""
            def __init__(self, base_url):
                self.base_url = base_url
            
            def get(self, endpoint, params=None):
                """GET请求"""
                response = requests.get(f'{self.base_url}/{endpoint}', params=params)
                return response.json()
            
            def post(self, endpoint, data=None):
                """POST请求"""
                headers = {'Content-Type': 'application/json'}
                response = requests.post(
                    f'{self.base_url}/{endpoint}',
                    data=json.dumps(data),
                    headers=headers
                )
                return response.json()
        
        # 使用API客户端
        client = APIClient('https://jsonplaceholder.typicode.com')
        posts = client.get('posts')
        print(f'获取到 {len(posts)} 篇文章')
        
        
      • 数据库操作
        SQLite操作

        import sqlite3
        from contextlib import contextmanager
        
        @contextmanager
        def get_db_connection():
            """获取数据库连接"""
            conn = sqlite3.connect('example.db')
            try:
                yield conn
            finally:
                conn.close()
        
        def setup_database():
            """设置数据库"""
            with get_db_connection() as conn:
                cursor = conn.cursor()
                
                # 创建表
                cursor.execute('''
                    CREATE TABLE IF NOT EXISTS users (
                        id INTEGER PRIMARY KEY AUTOINCREMENT,
                        name TEXT NOT NULL,
                        email TEXT UNIQUE NOT NULL,
                        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
                    )
                ''')
                
                # 插入数据
                cursor.execute(
                    'INSERT INTO users (name, email) VALUES (?, ?)',
                    ('Alice', 'alice@example.com')
                )
                conn.commit()
        
        def query_users():
            """查询用户"""
            with get_db_connection() as conn:
                cursor = conn.cursor()
                cursor.execute('SELECT * FROM users')
                users = cursor.fetchall()
                return users
        
        # 使用数据库
        setup_database()
        users = query_users()
        print(f'用户列表: {users}')
        
        

        ORM使用

        from sqlalchemy import create_engine, Column, Integer, String, DateTime
        from sqlalchemy.ext.declarative import declarative_base
        from sqlalchemy.orm import sessionmaker
        from datetime import datetime
        
        Base = declarative_base()
        
        class User(Base):
            """用户模型"""
            __tablename__ = 'users'
            
            id = Column(Integer, primary_key=True)
            name = Column(String(50), nullable=False)
            email = Column(String(100), unique=True, nullable=False)
            created_at = Column(DateTime, default=datetime.now)
        
        # 设置数据库连接
        engine = create_engine('sqlite:///advanced.db')
        Base.metadata.create_all(engine)
        
        Session = sessionmaker(bind=engine)
        
        def add_user(name, email):
            """添加用户"""
            session = Session()
            try:
                user = User(name=name, email=email)
                session.add(user)
                session.commit()
                return user
            except Exception as e:
                session.rollback()
                raise e
            finally:
                session.close()
        
        # 使用ORM
        user = add_user('Bob', 'bob@example.com')
        print(f'添加用户: {user.name}')
        
        
      • 测试与调试
        单元测试

        import unittest
        
        def add_numbers(a, b):
            """相加函数"""
            return a + b
        
        class TestMathFunctions(unittest.TestCase):
            """数学函数测试"""
            
            def test_add_positive_numbers(self):
                self.assertEqual(add_numbers(2, 3), 5)
            
            def test_add_negative_numbers(self):
                self.assertEqual(add_numbers(-2, -3), -5)
            
            def test_add_mixed_numbers(self):
                self.assertEqual(add_numbers(5, -3), 2)
        
        class TestStringMethods(unittest.TestCase):
            """字符串方法测试"""
            
            def test_upper(self):
                self.assertEqual('hello'.upper(), 'HELLO')
            
            def test_isupper(self):
                self.assertTrue('HELLO'.isupper())
                self.assertFalse('Hello'.isupper())
        
        if __name__ == '__main__':
            unittest.main()
        
        

        模拟测试

        from unittest.mock import Mock, patch
        import unittest
        
        class WeatherService:
            """天气服务"""
            def get_temperature(self, city):
                # 模拟网络请求
                raise ConnectionError('网络连接失败')
        
        class TestWeatherService(unittest.TestCase):
            """天气服务测试"""
            
            @patch('requests.get')
            def test_get_weather(self, mock_get):
                # 设置模拟返回值
                mock_response = Mock()
                mock_response.json.return_value = {'temperature': 25}
                mock_get.return_value = mock_response
                
                # 测试函数
                def get_weather():
                    import requests
                    response = requests.get('https://api.weather.com')
                return response.json()
            
            def test_mock_object(self):
                # 创建模拟对象
                mock_obj = Mock()
                mock_obj.some_method.return_value = 42
                
                result = mock_obj.some_method()
                self.assertEqual(result, 42)
        
        
      • 部署与打包

        虚拟环境管理

        # 创建虚拟环境
        python -m venv myenv
        
        # 激活虚拟环境
        # Windows
        myenv\Scripts\activate
        # Linux/Mac
        source myenv/bin/activate
        
        # 安装依赖
        pip install -r requirements.txt
        
        # 冻结依赖
        pip freeze > requirements.txt
        
        

        应用打包

        # setup.py 文件示例
        from setuptools import setup, find_packages
        
        setup(
            name='my_python_app',
            version='1.0.0',
            packages=find_packages(),
            install_requires=[
                'requests>=2.25.1',
                'sqlalchemy>=1.4.0',
            ],
            entry_points={
                'console_scripts': [
                    'myapp=my_package.main:main'
                ]
            },
            classifiers=[
                'Development Status :: 4 - Beta',
                'Intended Audience :: Developers',
                'Programming Language :: Python :: 3',
            ],
        )
        
        

        Docker部署

        # Dockerfile 示例
        FROM python:3.9-slim
        
        WORKDIR /app
        
        COPY requirements.txt .
        RUN pip install --no-cache-dir -r requirements.txt
        
        COPY . .
        
        CMD ["python", "main.py"]
        
        
      • 最佳实践

        代码组织

        # 项目结构建议
        """
        my_project/
        ├── src/
        │   ├── __init__.py
        │   ├── main.py
        │   ├── models/
        │   ├── services/
        │   └── utils/
        ├── tests/
        ├── docs/
        ├── requirements.txt
        ├── setup.py
        └── README.md
        """
        
        ### 配置管理
        import os
        from dataclasses import dataclass
        
        @dataclass
        class DatabaseConfig:
            """数据库配置"""
            host: str = os.getenv('DB_HOST', 'localhost')
            port: int = int(os.getenv('DB_PORT', '5432'))
            database: str = os.getenv('DB_NAME', 'myapp'))
            username: str = os.getenv('DB_USER', 'postgres'))
            password: str = os.getenv('DB_PASS', 'password'))
        
        @dataclass
        class AppConfig:
            """应用配置"""
            debug: bool = os.getenv('DEBUG', 'False').lower() == 'true'
        
        # 使用配置
        db_config = DatabaseConfig()
        app_config = AppConfig()
        
        

        日志管理

        import logging
        import logging.config
        
        def setup_logging():
            """设置日志配置"""
            logging.config.dictConfig({
                'version': 1,
                'disable_existing_loggers': False,
                'formatters': {
                    'standard': {
                        'format': '%(asctime)s [%(levelname)s] %(name)s: %(message)s'
                },
                'handlers': {
                    'file': {
                        'class': 'logging.FileHandler',
                        'filename': 'app.log',
                        'formatter': 'standard'
                },
                'loggers': {
                    '': {
                        'handlers': ['file'],
                        'level': 'INFO',
                        'propagate': True
                    }
                }
            })
        
        # 使用日志
        logger = logging.getLogger(__name__)
        logger.info('应用程序启动')
        logger.error('发生错误')
        
        

        本进阶教程涵盖了Python编程的高级主题,包括并发编程、异步处理、元编程、性能优化等关键领域。通过掌握这些知识,你将能够编写更高效、更健壮的Python应用程序

    第20课.Python3高阶
    • Python编程高阶
      • 深入Python数据模型与魔法协议
      1. 魔法方法的进阶应用
        Python数据模型的核心在于理解魔法方法如何与语言结构交互。__getattribute__和 __getattr__的区别至关重要:前者在每次属性访问时都会调用,后者仅在属性不存在时调用。

        class ControlledAccess:
            def __init__(self):
                self._data = {}
                self.access_count = 0
            
            def __getattribute__(self, name):
                # 统计所有属性访问,包括access_count自身
                if name == "access_count":
                    return object.__getattribute__(self, name)
                self.access_count += 1
                return object.__getattribute__(self, name)
            
            def __getattr__(self, name):
                """只有正常属性查找失败时才调用"""
                print(f"创建新属性 {name}")
                self._data[name] = None
                return None
        
        obj = ControlledAccess()
        print(obj.access_count)  # 0
        print(obj.some_value)    # 创建新属性 some_value
        print(obj.access_count)  # 2 (统计了两次访问)
        

        上下文管理器的异步支持是Python高级特性的重要体现:

        import asyncio
        from contextlib import asynccontextmanager
        
        class AsyncDatabaseConnection:
            async def __aenter__(self):
                await self.connect()
                return self
            
            async def __aexit__(self, exc_type, exc_val, exc_tb):
                await self.close()
            
            async def connect(self):
                print("建立数据库连接...")
                await asyncio.sleep(0.1)
            
            async def close(self):
                print("关闭数据库连接...")
                await asyncio.sleep(0.1)
        
        # 异步上下文管理器使用
        async def main():
            async with AsyncDatabaseConnection() as db:
                print("执行数据库操作")
        
        asyncio.run(main())
        
      2. 描述符协议的威力
        描述符是属性访问的底层机制,理解它们对元编程至关重要。以下是类型验证描述符的进阶实现:

        from abc import ABC, abstractmethod
        from typing import Type, Any, Union
        
        class ValidatedDescriptor:
            def __init__(self, expected_type: Union[Type, tuple] = None, validator: callable = None):
                self.expected_type = expected_type
                self.validator = validator
                self.private_name = None
            
            def __set_name__(self, owner, name):
                self.private_name = f"_{name}"
            
            def __get__(self, instance, owner):
                if instance is None:
                    return self
                return getattr(instance, self.private_name, None)
            
            def __set__(self, instance, value):
                if self.expected_type and not isinstance(value, self.expected_type):
                    raise TypeError(f"期望类型 {self.expected_type}, 但得到 {type(value)}")
                
                if self.validator and not self.validator(value):
                    raise ValueError(f"值 {value} 验证失败")
                
                setattr(instance, self.private_name, value)
        
        class PositiveNumber(ValidatedDescriptor):
            def __init__(self):
                super().__init__(
                    expected_type=(int, float),
                    validator=lambda x: x > 0
                )
        
        class BusinessModel:
            revenue = PositiveNumber()
            profit = PositiveNumber()
            
            def __init__(self, revenue, profit):
                self.revenue = revenue  # 自动验证
                self.profit = profit
        
        # 测试描述符
        try:
            biz = BusinessModel(1000, -500)  # 触发验证错误
        except ValueError as e:
            print(f"业务验证失败: {e}")
        
      • 元编程深度应用
      1. 元类的高级模式
        元类不仅控制类的创建,还能实现强大的API设计模式。以下是声明式API的元类实现:
        class RegistryMeta(type):
            """注册表元类,自动注册所有子类"""
            _registry = {}
            
            def __new__(cls, name, bases, attrs):
                new_class = super().__new__(cls, name, bases, attrs)
                
                # 跳过基类
                if bases != (object,) and bases != ():
                    cls._registry[name] = new_class
                
                # 自动添加类名到注册表
                if 'name' not in attrs:
                    new_class.name = name.lower()
                
                return new_class
            
            def get_registry(cls):
                return cls._registry.copy()
        
        class Plugin(metaclass=RegistryMeta):
            pass
        
        class AuthPlugin(Plugin):
            description = "认证插件"
        
        class StoragePlugin(Plugin):
            description = "存储插件"
        
        print(RegistryMeta.get_registry())  # 自动注册所有插件
        
      2. 类装饰器的元编程应用
        类装饰器可以修改或增强类的行为,是实现切面编程的强大工具:
        def singleton(cls):
            """单例类装饰器"""
            instances = {}
            
            def get_instance(*args, **kwargs):
                if cls not in instances:
                    instances[cls] = cls(*args, **kwargs)
                return instances[cls]
            
            return get_instance
        
        def auto_register(registry_dict):
            """自动注册装饰器工厂"""
            def decorator(cls):
                registry_dict[cls.__name__] = cls
                return cls
            return decorator
        
        # 使用类装饰器
        service_registry = {}
        
        @auto_register(service_registry)
        @singleton
        class DatabaseService:
            def __init__(self, connection_string):
                self.connection_string = connection_string
        
        @auto_register(service_registry)  
        @singleton
        class CacheService:
            def __init__(self, max_size=1000):
                self.max_size = max_size
        
        print(service_registry)  # 查看自动注册的服务
        
      • 异步编程高级模式
      1. 异步上下文管理与资源池
        异步编程的高级应用涉及复杂的资源管理和并发控制:
        import asyncio
        from contextlib import asynccontextmanager
        from typing import List, AsyncIterator
        
        class AsyncConnectionPool:
            def __init__(self, size: int = 5):
                self.size = size
                self._pool: List[str] = []
                self._semaphore = asyncio.Semaphore(size)
                self._created = 0
            
            async def _create_connection(self) -> str:
                """模拟异步创建连接"""
                await asyncio.sleep(0.1)
                conn_id = f"conn_{self._created}"
                self._created += 1
                return conn_id
            
            @asynccontextmanager
            async def get_connection(self) -> AsyncIterator[str]:
                """异步上下文管理器获取连接"""
                await self._semaphore.acquire()
                try:
                    if not self._pool:
                        connection = await self._create_connection()
                    else:
                        connection = self._pool.pop()
                    
                    yield connection
                    self._pool.append(connection)
                finally:
                    self._semaphore.release()
        
        # 使用连接池
        async def process_data(pool: AsyncConnectionPool, item: int):
            async with pool.get_connection() as conn:
                print(f"使用 {conn} 处理项目 {item}")
                await asyncio.sleep(0.2)
                return f"processed_{item}"
        
        async def main():
            pool = AsyncConnectionPool(size=3)
            tasks = [process_data(pool, i) for i in range(10)]
            results = await asyncio.gather(*tasks)
            print(f"处理完成: {results}")
        
        # asyncio.run(main())
        
      2. 异步生成器与流处理
        异步生成器是处理流式数据的强大工具:
        import asyncio
        import aiohttp
        from typing import AsyncIterator
        
        class AsyncDataStream:
            def __init__(self, urls: List[str], batch_size: int = 3):
                self.urls = urls
                self.batch_size = batch_size
            
            async def fetch_stream(self) -> AsyncIterator[str]:
                """异步获取数据流"""
                semaphore = asyncio.Semaphore(self.batch_size)
                
                async def fetch_with_limit(url: str) -> str:
                    async with semaphore:
                        async with aiohttp.ClientSession() as session:
                            async with session.get(url) as response:
                                data = await response.text()
                                await asyncio.sleep(0.1)  # 模拟处理延迟
                                return f"处理: {url} -> {len(data)} 字符"
                
                # 创建任务但按完成顺序产出
                tasks = {asyncio.create_task(fetch_with_limit(url)): url for url in self.urls}
                
                while tasks:
                    done, pending = await asyncio.wait(
                        tasks.keys(), return_when=asyncio.FIRST_COMPLETED
                    )
                    
                    for task in done:
                        url = tasks.pop(task)
                        try:
                            yield await task
                        except Exception as e:
                            yield f"错误 {url}: {e}"
        
      • 并发模式与性能优化
      1. 高级线程池模式
        对于I/O密集型应用,线程池的高级用法可以显著提升性能:

        import concurrent.futures
        import threading
        from functools import partial
        from typing import Callable, List, Any
        
        class AdvancedThreadPool:
            def __init__(self, max_workers: int = None, context=None):
                self.max_workers = max_workers or (threading.cpu_count() * 2)
                self.context = context
                self._local_data = threading.local()
            
            def _init_worker(self):
                """初始化工作线程"""
                if self.context:
                    for key, value in self.context.items():
                        setattr(self._local_data, key, value)
            
            def map_with_context(self, 
                                 func: Callable, 
                                 iterable: List[Any],
                                 timeout: float = None) -> List[Any]:
                """带上下文映射"""
                func_with_init = partial(self._wrap_function, func)
                
                with concurrent.futures.ThreadPoolExecutor(
                    max_workers=self.max_workers,
                    initializer=self._init_worker
                ) as executor:
                    futures = {
                        executor.submit(func_with_init, item): item 
                        for item in iterable
                    }
                    
                    results = []
                    for future in concurrent.futures.as_completed(futures, timeout=timeout):
                        try:
                            results.append(future.result())
                        except Exception as e:
                            results.append(f"错误: {e}")
                    
                    return results
            
            def _wrap_function(self, func, item):
                """包装函数以访问线程本地数据"""
                if hasattr(self._local_data, 'user_id'):
                    print(f"在用户上下文 {self._local_data.user_id} 中处理 {item}")
                return func(item)
        
        # 使用高级线程池
        def process_item(item):
            return item * 2
        
        pool = AdvancedThreadPool(context={'user_id': 'user123'})
        results = pool.map_with_context(process_item, [1, 2, 3, 4, 5])
        print(results)
        
      2. 内存视图与零拷贝优化
        对于高性能计算,理解内存视图和缓冲区协议至关重要:

        import array
        import numpy as np
        from typing import TypeVar, Generic
        
        T = TypeVar('T')
        
        class ZeroCopyProcessor(Generic[T]):
            def __init__(self, data: T):
                self.data = data
                self._view = None
            
            def create_memory_view(self):
                """创建内存视图以实现零拷贝"""
                if hasattr(self.data, '__array_interface__'):
                    # NumPy数组
                    self._view = memoryview(self.data)
                elif isinstance(self.data, (bytes, bytearray)):
                    # 字节数据
                    self._view = memoryview(self.data)
                elif isinstance(self.data, array.array):
                    # 数组
                    self._view = memoryview(self.data)
                else:
                    raise TypeError("不支持的数据类型")
                
                return self._view
            
            def process_slices(self, chunk_size: int = 1024) -> T:
                """处理数据切片而不复制"""
                if self._view is None:
                    self.create_memory_view()
                
                results = []
                for i in range(0, len(self._view), chunk_size):
                    chunk = self._view[i:i + chunk_size]
                    # 零拷贝处理块
                    processed = self._process_chunk(chunk)
                    results.append(processed)
                
                return self._combine_results(results)
            
            def _process_chunk(self, chunk):
                """处理单个块(示例:计算总和)"""
                return sum(chunk)
            
            def _combine_results(self, results):
                """合并结果"""
                return sum(results)
        
        # 使用零拷贝处理
        data = array.array('i', [1, 2, 3, 4, 5] * 1000)
        processor = ZeroCopyProcessor(data)
        result = processor.process_slices(chunk_size=100)
        print(f"处理结果: {result}")
        
      • 高级设计模式与架构
      1. 依赖注入容器
        依赖注入是构建可测试、可维护应用的核心模式:
        from typing import Dict, Type, Any, Callable
        from abc import ABC
        
        class DIContainer:
            def __init__(self):
                self._singletons = {}
                self._transients = {}
                self._factories = {}
            
            def register_singleton(self, interface: Type, implementation: Type = None):
                """注册单例"""
                if implementation is None:
                    implementation = interface
                self._singletons[interface] = implementation
            
            def register_transient(self, interface: Type, implementation: Type = None):
                """注册瞬时实例"""
                if implementation is None:
                    implementation = interface
                self._transients[interface] = implementation
            
            def register_factory(self, interface: Type, factory: Callable):
                """注册工厂函数"""
                self._factories[interface] = factory
            
            def resolve(self, interface: Type) -> Any:
                """解析依赖"""
                # 检查工厂
                if interface in self._factories:
                    return self._factories[interface]()
                
                # 检查单例
                if interface in self._singletons:
                    impl = self._singletons[interface]
                    if impl not in self._singletons or self._singletons[impl] is not impl:
                        instance = impl()
                        self._singletons[impl] = instance
                        return instance
                    return self._singletons[impl]
                
                # 检查瞬时实例
                if interface in self._transients:
                    return self._transients[interface]()
                
                raise ValueError(f"未注册的依赖: {interface}")
        
        # 使用依赖注入容器
        class DatabaseService(ABC):
            pass
        
        class MySQLService(DatabaseService):
            def __init__(self, connection_string):
                self.connection_string = connection_string
        
        class App:
            def __init__(self, db_service: DatabaseService):
                self.db_service = db_service
        
        container = DIContainer()
        container.register_singleton(DatabaseService, MySQLService)
        container.register_factory(str, lambda: "mysql://localhost")
        
        try:
            app = container.resolve(App)
        except ValueError as e:
            print(f"依赖解析: {e}")
        
      2. 事件驱动架构
        事件驱动架构支持高度解耦的系统设计:
        from typing import Callable, Dict, List, Any
        from dataclasses import dataclass
        from enum import Enum
        import asyncio
        
        class EventType(Enum):
            USER_CREATED = "user_created"
            ORDER_PLACED = "order_placed"
            PAYMENT_PROCESSED = "payment_processed"
        
        @dataclass
        class Event:
            type: EventType
            data: Any
            source: str
        
        class EventBus:
            def __init__(self):
                self._handlers: Dict[EventType, List[Callable]] = {}
                self._queue = asyncio.Queue()
                self._is_running = True
            
            def subscribe(self, event_type: EventType, handler: Callable):
                """订阅事件"""
                if event_type not in self._handlers:
                    self._handlers[event_type] = []
                self._handlers[event_type].append(handler)
            
            def unsubscribe(self, event_type: EventType, handler: Callable):
                """取消订阅"""
                if event_type in self._handlers:
                    self._handlers[event_type].remove(handler)
            
            async def publish(self, event: Event):
                """发布事件到队列"""
                await self._queue.put(event)
            
            async def start_processing(self):
                """开始处理事件"""
                while self._is_running:
                    try:
                        event = await asyncio.wait_for(self._queue.get(), timeout=1.0)
                        await self._process_event(event)
                    except asyncio.TimeoutError:
                        continue
            
            async def _process_event(self, event: Event):
                """处理单个事件"""
                if event.type in self._handlers:
                    for handler in self._handlers[event.type]:
                        try:
                            if asyncio.iscoroutinefunction(handler):
                                await handler(event)
                            else:
                                handler(event)
                        except Exception as e:
                            print(f"事件处理错误: {e}")
            
            def stop(self):
                """停止事件处理"""
                self._is_running = False
        
        # 使用事件总线
        async def handle_user_created(event: Event):
            print(f"处理用户创建: {event.data}")
        
        async def main():
            event_bus = EventBus()
            event_bus.subscribe(EventType.USER_CREATED, handle_user_created)
            
            # 启动事件处理
            processor = asyncio.create_task(event_bus.start_processing())
            
            # 发布事件
            await event_bus.publish(Event(
                type=EventType.USER_CREATED,
                data={"user_id": 123, "name": "Alice"},
                source="auth_service"
            ))
            
            await asyncio.sleep(0.1)
            event_bus.stop()
            await processor
        
        # asyncio.run(main())
        
      • 元编程与编译器优化
      1. AST操作与代码生成
        抽象语法树操作允许在编译时修改代码行为:
        import ast
        import inspect
        from textwrap import dedent
        
        class LoggingTransformer(ast.NodeTransformer):
            """AST转换器,自动添加日志"""
            
            def visit_FunctionDef(self, node):
                # 为函数添加日志语句
                log_stmt = ast.Expr(
                    value=ast.Call(
                        func=ast.Name(id='print', ctx=ast.Load()),
                        args=[ast.Constant(value=f"调用函数: {node.name}")],
                        keywords=[]
                    )
                )
                
                node.body.insert(0, log_stmt)
                return node
        
        def compile_with_logging(func):
            """编译时添加日志的装饰器"""
            source = inspect.getsource(func)
            tree = ast.parse(dedent(source))
            
            transformer = LoggingTransformer()
            new_tree = transformer.visit(tree)
            
            ast.fix_missing_locations(new_tree)
            
            code_obj = compile(new_tree, '<string>', 'exec')
            
            # 在新作用域中执行编译的代码
            namespace = {}
            exec(code_obj, namespace)
            
            return namespace[func.__name__]
        
        # 应用AST转换
        @compile_with_logging
        def example_function(x, y):
            result = x + y
            print(f"结果: {result}")
            return result
        
        # 转换后的函数会自动添加日志
        example_function(10, 20)
        
      • 性能分析与优化高级技术
      1. 字节码优化与缓存策略
        理解Python字节码可以帮助进行底层优化:
        import dis
        import time
        from functools import lru_cache
        from dataclasses import dataclass
        
        @dataclass
        class OptimizationProfile:
            call_count: int = 0
            total_time: float = 0
            cache_hits: int = 0
        
        def profile_optimizations(func):
            """优化分析装饰器"""
            profile = OptimizationProfile()
            
            def wrapper(*args, **kwargs):
                profile.call_count += 1
                start = time.perf_counter()
                
                try:
                    result = func(*args, **kwargs)
                    return result
                finally:
                    end = time.perf_counter()
                    profile.total_time += (end - start)
            
            wrapper.profile = profile
            return wrapper
        
        class SmartCache:
            def __init__(self, maxsize=128, ttl=300):
                self.maxsize = maxsize
                self.ttl = ttl
                self._cache = {}
                self._hits = 0
                self._misses = 0
            
            def cached(self, func):
                """智能缓存装饰器"""
                def wrapper(*args, **kwargs):
                    key = self._make_key(args, kwargs)
                    
                    if key in self._cache:
                        timestamp, value = self._cache[key]
                        if time.time() - timestamp < self.ttl:
                            self._hits += 1
                            return value
                    
                    # 缓存未命中
                    result = func(*args, **kwargs)
                    self._cache[key] = (time.time(), result)
                    self._misses += 1
                    
                    # 清理过期缓存
                    self._cleanup()
                    
                    return result
                
                wrapper.cache_info = lambda: {
                    'hits': self._hits,
                    'misses': self._misses,
                    'size': len(self._cache)
                }
                
                return wrapper
            
            def _make_key(self, args, kwargs):
                """创建缓存键"""
                return (args, tuple(sorted(kwargs.items())))
            
            def _cleanup(self):
                """清理过期缓存"""
                current_time = time.time()
                expired_keys = [
                    key for key, (timestamp, _) in self._cache.items()
                    if current_time - timestamp > self.ttl
                ]
                
                for key in expired_keys:
                    del self._cache[key]
        
        # 使用智能缓存
        smart_cache = SmartCache(maxsize=100, ttl=60)
        
        @smart_cache.cached
        @profile_optimizations
        def expensive_operation(n):
            """模拟昂贵操作"""
            time.sleep(0.1)
            return n * n
        
        # 测试缓存效果
        for i in [5, 5, 10, 5, 10]:  # 重复值测试缓存
            result = expensive_operation(i)
            print(f"expensive_operation({i}) = {result}")
        
        print("缓存统计:", expensive_operation.cache_info())
        print("性能分析:", expensive_operation.profile)
        
      这份高阶教程涵盖了Python编程的深层主题,从数据模型和元编程到高级并发模式和性能优化技术。掌握这些概念需要实践和实验,但它们将显著提升你构建高性能、可维护Python应用的能力
    第21课.Python3编程实战开发(CAM脚本开发)
    第22课.Python3编程实战开发(Line_Hooks开发)
    第23课.Python3编程实战开发(脚本全自动执行)
    第24课.Python3编程实战开发(外挂脚本执行)

    第六章.项目开发学习

    第25课.快板系统项目详解

2.制作规范的标准化建设

操作流程制定

  • 工程作业基本流程制定
    在这里插入图片描述

执行标准建立

操作指引建立

3.实施过程的标准管控

制作项目建立

任务计划排定

任务计划追踪


三、自动化


四、切片化


五、智能化


六、无人化


总结

提示:持续更新中......

本文章已经生成可运行项目
评论 8
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一阵寒风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值