醉月思 发布的文章

介绍

无监督学习允许我们在处理问题时几乎不知道结果应该是什么样子,我们可以从数据中获得结构,而不必知道变量的作用。我们可以根据数据中变量之间的关系对数据进行聚类,从而得到这种结构。在无监督学习中,没有基于预测结果的反馈。也就是说,机器可以在你提供的数据中主动的去分析,总共有几类?哪些数据属于什么类?

效果展示

列表顺序加载动画

本文会讲述如何使用scss/sass在微信小程序中实现列表顺序加载的动画。

所用的css特性

CSS animations

CSS animations 使得可以将从一个CSS样式配置转换到另一个CSS样式配置。动画包括两个部分:描述动画的样式规则和用于指定动画开始、结束以及中间点样式的关键帧。

相较于传统的脚本实现动画技术,使用CSS动画有三个主要优点:

  1. 能够非常容易地创建简单动画,你甚至不需要了解JavaScript就能创建动画。
  2. 动画运行效果良好,甚至在低性能的系统上。渲染引擎会使用跳帧或者其他技术以保证动画表现尽可能的流畅。而使用JavaScript实现的动画通常表现不佳(除非经过很好的设计)。
  3. 让浏览器控制动画序列,允许浏览器优化性能和效果,如降低位于隐藏选项卡中的动画更新频率。

css animations的属性和子属性见https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_Animations/Using_CSS_animations#%E9%85%8D%E7%BD%AE%E5%8A%A8%E7%94%BB

可主要分为两大部分,动画的实现形式和动画的属性规则。

以下仅列出本文所用的属性。

animation-timing-function

animation-timing-function 规定动画的速度曲线。

速度曲线

animation-delay

顾名思义,设置动画的持续时间,单位秒

animation-fill-mode

animation-fill-mode 属性规定动画在播放之前或之后,其动画效果是否可见。

animation-fill-mode

使用keyframes定义动画序列

keyframes就是一个描述关键帧的属性,通过使用@keyframes建立两个或两个以上关键帧来实现。每一个关键帧都描述了动画元素在给定的时间点上应该如何渲染。

因为动画的时间设置是通过CSS样式定义的,关键帧使用percentage来指定动画发生的时间点。0%表示动画的第一时刻,100%表示动画的最终时刻。因为这两个时间点十分重要,所以还有特殊的别名:from和to。这两个都是可选的,若from/0%或to/100%未指定,则浏览器使用计算值开始或结束动画。

示例

@keyframes list {
        0% {
            transform: scale(0);
        }

        100% {
            transform: scale(1);
        }
    }

如上代码所示,定义了一个@keyframe名字叫list,在动画开始时使用缩放0%,结束时缩放100%。那么它在整个动画的过程中,便会根据浏览器的性能展示一个从0%-100%渐变的动画。是不是根据有点意思?当然,你也可包含设置任何额外可选的关键帧,描述动画开始和结束之间的状态,比如45%。

animation.gif

至此我们已经实现了组件显示时逐渐放大的效果

所用的scss特性

以下为简介,详细内容请转至官方文档

嵌套规则 (Nested Rules)

scss/Sass允许将一个 CSS 样式嵌套进另一个样式中,内层样式仅适用于外层样式的选择器范围内。

引用父选择器:&

你可以 & 字符来明确地表示插入指定父选择器。

变量: $(Variables: $ )

以美元符开头,可当变量使用。

@mixin混入指令 (Mixin Directives)

混入(mixin)允许您定义可以在整个样式表中重复使用的样式,而避免了使用无语意的类(class),比如 .float-left。混入(mixin)还可以包含所有的CSS规则,以及任何其他在Sass文档中被允许使用的东西。
他们甚至可以带arguments,引入变量,只需少量的混入(mixin)代码就能输出多样化的样式。

插值:#{}(Interpolation: #{})

你可以通过 #{} 插值语法在选择器和属性名中使用 SassScript 变量:

@for

顾名思义,循环,要留意一下tothrough的区别

引用混合样式:@include (Including a Mixin: @include)

实现方式

wxml文件

<view class="list__item">
<view>...</view>
</view>

编译前的scss/sass

    .list {
        &__item {
            animation: list 1s ease both;
        }
    }

    @keyframes list {
        0% {
            transform: scale(0);
        }

        100% {
            transform: scale(1);
        }
    }

    @mixin item($num) {
        $waitTime: ($num)*0.2;
        animation-delay: #{$waitTime}s;
    }

    @for $i from 1 through 7 {
        .list__item:nth-child(#{$i}) {
            @include item($i);
        }
    }

less版

// list动画
    .list__item {
        animation: list .8s ease both
    }

    @keyframes list {
        0% {
            transform: scale(0);
        }

        100% {
            transform: scale(1);
        }
    }

    .generate-columns(7);

    .generate-columns(@n, @i: 1) when (@i =< @n) {
        .list__item:nth-child(@{i}) {
            animation-delay: @i * 0.2;
        }

        .generate-columns(@n, (@i + 1));
    }

编译后的css

.list__item {
  -webkit-animation: list 1s ease both;
          animation: list 1s ease both;
}
@-webkit-keyframes list {
0% {
    -webkit-transform: scale(0);
            transform: scale(0);
}
100% {
    -webkit-transform: scale(1);
            transform: scale(1);
}
}
@keyframes list {
0% {
    -webkit-transform: scale(0);
            transform: scale(0);
}
100% {
    -webkit-transform: scale(1);
            transform: scale(1);
}
}
.list__item:nth-child(1) {
  -webkit-animation-delay: 0.2s;
          animation-delay: 0.2s;
}
.list__item:nth-child(2) {
  -webkit-animation-delay: 0.4s;
          animation-delay: 0.4s;
}
.list__item:nth-child(3) {
  -webkit-animation-delay: 0.6s;
          animation-delay: 0.6s;
}
.list__item:nth-child(4) {
  -webkit-animation-delay: 0.8s;
          animation-delay: 0.8s;
}
.list__item:nth-child(5) {
  -webkit-animation-delay: 1s;
          animation-delay: 1s;
}
.list__item:nth-child(6) {
  -webkit-animation-delay: 1.2s;
          animation-delay: 1.2s;
}
.list__item:nth-child(7) {
  -webkit-animation-delay: 1.4s;
          animation-delay: 1.4s;
}

列表顺序加载动画效果展示

参考资料

使用CSS动画
CSS3 animation-timing-function 属性
sass中文文档

大家好,我是醉月思。

为什么我叫"醉月思"呢?这要追溯到很久很久以前,大约还是我在读高二的某一天晚上,有位朋友告诉我:"你的名字好中二啊!"。

刹那间,我恍然大悟,我怎么叫了个这样的网名“银慧空狼”(话外音:我TM当时脑袋是瓦特了吗?起了个这样的名字!)。

于是我坐在台阶上苦思冥想,立誓要起一个符合我气质的名字,要让人家见名知意,然后知其人。终于,在我某一刻抬头仰望夜空之时,灵光一现!

月夜.png

便想到了“醉月思”这个网名。于是,我屁颠屁颠的将一个中二的网名进行了"二转"————变成了一个比较含蓄的中二网名。

狼-夜.png

看出来没??引用当时一句比较潮的话,我也是醉了。。。从此,醉月思这个“二转”含蓄中二网名便陪我到现在。

2019-11-30T08:08:14.png

直到我上大学,我突然意识到,有着自己独特的网名还不能凸显我的气质,我应该还得拥有一个属于自己的专属头像。

放荡不羁.png

最开始,我使用的是这个头像。

小男孩头像

后来,由于某些原因我需要换掉这个头像。我就找了一个我喜欢的动漫的男女主头像————我当时以为的男女主,因为初中看过之后就直接看到后面的剧情感觉怪怪的,所以就没怎么看。如下图

现在的头像

以后“醉月思”和这个头像就成了我的第二身份标识,下面,就是一些个人经历回忆。

时间线

  • 2015年10月,编(chao)写了人生第一个程序a+b=c(居然不是hello world)。
  • 2015年11月,人生第一个游戏编写成功,也是第一次发圈装逼

2019-11-30T07:40:52.png

  • 2016年6月,第一次使用C++做界面

2019-11-30T07:39:38.png

  • 2016年8月,第一次以醉月思的名义在CSDN上发表人生第一篇博客

2019-11-30T07:52:37.png

  • 2016年9月,第一次解除java,并试图反编译APP

2019-11-30T08:00:10.png

  • 2016年10月,第一次上线"拼图游戏"

2019-11-30T08:02:52.png

  • 2016年10月,注册个人公众号。

2019-11-30T08:23:56.png

  • 2016年10月,注册域名“thinkmoon.cn”

2019-11-30T08:14:24.png

  • 2016年12月,第一次搭建个人博客网站

2019-11-30T07:41:32.png

  • 2017年1月,第一次接触Linux,然后就把电脑装为linux了

2019-11-30T08:04:17.png

  • 2017年2月,第一次使用脚本语言爬取四六级成绩

2019-11-30T08:05:08.png

  • 2017年4月,第一次打算组建个Team来运营公众号

2019-11-30T07:58:52.png

  • 2017年6月,完成第一个"微信小程序"。

2019-11-30T07:36:57.png

  • 2017年7月,人生第一个软件上线。

2019-11-30T07:38:24.png

  • 2017年9月,开始熟悉JavaScript

2019-11-30T07:54:26.png

  • 接下来的有兴趣的去我博客看吧。

一些成果展示。

  • 博客数据概览

2019-11-30T08:28:34.png

  • 篆书转换器小程序数据概览

2019-11-30T08:30:11.png

  • 指尖魔法屋公众号数据概览

2019-11-30T08:35:59.png

  • 博客收益数据概览

2019-11-30T08:35:30.png

后记

我庆幸我有着写博客的习惯,算上这篇,博客文章加上水文,刚好凑够了100篇,当时我就在想,到了100篇,我一定要写点什么。现在看来,也算是半个百篇总结吧。最后,愿我可以将这个习惯坚持下去!

后后记

本来是想写一篇广告文的,写着写着就偏离了主题。文末打波广告,这是我最近开发的博客小程序,对接typecho的。大家有钱的点个赞赏捧个钱场,不想赞赏的扫码进入捧个人场?在此,我谢谢大家这几年来的支持和陪伴,愿我们彼此交流,共同成长!

2019-11-30T08:49:11.png

前言

本文使用jQuery修改typecho让其在文章编辑页内支持CTRL + S保存文章草稿,typecho的版本为1.2 (18.10.23).

为什么需要?

由于个人博客使用的typecho,在编辑文章的过程中经常习惯性的点击CTRl + S,然后就会非常不友好的提示了这个。

2019-10-28T06:59:58.png

这对追求优雅的本宅来说,简直无法容忍。难道我要因此弃用typecho?这也太夸张了。那就来发挥我modify的能力吧,毕竟闲余折腾是我的一大乐趣,而且自己动手,丰衣足食嘛!

心路历程

  1. 首先,我知道这个理论上绝对可行,因为我用过很多此类功能。
  2. 经查阅资料,chrome的适配最好,当然我也没考虑别的浏览器,因为我眼中的浏览器只有两种,chrome和不是chrome。随便一提:不用chrome的程序员不是优雅的程序员。
  3. 分析实现方法,大致分为两步,监听ctrl+s时间和模拟点击保存草稿按钮
  4. 选型方面,由于typecho内置jquery,因此采用最快捷的办法

实现过程

确认页面是否支持jQuery

为了避免重复引入,我们可在console中输入$,根据提示来确认是否已有jQuery

确认是否已有jQuery

如图,则表示已有jQuery。

找到编辑文章的php页面

嗯,就是这个路径typecho/admin/write-post.php

找个合适位置放script

请在文件末尾插入一个script节点,以防止在jquery定义之前使用或者在if语句中未应用。

监听ctrl + S

在script节点中插入以下代码

$(window).keydown(function(event) {
        if (event.ctrlKey && event.which == 83) {
            alert("Ctrl+S pressed.");
            return false;
        } else {
            return true;
        }
    });

刷新编辑文章页,提示以下内容则监听成功。

好像暗黑背景有点看不清?

模拟点击保存

通过源代码分析,我们可以发现,保存文章的按钮id为btn-save。现在我们修改代码里面的内容如下

$(window).keydown(function(event) {
        if (event.ctrlKey && event.which == 83) {
            $("#btn-save").click();
            return false;
        } else {
            return true;
        }
    });

大功告成

2019-10-28T07:33:26.png

结语

本文从技术层面上来说没什么亮点,这是我在尝试一种新的写作方式的练手篇。在原先只记录如何做的基础上,增加了了心路历程这一项,侧重于记录我在实际过程中一个想法到把它实现出来的整个过程,目的在于分享如何思考,从哪里开始,怎么实现的整个思维过程。大家且当抛砖引玉看看吧!

参考资料

JavaScript或jQuery模拟点击超链接和按钮
javascript屏蔽Ctrl+s,F1,F3各浏览器兼容写法

What is Machine Learning?

Two definitions of Machine Learning are offered.
  1. Arthur Samuel described it as: "the field of study that gives computers the ability to learn without being explicitly programmed." This is an older, informal definition.
  2. Tom Mitchell provides a more modern definition: "A computer program is said to learn from experience E with respect to some class of tasks T and performance measure P, if its performance at tasks in T, as measured by P, improves with experience E."
Example: playing checkers.
E = the experience of playing many games of checkers
T = the task of playing checkers.
P = the probability that the program will win the next game.

In general, any machine learning problem can be assigned to one of two broad classifications:
Supervised learning and Unsupervised learning.

什么是机器学习?

机器学习的两个定义
  1. Arthur Samuel定义机器学习为: "研究使计算机在无需特定明确的编程下自主学习的邻域." 这是一个很老的非正式定义
  2. Tom Mitchell提供了一个正式的定义: "一个程序被认为能从经验E中学习,解决任务 T,达到 性能度量值P,当且仅当,有了经验E后,经过P评判, 程序在处理 T 时的性能有所提升。"
例如: 国际象棋.
E = 下棋的经验
T = 下棋的任务.
P = 程序赢得下一场比赛的概率.

一般来说,任何机器学习问题都可以分为两大类:监督学习和非监督学习

有监督学习

有监督学习(Supervised learning),是一个机器学习中的方法,可以由训练资料中学到或建立一个模式( learning model),并依此模式推测新的实例。训练资料是由输入物件(通常是向量)和预期输出所组成。函数的输出可以是一个连续的值(称为回归分析),或是预测一个分类标签(称作分类)。

回归问题

这是收集到的房价与房子大小相关性的数据轴

2019-11-23T13:11:57.png

现在假设你有750平的房子,想要预测它能卖多少钱。那么机器学习该如何帮助你呢?它会使用这些数据试图用一条线来拟合,拟合的线可能是线性关系也可能是其他函数关系。

2019-11-23T13:15:53.png

2019-11-23T13:16:41.png

拟合的越完美,学习算法预测的结果就越准确。而使用什么函数来拟合,就需要经验和技术。

这就是一个简单的线性回归问题,通过已知的数据集来预测一个连续的输出值。

分类问题

我们来看另一个例子,学习判断肿瘤是否为恶性的算法。

2019-11-23T13:23:24.png

以上是肿块大小与是否为恶性肿瘤的数据图,假设一个人的肿块大小为以下位置。

2019-11-23T13:25:58.png

想知道自己的肿瘤是否为恶性肿瘤的话,学习算法会根据已知的数据对患者患恶性肿瘤的概率进行预测。我们再拓展一下,我们可以对恶性肿瘤的各种性质数据做采集,然后根据其值判断其患恶性肿瘤的概率,甚至是判断其患的是哪种类型的肿瘤。这就是有监督学习中的分类问题。

Supervised Learning

In supervised learning, we are given a data set and already know what our correct output should look like, having the idea that there is a relationship between the input and the output.

Supervised learning problems are categorized into "regression" and "classification" problems. In a regression problem, we are trying to predict results within a continuous output, meaning that we are trying to map input variables to some continuous function. In a classification problem, we are instead trying to predict results in a discrete output. In other words, we are trying to map input variables into discrete categories.

参考资料

Supervised Learning - 斯坦福大学 | Coursera
机器学习中的有监督学习,无监督学习,半监督学习

引言

熟悉uni-app的人应该都知道,uni-app并未对微信小程序云函数(本文统称云函数)进行相应的适配。但是,如果我们在某些业务场景的下需要使用云函数呢?我们知道,云函数可以复制到微信开发者工具,这样的话我们不得不每次编译一次就手动复制一次,不得不说麻烦至极。本文就问题做出以下解决方案。

本文环境

  1. Hbuilder X

Hbuilder X版本

  1. 微信开发者工具

微信开发者工具版本

创建云函数目录

首先,我们需要在uni-app项目文件夹下,创建一个云函数目录,路径随意,我这里是functions。然后先随便在里面放一些文件,这里以new_file.css为例。

修改manifest.json

在uni-app根目录下,修改manifest.json中的微信小程序项,结构如下

"mp-weixin" : {
        /* 小程序特有相关 */
        "appid" : "wxd7de467f6e6cf741",
        "cloudfunctionRoot": "./functions/", // 这一行就是标记云函数目录的字段
        "setting" : {
            "urlCheck" : false
        },
        "usingComponents" : true
    }

编写vue.config.js

  1. 我们在项目根目录创建vue.config.js文件
  2. 写入以下内容(如路径不一样请做相应适配)
const path = require('path')
const CopyWebpackPlugin = require('copy-webpack-plugin')

module.exports = {
    configureWebpack: {
        plugins: [
            new CopyWebpackPlugin([{
                from: path.join(__dirname, 'cloudFunctions'),
                to: path.join(__dirname, 'unpackage/dist', process.env.NODE_ENV === 'production' ? 'build' : 'dev', process.env
                    .UNI_PLATFORM, 'cloudFunctions')
            }])
        ]
    }
}
  1. 编译运行

发现提示如下内容

提示内容

说明未安装copy-webpack-plugin插件,我们手动安装一下。

npm install -save copy-webpack-plugin
TIPS: 截至2020.6.4, uni-app暂不支持copy-webpack-plugin 6.0版,请安装5.0版

安装copy-webpack-plugin

然后编译运行,发现微信开发者工具里面出现以下内容。

微信开发者工具里面的内容


截止目前,已打通Hbuilder X到微信开发者工具的自动复制,即已解决本文的核心内容。以下为进一步测试。

创建云函数

我们在云函数根目录上右键,在右键菜单中,可以选择创建一个新的 Node.js 云函数,我们将该云函数命名为check。开发者工具在本地创建出云函数目录和入口 index.js 文件,同时在线上环境中创建出对应的云函数。创建成功后,工具会提示是否立即本地安装依赖,确定后工具会自动安装 wx-server-sdk。我们会看到以下内容。

创建好后将其同步复制到uni-app项目,即可为以后自动同步行方便,又可避免在输出文件夹中云函数的意外丢失。至此,相关文件编写工作转至Hbuilder X,云函数上传部署依旧在微信开发者工具。

云函数模板内容

编写云函数

默认的云函数只是一个返回用户基本数据的内容,我们将其修改至满足我们的业务需求,以内容安全云调用为例。

在云函数文件中写入以下内容

// 云函数入口文件
const cloud = require('wx-server-sdk')

cloud.init()

// 云函数入口函数
exports.main = async(event, context) => {
  try {
    console.log('待检测文本:' + event.content);
    let result = await cloud.openapi.security.msgSecCheck({
      content: event.content
    })
    console.log('result:' + JSON.stringify(result));

    if (result && result.errCode.toString() === '87014') {
      return {
        code: 300,
        msg: '内容含有违法违规内容',
        data: result
      }
    } else {
      return {
        code: 200,
        msg: 'ok',
        data: result
      }
    }

  } catch (err) {
    if (err.errCode.toString() === '87014') {
      return {
        code: 300,
        msg: '内容含有违法违规内容',
        data: err
      }
    }
    return {
      code: 400,
      msg: '调用security接口异常',
      data: err
    }
  }
}

权限申明

云函数config权限声明

如上图,在函数目录下,创建一个config.json,文档说会自动创建,但是我实际操作时未自动创建。config.json内容如下。

{
    "permissions": {
        "openapi": [
            "security.msgSecCheck"
        ]
    }
}

然后在函数目录右键,上传并部署。

小程序调用云函数

App.vue

<script>
  export default {
    onLaunch() {
      wx.cloud.init();
    }
  }
</script>

index.vue

let res = await wx.cloud.callFunction({
          name: 'checkText',
          data: {
            "content": this.displayString
          }
        })
        if (res.result.code != 200) {
          uni.showModal({
            title: "温馨提示",
            content: "你所输入的内容可能含有违法违规内容,不支持进行下一步操作"
          })
          return
        }

效果展示

微信图片_20191022110949.png

1. 创建一个Dynamic panel

2019-10-17T00:43:02.png

2. 添加面板状态

双击动态面板,点击state1添加,编辑面板状态

2019-10-17T00:47:06.png

添加至三个面板状态

2019-10-17T00:48:58.png

3. 创建选项卡

2019-10-17T00:45:12.png

确保是在对应的state里面添加

2019-10-17T00:50:59.png

4. 添加选项卡点击事件

为选项卡添加点击切换到对应的state的状态

2019-10-17T00:53:25.png

依次添加直至所有选项卡都有可切换到对应state的点击事件

2019-10-17T00:55:31.png

5. 设置响应状态

在不同的state下,设置对应state应该显示的效果

state1的效果

依次将组件复制到其他state并设置对应显示效果

2019-10-17T01:02:59.png

6. 预览效果

tab.gif

2019-10-16T02:05:03.png

前言

最开始是没有搜索引擎的,后来有了谷歌,也就有了搜索引擎。但别人却一直模仿不过来,直到谷歌公布了三篇论文,然后有了百度。

时至今日,谷歌与百度已经不单单是搜索引擎了,始于搜索引擎,但又都不止于搜索引擎,但是谷歌却一直在被模仿从未被超越。所以百度与谷歌的差距究竟在哪呢?

搜索引擎

个人在使用两家的搜索引擎有个很明显的感觉,百度能搜到的内容少而单一,谷歌则好些。但这还有一部分原因是GFW,被GFW拦住的网站,是注定在百度排不上号的。所以内容少并不能完全怪百度。内容重复或者参考价值不大的情况两个平台都有,百度结果比较多文章转载的,而谷歌则经常出现各种搜索集合网站,如下

2019-11-21T03:19:05.png

做这些产业的人,都已经非常熟悉搜索引擎的规则, 纯粹的营销网站罢了.这个也很难避免,有搜索规则就有人能摸索出来(顺便一提,我的网站怎么老是排不上名呢)

未完待续

为什么有些字体无法设置为控制台字体?

字体设置
因为windows对控制台的字体,有着极其严格的要求,只有满足要求的字体才能够被设置。

windows字体要求

原文已经找不到了,内容如下

windows字体要求

推荐的字体

Microsoft.YaHei.Mono

microsoft_yahei_mono字体是一款有着高辨识度的微软字体,字形清晰美观可读性强,电脑屏幕显示效果好,看着十分舒服,非常适合编程员使用

效果预览

2019-10-14T03:00:01.png

参考资料

  1. 自定义 Windows PowerShell 和 cmd 的字体
  2. Microsoft Support: Console (CMD) Fonts

比较官方的解释

伪类

伪类选择元素基于的是当前元素处于的状态,或者说元素当前所具有的特性,而不是元素的id、class、属性等静态的标志。由于状态是动态变化的,所以一个元素达到一个特定状态时,它可能得到一个伪类的样式;当状态改变时,它又会失去这个样式。由此可以看出,它的功能和class有些类似,但它是基于文档之外的抽象,所以叫伪类。

伪元素

伪元素是对元素中的特定内容进行操作,它所操作的层次比伪类更深了一层,也因此它的动态性比伪类要低得多。实际上,设计伪元素的目的就是去选取诸如元素内容第一个字(母)、第一行,选取某些内容前面或后面这种普通的选择器无法完成的工作。它控制的内容实际上和元素是相同的,但是它本身只是基于元素的抽象,并不存在于文档中,所以叫伪元素。

一级标题

二级标题

三级标题

四级标题