xulihang's blog 2019-02-19T07:38:56+00:00 xulihanghai@163.com 跳舞 2019-02-15T12:04:50+00:00 xulihang blog.xulihang.me/dance 音乐、诗歌、舞蹈都是表达感情的方法,而舞蹈可能是最富有表现力的一种形式。舞蹈动作与日常活动活动的关节和肌肉不一样,还能起到锻炼身体的作用。老百姓自发组织的广场舞可以说是兼具社交、锻炼等一系列功能。

作为普通人,我们不必像专业人士那样舞出高难度的动作,舞出健康,舞出快乐就行了。

《小苹果》的舞蹈配合音乐非常欢快,也较容易学习。可以参考下面这个视频学习:

比较难的可能是扭胯,可以按照以下方法感受如何做到:踮起右脚,重心往右前移,然后跨用力往左后方沉。

看到CH2女团跳《小苹果》,超越跳得很开心。

]]>
谁主张谁举证——谈网络黑子 2019-02-14T06:04:50+00:00 xulihang blog.xulihang.me/burden-of-proof 在江大学法律时,老师给我们强调“谁主张谁举证”以及“无救济无权利”。后者的意思是权利受到侵犯后,只有申诉才能享受司法救济。前者的意思是当事人对自己提出的主张提供证据并加以证明,这是举证责任(burden of proof)的通俗化说法。

网络黑子是一群喜欢贬低公众人物的人。他们往往没有认真了解贬低的对象,就跟风进行诋毁。另外还有捏造证据,以及高端黑。高端黑就是乍一眼看不出是黑,但本质是在贬低对方。我想,网络黑子也应该对自己的言论负责,没有确切的证据,不能轻易诋毁别人。

明星受到的关注多,有大量粉丝,也有很多黑子。《创造101》里,杨超越战队的二次公演,《麻烦少女》,被认为是车祸。看评论是一片诋毁,但是没有人说到底哪里表现得不好。杨超越也说二次公演翻船了,那么到底在哪里翻了?

我把麻烦少女的扒了下来,然后反复地看表演视频。

《麻烦少女》网上有多个版本,有腾讯视频的现场版、QQ音乐版和酷狗见面会版。前两个演唱的5个人相同,而后一个版本,也就是网上流传的车祸现场版本是晋级到22强的5个选手唱的,而且是合唱。

酷狗见面会版本我听了几遍,认为车祸的主要原因还是现场的设备问题,使得有的人的话筒没声音,有的人的话筒声音很大,盖过了别人。舞蹈和唱问题并不是很大。

然后再看二次公演的现场和QQ音乐版本的对比,差别主要是杨超越的一句词唱错了,并且QQ音乐版本杨超越的音色更像是录音棚里出来的。

我们作为观众,并不太可能像表演者那样熟悉自己表演的内容。所以,表演者会很清楚地知道自己哪里唱错了,而我们一时观察不出来。而且,表演即使错了,表演者也要装若无其事地继续表演下去。我为了研究《麻烦少女》到底哪里车祸了,也花了近一天时间。所以,网上随便发表的黑子的评论,我们看过算过,不必太过在意,而是要自己收集证据并做出判断。

]]>
《麻烦少女》简谱 2019-02-14T03:14:50+00:00 xulihang blog.xulihang.me/trouble-girl-transcription 上次扒谱还是高中时扒的仙剑的蝶恋,这次听到《创造101》里的《麻烦少女》,觉得很好听,但是网上搜不到现成的谱子,于是就自己上了。

我学过乐器,所以还算有点音感,听到曲调能唱出大致的音符,如果有吃不准的地方,就对着手机上的调音器软件唱并用乐器验证。手机上的调音软件还是不错的,可以显示唱的哪个音,对应多少频率。

把音符打下来,然后就要考虑节奏等其它因素了,可以直接边打谱边验证。我们这里需要使用打谱软件,常见的有overture、musescore、作曲大师等。打简谱的话,推荐jp-word。

我们先确定每个小节有几拍,也就是确定拍号。这个可以直接听出来,《麻烦少女》的节拍打得还是很清楚的,是4/4。然后确定每个音符的长度以及之间的停顿。

经过不断地听和修改后,得到如下的谱子:

这首歌要演唱得好,对节奏的掌握,要求还是挺高的,对于杨超越的确有难度。所以,节目里我们可以看到许诗茵拍了她肩膀两下,对应谱子里第二个哎呀后面的两个休止符。

再说说计算机自动扒谱。自动扒谱还是很有难度的,有一些商业软件已经实现了这一功能。Logic Pro X可以根据音乐生成midi,这样再用midi转乐谱比较简单。

一篇文章介绍了如何使用卷积神经网络扒谱:Music Transcription with Convolutional Neural Networks

不过,全自动的操作不一定靠谱,大多数还是机器辅助人来进行扒谱。除了上面提到的手机调音软件,还可以利用傅里叶变换生成频谱图以供借鉴。人自己听音去扒谱,可以提高技能,同时也有很大的成就感。

我这里扒的《麻烦少女》的主旋律,其它的什么和弦部分就没有涉及。如果是复调古典音乐,那就更加复杂了。

]]>
追星 2019-02-06T01:52:50+00:00 xulihang blog.xulihang.me/fandom 上次写有关明星的博客还是14年,李娜获得了澳网冠军。从小到大,我有喜欢过很多影视明星,比如看了《风云》,喜欢蒋勤勤;看了《射雕英雄传》,喜欢周迅。我记得小学时的《小学生时代》之类的书里有介绍周迅的,我便把那本书好好保存起来,然后还给那一对页喷上香水,有时候控制不住还亲上去。

但明星还是给我们一种距离感,毕竟他们比我岁数大很多,我的人生阅历也还有限。而随着年龄的增长,我对于明星也越来越理智,看到女同学们疯狂的追星行为有点难以理解。

而2018年的创造101节目,却给了我很强烈的真实感,让我第一次有了追星的感觉。这些女孩就像我平时生活中那些看似平凡的女孩。里面女孩们的团体生活,像极了我们平时的校园生活。

以大学生活为例,我们要认识从五湖四海而来的朋友,一起完成学习任务。平时还会有社团活动、学院活动和班级活动。每年,学院可能还有迎新晚会,有很多有才艺的同学会报名,但也有很多基础不太好的,需要经过3个月的训练才能为同学们带来一场尽善尽美的演出。创造101里的杨超越便是基础不好的代表。

一个集体的成员,每个人性格都不同,平时应该给予他们机会展现自己。最后成团的火箭少女中,有中性风的,有擅长说唱的,有擅长舞蹈的,有擅长搞笑的,每个人都有自己的特点。再举一个例子,我记得有一次主持人问团队的表演有什么不足,孟美岐说是有些音没唱准,这是专注于专业知识的学霸。其它人可能对专业知识没有那么敏感,关注的是团队合作。

但以集体活动时,应该保持方向的一致。比如小组为单位创作一首歌曲,不可能融合每个人的想法。创造101里麻烦少女组便面临了这一问题。我看过的美剧Austin and Ally的第二季第13集Couples & Careers也涉及了这一话题。

团队生活和我们校园生活的相似度吸引人,团员的个人魅力也是让人着迷。我最喜欢的还是杨超越。

杨超越我感觉是一个很单纯、很真实,但也有点小智慧的女孩。她给了我很强的代入感。她像我本科时一个嘻嘻哈哈,但有点学渣的女孩。她也像我自己。

我一个男人却被人评价为“很可爱”、“自带笑点”,杨超越有点孩子气的萌其实和我很像。我的确有一颗童心,单纯不掩饰,相信大人在小时候传播给我们的正能量。

在杨超越此前CH2的直播视频里,有人说出10000元让她跳舞,她机智地回应化解了骚扰。后来有人说她不跟着那个富二代亏了,她说她还年轻,应该靠自己过上幸福的日子。这莫不是小仙女吗?很多好的品质,我们幼时拥有,长大了却丢失了。

喜欢超越的原因很多,我就不多讲了。这里我也不从什么经济学之类的角度去分析她为什么成功。

需要注意的是,追星容易沉迷,不能一直刷。明星往往能给我们带来正能量,但沉迷于追星,影响正常生活就不好了。只有我们自己也不断努力,我们才能跟上偶像努力的步伐,对吧?

]]>
学点经济学 2019-02-01T03:34:50+00:00 xulihang blog.xulihang.me/learn-some-economics 最近薛兆丰的《经济学讲义》很畅销。他在得到平台上开设了课程,也上了《奇葩说》节目。这本书相比较传统的经济学教材,没有什么数学公式,名词定义通俗易懂,有大量的示例故事。这本书营销很成功,但内容细读会有错误和片面的地方,不过对于我来说还是可以学到很多。本书涉及的内容很多,我这里只把阅读过程中觉得重要的地方利用这篇博文记录一下。

第一章 稀缺

人类始终要面临一个稀缺的问题,一件商品有很多人想要,人想要的东西还会不断改变。人选择了一件东西却放弃了另一件东西,这种行为叫作歧视。歧视可能是不公平的,但有时候能够保证效率。比如海外的温州人只给温州人借贷,因为借给同乡承担的风险更低。而政府的反歧视行为可能会带来坏处,比如让银行不歧视穷人,给他们贷款,可能导致美国2008年这样的次贷危机。

作者提出商业是最大的慈善,人们为了满足自己的需要,会主动地和其他人进行交易,而只有真正会做生意的人,才能成功,推动社会资源的有效利用。公益组织的慈善行为不像市场行为,单纯发放物资没有很好的反馈机制,分发资源的代理人可能存在执行问题,穷人无偿受到资助可能没有了进取心。

第二章 成本

本书中的成本指放弃了的最大代价,指所有放弃了的选项中价值最高的那个(我觉得指的就是机会成本)。比如买了一个店铺,可以用来开餐馆或者超市。开了超市就不能开餐馆,这时成本是放弃开餐馆带来的成本。而买店铺可能花了100万,如果买了,那就是沉没成本。沉没成本不是本书定义的成本。

古董市场10元买来的碗,其实是真的古董,值10万,如果继续当做碗使用,使用成本就是10万元。而买这个碗得到的盈利是具有意外性的横财(windfall profit)。相反,如果花10万买了仅值10元的碗,用来吃饭的话成本是10元。自己蒙受了损失,英文是windfall loss。

高中经济学强调价值决定价格的成本决定论,但不能解释为什么有的明星的演唱会价格特别高的现象。这时,用供需关系决定价格来解释就可以解释得通。

带来收入的资源叫资产,对资产的付费叫租。北大给教授的工资,减少5000或者10000,他可能还是会选择留下来。那就是学校其实多给了这个教授工资,多给的部分便叫租。当然,只有这个教授的水平够好,他才能得到很高的租。

一个和租相关的概念叫寻租。为了得到更高的租,人之间会有竞争。人提高自身水平提高租是好的,但是通过不正当手段竞争或者争取政府优惠政策则会导致资源的消耗。

科斯定律从社会成本角度看问题。一个酒店扩建,遮挡了另一家酒店的露天游泳池,另一家酒店决定起诉这家酒店,如果你是法官,你会怎么判。一般人都倾向被遮挡泳池的酒店胜。但是如果这两个酒店属于一个老板呢?酒店的扩建能带来更多的收入,那游泳池就被挡住也是值得的。

科斯定律的意思就是谁用得好,资源就归谁。停止扩建还是继续扩建遮住游泳池,都会伤害到对方,这时要从社会这个角度看怎样才能把资源利用好。钻石只有戴在美女的项上才能发挥最大的价值。

但现实中,上面的例子中的两个酒店往往并不这样看问题,他们是两家酒店,要为了自己的利益考虑,所以会产生冲突。我们的社会是由无数人组成的,人与人之间要合作,这就会产生成本,叫作交易费用。这时,需要人们合作的时候寻找合作解,充分利用资源。

第三章 需求

首先讲个人估值这一概念,它是个人对一件商品进行的估值,具有主观性。客观价值论认为价格围绕价值上下波动,主观价值论则完全根据人的判断。主观价值论可以解释为什么一张老照片,对照片里的人的亲人来说价值连城,对其它人却一文不值的现象。主观价值论可以更好地指导生产,生产被人们需要的东西。

经济学中经常出现边际这个词,它的意思是新增带来的新增。比如边际效益是人们消耗某种商品带来的效益。吃一个包子很满意,但再吃4个包子,吃到最后一个时就不想吃了。这是边际效益递减定律,每多吃一个包子新增的效益是负数。

类似的概念还有边际成本:每新增一个单位产品所需要付出的新增成本;边际收入:每多卖一个产品带来的新增收入;边际利润:每多卖一个产品带来的新增利润。

边际平衡就是让资源在各种用途上的边际效益达到近似相同。比如中学生要学很多门课,需要平衡学科,不能偏科。数学考95已经很不错了,就没必要再花时间考100,应该花更多时间在薄弱学科上。

需求的三大定律。

第一定律是其它情况不变时,价格提高,需求变少,而价格降低,则需求增多。如果价格太高了,需求曲线来到第二象限,消费者会转变为供应者,自己生产产品。

第二定律是需求对价格的弹性和价格变化之后流失的时间长度成正比。大米这样的生活必需品受价格变动的影响小,需求的价格弹性就小。而高档汽车这样的奢侈品,价格弹性就大。

举的例子是房产。如果买房的需求量大于供给量,处于卖方市场,买家买房的弹性小。这时,如果有房产税,他需要承担更多的房产税。

第三定律是如果消费者必须支付一笔附加费,高品质的产品相对低品质的产品更加便宜。比如墨西哥的两种苹果,都运到中国来卖,因为有运费这一附加费,高品质的苹果能卖更多钱。用数字来说就是高品质苹果的成本是2+10元运费,低品质是1+10元运费,原来成本是两倍的关系,现在是12/11的关系。

第四章 价格

市场经济优于计划经济的地方在于它能利用价格充分配置资源。

人们会自发的追求效益的最大化,损失的最小化。政府的价格管制行为常常适得其反。比如政府限制租房价格,使得房子主人不愿意出租,造成租房供应紧张,反而让穷人更难租房。

第五章 权利

产权除了包含所有权,还主要包含使用权、收益权和转让权。我国的土地所有权归国家,但要是承包土地的百姓想把土地转给别人种呢,于是所有权和使用权可以分离,能够单独把使用权转让给别人。

产权保护的三个原则是财产原则、责任原则和不可转让原则。三个原则要根据具体情况进行选择。比如人体器官,我们认为是不可转让的。

仅可以供一个人使用的商品叫私用品,比如一个苹果。大家都可以享受的叫作公用品,比如一首歌曲。公用品也可以根据情况进行收费,比如一条快速公路,一条慢速公路,平时快速公路会拥堵,收费后可以平衡两条路的车流量。

第六章 耐心

一款手机,有现货和期货,期货要花几个月时间等待,但是便宜一点。这时,选择现货还是期货受对该商品的不耐(impatience)程度影响,如果急着用手机,那可能就会选择多花点钱买现货。

借了别人的钱需要支付利息,利息率就是现货和期货的比价。

投资是时间维度上的消费。我们投资教育,然后在未来得到回报。但如果我们没有投资教育,而是把时间花在了娱乐上,那以后的日子可能就不好过了。用来对付未来不确定的产品有保险、期货等。

第七章 供应

有一句话叫人无我有,人有我优,人优我廉,人廉我转。企业需要根据市场需要改变自己的供应。大卫·李嘉图的比较优势原理就是每个个体把有限的资源用来生产机会成本较低的产品,再和别人交换,可以使社会产品的总价值达到最大。

这时,需要个体之间进行分工合作。亚当·斯密认为主要有三点好处:减少工作之间往返的成本、促进熟能生巧以及是机器替代成为可能。

理解比较优势原理后再看贸易顺差和逆差,可以知道,单纯比较两个国家间的差额是没有意义的,因为现在国际分工合作,每个国家专注于生产自己有优势的产品然后交换,每个国家都会得到利益。

高质量的产品理应价格更高,这时就是一种不完全竞争状态,卖方是觅价者。而一个地方的农产品,质量都差不多,那就是完全竞争,农民接受价格,是受价者。

价格歧视指卖家根据用户不同的身份、位置、购买量、购买时间等,收取不同的价格。比如高铁的一等座、二等座。

第八章 信息不对称

卖假货、劣质产品都是利用了信息不对称。这样,买家不确定自己能不能买到高质量的产品,就会放弃购买。优质的产品,品质是稳定的,还具有一定的性价比。

建立互相信任,避免信息不对称的方法有重复交易和第三方背书。重复交易,比如淘宝选择一家店多次交易,发现商品值得信赖。第三方背书,就是有一个中间人进行担保。国外留学写推荐信也是一种。

除此之外,付出沉没成本、人质和抵押都是取得信任的办法。付出沉没成本,比如银行在繁华地段买房,让人们相信它会一直开下去。

第九章 合作

企业是一个大的人与人之间进行合作的地方。同事是比较熟悉的人,所以彼此的交易费用比和陌生人的要小,于是人选择到企业打工而不是自己单干。当然,企业规模太大,人之间彼此就相对不熟悉,交易成本会升高。

老板提供资源,雇员提供劳动力。其实老板是弱者,因为他的资源容易被滥用,而劳动力容易偷懒、滥用资源。

汽车工程师和保洁员的区别是前者需要在特定的平台发挥作用,是企业的专业资源。而后者在哪家公司都可以发挥作用,对应通用资源。一般来说,专业资源的提供者更需要企业兴旺发达,他们应该具有更大的决策权。

一个员工的议价能力取决于他在别处的机会,如果他没有地方可以跳槽了,他只有接受目前的工资。有的工作容易考核,可以根据考核结果分配工资,而不容易考核的可以给他们企业剩下的收入,他们叫做“剩余索取者”。

收入的节奏,有时薪、月薪和年薪。像教授这样按年薪计算,就不用想着每天有贡献,可以有时间做长期计划。

也可以按投入和产出划分收入。比如翻译,翻译了多少字数就给多少钱。而选秀比赛,第一名得的奖励多,最后一名可能啥也没有。

市场上存在同工不同酬的现象,但是因为市场竞争,最后这种现象会趋于减少和消失。如果强制规定同工同酬,弱者可能就没有机会了。

还有最低工资,比如白人的工资本来就高于最低工资,所以只对工资低的黑人有影响,这样雇佣黑人的企业可能因为人力成本高而难以为继。

基尼系数反应收入差距问题,但它有不足的地方。

  1. 现实中有不同收入节奏的职业和人群。收入和年龄的关系有三种,A类是公务员这样早工作、早受益、收入稳定、低风险的,B类是明星这样收入集中在中青年以前的,C类是教授、医生这样集中在中青年以后的。
  2. 不能以瞬时收入衡量收入差距。
  3. 收入不平均和收入不公是两回事。阶层是流动的,今天是富人可能明天就变成穷人。

穷人要不断努力,不过因为社会进步,现在的穷人比从前的穷人能享受到更好地物质生活。

第十章 协调

这一章主要讲宏观经济。调控宏观经济的一个手段就是货币。

商业银行通过在社会上流通钱,可以增加账面上的金额,但这个过程不能是无止境的,所以政府会规定一个法定准备金率,就是1000元存进来,只能拿出800进行放贷。因为增加的钱是账面上的,还没有成为印刷出来的现金,所以如果大家去银行挤兑,银行是取不出来这么多钱来的,这就是流动性风险。

银行通过给存款支付利息,用贷款赚取更高的利息来赚钱的,如果经营不善,就会出现资不抵债的困难,那这家银行还是关门大吉吧。

通货膨胀是宏观经济变化的一个表现,关于其原因有很多观点,有说是货币发行多了,有说是工资涨了。根据原因,有不同的应对通货膨胀的方法。

]]>
B4X游戏开发 2019-01-31T13:36:50+00:00 xulihang blog.xulihang.me/B4X-game-development 最近研究了以下如何用B4X开发2D游戏。2D游戏本质其实就是不断地在屏幕上显示新的图像。图像的显示一般都要使用图形库,比如javafx。

一个简单的记忆力对对碰游戏(若干张牌,只显示背面,点击可以显示正面。如果连续点击的两张正面相同则消除,不同则恢复为背面。),使用自带的ImageView控件就能搞定。

利用B4X的XUI,可以用通用的类B4XView表示对应平台的图形组件,这样跨平台时可以共用代码。

B4XCanvasBitmapCreatorGameView都是用来画图的类库。Canvas简单,BitmapCreator的功能更加强大,而GameView可以使用硬件加速。GameView是安卓的类库,点进它的Tutorial页,可以知道Erel推荐开发安卓游戏用libGDX。

How to make games是论坛的游戏开发者写的教程,列举了游戏开发要注意的事项和可以使用的资源。

一般2D游戏会有一个Sprite精灵的概念,相当于游戏里的一个对象,对应的代码要负责它的图像更新、动画等细节。然后一个游戏控制的代码文件,管控游戏的逻辑。图像的更新一般通过计时器来实现,还有用户输入的按键等信息,也在计时器的时间里处理。

为了让游戏具有真实性,我们还可以引入物理引擎,这里推荐的是Box2D,Erel已经封装好,我们可以直接使用。利用Box2D进行跨平台开发的一系列类文件统一叫做XUI2D,这里可以看到示例文件:[XUI2D] Example Pack

复杂的游戏都推荐使用XUI2D来完成。要学习XUI2D,首先的了解Box2D。我们可以先阅读它的手册,然后找几个示例来研究。

XUI2D主要包含以下几个bas类:

X2Utils.bas	X2的主要模块,有各种方法
X2BodyWrapper.bas	管理Box2D的物体(Body)
X2SoundPool.bas	管理音乐文件
X2SpriteGraphicCache.bas	缓存图片
X2TileMap.bas	利用TileMap来生成物体
X2DebugDraw.bas	Debug用
ScoreLabel.bas	处理状态栏信息

示例文件里项目结构按照这篇跨平台方案如下:

对应平台的代码主要是一个main类,负责针对平台处理输入输出以及设计界面。共享代码部分,Game.bas是游戏的主体,然后可以有很多的Body Degelate类。

这里再结合代码简单介绍一下Box2D,它是一个c++的物理引擎类库,变量命名方法是有一个B2的前缀,比如B2Vec2,B2World。

使用Box2D,首先要创建一个世界(B2World),这个世界的大小是以米(meter)为单位而不是像素,所以图片导入进去是都要做一个像素到米的转换。世界有一些属性,其中重力属性是必需的。

B4X中建立世界的代码如下:

Public world As B2World
world.Initialize("world", world.CreateVec2(0, -20))

建立好世界后我们再往里面添加物体,我们需要先使用B2BodyDef定义这个物体。Box2D的物体都是刚体(rigid body),坚硬不易变形,主要分为3类:Static、Kinematic、Dynamic。Static就是静止不动的物体,Kinematic物体可以拥有速度,而Dynamic物体除了速度,还可以添加力。此外,还要定义物体的位置、形状、大小和摩擦系数等。形状、摩擦系数等信息保存在固定装置(fixture)里,

以下代码建立一个地面。

Private Sub CreateGround
	Dim GroundBox As B2Vec2 = X2.CreateVec2(9.6, 0.96)
	Dim sb As X2ScaledBitmap = X2.LoadBmp(File.DirAssets, "ground.png", GroundBox.X, GroundBox.Y, False)
	X2.GraphicCache.PutGraphic("Ground", Array(sb))
	Dim bd As B2BodyDef
	bd.BodyType = bd.TYPE_STATIC 'the engine should not move it
	bd.Position = X2.CreateVec2(X2.ScreenAABB.Center.X, X2.ScreenAABB.BottomLeft.Y + GroundBox.Y / 2)
	Ground = X2.CreateBodyAndWrapper(bd, Null, "Ground")
	Ground.GraphicName = "ground"
	Dim rect As B2PolygonShape
	rect.Initialize
	rect.SetAsBox(GroundBox.X / 2, GroundBox.Y / 2)
	Ground.Body.CreateFixture2(rect, 1)
	GroundLevel = X2.ScreenAABB.BottomLeft.Y + GroundBox.Y
	Dim edge As B2EdgeShape
	edge.Initialize(X2.CreateVec2(-20, X2.ScreenAABB.TopRight.Y - bd.Position.Y - 0.01), _
		X2.CreateVec2(20, X2.ScreenAABB.TopRight.Y - bd.Position.Y - 0.01))
	Ground.Body.CreateFixture2(edge, 1)
End Sub

两个物体可以通过关节或叫连接装置(joint)连接起来。比如坦克的炮台可以转动,是通过连接装置连接起来的。以下面便是建立这个连接的代码:

Private Sub CreateRevJoint
	Dim template As X2TileObjectTemplate = TileMap.GetObjectTemplateByName(ObjectLayer, "hinge")
	Dim revdef As B2RevoluteJointDef
	revdef.Initialize(Tank.Body, Kane.Body, template.BodyDef.Position)
	revdef.SetLimits(0, cPI * 2/3) '设置可以转动的范围
	revdef.LimitEnabled = True
	revdef.MaxMotorTorque = 10
	revjoint = world.CreateJoint(revdef)
	revjoint.MotorEnabled = True
	Kane.Body.GravityScale = 0
End Sub

这里使用了多层地图TiledMap制作地图,通过读取对象层的对象来建立hinge这个连接装置,不用手写具体的代码。

以上代码来自clumsy bird和tank这两个示例项目。

]]>
如何写出好的英语文章 2019-01-22T02:11:50+00:00 xulihang blog.xulihang.me/notes-on-english-writing 英语是一种逻辑严密的语言,写好英语文章,需要遵循一定的规矩。

我这里梳理一下《书面英语基本功训练》中的内容。这本书是清华大学出版社出的影印版书籍,原书标题是English for Writers and Translators,作者是Robin Macpherson。翻译也是一种写作,所以看此书对翻译也有借鉴意义。

Part One

Paragraphing 分段

段落的存在使得文章有层次结构。段落的每句话应该都和该段的内容相关。英语的段落一般开头会有主题句(topic sentence),结尾处也会做一个总结。

Brainstorming and Ordering Material 构思与组织内容

这很像我们中学时考试写作文时的做法。你要想论述什么话题,怎样来提供证据,支持自己的观点。用关键词来写一个大纲。

First Paragraph 第一段

文章的第一段往往是介绍性质的,引起读者阅读兴趣的。很多著名的小说,都有非常精彩的第一段。比如《双城记》和《洛丽塔》。

小知识:英文第一段通常是没有缩进的。

Substantiating the Argument 论据要充实

一篇文章如果只是概述性地抛出一些观点,没有具体的论据,很难让人信服。我们可以在观点后面多加一些例子。

Perserving Clarity 保持内容的清晰

作为一个领域的专家,给业余人士解释专业知识并不是一件容易的事情。他认为很简单的东西,对于业余人士来说可能仍然很难理解。所以文章要有特定的读者,这样,我们写作的时候可以有针对性地调整专业知识的深入程度,让文章清晰易懂。

另外,文章要有连贯性(coherent),可以用Firstly、Secondly和Thirdly这样的词来提醒读者论点的转换。文章的开头可以写一个总结(Summary),让读者了解大概的内容。

Narrative 叙事

叙事内容一般遵循时间顺序(chronological order),要多用表示时间转换的词。中文的评书的时间顺序就很明显。

Part Two

Coordination 协调

并列结构中的子结构应该协调一致。比如统一采用动词不定式,而不是动词ing形式,还有前后主语的一致。

Left- and Right-Handed Sentences 多样的句型

一段介绍人物的文本,如果全都用he/she来开头,会显得很单调。这时可以调整句子内部成分的顺序,添加状语从句,让句型富于变化。

状语从句在主句之前,叫做Left-handed sentence,在后则叫做Right-handed sentence。

Emphasis 强调

有很多方式来表示强调。

  • 改变词语顺序,比如把副词放到前面。例:Slowly the tension mounted.
  • 使用所属格。例:The desion is yours.
  • 倒装。中学作文常用Under no circumstances、Only then等。
  • It is … that … 强调句

Comparison and Contrast 比较与对比

比较两个事物的异同,可以先介绍A事物,然后介绍B事物,或者介绍A事物的一个特点的同时介绍B事物对应的特点。

Cause and Effect 因果

原因并不是非常容易确定的,比如根据对少数样本的观察,得出作家都有抑郁症的结论,这个结论是以偏概全的。

原因和结果还容易混淆,比如癌症患者的维生素水平低,我们不清楚癌症是维生素水平低的原因,还是维生素水平低是导致癌症的原因。

Qualification and Concession 限定与让步

为了让我们说的话更加严谨,我们通常会加一些词来修饰,比如I think表示仅代表个人观点,perhaps表示不确定。

Discourse Markers 话语标志

In fact、What’s more、Similarly、Provided等词可以用来引出新的内容,起到标志话语作用的功能。

Word-Order 词语顺序

词语的顺序需要遵循语法规则,比如有的形容词只能放在名词的后面。

Punctuation 标点

英文的标点用法和中文的有很多不同,这里仔细讲一下。

冒号(colon)

用于人说话时的直接引语时用逗号而不是冒号。英文的冒号可以用来引用的话或者演讲文本前面。另外冒号还用于解释说明和罗列项目。

撇号(Apostrophe)

注意单复数形式时撇号的位置,还有children等不规则复数形式时撇号的位置。

撇号不能连续使用。my father’s friend’s son 应该作a son of my father’s friend。

逗号(comma)

逗号有分割句子内部成分、区别直接引语和主句等作用。

逗号还可以起一个非限定性的作用,比如以下两句:

Pop-star who earn fortunes should pay higher taxes.

Pop-star, who earn fortunes, should pay higher taxes.

前一个句子表示赚很多钱的明星应该付更多税,后一句表示明星都能赚很多钱,他们都应该交更多税。

破折号(Dash)

破折号在计算机中分为em dash、en dash等好几种,具体可以见维基百科。

这里我们按书中来,把它们都当做一种。

Dash的作用主要有以下几种

  • 非正式场合代替冒号和分号
  • 表示转念一想
  • 举例
  • 插入语(Parentheses)

省略号(Ellipsis)

省略号表示内容的省略或者话语的断断续续。

连字符(Hyphen)

连字符可以用来连接词语,比如two-year-old。在行尾,如果需要把词按音节断开,断开的位置也需要连字符。

括号(Parenthesis)

括号的内容用来解释说明,内容尽量简短。

引号(Quatation Marks)

引号里引用句子,要注意大写,不是句子就不需要大写。如果主句是问句,引号里也是问句,问号放在引号外面。引用里的引用用单引号引起来。

分号(Semicolon)

分号是介于逗号和句号之间的存在,它用来分割意思有紧密联系的句子,且分号后面的句子不需要首字母大写。

一个有用的地方是用于列举事物,比如以下片段:

The contrary possesses huge oil-deposits, though yet to be fully exploited; extensive coffee plantations, albeit hampered by antiquated technology; and finally, almost unlimited resources of rain-forest.

Part Three

Style and Register 语体与语域

一篇文章的风格或者叫语体,需要对应其使用的语域。比如非正式文本和正式文本。

Words of Latin Origin 拉丁语词

英语的词源有盎格鲁撒克森和拉丁语等,来自前者的词比较简单,比如big、old,来自后者的词则往往比较复杂,比如antique。拉丁语词一般比较正式。

Foreign Borrowings 外来语的借用

有很多其它语言的词直接进入了英语中,比如意为政变的法语coup d’etat、意为时代精神的德语词Zeigeist。使用这类词的场景一般学术性比较强。

Words and Expressions Best Avoided 应避免使用的表达

一些表达太过口语化,书面语中应该减少使用。比如a lot of、nice、kids。

Confusing Words 容易弄混的词

有很多词形相近的词,要正确进行区分和使用并不容易。比如economic和economical。相近的词还容易拼写错误,比如dependant和dependent。

Collocations 搭配

我们记单词时不仅要知道这个单词的发音、含义和拼写,还要知道它能和哪些词搭配。其实很多词只有在使用固定搭配时才会出现。比如beset with。

Capital Letter 大写

以下几种情况下需要首字母大写:

  1. 表示某种头衔,比如主教Archbishop Ramsay。
  2. 与宗教相关,比如Christian,Buddhist。
  3. 表示地理位置和历史事件,比如the Battle of Hastings、the Middle East。
  4. 用在标题中,除了介词、连词和冠词,都要首字母大写。
  5. 放在句子中的问句形式内容要首字母大写。
  6. 直接引语里的句子要首字母大写。

Italics 斜体

斜体可以表示强调,书名。

The Article 冠词

冠词并不容易掌握,以下是冠词的一些属性:

  • 冠词一般都在名词的前面
  • 冠词是限定词的一种,如果用了my这样的限定词,就不需要再加冠词。
  • The一般表示特指,不加the或者加a/an的则是泛指。
  • 复数的可数名词和不可数名词视情况可以不用冠词。而单数的可数名词,通常都需要在前面添加冠词。

以上只是知识点的整理,书中有更具体的表达和丰富的练习。毕竟写作光看理论是不行的,需要长时间练习才能取得进步。

]]>
B4J Web开发之BANano 2019-01-21T08:02:50+00:00 xulihang blog.xulihang.me/B4J-web-development-banano BANano是用来开发渐进式Web应用(Progressive Web App, PWA)的一个类库,和前文的ABMaterial都是由alwaysbusy创作。PWA的特点是可以离线使用,能像普通的应用一样出现在主屏,甚至安卓的应用列表里,拥有推送等本地化的功能。当然,BANano也能用来开发普通的网页。

BANano的读法类似banana,最后的一个音是o。

一般开发网页,需要使用HTML、CSS和Javascript。使用Bootstrap等框架,我们不用写复杂的CSS就能完成布局,而且能根据设备的尺寸调整显示的内容的尺寸,做到自动响应式布局。现在的网页一般基于div标签使用的一个网格式布局(grid layout),一个例子如下:


<div class="container">
   <h1>Hello, world!</h1>
 
   <div class="row">
 
      <div class="col-md-6 col-lg-4">
         <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit
         </p>
 
         <p>Sed ut perspiciatis unde omnis iste natus error sit voluptatem 
         </p>
      </div>
 
      <div class="col-md-6 col-lg-8">
         <p>Sed ut perspiciatis unde omnis iste natus error sit voluptatem 
            accusantium doloremque laudantium.
         </p>
      </div>
   </div>
</div>

一般div依次是container、row和column。column的尺寸由col-md-6中的数字决定,一般一行分为12等份,所有colum的数字加起来是12。更多可以看bootstrap的教程。

BANano可以把各种组件封装成B4J里的类,然后我们就可以像写B4J程序一样写网页,甚至使用B4J的界面设计器。这类似于使用jade生成html、coffeescript生成javascript。

BANano提供的例子中对Skeleton CSS进行了封装,可以方便地使用界面设计器进行设计。它参考了之前tchart 写的Skeleton (CSS + Library)。比如使用下面的B4J代码:

	Dim skc2a As SK_Column
	Dim skc2b As SK_Column
	Dim skc2c As SK_Column
	skc2a.Initialize(4)
	skc2b.Initialize(4)
	skc2c.Initialize(4)
	
	skc2a.AddContent("Light as a feather at ~400 lines & built with mobile in mind.")
	skc2b.AddContent("Styles designed to be a starting point, not a UI framework.")
	skc2c.AddContent("Quick to start with zero compiling or installing necessary.")
	
	Dim row As SK_Row
	row.Initialize
	row.Columns.Initialize
	row.Columns.Add(skc2a)
	row.Columns.Add(skc2b)
	row.Columns.Add(skc2c)

	Dim c1 As SK_Container
	c1.Initialize
	c1.Align = "center"
	c1.MarginTop = 3
	c1.Padding = 1
	c1.Rows.Initialize
	c1.Rows.Add(row)

可以生成如下的HTML代码:

<div class="section" align="center" style="margin-top:3rem;padding:1rem;">
    <div class="container">
        <div class="row">
            <div class="four columns">
                <p>Light as a feather at ~400 lines & built with mobile in mind.</p>
            </div>
            <div class="four columns">
                <p>Styles designed to be a starting point, not a UI     framework.</p>
            </div>
            <div class="four columns">
                <p>Quick to start with zero compiling or installing necessary.</p>
            </div>
        </div>
    </div>
</div>

上述代码描述了在一行里三等分的三个段落。不过,目前BANano偏向于使用设计器,对使用代码创建组件的设计并不完善。

BANano还可以把Basic语言转译(transpile)为JavaScript。

比如以下代码:

Sub test
	Dim style As String
	style=$"{"background":"green"}"$
	BANano.GetElement("#sklabel1").SetStyle(style)
End Sub

会转译为:

this.test= function() {
    if (self==null) self=this;
    var _style;
    _style='';
    _style = "{\"background\":\"green\"}";
    u("#sklabel1").css(JSON.parse(_style));
};

我开发了一个语音转文字的应用测试,发的帖子很快就得到了不少B4X论坛用户的点赞。可以访问这里查看。

]]>
B4J Web开发之ABMaterial 2019-01-19T07:56:50+00:00 xulihang blog.xulihang.me/B4J-web-development-abmaterial B4J支持使用WebSocket开发WebApp,利用服务器来处理一切操作。而ABMaterial是一个B4J WebApp开发框架,利用它,使用者不需要HTML、CSS和Javascript的知识,单纯用B4J就能开发出不错的网页应用。

ABMaterial集成了Materialize CSS框架,所以叫做ABMaterial,可以在Objects\www文件夹里看到css、js、font等文件夹。我们写的Basic语句,会被用来生成HTML和CSS,并利用Websocket操作DOM以及执行从Basic转译过去的JavaScript语句。

下载ABMaterial。

使用文档:

  1. http://abmaterial.com/,这是用ABMaterial写的用作文档的WebApp。

  2. ABMaterial For Dummies,B4X论坛的Harris网友写的新手教程。

模板分析

下载ABMaterial for Dummies的模板,我们对它进行分析。

项目主要有以下文件:


ABMPageTemplate.bas
AboutPage.bas
ABMShared.bas
Template.b4j
ABMApplication.bas

ABMCacheControl.bas
ABMCacheScavenger.bas
ABMErrorHandler.bas
ABMRootFilter.bas
DBM.bas

开头五个文件是平时会修改的文件,之后几个是ABMaterial运行需要的class文件,平时不需修改。

这个模板项目中,ABMPageTemplate.bas和AboutPage.bas是两个ABMPage的类,是用户能看到的页面,我们在这类文件里修改网页的内容。ABMShared.bas包含所有Page共享的操作,比如程序的导航栏是共享的,主题是共享的。ABMApplication类是WebApp的主体,管控其它的子页面,这里可以设置整个App的属性。而在程序的Main类里,我们平时需要做的是添加页面,Template.b4j的内容如下:

Sub Process_Globals
	Public srvr As Server
	
End Sub

Sub AppStart (Args() As String)
	' the user needs to login
	'ABMShared.NeedsAuthorization = True
	
	' Build the Theme
	ABMShared.BuildTheme("mytheme")	
	
	' create the app
	Dim myApp As ABMApplication
	myApp.Initialize
		
	' create the pages
	Dim myPage As ABMPageTemplate
	myPage.Initialize	
		
	Dim about As AboutPage
	about.Initialize
		
	' add the pages to the app
	myApp.AddPage(myPage.Page)
	myApp.AddPage(about.page)
	
	' start the server  - server name and port.
	myApp.StartServer(srvr, "srvr", 51045)	
	
	' When running on a remote server, uncomment this line below to record your log messages to a file!!!
	' Helps you debug remotely...		
	'ABMShared.RedirectOutput(File.DirApp, "errlogs.txt")
			
	StartMessageLoop
End Sub

然后是ABMPage页面类的分析,它主要包含以下Sub:

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize
	BuildPage
End Sub

public Sub BuildTheme()

public Sub BuildPage()

Private Sub WebSocket_Connected (WebSocket1 As WebSocket)

Private Sub WebSocket_Disconnected


public Sub ConnectPage()

Sub Page_ParseEvent(Params As Map)

' clicked on the navigation bar
Sub Page_NavigationbarClicked(Action As String, Value As String)

' this is the event that is fired when associated button is clicked... 
Sub guessbtn_clicked(Target As String)

在main类里实例化页面类时,完成了页面的Build工作,在用户通过WebSocket连接后,运行ConnectPage过程,渲染页面。ABMaterial会截获客户端的javascript事件,利用Page_ParseEvent,调用对应的B4J的事件Sub。

源代码中都有具体的注释。

开发流程

我们以开发一个猜数字的页面,简单介绍下开发流程。

  1. 新建一个Server Websocket的class,把template页面的代码复制进去,并修改Name属性为页面的名字。

  2. 使用ABMGridBuilder构建布局。ABMaterial采用Grid布局,一个行(row)的宽度被分为12等分,可以添加指定份宽度的列(column)。这里我选择以page为生成对象,生成3行,每行都只有占满12宽度的一列内容,分别存放Label、Input和Button组件。生成的布局代码如下:

     Page.AddRows(3,true,"").AddCells12(1,"")
     Page.BuildGrid ' IMPORTANT!
    
  3. 在ConnectPage Sub里创建组件,并将它们添加到Page里,代码如下:

     Dim lbl As ABMLabel
     lbl.Initialize(page,"resultlbl","Input a number and press the button to guess. You have 10 chances to guess.",ABM.SIZE_PARAGRAPH,False,"")
     page.Cell(1,1).AddComponent(lbl)
     Dim inp As ABMInput
     inp.Initialize(page,"numinput",ABM.INPUT_NUMBER,"Num:",False,"")
     page.Cell(2,1).AddComponent(inp)
     Dim btn As ABMButton
     btn.InitializeFlat(page,"guessbtn","","","Guess","")
     page.Cell(3,1).AddComponent(btn)
    

    ABM.INPUT_NUMBER、ABM.SIZE_PARAGRAPH等都是特定组件需要用到的值,可以通过ABMaterial类调用。

  4. 添加按钮的响应代码,实现输入的数字不等于生成的随机数时提示是大了还是小了,超过10次尝试次数就提示失败并重置,如果猜对了就获胜:

     Sub guessbtn_clicked(Target As String)
         Log("clicked")
         Dim inp As ABMInput
         inp=page.Component("numinput") '通过设置的id获得某个元素
         If inp.Text="" Then
             myToastId = myToastId + 1
             page.ShowToast("toast" & myToastId, "toastgreen", "Input a num to guess.", 5000, False)
             Return
         End If
         times=times+1
         Dim usernum As Int
         usernum=inp.Text
         Dim chances As Int
         chances=10-times
         If usernum=num Then
             myToastId = myToastId + 1
             page.ShowToast("toast" & myToastId, "toastgreen", "You win! Game reset.", 5000, False)
             num=Rnd(1,100)
             times=0
         Else
             If times>10 Then
                 myToastId = myToastId + 1
                 page.ShowToast("toast" & myToastId, "toastgreen", "You lose. The num is "&num&". Game reset.", 5000, False)
                 num=Rnd(1,100)
                 times=0
                 Return
             End If
             If usernum>num Then
                 myToastId = myToastId + 1
                 page.ShowToast("toast" & myToastId, "toastgreen", "Too big. "&chances&" chances left.", 5000, False)
             Else
                 myToastId = myToastId + 1
                 page.ShowToast("toast" & myToastId, "toastgreen", "Too small. "&chances&" chances left.", 5000, False)
             End If
         End If
     End Sub
    
  5. 在Main类里添加该页面。另外还可以修改ABMShared.bas里创建导航栏的代码,添加这个猜数字页面的链接。

    通过http://127.0.0.1/template/GuessNum这样的路径访问,template是应用的名字,GuessNum是页面的名字。以下是运行的效果:

ABMaterial的好处在于组件丰富、功能强大,且只需用户会用B4J。但缺点在于严重依赖于服务器,如果服务器的ping值高,响应会很慢,如果断网,网页就不能运作。另外服务器要处理所有操作,负担也会比较重,不过ABMaterial的B4JS可以在客户端运行javascript,可以一定程度解决这个问题。

]]>
计算机学习资源整理 2019-01-19T05:52:50+00:00 xulihang blog.xulihang.me/resources-of-learning-computer 现在的时代,每个人都会使用电子设备,但要用好它们,还得较深入地了解它们。不然,计算机对我们来说就是一个能完成特定任务的黑盒系统,要想定制任务或者解决遇到的故障就无从下手了。

网上的资源很多,我这里只列出我觉得是值得一看的内容。有的是别人的资源收集帖,有的是高阶程序员的文章或者著作,大家谷歌百度能搜到的我也没必要列出来。

资源集合

  • Teach Yourself Computer Science,告诉你自学计算机科学需要学习哪些内容。

  • 左耳听风,左耳朵耗子在极客时间上开的专栏,里面有程序员修炼资源帖,罗列的资源较多,怎么学习某种技术都有涉及。

博客

  • 阮一峰的博客,阮一峰是上财的经济学博士,现在是阿里的前端工程师,他的文章写得深入浅出,不过翻译水平我不敢恭维。

  • 王垠,王垠从清华计算机博士退学,是个争议人物,也是理想主义者。他对编程语言有非常深入的理解。

    比如以下几篇文章,对于编程实践有很好的指导作用。

书籍

  • Computer Science Distilled,巴西人创办的Code Energy公司写的书籍,中文版《计算机科学精粹》由人民邮电出版,概要性地介绍了计算机科学的基本概念。

  • Effective Programming:More Than Writing Code,StackOverFlow创始人Jeff Atwood写的书,中文版《高效能程序员的修炼》由人民邮电出版。里面很多观点在王垠的博客里也有提到,比如程序注释,只要代码写得好,通常是不需要的。

]]>