编程的乐趣
/@峰哥何峰 /
峰哥虽然后来去学了个 MBA,但其实本科时候是学习数学的,并且也曾经会写程序。毕业之后,做起了 management consulting, 读了 MBA,编程技能就生疏了。
不过偶尔有机会,还是会写点代码。从中获得很大乐趣。比如上周【简单心理】工程师导出了一些数据,需要分析。但是工程师开发太忙,而需要做的分析又足够复杂到 Excel 不能胜任。于是乎峰哥自己手痒在周末写了些代码,搞的不亦乐乎。
周末的代码不便分享,不过还是可以分享以前写的另一个小程序。首先说明,我对自己的代码能力还是有自知之明。在很多略懂编程的朋友看来,下面的代码肯定是惨不忍睹。之所以还好意思拿出来分享,是因为我想支持一个写代码的文化。在现代社会,对电脑技术有个基本的了解,并且能够写一些简单的代码,简直就想算数、识字、英语一样重要。这是一个非常实用的技能,甚至像峰哥这样粗糙的水平,也能够派上用场。
并且,编程本身就是件非常快乐的事情!
有个很好的活动叫做 Rails Girls (http://railsgirlschina.org),是教女生学编程的活动。峰哥大爱 ruby 语言,但是水平不足以当教练,那就以自己的经历分享来支持!希望更多人(无论男生女生)会喜欢上编程:)
===
曾经有人给我出了这么一道数学题:今有A、B、C 三门大炮。三门大炮的命中率分别是:
A:1/2
B:1/3
C:1/6
三门大炮互相开炮,问最后幸存的那门炮是A、B、C,以及大家同归于尽的概率分别是几何?
这道数学题是为了演示一个有点违背常理的结果:A、B 各自的最佳战略是相互开炮,因为彼此都是对方最大的敌人。结果就是反而是 C 很有可能成为最后的幸存者。
这个概念并不复杂,可到底 C 幸存的概率是多少?比 A、B 如何?要能够量化的回答这个问题,还是需要比较繁琐的概率分析。但是可能的情况很多,分析起来不厌其烦。有一个简单的方法:通过很多次模拟和统计,求得概率的近似值。这也就是通常所说的 monte carlo method。
作为一个 math 和 CS geek,我忍不住写了一个简单的 python 程序。因为好久没有写程序了,以前也没有用过 python,所以程序写的想必是非常糟糕,但是结果是正确的。从中得到莫大乐趣。以下是模拟 30w 次后的结果。可以看出 C 幸存的概率远远高于 A、B。
这是 python 程序:
import random
class Cannon(object):
def __init__(self, name, accuracy):
self.name = name
self.accuracy = accuracy
self.alive = True
self.target = None
def setTarget(self, target):
self.target = target
def hit(self):
result = random.uniform(0, 1)
if result < self.accuracy:
#print "hit!"
self.target.alive = False
return True
else:
#print "miss!"
return False
def __str__(self):
return 'This cannon is named ' + self.name + ", accuracy " + str(self.accuracy)
def testCannon():
myCannon = Cannon('A', 0.5)
target = Cannon('target', 0)
hitcount, misscount = 0, 0
for i in range(0,500):
myCannon.setTarget(target)
if myCannon.hit() == 1:
hitcount = hitcount + 1
else:
misscount = misscount + 1
print "hit " + str(hitcount) + " miss " + str(misscount)
class Game(object):
def __init__(self):
self.cannons = []
def addCannon(self, newCannon):
if newCannon in self.cannons:
raise ValueError('Duplicate cannon')
else:
self.cannons.append(newCannon)
def removeCannon(self, cannon):
if cannon in self.cannons:
self.cannons.remove(cannon)
else:
raise ValueError('Cannon not found')
def bestPlayer(self):
if len(self.cannons) == 0:
return None
bestcannon = self.cannons[0]
for cannon in self.cannons:
if bestcannon.accuracy > cannon:
bestcannon = cannon
return bestcannon
def secondBest(self):
if len(self.cannons) < 2:
return None
bestcannon = self.bestPlayer()
secondBest = self.cannons[0]
if secondBest == bestcannon:
secondBest = self.cannons[1]
for cannon in self.cannons:
if (secondBest.accuracy < cannon.accuracy) and (bestcannon != cannon):
secondBest = cannon
return secondBest
def endGame(self):
#print "there are " + str(len(self.cannons)) + "cannons right now."
if len(self.cannons) <= 1:
return True
else:
return False
def winner(self):
if not self.endGame():
return
if len(self.cannons) == 0:
#print "no winner!!!"
return None
else:
return self.cannons[0]
def printCannons(self):
for cannon in self.cannons:
print cannon
def setTargets(self):
best = self.bestPlayer()
secondBest = self.secondBest()
for cannon in self.cannons:
cannon.setTarget(best)
best.setTarget(secondBest)
#for cannon in self.cannons:
# print str(cannon) + ' target is ' + str(cannon.target)
def fire(self):
if self.endGame():
print "Game ended."
return None
self.setTargets()
for cannon in self.cannons:
cannon.hit()
for i in range(len(self.cannons)-1, -1, -1):
#print i
if not self.cannons[i].alive:
#print "hahaha this one dead " + str(cannon)
del self.cannons[i]
#self.printCannons()
def play(self):
while not self.endGame():
self.fire()
#winner = self.winner()
def testGame():
game = Game()
cannonA = Cannon('A', 1.0/2)
cannonB = Cannon('B', 1.0/3)
cannonC = Cannon('C', 1.0/6)
game.addCannon(cannonA)
game.addCannon(cannonB)
game.addCannon(cannonC)
game.printCannons()
game.endGame()
print "best " + str(game.bestPlayer())
print "2nd best " + str(game.secondBest())
#game.removeCannon(cannonA)
#print game.bestPlayer()
game.play()
def gameRuns():
totalRuns = 300000
aCount, bCount, cCount, nowinner = 0, 0, 0, 0
for i in range(totalRuns):
game = Game()
cannonA = Cannon('A', 1.0/2)
cannonB = Cannon('B', 1.0/3)
cannonC = Cannon('C', 1.0/6)
game.addCannon(cannonA)
game.addCannon(cannonB)
game.addCannon(cannonC)
game.play()
winner = game.winner()
if winner == cannonA:
aCount = aCount + 1
elif winner == cannonB:
bCount = bCount + 1
elif winner == cannonC:
cCount = cCount + 1
else:
nowinner = nowinner + 1
print "game " + str(i),
if winner is None:
print ": No winner"
else:
print ": winner is " + str(winner.name)
print "total simulation runs: " + str(totalRuns)
print "A wins " + str(aCount*1.0/totalRuns)
print "B wins " + str(bCount*1.0/totalRuns)
print "C wins " + str(cCount*1.0/totalRuns)
print "no winner " + str(nowinner*1.0/totalRuns)
#print "total: " + str(aCount + bCount + cCount + nowinner) + " " + str(totalRuns)
gameRuns()
======
简单心理
加入我们!戳 =>http://www.jiandanxinli.com/pages/37