精华内容
下载资源
问答
  • 按照他们的教程,仅仅做到一半,各种错误窗口就开始弹出来了:“非同一代码库”、“代码不同步”等等……,着实让我们新手晕头晕脑,心里这个盘算啊:为什么人家能成,到咱这儿就不行了呢?! 后来才明白,原来他们...

    1,注意:

    网上大部分教程都是从“Create New Repository”讲起,这其实是给我们新手埋了很大的一个坑。按照他们的教程,仅仅做到一半,各种错误窗口就开始弹出来了:“非同一代码库”、“代码不同步”等等……,着实让我们新手晕头晕脑,心里这个盘算啊:为什么人家能成,到咱这儿就不行了呢?!

    后来才明白,原来他们这些教程的路子根本就不是从文章开头往下看的,而是应该先从中间开始看,然后再开头、再看结尾;还有的得需要倒序着看……这的确够绕的!

    为什么要这样腻?现在想明白了:每每当我们新手遇到各种各样的错误弹窗,继而无从下手的时候,会不会对这些所谓的大神们油然升起无比的敬佩之情啊?人家就是能成功,厉害不?牛掰不!!!关键就在此啊!给你埋了这么深的坑,让你绕了这么久,原来只是他们用来装B的!

    按照正确的路子,本就是一个非常简单、非常好用的工具,可到了这些半吊子手里呢?搞得有多复杂、多神秘、多高端,乌烟瘴气……想想因为这些无聊的坑而浪费的宝贵时间啊,心疼啊!……呵呵,扯远了吧?赶快回正题,咱们从“Clone Existing Repository”开始讲起。

    2,打开 Git GUI,单击 Clone Existing Repository:

    3,输入下面的内容:

    (1)Source … 就是 Clone with SSH 地址:(参考:GitHub 新手教程 一,GitHub 注册
    git@github.com:wqMV/wqMV.git

    (2)Targer … 就是您要本地存放的文件夹:
    D:/WangQiang/Source/Repos/wqMV

    有一点要注意:在 D:/WangQiang/Source/Repos 文件夹下,一定不能有 wqMV 这个文件夹,但是我们还要把名字输入上:

    因为一会儿程序会自动创建 wqMV 这个文件夹,否则会给你弹错误窗口:

    4,然后是等待……,千万不要退出窗口,直到弹出下面的窗口:

    5,配置编码,改为 utf-8,然后点击“Save”按钮保存:

    6,更改远端名称:

    此时会弹出窗口,请等待弹出如下窗口:

    7,现在打开您的代码库文件夹,看看是不是和 GitHub上面的已经一样了啊:

     

     

    展开全文
  • Python新手写出漂亮的爬虫代码2——从json获取信息

    万次阅读 多人点赞 2017-11-21 15:38:08
    Python新手写出漂亮的爬虫代码2——从json获取信息好久没有写关于爬虫的东西了,如果正在读这篇博客的你看过我的另一篇《Python新手写出漂亮的爬虫代码1——从html获取信息》想必已经对一些写在html中的信息进行过...

    Python新手写出漂亮的爬虫代码2——从json获取信息

    好久没有写关于爬虫的东西了,如果正在读这篇博客的你看过我的另一篇《Python新手写出漂亮的爬虫代码1——从html获取信息》想必已经对一些写在html中的信息进行过爬取了,今天给大家介绍一下另一种爬虫——动态爬虫。

    1.静态爬虫与动态爬虫

    何为动态爬虫,html中的信息是静态的,或者说是通过html语言生成了网页中的对应信息,是写好的,你把网页的html源代码粘贴过来,你要的信息就在里面,这种情况下就是静态爬虫,而有的时候我们会发现我们需要的信息不在html源码中,比如电商网站的评论,某些网站的一些条形图啊,折线图啊,(这些图实际上是数字,只是通过某种接口传到网页上,然后渲染成了图的形式,其本质上是数字),这些可能频繁更新的信息(比如评论每小时甚至每分钟都在更新),这时候,如果将它写在html中,是一个很难受的过程,因为有一个新评论你就要改写html,所以对于这种情况,我们想要的数据都会存在一个json文件中。

    这里需要做一个说明,我们看网页源代码,通过在网页上鼠标邮件,点选“查看网页源代码”出来的才是html源码,而通过F12调出的开发者工具中的element或元素中的那些,不是html代码,而是html代码的一个超集,它比真实的html代码内容要多,所以查看信息是否在html中还是需要点选“查看网页源代码”才准确。

    2.json

    json是一种数据格式,类似于python中的字典,以key:value的形式存储信息,是一种目前越来越常用的方便的数据存储方式。

    3.动态爬虫思路

    动态爬虫较静态爬虫而言难点在于定位数据或信息的存储位置,而一旦获取了这个位置(json文件对应的url),那么就非常简单了,使用python的json库可以对json数据轻松的解析,说白了只是根据你要的key提取其value而已,所以动态爬虫是比较简单的(当然,这里还有另一个问题,是异步加载问题,这个以后有机会再讲,异步加载是啥?比如说某个网页,没有“下一页”按钮,而是用鼠标滚轮或者屏幕右侧的滑块,向下滑就会刷新,你连往下刷多久会到底都不知道,这就是异步加载,异步加载可以通过抓包工具去解决,也可以使用selenium模拟鼠标点击去解决,以后会讲到)。

    4.定位json存储位置

    定位json的位置通常是通过“换页”来查看Network的变更,在网页上按F12打开开发者工具,界面放到Network中,然后换页,查看“js”或是“XHR”中文件的更新,然后一一查看更新的json文件,来定位我们需要的信息在哪里。

    5.实例讲解

    说了这么多你可能还是有点儿糊涂,没关系,来个例子就懂了,就拿天猫的一个女装来说吧,其url为https://detail.tmall.com/item.htm?spm=a1z10.3-b-s.w4011-14681080882.119.17398fc89ncLzj&id=529355863153&rn=ec60f51904f6286d9b2d8bb02c8ca5a8&abbucket=5
    (这个模特身材还不错哈哈)

    请看图1,我们点击红色方块中的“累计评价”,就可以看到以往的评价,按照我们前一篇爬虫的讲解来说,这个信息可能在html代码中,好,那么我们看一看,按下F12,如图2所示。

    这里写图片描述

    图1

    图2中的1和2位置可以看到,评论仿佛是在一个标签中的,但是还记得我前面的说明么,你在这里看到的html代码是真实html代码的一个超集,比实际的html代码要多,那么我们右键鼠标,选择“查看网页源代码”,并把源码复制粘贴到文本编辑器中,查找图2中1对应的评论,结果如图3所示。

    这里写图片描述

    图2

    图3中竟然没有搜索到这个评论,也就是说图2的开发者工具欺骗了我们,too young too sample,sometime naive,哈哈,没关系,以后每次爬虫之前都这么看一看,就知道你要的信息是不是在html中了。好了,既然不在html中,那么我们需要去寻找我们想要的信息在哪里了。

    这里写图片描述

    图3

    按照图4,在开发者工具中选择“Network”,来查看网页其他组件信息。

    这里写图片描述

    图4

    如图5的红色方块,点击“JS”,不出以外应该是空的,当然如果你那里不是空的也无所谓,无伤大雅,我们要的数据就在JS下,只是现在还未显示出来(还有一些情况,尤其是折线图这些图像形式的数据,一般会存储在XHR下,也就是图5中的粉色圈中,也是.json形式的),接下来我们就要去寻找存储评论数据的json文件了。

    这里写图片描述

    图5

    此时“JS”下的界面如图5所示,有可能是空的,当然也可能会有一些其他的东西,接下来看图6,点击图6中A处页码“2”,将评论页切换到第二页,这时候你会发现B处,也就是JS界面中出现了一个文件(如果你先前图5中有内容,那此时应该是多出一个文件),这个文件叫“list-detail**********”。我们的数据就存放在这里。

    有些时候,你换页后可能会出现或新增多个json文件,不过一般都不会很多,最多也就5个,你只需要挨个点进去看看哪个存放了你需要的信息即可。

    这里写图片描述

    图6

    接下来,我们双击这个文件,或者单击选中这个文件,复制其url然后粘贴到浏览器的地址栏中也可,其内容如图7所示,这里红框标出了其前三条评论。因为我们是在评论的第二页打开的这个json,所以它对应的是第二页的评论内容,而网页中第二页评论的前三条如图8所示。

    这里写图片描述

    图7

    可以看到,数据对上了,我们已经成功的定位到了评论的位置,图7的json诚如各位所见,是一个字典的形式,评论内容对应的key为”rateContent”。

    这里写图片描述

    图8

    接下来看一下评论的页码是怎么控制的。如图9所示,其实两个url只差了之歌数字,就是图9红框标出的”currentPage=”后面的数字,如果是第一页,数字就是1,如果是第二页,数字就是2。好了,换页规律找到了,剩下就是解析json了,就是最简单的一步。

    这里写图片描述

    图9

    关于json的解析我不准备过多解释了,有python基础的朋友一定对json这个库不陌生,我在代码中以注释的方式给出吧。本例代码使用Python3。

    6.代码实战

    import urllib
    import urllib.request
    import re
    from bs4 import BeautifulSoup
    import time
    import random
    import json
    import math
    
    # 创建一个文件存储评论及其他数据
    myfile = open("tm_fz_gn_1_1_1.txt","a")
    # 共获取四个变量,评论者昵称,是否超级会员,评论时间,评论内容
    print("评论者昵称","是否超级会员","评论时间","comment",sep='|',file=myfile)
    stop = random.uniform(0.5,2)
    
    # 获取页数
    try:
        url0 = "https://rate.tmall.com/list_detail_rate.htm?itemId=544442011638&spuId=718591114&sellerId=196993935&order=3&currentPage=1&append=0&content=1&tagId=&posi=&picture=&ua=025UW5TcyMNYQwiAiwQRHhBfEF8QXtHcklnMWc%3D%7CUm5Ockp3S39AeU13QnhDeC4%3D%7CU2xMHDJ7G2AHYg8hAS8XIw0tA18%2BWDRTLVd5L3k%3D%7CVGhXd1llXWBcaFduWmBVb1RvWGVHe0Z9SXRLc05zRnlDfkZ6VAI%3D%7CVWldfS0TMww1CioWIgIsCCNMMWwyVDlrME8iakFhXn5BZEocSg%3D%3D%7CVmhIGCUFOBgkGiMXNwwzBzsbJxkiGTkDOA0tES8ULw81Cj9pPw%3D%3D%7CV2xMHDIcPAA%2FASEcPAM4Az9pPw%3D%3D%7CWGBAED4QMGBaZ1p6RXBKc1NoXWBCfUh0S3NTbVBqSnROblBkMhIvDyEPLxciGSx6LA%3D%3D%7CWWBdYEB9XWJCfkd7W2VdZ0d%2BXmBdfUF0Ig%3D%3D&isg=AnBwr9DL3fao4YAwe7Eb61VPQT4CEVRrBvSVMGrBPUueJRHPEskkk8YHCxu-&needFold=0&_ksTS=1501924984733_1070&callback=jsonp1071"
        req0 = urllib.request.Request(url0)
        req0.add_header('User-Agent','Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36')
        html0 = urllib.request.urlopen(req0,timeout=500).read()
        html0 = bytes.decode(html0,encoding="gbk")
        # print(type(html0))
        '''
        下面这一步是因为这个json不是标准的json,json是一个完完全全的字典,而这个json是在类似json1234()这个结构的括号中,打开看看这个json你就懂了,所以需要用正则表达式去获取真实的json(即字典)
        '''
        js0 = re.search('{"rateDetail(.*)',html0).group()[:-1]
        # 将json主要内容存入content
        content0 = json.loads(js0)
        content = content0['rateDetail']
        # print(content.keys())
        # print(json.dumps(content0, sort_keys=True, indent=2))
        #尾页
        lastpage = int(content['paginator']['lastPage'])
    except:
        print("获取尾页失败,默认爬取99页")
        lastpage = 99
    
    # 构造循环遍历每一页
    for i in range(1,lastpage):
        try:
            url = 'https://rate.tmall.com/list_detail_rate.htm?itemId=544442011638&spuId=718591114&sellerId=196993935&order=3&currentPage='+str(i)+'&append=0&content=1&tagId=&posi=&picture=&ua=025UW5TcyMNYQwiAiwQRHhBfEF8QXtHcklnMWc%3D%7CUm5Ockp3S39AeU13QnhDeC4%3D%7CU2xMHDJ7G2AHYg8hAS8XIw0tA18%2BWDRTLVd5L3k%3D%7CVGhXd1llXWBcaFduWmBVb1RvWGVHe0Z9SXRLc05zRnlDfkZ6VAI%3D%7CVWldfS0TMww1CioWIgIsCCNMMWwyVDlrME8iakFhXn5BZEocSg%3D%3D%7CVmhIGCUFOBgkGiMXNwwzBzsbJxkiGTkDOA0tES8ULw81Cj9pPw%3D%3D%7CV2xMHDIcPAA%2FASEcPAM4Az9pPw%3D%3D%7CWGBAED4QMGBaZ1p6RXBKc1NoXWBCfUh0S3NTbVBqSnROblBkMhIvDyEPLxciGSx6LA%3D%3D%7CWWBdYEB9XWJCfkd7W2VdZ0d%2BXmBdfUF0Ig%3D%3D&isg=AnBwr9DL3fao4YAwe7Eb61VPQT4CEVRrBvSVMGrBPUueJRHPEskkk8YHCxu-&needFold=0&_ksTS=1501924984733_1070&callback=jsonp1071'
            req = urllib.request.Request(url)
            req.add_header('User-Agent','Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36')
            html = urllib.request.urlopen(req,timeout=500).read()
            html = bytes.decode(html,encoding="gbk")
            js = re.search('{"rateDetail(.*)', html).group()[:-1]
            infos0 = json.loads(js)
            infos = infos0['rateDetail']['rateList']
            tiaoshu = 0
            for info in infos:
                try:
                    tiaoshu += 1
                    time.sleep(stop)
                    ss = "正在爬取第%d页的第%d条评论,共%d页" % (i,tiaoshu,lastpage)
                    print(ss)
                    # 用户姓名
                    try:
                        user_name = info['displayUserNick'].strip().replace('\n','')
                    except:
                        user_name = ""
                    # 是否黄金会员
                    try:
                        user_status = info['goldUser'].strip().replace('\n','')
                    except:
                        user_status = ""
                    # 评论时间
                    try:
                        comment_date = info['rateDate'].strip().replace("\n","")
                    except:
                        comment_date = ""
                    # 评论内容
                    try:
                        comment = info['rateContent'].strip().replace("\n","").replace('\t','')
                    except:
                        comment = ""
                    print(user_name,user_status,comment_date,comment,sep='|',file=myfile)
                except:
                    sss = '爬取第%d页的第%d条评论失败,跳过爬取' % (i,tiaoshu)
                    print(sss)
                    pass
        except:
            print("该产品url获取失败,请检查")
    myfile.close()
    

    到此,爬虫的第二课——从json获取信息就结束了,以后会陆续退出selenium、异步加载、scrapy的使用教学和案例。敬请关注哈~

    展开全文
  • 最后附上我安装PYAUDIO时的错误,方便的话帮我看看不了PYaudio是不是因为没有PORTAUDIO的问题,跪谢! Microsoft Windows [版本 6.1.7601] 版权所有 (c) 2009 Microsoft Corporation。保留所有权利。 C:\...
  • 来源:大数据文摘编译:傅一洋、汪小七、张南星、GAO Ning、夏雅薇本文共1W+字,建议阅读8分钟。高级的编程是逻辑思维的流露,会编程只代表你懂了这门语言的语法,但是会写...首先我要声明的是:如果你是编程新手,本文

    来源:大数据文摘

    编译:傅一洋、汪小七、张南星、GAO Ning、夏雅薇

    本文共1W+字,建议阅读8分钟
    高级的编程是逻辑思维的流露,会编程只代表你懂了这门语言的语法,但是会写清晰简洁易懂可迭代的代码才是程序员该追求的境界。编程入门已经不容易,但是如果能够在早期树立一些正确的“代码观”,或许可以让你的编程之路升级得更快。作者苦口婆心地给出了25条建议,句句真言。


    首先我要声明的是:如果你是编程新手,本文并不是要让你对自己犯的错误感到愧疚,而是要你对这些错误有更好的认知,并避免在未来再犯。


    当然,这些错误我也经历过,但是从每个错误中都学到了一些新东西。现在,我已经养成了一些好的编程习惯,我相信你也可以!


    下面是这些常见的错误,顺序不分先后。


    写代码前缺少规划 


    一般来说,创作一篇高质量的文章不易,因为它需要反复推敲研究,而高质量的代码也不例外。


    编写高质量代码是这样一个流程:思考、调研、规划、编写、验证、修改。(貌似没办法编成一个好记的顺口溜)


    按照这样的思路走,你会逐渐形成良好的编程习惯。


    新手最大的错误之一就是太急于写代码,而缺乏足够的规划和研究。虽然对于编写小程序而言是没多大问题的,但对于大项目的开发,这样做是很不利的。


    为了防止代码写完之后发现重大问题,写之前的深思熟虑是必不可少的。代码只是你想法的流露。


    生气的时候,在开口说话前先数到十。如果非常生气,就数到一百。

    ——托马斯·杰斐逊


    我把它改成针对写代码的版本:


    审查代码时,重构每一行之前,先数到十。如果代码还没有测试,就数到一百。

    ——Samer Buna


    编程的过程主要是研读之前的代码,思考还需要修改什么,如何适应当前系统,并规划尽量小的改动量。而实际编写代码的过程只占整个过程时间花费的10%。


    不要总认为编程就是写代码。编程是基于逻辑的创造,慢工出细活。


    写代码之前规划过度


    虽说写代码前充分规划是好,但凡事都有个度,还没开始做,就思考太多,也是不可取的。


    不要期望世界上存在完美的规划,至少编程的世界中是不存在。好的规划可以作为起点,但实际情况是,规划是会随后续进行而改变的,规划的好处只是能让程序结构条理更清晰,而规划太多只会浪费时间。


    瀑布式开发是一种系统线性规划的开发方法,它严格遵循预先计划的需求、分析、设计、编码、测试的步骤顺序进行,步骤成果作为进度的衡量标准。在这种方法中,规划是重中之重。如果只是编写小程序,也完全可以采用这种方法,但要对于大的项目,这种方法完全不可取。任何复杂的事情都需要根据实际情况随机应变。


    编程是一个随时需要根据实际情况作出改变的工作。你后续可能会因为一些原因要添加或删除的某些功能,但这些情况瀑布计划中可能你永远也想不到。所以,你需要敏捷的开发模式。


    但是,每一步之前是要有所规划的,只不过规划的过少或过多都会影响代码的质量,代码的质量非常重要。


    低估代码质量的重要性


    如果你无法兼顾代码的多项质量指标,至少要保证它的可读性。凌乱的代码就相当于废品,而且不可回收。


    永远不要低估代码质量的重要性。你要将代码看作沟通的一种方式,作为程序员,你的任务是交代清楚目前任务是如何实施的。

    我最喜欢一句编程俚语是:


    写代码的时候可以这样想,维护你代码的家伙是一个知道你住在哪里的暴力精神病患者。
    ——John Woods


    很形象是不是?


    即便是一些细节。例如,你的代码可能会因为排版问题或大小写不一致而不被认可。


    tHIS is
     WAY MORE important
    than
            you think


    还需要注意的是避免语句过长。任何超过80个字符的文本都是难以阅读的。你可能想在同一行放置长条件以便看到完整的if语句,这是不可取的,一行永远不要超过80个字符。


    这种小问题可以通过linting工具或格式化工具轻松解决。比如在JavaScript中两个完美结合的优秀工具:ESLint和Prettier。多用它们,让工作更轻松。


    还有一些与代码质量相关的错误:


    • 任何超过10行的函数都太长了。


    • 一定不要出现双重否定句。


    • 使用简短的,通用的或基于类型的变量命名。尽量保证变量命名能清晰地表述变量。计算机科学领域只有两件难事:缓存失效和变量命名。


    • 缺乏描述地插入一些字符串和数字。如果要使用固定的字符串或数值,应该将其定义为常量,并命名。


    • “对于简单的问题,担心花费时间而草率地处理”。不要在众多问题中进行跳跃式选择,按部就班地来。


    • 认为代码越长越好。其实,大多数情况下,代码越短越好。只有在追求可读性的情况下可适当详细些。比如,不要为了缩短代码而使用很长的单行表达式或嵌套表达式,但也不要增加冗余的代码。最好的是,删去所有不必要的代码。


    • 过多使用条件语句。大部分你认为需要条件语句的情况都可以不通过

      它来解决。因此,考虑尽可能多的备选方案,根据可读性进行挑选。除非你知道如何测试代码性能,否则,不要试图优化。还有就是:避免Yoda条件或条件嵌套。


    选择1号方案


    当我刚开始编程时,一旦遇到问题,我会立刻寻找解决方案并重新运行我的程序。而不是先考虑我的头号方案复杂性和潜在的失败原因。


    虽然1号方案极具诱惑性,但在研究了所有解决方案后,通常能发现更好的。如果无法想出多种方案,说明你对问题了解不够。


    作为专业程序员,你的工作不是找到办法,而是找到最简捷的办法。“简捷”的意思是方案必须正确,可执行,且足够简单,易读,又便于理解和维护。


    软件设计有两种方法。一种是设计的足够简单,没有瑕疵,另一种是设计的足够复杂,没人看得出明显瑕疵。

    ——C.A.R.霍尔


    吊死在一棵树上


    这是我常犯的错误,即便确定了我的头号方案并不是最简单的解决方案,仍然不放手。这可能与我的性格有关。大多数情况下这是一种很好的心态,但不适用于编程。事实上,正确的编程心态是,将早期失败和经常性失败看成一种常态。


    当你开始怀疑某个方案的时候,你应该考虑放下它并重新思考,不管你之前在它这里投入了多少精力。学会利用像GIT这样的源代码管理工具,它可以帮助你实现代码分支,尝试多种方案。


    不要认为你付出了精力的代码就是必须采用的。错误的代码要摒弃。


    闭门造车


    很多次,在解决问题需要查阅资料时,我却直接尝试解决问题,浪费了很多时间。


    除非你正在使用的是某种尖端技术,否则,遇到问题时,谷歌一下吧,因为一定会有人也遇到了同样的问题,并找到了解决方法,这样,能节省很多时间。


    有时候谷歌之后,你会发现你所认为的问题并不是问题,你需要做的不是修复而是接受。不要认为你了解一切,Google会让你大吃一惊的。


    不过,要谨慎地使用谷歌。新手会犯的另一个错误是,在不理解代码的情况下,原样照搬。尽管这可能成功解决了你的问题,但还是不要使用自己不完全了解的代码。


    如果想成为一名创造性的程序员,就永远不要认为,自己对在做的事情了如指掌。


    作为一个有创造力的人,最危险的想法是认为自己知道自己在做什么。

    ——布雷特·维克多


    不使用封装


    这一点不只是针对使用面向对象语言的例子,封装总是有用的,如果不使用封装,会给系统的维护带来很大的困难。


    在应用程序中,每个功能要与用来处理它的对象一一对应。在构建对象时,除了保留被其他对象调用时必须传递的参数,其他内容都应该封装起来。


    这不是出于保密,而是为减少应用程序不同部分之间的依赖。坚持这个原则,可以使你在对类,对象和函数的内部进行更改时,更加的安全,无需担心大规模的毁坏代码。


    对每一个逻辑概念单元或者块都应该构建对应的类。通过类能够勾画出程序的蓝图。这里的类可以是一个实际对象或一个方法对象,你也可以将它称作模块或包。


    在每个类中,其包含的每套任务要有对应的方法,方法只针对这一任务的执行,且能成功的完成。相似的类可共同使用一种方法。


    作为新手,我无法本能地为每一个概念单元创建一个新类,而且经常无法确定哪些单元是独立的。因此,如果你看到一套代码中到处充斥着“Util”类,这套代码一定是新手编写的。或者,你做了个简单的修改,发现很多地方也要进行相应地修改,那么,这也是新手写的。


    在类中添加方法或在方法中添加更多功能前,兼顾自己的直觉,花时间仔细思考。不要认为过后有机会重构而马虎跳过,要在第一次就做对。


    总而言之,希望你的代码能具有高内聚性和低耦合性,这是一个特定术语。意思就是将相关的代码放在一起(在一个类中),减少不同类之间的依赖。


    试图规划未知


    在目前项目还正在编写的时候,总是去想其他的解决方案,这是忌讳的。所有的谜团都会随着代码的一行行编写而逐一解开。如果,对于测试边缘案例进行假设,是件好事,但如果总想要满足潜在需求,是不可取的。


    你要明确你的假设属于哪一类,避免编写目前并不需要的代码,也不要空想什么计划。


    仅凭空想,就认为未来会需要某种功能,因而尝试编写代码,是不可取的。


    根据目前的项目,始终寻求最少的代码量。当然,边缘情况是要考虑的,但不要过早落实到代码中。


    为了增长而增长是癌细胞的意识形态。

    ——Edward Abbey


    错误使用数据结构


    在准备面试的时候,新手往往太过于关注算法。掌握好的算法并在需要时使用它们固然不错,但记住,这与你的所谓“编程天赋资质”无关。


    然而,掌握你所用语言中各种数据结构的优缺点,对你成为一名优秀的开发者大有裨益。


    一旦你的代码中使用了错误的数据结构,那明摆着,你就是个新手。


    尽管本文并不是要教你数据结构,但我还是要提几个错误示例:



    使用list(数组)来替代map(对象)


    最常见的数据结构错误是,在管理记录表时,使用了list而非map。其实,要管理记录表,是应该使用map的。


    例如,在JavaScript中,最常见的列表结构是数组,最常见的map结构是对象(最新JavaScript版本中也包含图结构)。


    因此,用list来表示map结构的数据是不可取的。虽然这种说法只是针对于大型数据集,但我认为,任何情况下都应如此,几乎没有什么情况,list能比map更好了,而且,这些极端情况在新版本的语言中也逐渐消失了。所以,只使用map就好。


    这一点很重要。主要是由于访问map中的元素会比访问list中的元素快得多,访问元素又是常有的过程。


    在以前,list结构是很重要的,因为它能保证元素的顺序,但现在,map结构同样能实现这个功能。



    不使用栈


    编写任何需要递归的代码时,总是去使用递归函数。但是,这样的递归代码难以优化,特别在单线程环境下。


    而且,优化递归代码还取决于递归函数返回的内容。比如,优化两个或多个返回的递归函数,就要比优化单个返回值的递归函数困难得多。


    新手常常忽略了使用栈来替代递归函数的做法。其实,你可以运用栈,将递归函数的调用变为压栈过程,而回溯变为弹栈过程。


    把目前的代码变得更糟


    想象一下,给你这样一间凌乱的房间:



    然后,要求你在房间里再增加一个物件。既然已经一团糟了,你可能会想,把它放在任何地方都可以吧。因此,很快就能完成任务。


    但是,在编写代码时,这样做只会让代码越来越糟糕!你要做的是,保证代码随着开发的进行,变得越来越清晰。


    所以,对于那间凌乱的房间,正确的做法是:做必要的清理,以便能将新增的物品放置在正确的位置。比如,你要在衣柜中添置一件衣服,那就需要先清理好地面,留出一条通向衣柜的路,这是必要的一步。


    以下是一些错误的做法,通常会使代码变得更糟糕(只举了一部分例子):


    • 复制代码。如果你贪图省事而复制代码,那么,只会让代码更加混乱。就好比,要在混乱的房间中,添加一把新椅子,而不是调整现有椅子的高度。因此,头脑中始终要有抽象的概念,并尽可能地去使用它。


    • 不使用配置文件。如果你的某个值在不同时间、不同环境下是不一样的,则该值应写入配置文件中。或者,你需要在代码中的多个位置使用某值,也应将它写入配置文件。这样的话,当你引入一个新的值时,只需要问自己:该值是否已经存在于配置文件?答案很可能是肯定的。


    • 使用不必要的条件语句或临时变量。每个if语句都包含逻辑上的分支,需要进行双重测试。因此,在不影响可读性的情况下,尽量避免使用条件语句。与之相关的一个错误就是,使用分支逻辑来扩展函数,而不去引入新函数。每当你认为你需要一个if语句或一个新的函数变量时,先问问自己:是否在将代码往正确的方向推进?有没有站在更高的层面去思考问题?


    关于不必要的if语句的问题,参考一段代码:


    function isOdd(number) {
     if (number % 2 === 1) {
       return true;
     } else {
       return false;
     }
    }


    上面的isOdd函数是存在一些问题的,你能看出最明显问题吗?


    那就是,它使用了一个不必要的if语句。以下为其等效的代码:


    function isOdd(number) {
     return (number % 2 === 1);
    };


    注释泛滥


    我已经学会了,尽量不去写注释。因为大多数的注释可以通过对变量更好的命名来代替。


    例如以下代码:


    // This function sums only odd numbers in an array
    const sum = (val) => {
     return val.reduce((a, b) => {
       if (b % 2 === 1) { // If the current number is even
         a+=b;            // Add current number to accumulator
       }
       return a;          // The accumulator
     }, 0);
    };


    其实,也可以写成这样没有注释的,效果相同:


    const sumOddValues = (array) => {
     return array.reduce((accumulator, currentNumber) => {
       if (isOdd(currentNumber)) {
         return accumulator + currentNumber;
       }
       return accumulator;
     }, 0);
    };


    所以,每次写注释前,先思考一下:能否通过改善参数的命名来避免写注释呢?


    但有一些情况下,是必须写注释的。比如,当你用需要注释来表述代码的目的,而不是代码在做什么时。


    如果你实在想写注释的话,那就不要描述那些过于明显的问题。以下是一些无用注释的例子,它们只会干扰代码的阅读:


    // create a variable and initialize it to 0
    let sum = 0;
    // Loop over array
    array.forEach(
     // For each number in the array
     (number) => {
       // Add the current number to the sum variable
       sum += number;
     }
    );


    所以,不要成为这样的程序员,也不要接受这样的代码。如果必须处理这些注释的话,那就删掉好了。要是碰巧你雇佣的程序员总是写出这样的代码的话,快点解雇他们。


    不写测试


    我认同这一点:如果你自认为是专家,且有信心在不测试的情况下编写代码,那么在我看来,你就是个新手。


    如果不编写测试代码,而用手动方式测试程序,比如你正在构建一个Web应用,在每写几行代码后就刷新并与应用程序交互的话,我也这样做过,这没什么问题。


    但是,手动测试代码,是为了更明确如何在之后进行自动测试。如果成功测试了与应用的交互,那就应该返回到代码编辑页,编写自动测试代码,以便下次向项目添加更多代码时,自动执行完全相同的测试。


    毕竟,作为人类,每次更改代码后,难免会有忘记去重新测试曾经成功过的代码,所以,还是把它交给计算机完成吧!


    如果可以,就在编写代码之前,先猜测或设计测试的过程。测试驱动开发(TDD)这种方法不仅仅是流行,它还能使你对功能的看法发生积极的变化,以及为它们提供更好的设计方案。


    TDD并不适合每个人,每个项目,但是,至少要会用它。


    认为不出错就是正确的


    看看这个实现了sumOddValues功能的函数,有什么问题吗?


    const sumOddValues = (array) => {
     return array.reduce((accumulator, currentNumber) => {
       if (currentNumber % 2 === 1) {
         return accumulator + currentNumber;
       }
       return accumulator;
     });
    };
    console.assert(
     sumOddValues([1, 2, 3, 4, 5]) === 9
    );



    测试通过,一切顺利,但情况真是如此?


    上述代码问题在于,没有考虑到所有情况。尽管,它能正确地处理一部分的情况(测试时恰好命中这些情况之一)。来看看其中的几个问题:


    问题#1:没有考虑输入为空的情况。在没有传递任何参数的情况下调用函数,会发生什么?会出现如下所示的错误:


    TypeError: Cannot read property 'reduce' of undefined.



    这通常是个坏兆头,原因主要有二:


    1.用户无法看到函数内部,不知其如何实现的。


    2.异常提示对用户没有任何帮助,但你的函数又无法满足用户需求。倘若异常提示表述的更明确些,用户就能知道自己是如何错误地调用了函数。比如,可以在函数中,设计抛出一个异常,提示用户定义出错了,如下所示:


    TypeError: Cannot execute function for empty list.


    也可以不抛出异常,忽略空输入并返回0的总和。但是,无论如何,必须对这些情况有所处理。


    问题#2:没有处理无效输入的情况。如果传入的参数是字符串,整数或对象而不是数组,会发生什么情况?


    出现了下面的情况:


    sumOddValues(42);
    TypeError: array.reduce is not a function


    那么,很不幸,因为array.reduce确实是定义过的!


    我们命名了函数的参数数组,因此,在函数中,将所有调用该函数的对象(42)标记为数组。所以,就会抛出异常:42.reduce不是一个函数。


    这个错误很令人困惑不是?也许,更值得注意的错误是:


    TypeError: 42 is not an array, dude.


    问题#1和#2被称为边缘情况,他们都是常见的边缘案例。但通常,有一些不太明显的边缘案例也是需要考虑的。例如,我们传入负数,会发生什么?


    sumOddValues([1, 2, 3, 4, 5, -13]) // => still 9


    -13是奇数,但结果是你想要的吗?或许它应该抛出异常?求和过程是否应该包括参数中的负数?还是应该忽略?也许你意识到,该函数应命名为sumPositiveOddNumbers。


    这种情况处理起来很容易,但是,更重要的一点,如果不写一个测试文档来记录测试案例的话,后续的维护者也将对此毫无线索,甚至认为忽视负数是故意的或是出现了疏忽。


    问题#3:测试没有涵盖所有的一般情况。除了边缘情况,函数也有可能无法正确处理某个合理、有效的情况:


    sumOddValues([2, 1, 3, 4, 5]) // => 11


    上例中,不应将2计入总和。


    原因很简单:reduce函数是将第二个参数作为累加器的初始值的,如果该参数为空(如代码所示),reduce将使用数组中第一个值作为累加器的初始值。这就是为什么在上面测试用例中,第一个偶数值也包含在了总和中。


    即便你在编写的过程中就发现了这个问题(并解决了),也是要编写相应的测试案例并记录的,测试记录还应包含其他测试用例,如全偶数的情况,列表中存在0的情况,列表为空的情况。


    如果测试记录很少,又忽略了很多情况,忽视了边缘情况,那么,这一定是新手干的。


    对已经存在的代码不再质疑


    除非你是超级程序员,可以独当一面。否则,毫无疑问你会碰到许多愚蠢的代码。新手往往意识不到这些,他们会认为,既然作为代码库一部分,又用了很长时间的代码,一定是没有问题的。


    更糟的是,如果这些代码中存在不妥,新手可能就会在其他地方重复这些不妥。因为他们认为,代码库中的代码是没有问题的,从中学到的方法也是没有问题的。


    还有一些代码,看起来很糟糕,但是,它可能包含着某种特殊的情况,从而迫使开发人员必须这么写。这些地方,常常会有详细的注释,以将情况告知给新手,并说明,代码为何要这么写。


    作为新手,你应该假设任何不明白或不正规的代码都是不好的。然后,去提问,去质疑,去查他的git blame记录!


    如果代码的作者无处可寻,那就仔细研究代码本身,理解其中的所有。只有当你完全理解后,才能形成自己的观点(不论好与坏)。在此之前,不要草率地对代码下结论。


    沉迷于最佳实践


    我认为“最佳实践”这个词着实不好,它意味着无需再深入研究,这已经是最好的结果了,毋庸置疑!


    但编程中没有最好只有更好,只能说对某种程序而言,目前这已经是比较好的方案了。


    甚至某些我们以前认为的最佳实践,现在已经不是最好的解决方案了。


    只要你肯花时间去研究,总能发现更好的方案,所以不要再执着于最佳实践,尽你努力做到最好即可。


    不要因为你在某个地方读到的一句名言,或是你看到别人这么做了,或是听人说这是最佳实践就去做某件事。


    沉迷于性能优化


    在编程中过早优化是万恶之源(至少大部分是)。

    ——Donald Knuth (1974年)


    自从Donald Knuth发表了以上观点之后,编程就发生了很大的变化,至今为止,我认为这个观点都是有价值的。


    记住一条好的规则:如果你不能有效地量化代码中的问题,那就别试图去优化它。


    如果在执行代码前已经在优化了,那么你很可能过早的进行了优化,这是完全没必要的,只是在浪费时间。


    当然在你写新代码之前一些明显需要优化的内容还是要考虑优化的。例如,在Node.js中,你要确保你的代码中没有泛滥的使用循环或阻止调用堆栈,这些是非常重要的,这是你必须牢记要提前优化的一个例子。所以在编写过程中,可以时常问问自己:我准备写的代码会阻止调用堆栈吗?


    应该避免对任何不能量化的代码进行任何不明显的优化,否则反而会不利。可能你认为你这样做会带来性能上的提升,但事实上这会成为新的不可预料的bug来源。


    因此,不要浪费时间去优化那些不能量化的性能问题。


    不以最终的用户体验为目标


    在应用程序中添加特性最简单的方法是什么?从你自己的角度看,或许是看它如何适应当前的用户界面,对吧?如果这个功能是要捕获用户输入的,那么把它加到已有的那些表单中。如果这个功能是要添加一个页面链接,那就把它加到已有的嵌套链接菜单中。


    不要自以为是。要站在终端用户角度来开发,这样才是真正的专业人员。这样的开发者才会去思考有这个功能诉求的用户需要什么,用户又会如何操作。而且他们会考虑如何能让用户更便捷地找到和使用这个功能,而不是只考虑如何在应用程序中添加这个功能,而不考虑这个功能的可发现性和可用性。


    工作时没有选对适合的工具


    每个人在完成编程的相关活动中,都有一套自己喜欢使用的工具。其中有一些很好用,也有一些不好用,但是大多数工具只是对某一项特定任务很棒,而对其他任务来说都没有那么好。


    如果要把钉子钉在墙上,锤子确实是把好工具,但如果要用锤子来旋螺丝钉,那就是很糟糕的工具了。不能只是因为你“喜欢”锤子,就用它来旋螺丝钉。也不能因为锤子是亚马逊中最受欢迎的工具,用户评价得分5.0,就用它来旋螺丝钉。


    根据受欢迎程度来选择工具,而不是针对问题的适用性来选择工具是新手的一个标志。


    对于新手而言,另一个问题是:你也许根本不知道对一项特定工作来说什么工具“更好”。在你当前的认知范围内,也许某一种工具就是你所知道的最好的工具。但是,跟其他工具相比时,它并不是首选。你需要熟悉所有可用的工具,并且对刚开始使用的新工具保持开放的心态。


    一些程序员是拒绝使用新工具的,他们对于现有的工具很满意,而且他们可能也不想去学习任何新的工具。我明白,我也能理解,但是这显然是不对的。


    工欲善其事,必先利其器。你可以用原始工具建造一个小屋,并享受你的甜蜜时光;你也可以投入时间和资金去获得好工具,这样你就可以更快地建造一座更好的房子。工具是不断更新的,而你也需要习惯去不断学习并使用它们。


    不理解代码问题会造成数据问题


    一个程序非常重要的一方面就是某种格式数据的管理,该程序将是添加新记录、删除旧记录和修改其他记录的界面。


    程序的代码即使有一点点的小问题,都会给其管理的数据带来不可预估的后果,尤其当你所有的数据验证都是通过那个漏洞程序完成时,则更是如此。


    当涉及到代码和数据的关系时,初学者可能不会立即将这些点联系起来。他们可能觉得在生产中继续使用一些错误代码也是可以的,因为特征X是不用运行的,它没那么重要。但问题是错误代码可能会不断地导致数据完整性问题,虽然这些问题在一开始的时候并不明显。


    更糟糕的是,在修复漏洞时,并没有修复漏洞所导致的细微的数据问题,就这样交付代码只会积累更多的数据问题,且这样的问题会被贴上“不可修复”的标签。


    那么如何避免让自己发生这些问题呢?你可以简单地使用多层次的数据完整性验证,不只依赖于单个用户界面,应该在前端、后端、网络通信和数据库中都创建验证。如果你不想这么做,那么请至少使用数据库级别的约束。


    要熟练掌握数据库约束,并学会在数据库中添加新列或新表时使用它们:


    • NOT NULL是对列的空值约束,表示该列不允许使用空值。如果你的应用程序中设定某个字段必须有值,那么在数据库中它的源数据就应该定义为not null。


    • UNIQUE是对列的单一约束,表示在整个表中该列不允许有重复值。比如,用户信息表的用户姓名或者电子邮件字段,就适合使用这个约束。


    • CHECK约束是一个自定义表达式,对于满足条件的数据,计算结果为True。例如,如果有一列值必须是介于0到100之间的百分比,则可以使用CHECK约束来强制执行。


    • PRINARY KEY(主键)约束表示某一列的值必须不为空,且不重复。你可能一直在用这个约束,数据库中的每个表都必须有一个主键来识别不同的记录。


    • FOREIGN KEY(外键)约束表示某一列的值必须与另一个表的某一列值相匹配,通常来说外键约束也会是主键约束。


    对于新手来说,另一个与数据完整性相关的问题是缺乏对事务处理(transactions)的思考。如果多个操作需要更改同一个数据源,且它们相互依赖时,则必须把它们包装在一个事务当中,这样当其中一个操作失败时就可以进行回滚。


    推倒重来


    这是一件很麻烦的事情。编程过程中,有时的确是需要推倒重来。编程不是一个界限分明的领域,变化层出不穷,新需求提出的速度远超于任何团队可以应对的能力范围。


    打个比方,基于当前的速度,如果你需要不同种类的轮胎,除了改进我们都熟悉且喜爱的轮胎以外,也许我们需要换一种角度思考。然而,除非真的需要特殊设计的轮胎,否则没有必要推倒重来。就将就用用原来的轮胎吧。


    不要浪费宝贵的时间在寻找所谓的最好的轮胎之上。快速搜索,然后使用所寻找到的内容。只有在这些轮胎真的没法像宣传的那样好好工作时,再进行更换。


    编程最酷的一件事就是大多数轮胎都是透明的,你可以看到它内部的构造,能够非常容易地判断代码的质量高低。


    所以尽量使用开源代码。开源包的缺陷更容易解决,更容易被替代,也更容易从内部支持。然而,当你需要一个轮子时,不要买一个全新的车,然后把你现在的车放在那辆新车上。


    也就是说,不要在代码里加载一整个包,然后只使用里面的一两个函数。最好的例子就是JavaScript中的lodash程序包。如果你只是想随机排列一个数组,只需要加载shuffle方法就好,不要加载一整个令人绝望的lodash程序包。


    厌恶代码审查


    新程序员们的一个明显特征就是把代码审查当做批评,他们不喜欢、不珍惜,甚至是恐惧代码审查。


    大错特错,如果你也有同样的感受,那么你需要立刻改变你的态度。把每次代码审查都看做是学习机会,用开放的心态欢迎、珍惜它们,并且从中学习。更为重要的是,要向给你提供了指导的审查员们表示感谢。


    你需要接受一个事实——每个人都是终生代码学习者。大多数代码审查都能教给一些你以前可能不知道的知识,所以请将代码审查当做是一项学习资源吧。


    有时,审查员也会犯错误,这时候就轮到你去教他们一些东西了。然而,如果审查出来的问题不仅仅是由于你的代码导致的错误,那么也许还是需要进行代码修改。如果无论如何你都需要教审查员一些东西的话,那么谨记:教授别人是你作为程序员最有收获的一件事。


    不使用源代码控制


    新手们有时会低估一个好的源代码/版本控制系统,所谓好的系统,我指的是Git。


    源代码控制并不仅仅是指把代码修改推送给别人,然后进行版本变更,这个行为的意义远不止如此。源代码控制的主要目的在于清晰的历史记录。


    代码需要时常进行回顾,而代码的修改过程的记录将会极大助力于一些疑难杂症的解决,这也是为什么我们会很在意提交信息。代码控制同样也是一个沟通实施信息的渠道,使用这些零碎的提交历史,能够帮助未来的代码维护人员了解代码的发展情况以及现在所处的状态。


    常常提交、尽早提交,并且出于对连贯性的尊重,请在提交标题中使用现在时态。信息最好尽量详尽,但谨记它们应该是经过提炼总结的。如果你需要好几行来阐述想表达的内容,也许意味着你的提交信息太长了。重来吧!


    不要在提交信息中不要放入任何不必要的信息。例如,不要列出被加载、被修改或者被删除的文件。


    这些列表本身已经包含在提交的代码中了,并且能够通过一些Git命令参数实现,它们只会成为总结信息中的噪音。一些团队喜欢在每个文件改变中都做一次总结,我认为这是另一种提交信息太冗长的标志。


    源代码控制和可发现性也有关系。当你遇到一个函数,需要开始了解它的需求或者设计,你可以寻找介绍它的提交信息,然后阅读函数相关内容。


    提交信息甚至可以帮你找到程序中导致缺陷的代码是哪些。Git在提交中提供了一个二进制搜索(bisect命令)来精准定位导致缺陷的罪恶源头。


    源代码控制也可以在代码变动正式生效之前发挥极大的作用。诸如阶段转换、选择性打补丁、重置、隐藏、修复、应用、区分、撤销以及其他许多对代码编辑有用的工具。所以好好理解、学习、使用并且珍惜他们吧。


    你知道的Git特性越少,那么你离文章中所说的新手就越接近。


    过度使用共享状态


    同样的,这一点并不是在比较函数式编程与其他算法的优劣区别,那是另外一篇文章要谈论的话题。


    需要指出的是,共享状态往往是问题的源头,如果可能的话,尽量避免使用它。如果无法避免,那么需要把使用共享状态控制在最低限度。


    当我还是编程初学者的时候,我没有意识到我们所定义的每一个变量都是一个共享状态。变量当中包含了数据,并且可以被该变量所处的域内所有元素改变。域的范围越大,那么这个共享状态的范围就越广。尽量把新变量声明维持在一个小范围内,并确保它们不会向上渗透。


    情况比较严重的问题就是当共享状态生效、多个源头都会导致同一个事件循环标记发生改变时(在事件循环环境中),会发生争用条件。


    事实是:新手有可能会采取计时器作为共享状态争用条件的曲线救国之道,特别是当他们需要处理数据锁定的问题时。


    这是在立flag,别这样做。切记,处处留心,并且在代码审查时指出这个问题,绝对不要接受这种情况。


    不正确地面对错误


    错误是一个好东西,它们的存在意味着进步,意味着你更容易获得成长。


    编程大牛们对错误爱不释手,而新手则恨之入骨。


    如果看着这些可爱的小小红色错误信息,会让你觉得心烦,那么你需要改变一下态度,把它们视为助手。你需要好好对待它们,并充分发挥它们的作用,促进自己的成长。


    有些错误需要升级至异常情况。异常情况是需要你给出解决方法的用户自定义错误。有些错误需要单独进行处理,它们的存在将会让程序崩溃,并且强制退出。


    从不休息


    程序员也是人类,你的大脑、你的身体都需要休息。常常,当你进入编程状态时,就忘记了休息。我把这一点也视为新手的一个标志。这不是你可以妥协的点。把一些能够强制你休息的内容整合到你的工作流中,然后短暂地休息一下。


    离开椅子,在附近走走,同时想想下面需要做的事情。当你回到代码的世界时,就可以用全新的视角看待你的成果。


    这篇文章很长,现在你可以休息一下了。


    你在学习编程的过程中踩过哪些坑呢?请给我们留言吧!感谢阅读!


    原文链接:

    https://medium.com/@samerbuna/the-mistakes-i-made-as-a-beginner-programmer-ac8b3e54c312


    展开全文
  • 这个标题是干什么用的? 最近看晚上某些人耍cmd耍的十分开心,还自称为...纯属娱乐,新手教程,大佬勿喷 注:本文所有代码,都为.bat格式 *1:蹦迪必备颜色转换 这个十分简单,先看效果 原理,也不复杂,就是不停的变...

    这个标题是干什么用的?

    最近看晚上某些人耍cmd耍的十分开心,还自称为“黑客”,着实比较搞笑.他们那些花里胡哨的东西在外行看来十分nb,但只要略懂一些,就会发现他们的那些十分搞笑和滑稽。

    今天这里分享几个类似的方法,让你在不懂行的朋友面前秀一波“黑客技术”

    纯属娱乐,新手教程,大佬勿喷

    注:本文所有代码,都为.bat格式

    *1:蹦迪必备颜色转换
    这个十分简单,先看效果

    原理,也不复杂,就是不停的变颜色,比较晃眼,在外行面前比较高级

    不说废话,直接上源代码

    color 
    echo 艾瑞巴蒂嗨起来!!!
    color 1a
    echo
    color 2b
    echo
    color 3c
    echo
    color 4d
    echo 
    color 5e
    echo
    color 6f
    echo
    color 70
    echo
    %0
    

    使用方法:创建文件,将后缀名改为bat(没有后缀名的自行百度),右键文件,点击编辑,输入代码,按住“Ctrl + s”保存,退出,打开(本文所有文件都为这种方法)

    2:树形浏览文件
    不说废话,先看效果

    说一下它的原理,tree指令用于将文件以树形格式输出,"tree e:"就可以以树形结构输出电脑中的文件夹和文件

    tree 在英语中是树的意思,在bat中为树形输出

    代码:

    color a
    tree e:
    %0
    

    没有错,非常简单,只有三行

    注:%0表示重复循环

    3:遍历所有文件
    这个怎么硕呢,跟上面那个差不多(本文比较简单),就是正常的输出文件

    看看效果吧

    源代码:

    color a
    dir /s
    %0
    

    "dir /s"是输出所有文件,“/s”应该是bat里的一个正则表达式

    附:color 是用来调整颜色的,如果我选择的颜色你不满意,你可以打开dos界面,输入“help color”获得信息
    在这里插入图片描述
    这里在附一个骂人的bat脚本,效果就不演示了,直接上代码

    color a
    echo 我真帅
    %0
    

    echo后面可以接你想输出的内容

    未经允许,禁止转载

    展开全文
  • 学习笔记:从PS封装格式的视频文件中提取H.264(方法+资料+代码) 欢迎使用Markdown编辑器 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解...
  • 发信人: rainboyfdy (飘雨时分), 信区: BBSMan_Dev标 题: 我以前BBS的笔记,比较适合LINUX新手发信站: 水木社区 (Fri Nov 11 18:10:17 2005), 转信暑假想学LINUX,就了个REDHAT,没事干就用BBS来学LINUX了只是...
  • windows的一些装B用法

    千次阅读 2011-08-02 22:52:16
    高手新手都适用的137个技巧   ● 绝对有用的20条电脑使用超级技巧  ● 在IE上显示自己的名字   ● “网页上有错误”的解决方法  ● 防止QQ密码被盗的五个绝招  ● 电脑各种错误信息...
  • STM32新手入门教程

    万次阅读 多人点赞 2020-11-24 09:53:38
    5 B B这一项代表内嵌Flash容量,其中6代表32K字节Flash,8代表64K字节Flash,B代表128K字节Flash,C代表256K字节Flash,D代表384K字节Flash,E代表512K字节Flash,G代表1M字节Flash。 6 T T这一项代表封装,其中H...
  • 2020年 IOS 逆向 反编译 注入修改游戏或APP的调用参数新手系列教程——使用theos tweak 注入hook修改游戏执行代码上传动态头像开篇需求&最终效果bfinject对正在运行的APP脱壳打包成.ipa注入自己的动态...
  • 树莓派新手入门教程

    千次阅读 2017-11-08 20:32:44
    链接:树莓派新手入门教程 树莓派新手入门教程 作者: 阮一峰 日期: 2017年6月15日 树莓派(Raspberry Pi)是学习计算机知识、架设服务器的好工具,价格低廉,可玩性高。 本文根据我的亲身...
  • 谷粒商城笔记-新手级教程(1/4)

    万次阅读 多人点赞 2020-06-23 13:59:12
    主要了vitualbox,vagrant可以帮助我们快速创建出一个虚拟机。他有一个镜像仓库。 去https://www.vagrantup.com/ 下载vagrant安装,安装后重启系统。cmd中输入vagrant有版本代表成功了。 输入vagrant init centos/...
  • 无人机航模新手100 问

    千次阅读 2016-11-05 19:54:56
    原文地址:无人机航模新手100问作者:春风慕雪 ​ 1.新手入门须知 答:首先根据个人的爱好、动手能力、财力水平做一个自我评价,决定入手航模的方向,如固定翼、直机、多轴,固定翼入门较为简单,直机较难,多轴...
  • linux新手

    千次阅读 2015-08-11 15:44:54
    新手入门-LINUX(转)[@more@]如何安装LINUX? 搜索论坛就有了。 如何安装新内核? 有以下六步: make mrproper (用来消除原来编译的影响) make menuconfig (用config, xconfig也可以) make dep make ...
  • Python新手入门

    2019-07-11 14:29:51
    Python新手入门 author:Sisythus 传说中的目录: 文章目录Python新手入门author:Sisythus巨人的肩膀在这里呢:导读如果你是小白用户,满足以下条件:简介这是最近10年最常用的10种编程语言的变化图:编程语言排行...
  • typora新手使用笔记

    2020-07-17 17:06:12
    Typora新手使用笔记 Markdown的教程 Markdown是一种轻量级标记语言,让人们以一种易读写的纯文本格式编写文档。 ctrl + / 可实现源代码模式 和编辑模式的快速切换。 1.标题的配置 可以以#加空格的形式来配置标题。...
  • 反射进阶,编写反射代码值得注意的诸多细节

    万次阅读 多人点赞 2017-07-27 23:56:12
    前面一段时间,我编写了一篇关于 Java 反射基础知识的博文,内容挺...但是,因为反射这一块的内容实在是太多了,编写代码过程中难免会遭遇到各种各样的 Exception,对于一个刚熟悉反射基础知识的新手而言,往往会感...
  • bootthink也是中国人研发的,当然,它同样使用了经典的Chameleon变色龙代码,现在支持雪豹。安装后,Windows的启动菜单就会多了Bootthink的选项。在Windows的启动菜单选择Bootthink就会出现类似与苹果Boot Camp的...
  • 前天给新买的台式机了ubuntu10.04,刚用没多久就发现网络时不时地掉线,刚开始以为是坑爹的校园网的问题,但是切回到windows下网络又是出奇地稳定,心里不禁犯了嘀咕,别是驱动神马的出了问题吧。第二天掉线的情况...
  • 超全的css新手学习笔记

    千次阅读 多人点赞 2016-10-11 10:27:52
    适合新手的css学习笔记,超级全面
  • 几百行代码写个Mybatis,原理搞的透透的!

    万次阅读 多人点赞 2021-08-02 08:37:14
    } 测试结果 22:53:14.759 [main] DEBUG o.s.c.e.PropertySourcesPropertyResolver - Could not find key 'spring.liveBeansView.mbeanDomain' in any property source 22:53:14.760 [main] DEBUG o.s.b.f.s....
  • JEECG 新手常见问题大全,入门必读

    万次阅读 2016-07-05 13:25:14
    代码生成器相关配置文件src/main/resources/jeecg/jeecg_config.properties(比如代码生成根路径)  详细请参看文档《JEECG 开发指南》第7节代码生成器专题    特别注意参数:  代码生成器是单独的数据库配置...
  • Mac新手入门

    千次阅读 2015-10-13 17:46:07
    这两天rmbp到手,开心,但是无奈我不会用,app出各种篓子,真是日了
  • TensorFlow 新手入门

    千次阅读 2017-03-07 16:35:33
    上TensorFlow,还是不太会用,主要去官网还要翻墙太麻烦了。。随手翻一下教程备用初识TensorFlow初期准备: 安装好TensorFlow 知道如何在Python中编程 懂一点数组知识 最好了解机器学习(不必要) TensorFLow...
  • 万字干货:教新手从0到1搭建完整的增长数据体系

    万次阅读 多人点赞 2020-07-14 01:00:57
    在实际的业务中,大多数人可能只会遇到以下一种或几种常见的场景,并且对于各个细分场景,所需要解决的问题和关注重点都是不一样的。 场景一:你刚加入一个成熟产品的用户增长部门,会发现业务当前有非常全面详实...
  • 渗透新手入门

    千次阅读 多人点赞 2018-12-26 20:23:38
    这个我不懂,只知道他有储存型和反射型,最好利用的是储存型,可以直接利用,反射型就是给管理留言那里给管理员留言带一句话木马的xss代码。只要管理员点了,就可以获取一个shell。(这一块你们最好自己在网上找找...
  • 高级的编程是逻辑思维的流露,会编程只代表你懂了这门语言的语法...首先我要声明的是:如果你是编程新手,本文并不是要让你对自己犯的错误感到愧疚,而是要你对这些错误有更好的认知,并避免在未来再犯。 当然,这...
  • 如何写出无法维护的代码  2011年06月03日 陈皓 评论 120 条评论 124,691 人阅读 酷壳里有很多我觉得很不错的文章,但是访问量最大的却是那篇《6个变态的Hello World》,和它能在本站右边栏“全...
  • latex新手入门

    千次阅读 2014-04-14 21:59:03
    1. 基础 对于真心渴望迅速上手LaTeX的人,可以只看正文。 曾经在缝缝补补中变得长长的“前言”被我丢到了正文后面当“后记”。 后记部分可以跳过不看或只看粗体。...注:文章里的代码我自己测试
  • VIM新手入门

    千次阅读 2013-10-22 09:26:19
    简介 工欲善其事,必先利其器。 Vim 是个神奇的编辑器(简称“神器”),Vim 运行...Vim 在许多人心目中是13神器,至于是不是这样也只有用的人知道了。 Vim 家族中还有 gVim 和 VimTouch 等项目,Windows/*nix

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 13,989
精华内容 5,595
关键字:

新手装b代码