Category Archives: 他山石

他山石 梦游记 美图酷图

峨眉山

记得读高中时,有个爱看武侠的同学,每次见到我都会来一句“你怎么不叫蒋峨眉?”

哈哈,对于大部分非四川的同学,估计都是在“倚天屠龙记”里第一次听说峨眉山,而且大概率是李连杰电影版的倚天屠龙记——“围攻光明顶”可算是金庸武侠的名场面之一。不过,小说里的光明顶在昆仑山,可其实光明顶在峨眉~~O(∩_∩)O哈哈~。另外,小说里峨眉派是道教,可现实是,魏晋时峨眉确实道教兴盛,但到了隋唐,佛教盛行,到明清时,峨眉基本就只有佛寺了,而且成了传说中“普贤菩萨的道场”。再到当代,更是“佛教四大名山之一”,山上分布着大大小小十几处寺庙

这次出来,本来目标是“318国道-拉萨-珠峰大本营”一线,顺道去了张家界和黄山,既然路过四川,也就顺便把峨眉山也逛了。从张家界到峨眉山市,又是一千公里,一天时间刚好。

峨眉山月半轮秋,影入平羌江水流。
夜发清溪向三峡,思君不见下渝州。
——李白 《峨眉山月歌》

峨眉第一亭

峨眉山

一首隔壁眉州老乡的思乡词

归去来兮,吾归何处?万里家在岷峨。
百年强半,来日苦无多。
坐见黄州再闰,儿童尽楚语吴歌。
山中友,鸡豚社酒,相劝老东坡。
云何,当此去,人生底事,来往如梭。
待闲看秋风,洛水清波。
好在堂前细柳,应念我,莫剪柔柯。
仍传语,江南父老,时与晒渔蓑。
——苏轼 《满庭芳·归去来兮》

山亭

万年寺

接引殿

洗象池

清音阁

一线天

一线天,换个角度

金顶

当然,峨眉山最有名的,还有它的猴子

峨眉猴

峨眉猴

最后,来一首李白版的“月亮代表我的心”

我在巴东三峡时,西看明月忆峨眉。
月出峨眉照沧海,与人万里长相随。
黄鹤楼前月华白,此中忽见峨眉客。
峨眉山月还送君,风吹西到长安陌。
长安大道横九天,峨眉山月照秦川。
黄金狮子乘高座,白玉麈尾谈重玄。
我似浮云殢吴越,君逢圣主游丹阙。
一振高名满帝都,归时还弄峨眉月。
——李白 《峨眉山月歌送蜀僧晏入中京》

 

 

他山石 梦游记 美图酷图

张家界

千丈绝壁挂金松,万尺深涧锁玉龙。
百仗留得佳话在,两壁对插白云中。
—-宋·佚名《咏张家界》

行者无疆,告别美丽的黄山,再次踏上西行之路~~沿高速一路向西,一口气开出近1000公里,来到了湖南张家界。第二天一早,先来到武陵源景区……再次被大自然的鬼斧神工所震撼。

 天子山

峡高百丈洞云深,要识桃源此处寻。
戎旅徐行风雪紧,谁将兴尽类山阴。
—-明·胡桂芳《咏百丈峡》

袁家界

索溪峪

十里画廊

缥缈云烟画卷开,凝香染墨净尘埃。
幽姿淑态呈祥瑞,水色山光着眼来。
百鸟齐鸣深涧响,众仙恭立向王台。
千杯寻醉非虚幻,焉问刘郎谁与栽。 

金鞭溪

金鞭溪

黄石寨

寻常山里数青峰,玉笋成群插楚封。涧道冻云隐斜日,寺门长阪度疏钟。
古苔一望迷幽径,峭壁千年挂老松。玉垒匡庐曾浪迹,巨灵移岳此重逢。
—-明·夏子云诗

 武陵源景区面积很大,在里面整整转了两天,第三天,我们来到了隔壁的天门山和大峡谷景区

天门山

 大峡谷

 

大峡谷

…这张错了,这张不在地球上O(∩_∩)O哈哈~

他山石 梦游记 美图酷图

游黄山

黄山四千仞,三十二莲峰。
丹崖夹石柱,菡萏金芙蓉。
——李白《送温处士归黄山白鹅峰旧居》

一早四点钟从北京出发,一路向南,一直到晚上八点,行程1300公里终于到达目的地:黄山汤口镇。一夜无话,第二天早早起来前往本次黄山游的起点:慈光阁

~~嘿嘿,节约点体力,先走索道直接到迎客松。记得小时候家里客厅挂的画就是“黄山迎客松”,今天终于看到真的了

迎客松

 天都峰

莲花峰

 鳌鱼峰

折腾一天,终于来到了光明顶~~哈哈,没错,光明顶不在昆仑,而是在黄山。下山休息太绕,光明顶酒店小睡一晚,一千多块…心疼ε=ε=ε=(#>д<)ノ

第二天,早早起来继续逛,开始进入后山

“猴子观海”

“飞来石”

始信峰

峰奇石奇松更奇,云飞水飞山亦飞。
——魏源《黄山绝顶题文殊院》

宽围白浪身千叶,峭入青天手一藤。
——汤宾尹《同友人游黄山》

人间多少佳山水,独许黄山胜太华。
——老舍《咏黄山》

且持梦笔书奇景,日破云涛万里红。
——《登黄山偶感》

 over~~奇美黄山之旅就到这里 O(∩_∩)O哈哈~

 

他山石

[转]python Pandas 常用方法备忘

关键缩写和包导入
缩写:

df:任意的Pandas DataFrame对象
s:任意的Pandas Series对象
导入包:

import pandas as pd
import numpy as np

导入数据
pd.read_csv(filename):从CSV文件导入数据
pd.read_table(filename):从限定分隔符的文本文件导入数据
pd.read_excel(filename):从Excel文件导入数据
pd.read_sql(query, connection_object):从SQL表/库导入数据
pd.read_json(json_string):从JSON格式的字符串导入数据
pd.read_html(url):解析URL、字符串或者HTML文件,抽取其中的tables表格
pd.read_clipboard():从你的粘贴板获取内容,并传给read_table()
pd.DataFrame(dict):从字典对象导入数据,Key是列名,Value是数据

导出数据
df.to_csv(filename):导出数据到CSV文件
df.to_excel(filename):导出数据到Excel文件
df.to_sql(table_name, connection_object):导出数据到SQL表
df.to_json(filename):以Json格式导出数据到文本文件

创建测试对象
pd.DataFrame(np.random.rand(20,5)):创建20行5列的随机数组成的DataFrame对象
pd.Series(my_list):从可迭代对象my_list创建一个Series对象
df.index = pd.date_range(‘1900/1/30’, periods=df.shape[0]):增加一个日期索引

查看、检查数据
df.head(n):查看DataFrame对象的前n行
df.tail(n):查看DataFrame对象的最后n行
df.shape():查看行数和列数
df.info():查看索引、数据类型和内存信息
df.describe():查看数值型列的汇总统计
s.value_counts(dropna=False):查看Series对象的唯一值和计数
df.apply(pd.Series.value_counts):查看DataFrame对象中每一列的唯一值和计数

数据选取
df[col]:根据列名,并以Series的形式返回列
df[[col1, col2]]:以DataFrame形式返回多列
s.iloc[0]:按位置选取数据
s.loc[‘index_one’]:按索引选取数据
df.iloc[0,:]:返回第一行
df.iloc[0,0]:返回第一列的第一个元素

数据清理
df.columns = [‘a’,’b’,’c’]:重命名列名
pd.isnull():检查DataFrame对象中的空值,并返回一个Boolean数组
pd.notnull():检查DataFrame对象中的非空值,并返回一个Boolean数组
df.dropna():删除所有包含空值的行
df.dropna(axis=1):删除所有包含空值的列
df.dropna(axis=1,thresh=n):删除所有小于n个非空值的行
df.duplicated():判断重复数据记录
df.drop_duplicates():删除数据记录,可指定特定列或全部
df.fillna(x):用x替换DataFrame对象中所有的空值
s.astype(float):将Series中的数据类型更改为float类型
s.replace(1,’one’):用‘one’代替所有等于1的值
s.replace([1,3],[‘one’,’three’]):用’one’代替1,用’three’代替3
df.rename(columns=lambda x: x + 1):批量更改列名
df.rename(columns={‘old_name’: ‘new_ name’}):选择性更改列名
df.set_index(‘column_one’):更改索引列
df.rename(index=lambda x: x + 1):批量重命名索引

数据处理:Filter、Sort和GroupBy
df[df[col] > 0.5]:选择col列的值大于0.5的行
df.sort_values(col1):按照列col1排序数据,默认升序排列
df.sort_values(col2, ascending=False):按照列col1降序排列数据
df.sort_values([col1,col2], ascending=[True,False]):先按列col1升序排列,后按col2降序排列数据
df.groupby(col):返回一个按列col进行分组的Groupby对象
df.groupby([col1,col2]):返回一个按多列进行分组的Groupby对象
df.groupby(col1)[col2]:返回按列col1进行分组后,列col2的均值
df.pivot_table(index=col1, values=[col2,col3], aggfunc=max):创建一个按列col1进行分组,并计算col2和col3的最大值的数据透视表
df.groupby(col1).agg(np.mean):返回按列col1分组的所有列的均值
data.apply(np.mean):对DataFrame中的每一列应用函数np.mean
data.apply(np.max,axis=1):对DataFrame中的每一行应用函数np.max

数据合并
df1.append(df2):将df2中的行添加到df1的尾部
df.concat([df1, df2],axis=1):将df2中的列添加到df1的尾部
df1.join(df2,on=col1,how=’inner’):对df1的列和df2的列执行SQL形式的join

数据统计
df.describe():查看数据值列的汇总统计
df.mean():返回所有列的均值
df.corr():返回列与列之间的相关系数
df.count():返回每一列中的非空值的个数
df.max():返回每一列的最大值
df.min():返回每一列的最小值
df.median():返回每一列的中位数
df.std():返回每一列的标准差

转自:https://www.cnblogs.com/feiqixia/p/11241925.html

他山石

几个简单的推荐算法图解(转)

1. 基于内容的推荐:

上图给出了基于内容推荐的一个典型的例子,电影推荐系统,首先我们需要对电影的元数据有一个建模,这里只简单的描述了一下电影的类型;然后通过电影的元数据发现电影间的相似度,因为类型都是“爱情,浪漫”电影 A 和 C 被认为是相似的电影(当然,只根据类型是不够的,要得到更好的推荐,我们还可以考虑电影的导演,演员等等);最后实现推荐,对于用户 A,他喜欢看电影 A,那么系统就可以给他推荐类似的电影 C。

2. 基于用户的协同过滤推荐(User-based Collaborative Filtering Recommendation)

上图示意出基于用户的协同过滤推荐机制的基本原理,假设用户 A 喜欢物品 A、物品 C,用户 B 喜欢物品 B,用户 C 喜欢物品 A 、物品 C 和物品 D;从这些用户的历史喜好信息中,我们可以发现用户
A 和用户 C 的口味和偏好是比较类似的,同时用户 C 还喜欢物品 D,那么我们可以推断用户 A 可能也喜欢物品 D,因此可以将物品 D 推荐给用户 A。

3. 基于项目的协同过滤推荐(Item-based Collaborative Filtering Recommendation)

上图表明基于项目的协同过滤推荐的基本原理,用户A喜欢物品A和物品C,用户B喜欢物品A、物品B和物品C,用户C喜欢物品A,从这些用户的历史喜好中可以认为物品A与物品C比较类似,喜欢物品A的都喜欢物品C,基于这个判断用户C可能也喜欢物品C,所以推荐系统将物品C推荐给用户C。
———
转自:https://www.zhihu.com/question/19971859

Hello World 他山石

defineProperty

学习VUE“双向绑定”的实现,DOM变化时,同步给js变量,这一层比较容易理解,使用DOM的事件绑定就好了;但是当js变量发送变化时,是如何监控到、然后更新到DOM的,这点就比较有意思的。
看VUE代码,里面使用了ES5新加入的“Object.defineProperty()”,属性拦截器

看名字就比较好理解,使用defineProperty定义的属性,可以针对getter,和setter操作做监控、拦截,比如下面:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
let o = {};
Object.defineProperty(o, 'b', {
  configurable: true,
  enumerable: true,
  get: function(){
    console.log('get run');     //log1
  },
  set: function(v){
    console.log('set run', v);  //log2
  }
});
 
setInterval(function(){
  o.b = new Date().toLocaleString();
  console.log('o.b, ', o.b);     //log3  undefined
}, 3000);

这样,每隔3秒,log2,o.b赋值时,log2,就会被打印出来
但是,下面的反应比较奇怪,getter也被拦截了,log3位置,打印出来的是“undefined”。。。
这是因为getter里没有返回值
但是如果你胆敢在getter“return this.b”,运行时就会死循环,因为如果this.b又会去调getger
(是的,这就是js。。。增加一个看似“美丽强大”的新特性的同时,还给你附加几个坑,等你往里跳。。。。。)
那么,还能不能让人好好使用这个拦截器哪?
当然可以,这里,我们可以加一个“中间变量”过渡,setter时,给中间变量赋值;getter时,return这个中间变量,就不会死循环了

当然,还可以借助经典的“function-Class”定义,对整个过程做封装,比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function O1(){
  let v1;     //中间变量
 
  Object.defineProperty(this, 'v1', {
    get: function(){
      console.log('get run', v1);
      return v1;
    },
    set: function(v){
      v1 = v;
      console.log('set run', v);
    }
  });
}
 
var o1 = new O1();
 
setInterval(function(){
  o1.v1 = new Date().toLocaleString();
  console.log('o1.v1, ', o1.v1);
}, 3000);

———
转载请注明出处: http://www.jiangkl.com/2019/06/js_defineproperty

Hello World 他山石

[转]php字符串首字母转换大小写

首字母变大写:ucwords()

$foo = 'hello world!';
$foo = ucwords($foo); // Hello World!
$bar = 'HELLO WORLD!';
$bar = ucwords($bar); // HELLO WORLD!
$bar = ucwords(strtolower($bar)); // Hello World!

第一个词首字母变大写:ucfirst()

$foo = 'hello world!';
$foo = ucfirst($foo); // Hello world!
$bar = 'HELLO WORLD!';
$bar = ucfirst($bar); // HELLO WORLD!
$bar = ucfirst(strtolower($bar)); // Hello world!

第一个词首字母小写lcfirst()

$foo = 'HelloWorld';
$foo = lcfirst($foo); // helloWorld
 
$bar = 'HELLO WORLD!';
$bar = lcfirst($bar); // hELLO WORLD!
$bar = lcfirst(strtoupper($bar)); // hELLO WORLD!

字母变大写:strtoupper()

字母变小写:strtolower()

转自:http://www.jiangkl.com/?p=1454&preview=true

他山石

[转]前端开发的一些经验

上上周百度技术沙龙的是前端开发专题,第二场,来自豆瓣的前辈王克军所讲的“工程之美”给我留下了深刻的印象,以下ppt节选

  • 业务逻辑复杂时,通用和业务代码的分离、复杂度控制
  • 需求多变时,大而全的通用组件无用武之地,轻量的,功能单一的更便于复用
  • 工具防止人做愚蠢的事,也阻碍人干聪明的事
  • 工具不是越强大越好,而是简单有效最好
  • 工具不是越傻瓜越好,要留给他人发挥的空间
  • 前端开发,80%是工程问题,20%是技术问题
  • 模块要完全独立(借助工具实现)
  • 通用代码中绝不混杂业务逻辑
  • 代码逻辑复杂时,应该按业务拆分,不是按展现拆分
  • 代码架构借鉴SOLID原则(职能分离、开闭、里斯替换、接口分离、依赖反转)
  • 从实际开发中积累形成生态体系
  • 技术问题上开放,工程问题上保守
  • 在完成的基础上追求完美
  • 工具要简单,配置要简单
  • 工具是可以替换的,而且总是多变的,不要成为工具的努力
  • 对于复杂的问题,不断进行才接直到足够简单
  • 学点原研哉的Exformation哲学
  • 更多的时间做有趣的事!

“我们的发明常常是漂亮的工具,只是吸引我们的注意力,使我们离开了严肃的事物。”—-卢梭《瓦尔登湖》

更多精彩,请关注现场视频(估计过几天会更新上来):http://www.infoq.com/cn/zones/baidu-salon/

 

 

 

业界杂谈 他山石

关于WebKit的几个问题

1. WebKit是什么?

WebKit是一个开源的Web浏览器引擎。
WebKit的HTML解析器和JavaScript解析器代码分别源自KDE的KHTML和KJS代码库。

2. 谁在使用WebKit?

“MacOS X系统的Safari、Dashboard、Mail和很多其他OS X程序”
这就是在说,WebKit是Safari背后的浏览器引擎。还需要补充的是,Apple在Safari里面使用了自己的Nitro JavaScript引擎(只用WebKit来渲染HTML)。

Google官方说明:Chromium使用WebKit做为渲染引擎。与其打造Chromium特有的实现方式,我们更希望去尽可能多的去为使用WebKit核心的浏览器做贡献。

这是说Chrome也在使用Nitro JS引擎?不,Chrome有他自己的V8 JavaScript引擎。简单的说,Chrome也使用WebKit,但是它也实现了自己的JavaScript处理方式。V8同时还是驱动Node.js的JavaScript引擎。

Opera会使用Chromium实现的WebKit,也会使用V8引擎。这就是说虽然Opera在宣称自己使用WebKit,但事实上它使用WebKit和Safari与其他浏览器使用的WebKit并不完全一样。如果你想客观了解现状,这是必须清楚的概念。

3. 现在WebKit究竟有多少分支?

所以我们知道现在WebKit正在驱动,或者将会驱动3个主流浏览器。但是WebKit还有多少其他类型的实现?
确实还有很多很多WebKit的变种,特别是在移动领域。他们都是WebKit的分支。

4. 这些WebKit的分支有多少差别?

有一种假设:因为这些浏览器都在使用WebKit,所以他们也会以同样的方式去支持相同的特性。
对于很多基本的特性来说,确实是这样。但是对于很多小众特性,就未必如此了。

举例来说,当Chrome开始支持游戏手柄API的时候,Safari不但还没开始支持,而且以后也不太可能支持。另一个例子是WebGL。做为在Chrome已经支持了很久的特性之一,Safari却才刚刚看到了曙光(而且还是在开发者选项里)。当然,这些还都是比较出名的例子。还有很多试验性的例子潜伏在大众的视野之下。

甚至很多基础的、日常的功能,在不同的代码分支下都有所不同。PPK完整的总结了这些WebKit的差异。

5. WebKit的逐步普及,对web开发有什么影响?

如果一个浏览器迁移到了WebKit,那是不是意味着(在编写代码的时候)可以少测试一个浏览器了?
不。每个浏览器都有它自己的怪异模式、性能差异、设计,和功能。所以每个浏览器都要测试。

当一个功能加入到WebKit的时候,是不是意味着在其他浏览器里就可以使用这功能了?
当然不是。比如游戏手柄API的例子。Paul Irish强调了这样一个事实:WebKit浏览器们可以挑选究竟把哪些API放入他们的版本。比如Chrome选择支持游戏手柄API。很多API在WebKit的层面就已经被实现了,但是WebKit项目书允许关闭这些功能。(编者注:Paul Irish是Google Chrome的员工,他曾在jQuery团队工作两年。)

如果所有的浏览器都使用相同的引擎,这对程序员来说意味着什么?
随着时间的流逝,他们会意识到尽管同是WebKit,也会有很多不同的东西。

6. 新特性如何加入到WebKit中,谁又来负责审核?

现在有许多公司正在为WebKit项目贡献自己的力量。

WebKit项目提交和审查页面提到只能有老的代码提交员和审核员才能提名新的新的代码提交员与审核员。这比较合理。然而,无论WebKit项目决定让谁参与进来,最终都还是要让Apple来做审核:
当有人被WebKit代码提交员成功提名后,Apple会处理发送代码提交员协议,在签署协议之后,Apple会继续开通SVN账户。

对于这一点并没有什么隐秘的动机,但这确实在告诉大家,WebKit和很多开源项目一样,并不是真正分散和民主的。权利是且必须是集中的——只有这样才能保证能做出决定,并且把事情做成。

7. 如何评价WebKit?

允许我们强调一下,WebKit是好的。它有开放的流程和强大的贡献者。我们只是想澄清一个当下被广泛接受的错误概念——一个WebKit等于所有WebKit,还有——如果所有浏览器都选择WebKit,那么对开发者来说,工作会变得更轻松。
我的意思是说,与众多独立的浏览器引擎会为市场带来多样性一样,WebKit在这一点来说,同样会表现的很棒。

—————

转自:http://www.infoq.com/cn/news/2013/02/webkit-history-and-now

 

Hello World 他山石 点点滴滴

你真的会用javascript吗?

偶然在csdn看到几个js的小题,考察的都是很基础的知识,拿来分享一下
1.

1
2
3
4
if (!("a" in window)) {
  var a = 1;
}
alert(a);

开始,我以为是1,后来试了下,结果是undefined,仔细看看,也对:js在执行是,会首先提取所有var的新变量,让后给其赋值undefined,并将其加入到当前的执行环境总,比如这里,程序还没执行,实际就有了window.a=undefined,所以“(“a” in window)==true”
2.

1
2
3
4
5
var a = 1;
var b = function a(x) {
  return x*x;
};
alert(a);

一直以为这种写法会报错,汗颜的是,前段时间去某家公司面试,还碰上了类似的题目,回来也没写写试试。
实际试了下,这里的alert仍然是1,这种写法,a只在function a的内部是function,但是如果在a内部调用a(x),会递归
3.

1
2
3
4
5
function a(x) {
    return x * 2;
}
var a;
alert(a);

呵呵,有了第一个题,这个就比较简单了,function
4.

1
2
3
4
5
function b(x, y, a) {
    arguments[2] = 10;
    alert(a);
}
b(1, 2, 3);

这个也简单,arguments[2]就是a的替身,a会被修改为10
5.

1
2
3
4
function a() {
    alert(this);
}
a.call(null);

这里考察的是call的使用,正常call的参数是什么,里面的this就是什么(我也是这么理解的),但是关于call还有一条说明:如果call的参数是null或者undefined,里面的this仍然是当前执行环境,即window
————-
参考:http://bbs.csdn.net/topics/390300541