我为什么讨厌程序员
PM与工程师的交恶,由来已久。不仅如此,视觉与工程师的交恶也由来已久。
还有些哥们之所以能游刃有余,是因为在产品实现的过程中,已经习惯了打人情牌。
很多产品或工程师朋友可能会交流这些沟通过程中,如何很好的搞定SB般的对方?
这些冲突,我认为没有讨论的必要。等活在这些冲突里的朋友们,level up后,就会脱离这样的苦海,自当能理解“没有必要”的意思。
今天,我想说的是,我为什么讨厌程序员?!
我是谁?我是Producer。
真的很讨厌么?其实不然,我非常爱工程师。按我的经验来看,多数工程师比多数PM,其实更理解用户。
不仅是如此,我的技术涉猎也比较广,django、python、mootools、html/css这些写得很溜,在不知所以的情况下,node.js、Java、PHP、jython、AS等,也照用不误。
技术是什么?程序是什么?这跟程序语言没有本质的关系,极端的说,它就是+1和-1而已。
虽然常会误解为一个纯coder,但自己程序员这种角色,坦诚说,厌恶的很。
按照自己几年前的性格,逮到垃圾程序员,能直接破口大骂。后来,发现人都好面子,不能骂了。所以,憋了很久的气,今天要倒一倒。
##理由1:装逼
他们经常会用一些技术上的关键词来说话,如果关键词的含金量很高,咱听不懂,那没有办法,术业有专攻。但一旦你理解那些所谓的术语有多么简单以及自然的时候,你心里最想说的恐怕是骂娘了。
这样的程序员,比郭小四不相上下。
##理由2:傻逼
我需要你来设计产品的实现,换句话说,就是告诉我程序打算怎么写,数据结构是什么设计的,数据流动的环节是打算如何处理的。
你会给一个方案。基本上会是最笨的办法。然后,哥还得夸你,嗯,做的不错,有进步;不夸的话,你会觉得自己的价值没有得到尊重。
用谢耳朵的话说,你在你的领域做的非常出色,但你做的事情没有任何意义。
大白话:你是一名出色的傻逼。
##理由3:冷忽悠
程序员都很木讷?都不会忽悠?
知道什么叫冷暴力忽悠么?!
我们当前的结构不支持这样的实现的⋯⋯
这个技术上是没有办法实现的⋯⋯
但按照我的经验来看,对于你无法佩服的程序员,别信他们这样的鬼话,他们不仅仅会忽悠你,他们同时也在忽悠自己,因为他们自己真是这么想的。
碰到你非常佩服的程序员,请相信我,再逼一逼他,一起探讨各种hack的方法,有些所谓的“不可能”就迎刃而解了。
真遇到了不可能,那就让它去吧。有一天,灵感会光临的。
理由4:看起来很忙,出BUG都是有原因的
会存在没有原因的bug么?!!
不过,呃,这个bug的原因不是我造成的⋯⋯
靠!
##理由5:缺乏想象力,不思进取
对程序员来说,最大的侮辱,是重构他的代码,并且效率提升了100、10000倍。
但多数程序员不会碰到这样的事情,所以还有个办法,你直接骂他在写垃圾代码就好了。
但这算是侮辱么?!
真正的coder最关心的是对方重构的方式和思维的哲学,是不是质变性的。如果有人只为了骂而骂,为了重构而重构,coder倒是要开心了,又来个傻逼。
我认为现在这个行业的从业人员实在太多,弱者也实在太多,为了照顾弱者的脆弱心灵,容忍他们贫乏的想象力,容忍他们的不思进取,同时还谎称他们人不错,很上进;才是让我们的互联网技术力量无法跟老美他们匹敌的原罪。
##理由6:不知廉耻
写垃圾代码,做垃圾的解决方式,然后自鸣得意去分享。
被斥责的时候,会说,你不尊重人,退一万步讲,我就算写垃圾代码,那也是我能力所限呀。
我最厌恶这种固步自封的家伙,简直就是不知廉耻的流氓。
Excerpted from 我为什么讨厌程序员
VVDocumenter文档注释和appledoc生成文档
代码注释可以让代码更容易接受和使用,特别是在大型项目合作开发或模块开发中。Objective-C中也有一些很方便的注释插件和文档生成工具。本文推荐两个开源软件:VVDocumenter注释工具和appledoc文档生成工具。
###下载和安装VVDocumenter
VVDocumenter插件是github上的一个开源项目,地址是https://github.com/onevcat/VVDocumenter-Xcode。
你可以git clone或在github网站上下载工程的zip压缩文件。下载完成后,打开其中的工程,build&run一下就安装成功了。然后记得要重新启动一下Xcode应用,VVDocumenter插件就生效了。试试在方法定义前输入“///”。
###appledoc
我们开发自己的模块时,经常会将模块接口提供给别人使用,这样我们不得不写一些接口说明文档。很多语言都提供了这种工具比如javadoc,doxygen等,可以将注释代码转化成在线文档。这里推荐一个特别适合Objective-C语言的一种文档输出工具appledoc。它可以把一些格式的注释转换成Apple SDK风格的文档,同时它支持VVDocumenter的输出注释格式。
1.安装
git clone git://github.com/tomaz/appledoc.git
cd ./appledoc
sudo sh install-appledoc.sh
安装完成后,验证一下OK了没
appledoc --version
2.使用
进入code所在目录,跑一下下面的命令,默认会编译出docset并安装进Xcode。
appledoc --project-name MyProject --project-company ibireme ./
其中 MyProject是生成的Docset文件名,执行上面的命令之后会在工程目录底下生成一个名字为docset-installed的txt文档。
docset-installed.txt:
Documentation set was installed to Xcode!
Path: /Users/liunian/Library/Developer/Shared/Documentation/DocSets/com.ibireme.lnuniversal.LNUniversal.docset
Time: 2015-05-26 10:01:00 +0000
如果想要详细的参数,可以查看帮助
appledoc --help
###如果想要集成进Xcode工程:
1.选中你的工程,点击Add Target按钮,选择 Other -> Aggregate模板新建.
2.点击Add Build Phase按钮,添加一个Run Script.
3.把下面的模板代码复制进去,把前几行参数改成你自己的.
4.在Xcode左上角选择这个新建的Target,然后点击build.
5.文档就会编译好并且自动安装进Xcode了(重启Xcode生效).
#appledoc Xcode script
# Start constants
company="ACME";
companyID="com.ACME";
companyURL="http://ACME.com";
target="iphoneos";
#target="macosx";
outputPath="~/help";
# End constants
/usr/local/bin/appledoc \
--project-name "${PROJECT_NAME}" \
--project-company "${company}" \
--company-id "${companyID}" \
--docset-atom-filename "${company}.atom" \
--docset-feed-url "${companyURL}/${company}/%DOCSETATOMFILENAME" \
--docset-package-url "${companyURL}/${company}/%DOCSETPACKAGEFILENAME" \
--docset-fallback-url "${companyURL}/${company}" \
--output "${outputPath}" \
--publish-docset \
--docset-platform-family "${target}" \
--logformat xcode \
--keep-intermediate-files \
--no-repeat-first-par \
--no-warn-invalid-crossref \
--exit-threshold 2 \
"${PROJECT_DIR}"
PS:集成到Xcode我一直没走通,估计是代码没有设置好的原因,回头可以好好研究下
###其他
编译出的Docset默认会放在/Users/ibireme/Library/Developer/Shared/Documentation/DocSets路径下。
Docset格式,实际上是一个bundle,里面包含了一些xml和html。显示包内容后就可以查看和修改了。如果需要放到网站上,那单独将html部分取出来就行。
Docset安装后,在Xcode中就可以实时查看某个方法的说明了,体验和官方文档保持一致。(有一点,category中的注释不会出现在xcode的快速帮助中,不知道新版xcode是否会有改进..)
NSPredicate是什么
##NSPredicate:谓词
字面翻译是这个意思,但是我觉得谓词这个词太难以理解了
NSPredicate的具体用途应该还是过滤,类似于过滤条件之类的,相当于一个主语的谓语,所以说会是谓词这个名字。(我是这么理解的)
##NSPredicate的创建
我们看到创建谓词使用类方法predicateWithFormat: (NSString*) format,format 里的东西真的
和SQL 的where 条件差不多。
另外,参数format 与NSLog 的格式化模版差不多,如果1 和
188.0 是传递过来的参数,你可以写成如下的形式:
@“pid>%d and height<%f”,1,188.0
##NSPredicate中主要的几种运算方式
-
比较运算符 > 、< 、== 、 >= 、<= 、 !=
例:@“number >= 99” -
逻辑运算符:AND、OR、NOT 这几个运算符计算并、或、非的结果。
-
范围运算符:IN 、BETWEEN
例:@“number BETWEEN {1,5}”
@“address IN {‘shanghai’,’nanjing’}” -
字符串本身:SELF
例:@“SELF == ‘APPLE’” -
字符串相关:BEGINSWITH、ENDSWITH、CONTAINS
例: @“name CONTAIN[cd] ‘ang’” //包含某个字符串
@“name BEGINSWITH[c] ‘sh’” //以某个字符串开头
@“name ENDSWITH[d] ‘ang’” //以某个字符串结束
注:[c]不区分大小写 , [d]不区分发音符号即没有重音符号 , [cd]既不区分大小写,也不区分发音符号。 -
通配符:LIKE
例:@“name LIKE[cd] ‘er’” //代表通配符,Like也接受[cd].
@“name LIKE[cd] ‘???er’” -
正则表达式:MATCHES
例:NSString *regex = @“^A.+e$”; //以A开头,e结尾
@“name MATCHES %@“,regex
##如何使用NSPredicate对一个自定义实体进行筛选
NSPredicate我暂时都是用于过滤的,否则我们过滤就需要自己写判断 写循环,去判断输出了。
接下来就上代码和例子吧。
建立一个实体类 Dog
@property (copy , nonatomic) NSString* name;
@property (assign , nonatomic) int age ;
这样我们就有一个类了
我们创建 5只Dog的实体
Dog * dog1=[Dog news];dog1.name=@“这是第一只Dog”;dog1.age=@“11”;
Dog * dog2=[Dog news];dog2.name=@“这是第二只Dog”;dog2.age=@“22”;
Dog * dog3=[Dog news];dog3.name=@“这是第三只Dog”;dog3.age=@“33”;
Dog * dog4=[Dog news];dog4.name=@“这是第四只Dog”;dog4.age=@“44”;
Dog * dog5=[Dog news];dog5.name=@“这是第五只Dog”;dog5.age=@“55”;
不要吐槽我的Dogs的年龄 → 。→
然后我们需要一个Array把他们都装进去
NSArray * dogArr=@[dog1,dog2,dog3,dog4,dog5];
酱紫所有的Dog都装到一个数组里了
使用NSPredicate的筛选
没有使用NSPredicate的筛选应该大家都会写,循环+判断。。。
使用NSPredicate的筛选
具体使用的代码
//创建谓词的对象 谓词条件是基于KVC的,所以需要说明一点,加入Dog里面有个属性是Doginfo指向Doginfo类,在使用的时候 我们的条件就要写成Doginfo.xxx了。
NSPredicate* predicate = [NSPredicate predicateWithFormat:@“name==‘这是第一只Dog’ AND age ==11”];
for(Dog * d in dogArr)
{
if([predicate evaluateWithObject:d])
{
NSLog(d.name);
}
}
以上的代码打印出来的结果就是 这是第一只Dog
NSPredicate筛选一个对象逻辑还是很清晰的,不过这里比较麻烦的就是 还有一个循环,这里我们会发现数组提供了一个方法可以更方便的检索数组对象
直接筛选出一个符合谓词的新数组。
NSPredicate *pre = [NSPredicate predicateWithFormat:@“age >11”];
NSMutableArray *arrayPre=[dogArr filteredArrayUsingPredicate: pre];
arrayPre里面的对象就会是 除了dog1之外的所有的dog。(至于为什么看我的条件...)
看到这里发现NSPredicate 可以用于自定义的实体的检索、筛选,那如果用于 NSString,NSInteger,bool呢?那我们再看一段代码吧
NSArray *arrays=[NSArray arrayWithObjects: @“Apple”, @“Google”, @“MircoSoft”, nil];
NSPredicate *pre2 = [NSPredicate predicateWithFormat:@“SELF==‘Apple’”];
上面这段代码是匹配字符串的时候 NSPredicate 需要如何声明
##使用NSPredicate在两个数组之间进行差异筛选
NSArray* array = @[@“aa”,@“bb”];
NSArray* array2 = @[@“aa”,@“bb”,@“cc”,@“dd”];
NSPredicate* thePredicate = [NSPredicate predicateWithFormat:@“NOT(SELF in %@)”,array];
NSArray* arr3 = [array2 filteredArrayUsingPredicate:thePredicate];
NSLog(@“%@“,arr3);
上面的代码输出结果 arr3={@“cc” ,@“dd”}
这样大家就很容易理解了
SELF在前面有介绍过 可以往回翻阅一下
如何使用正则筛选一个数组
NSString *regex = @“^A.+e$”;//以A 开头,以e 结尾的字符。
NSPredicate *pre= [NSPredicate predicateWithFormat:@“SELF MATCHES %@“, regex];
if([pre evaluateWithObject: @“Apple”]){
printf(“YES\n”);
}else{
printf(“NO\n”);
}
##关于NSPredicate的其他说明和注意事项,以及技巧
- 动态属性名
- 假如你的代码如下
NSPredicate *p = [NSPredicate predicateWithFormat:@“name = %@“, @“name1”];
显然代码没有任何问题,但是这个不是最好的写法我建议如下写法:
NSPredicate *preTemplate = [NSPredicate predicateWithFormat:@“name==$NAME”];
NSDictionary *dic=[NSDictionary dictionaryWithObjectsAndKeys:
@“name1”, @“NAME”,nil];
NSPredicate *pre=[preTemplate predicateWithSubstitutionVariables: dic];
这样看上去可能会让代码逻辑更清晰。
当过滤条件字段都是动态的时候
NSString *key = @“name”;
NSString *value = @“name1”;
NSPredicate *p = [NSPredicate predicateWithFormat:@“%@ = %@“, key, value];
然后当你执行到第三行的时候代码就会报错!
逻辑上没错误啊!!!为什么会出错呢?
NSPredicate要自动添加引号,所以最后得到的格式应该是@“’name’ = ‘name1’”。明显不对。要做的就是:
NSPredicate *p = [NSPredicate predicateWithFormat:@“%K = %@“, key, value];
##总结
NSPredicate 的简单的使用就介绍到这里,这里有些都是从网络上其他人的额博客转过来的内容,我自己加以修改和一些自己的理解。希望可以帮到大家。
转载:NSPredicate谓词的用法 数组过滤
贴一段实用代码
Cocoa用NSPredicate描述查询的方式,原理类似于在数据库中进行查询
计算谓词:
//基本的查询
NSPredicate *predicate;
predicate = [NSPredicate predicateWithFormat: @“name == ‘Herbie’”];
BOOL match = [predicate evaluateWithObject: car];
NSLog (@“%s”, (match) ? “YES” : “NO”);
//在整个cars里面循环比较
predicate = [NSPredicate predicateWithFormat: @“engine.horsepower > 150”];
NSArray *cars = [garage cars];
for (Car *car in [garage cars]) {
if ([predicate evaluateWithObject: car]) {
NSLog (@“%@“, car.name);
}
}
//输出完整的信息
predicate = [NSPredicate predicateWithFormat: @“engine.horsepower > 150”];
NSArray *results;
results = [cars filteredArrayUsingPredicate: predicate];
NSLog (@“%@“, results);
//含有变量的谓词
NSPredicate *predicateTemplate = [NSPredicate predicateWithFormat:@“name == $NAME”];
NSDictionary *varDict;
varDict = [NSDictionary dictionaryWithObjectsAndKeys:
@“Herbie”, @“NAME”, nil];
predicate = [predicateTemplate predicateWithSubstitutionVariables: varDict];
NSLog(@“SNORGLE: %@“, predicate);
match = [predicate evaluateWithObject: car];
NSLog (@“%s”, (match) ? “YES” : “NO”);
//注意不能使用$VARIABLE作为路径名,因为它值代表值
//谓词字符窜还支持c语言中一些常用的运算符
predicate = [NSPredicate predicateWithFormat:
@“(engine.horsepower > 50) AND (engine.horsepower < 200)”];
results = [cars filteredArrayUsingPredicate: predicate];
NSLog (@“oop %@“, results);
predicate = [NSPredicate predicateWithFormat: @“name < ‘Newton’”];
results = [cars filteredArrayUsingPredicate: predicate];
NSLog (@“%@“, [results valueForKey: @“name”]);
//强大的数组运算符
predicate = [NSPredicate predicateWithFormat:
@“engine.horsepower BETWEEN { 50, 200 }”];
results = [cars filteredArrayUsingPredicate: predicate];
NSLog (@“%@“, results);
NSArray *betweens = [NSArray arrayWithObjects:
[NSNumber numberWithInt: 50], [NSNumber numberWithInt: 200], nil];
predicate = [NSPredicate predicateWithFormat: @“engine.horsepower BETWEEN %@“, betweens];
results = [cars filteredArrayUsingPredicate: predicate];
NSLog (@“%@“, results);
predicateTemplate = [NSPredicate predicateWithFormat: @“engine.horsepower BETWEEN $POWERS”];
varDict = [NSDictionary dictionaryWithObjectsAndKeys: betweens, @“POWERS”, nil];
predicate = [predicateTemplate predicateWithSubstitutionVariables: varDict];
results = [cars filteredArrayUsingPredicate: predicate];
NSLog (@“%@“, results);
//IN运算符
predicate = [NSPredicate predicateWithFormat: @“name IN { ‘Herbie’, ‘Snugs’, ‘Badger’, ‘Flap’ }”];
results = [cars filteredArrayUsingPredicate: predicate];
NSLog (@“%@“, [results valueForKey: @“name”]);
predicate = [NSPredicate predicateWithFormat: @“SELF.name IN { ‘Herbie’, ‘Snugs’, ‘Badger’, ‘Flap’ }”];
results = [cars filteredArrayUsingPredicate: predicate];
NSLog (@“%@“, [results valueForKey: @“name”]);
names = [cars valueForKey: @“name”];
predicate = [NSPredicate predicateWithFormat: @“SELF IN { ‘Herbie’, ‘Snugs’, ‘Badger’, ‘Flap’ }”];
results = [names filteredArrayUsingPredicate: predicate];//这里限制了SELF的范围
NSLog (@“%@“, results);
//BEGINSWITH,ENDSWITH,CONTAINS
//附加符号,[c],[d],[cd],c表示不区分大小写,d表示不区分发音字符,cd表示什么都不区分
predicate = [NSPredicate predicateWithFormat: @“name BEGINSWITH ‘Bad’”];
results = [cars filteredArrayUsingPredicate: predicate];
NSLog (@“%@“, results);
predicate = [NSPredicate predicateWithFormat: @“name BEGINSWITH ‘HERB’”];
results = [cars filteredArrayUsingPredicate: predicate];
NSLog (@“%@“, results);
predicate = [NSPredicate predicateWithFormat: @“name BEGINSWITH[cd] ‘HERB’”];
results = [cars filteredArrayUsingPredicate: predicate];
NSLog (@“%@“, results);
//LIKE运算符(通配符)
predicate = [NSPredicate predicateWithFormat: @“name LIKE[cd] ‘*er*’”];
results = [cars filteredArrayUsingPredicate: predicate];
NSLog (@“%@“, results);
predicate = [NSPredicate predicateWithFormat: @“name LIKE[cd] ‘???er*’”];
results = [cars filteredArrayUsingPredicate: predicate];
NSLog (@“%@“, results);
Copyright © 2015 Powered by MWeb, 豫ICP备09002885号-5