闲来自己写了一个小的简单数据库(Simple Database),要求最好用python写。因为很久没写python了,语法都忘了很多,写的过程中温故知新。
首先这个数据库实现了如下功能:
数据命令:
- SET name value – Set the variable name to the value value. Neither variable names nor values will contain spaces.
- GET name – Print out the value of the variable name, or NULL if that variable is not set.
- UNSET name – Unset the variable name, making it just like that variable was never set.
- NUMEQUALTO value – Print out the number of variables that are currently set tovalue. If no variables equal that value, print 0.
- END – Exit the program. Your program will always receive this as its last command.
事务命令:
- BEGIN – Open a new transaction block. Transaction blocks can be nested; a BEGINcan be issued inside of an existing block.
- ROLLBACK – Undo all of the commands issued in the most recent transaction block, and close the block. Print nothing if successful, or print NO TRANSACTION if no transaction is in progress.
- COMMIT – Close all open transaction blocks, permanently applying the changes made in them. Print nothing if successful, or print NO TRANSACTION if no transaction is in progress.
我的程序的时间复杂度
SET O(1)
GET O(1)
UNSET O(1))
NUMEQUALTO O(1)
BEGIN O(1)
ROLLBACK O(k) where k is the number of set and unset command within a transaction.
COMMIT O(1)
#!/usr/bin/python class SimpleDatabase: keysDict = {} numsDict = {} blocksNum = 0 isBegin = False def setFun(self, name, value): if name in self.keysDict and len(self.keysDict[name]) > 0: preValue = self.keysDict[name][-1] self.numsDict[preValue].remove(name) if value not in self.numsDict: self.numsDict.setdefault(value, []).append(name) else: self.numsDict[value].append(name) if self.isBegin == True: self.keysDict.setdefault(name, []).append(value) else: if name not in self.keysDict: self.keysDict.setdefault(name, []).append(value) else: self.keysDict[name][-1] = value def getFun (self, name): if name not in self.keysDict or len(self.keysDict[name]) == 0 or self.keysDict[name][-1] == None: print "NULL" else: print self.keysDict[name][-1] def unsetFun(self, name): setFun(name, None) def numEqualToFun(self, value): if value in self.numsDict: print len(self.numsDict[value]) else: print 0 def rollbackFun(self): if self.blocksNum == 0: print "NO TRANSACTION" else: self.blocksNum -= 1 self.isBegin = False for item in self.keysDict: if self.keysDict[item][-1] != None: self.numsDict[self.keysDict[item][-1]].remove(item) self.keysDict[item].pop() if len(self.keysDict[item]) > 0: self.numsDict[self.keysDict[item][-1]].append(item) def commitFun (self): if self.blocksNum == 0: print "NO TRANSACTION" else: self.blocksNum = 0 self.isBegin = False def beginFun (self): self.blocksNum += 1 self.isBegin = True def run(self): while True: raw_command = raw_input() if raw_command == "END": break commands = raw_command.split() if commands[0] == "SET": assert (len(commands) >= 3) self.setFun (commands[1], commands[2]) elif commands[0] == "GET": assert (len(commands) >= 2) self.getFun (commands[1]) elif commands[0] == "UNSET": assert (len(commands) >= 2) self.unsetFun (commands[1]) elif commands[0] == "NUMEQUALTO": assert (len(commands) >= 2) self.numEqualToFun (commands[1]) elif commands[0] == "BEGIN": self.beginFun() elif commands[0] == "COMMIT": self.commitFun() elif commands[0] == "ROLLBACK": self.rollbackFun() sd = SimpleDatabase() sd.run()
先说我的思路:
1.先介绍这里的事务命令(begin,rollback和commit),在这里采用栈的方式实现,即进入一个新的事务就将其中的操作加到栈中,如果还是在同一个事务中就覆盖之前的结果
2. 两个dict分别存储key的values(列表)和num的values(列表),values为列表类似于栈的功能,因为python中没有stack这个数据结构.
3. blocksNum控制blocks的数量,isBegin控制是否进入了一个block的操作.所以这两个变量是控制逻辑的关键.
总结学习心得:
1. python中global变量:dict可以省去global,其它类型变量不能省。global A, B
2. python中的类:__init__是构造函数,不定义就是默认构造函数,实例方法的第一个参数self我理解为C++的this; python类名之后可以加括号
3. python的split默认以空格换行;
4. 尽量用in不用has_key
5. 区分len() == 0, () == None, not in等
6. vim中的添加注释和取消注释命令!
7. raw_input和input的区别
8. list的remove, [-1], append, extend等使用
9.dict的value为list的情况:dict = {}; dict.setdefault(name, []).append(1)