Skip to content

Instantly share code, notes, and snippets.

@youngershen
Created October 6, 2014 19:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save youngershen/c97497b3ff1e8ff0ae18 to your computer and use it in GitHub Desktop.
Save youngershen/c97497b3ff1e8ff0ae18 to your computer and use it in GitHub Desktop.
homeword1
#!/usr/bin/env python
#-*- coding: utf-8 -*-
# author : younger shen
# email : younger.x.shen@gmail.com
# implement all of the task except extra bonus 3
import sys
import re
#constant
BLINK_RED = '\033[5;31;47m'
EDIT_WHITE = '\033[1;30;47m'
HELPER_COLOR = '033[4;33;44m'
DEFAULT_COLOR = '\033[0m'
INSERT_CMD_HELPER = 'insert linenumber yourstring'
DELETE_CMD_HELPER = 'delete linenumber'
PRINT_CMD_HELPER = 'print num'
QUIT_CMD_HELPER = 'quit'
#exceptions
class LinkedListIndexOutOfRangeError(Exception):
def __init__(self, index):
self.index = index
def __str__(self):
return str(self.index) + ' is out of range \n'
class LinkedListInsertError(Exception):
def __init__(self, index, total):
self.index = index
self.total = total
def __str__(self):
return 'you insert ' + str(self.index) + ' out of 1 to ' + str(self.total)
#data structures
class Node(object):
def __init__(self):
self.data = None
self.next = None
def next(self):
self.next = Node()
return self.next
def __str__(self):
return self.data
class LinkedList(object):
def __init__(self, data = ''):
self.head_node = Node()
self.list_size = 1
self.list_node = self.head_node
self.list_node.data = data
def build_from_list(self, list):
for i,e in enumerate(list):
self.add_node(e)
def add_node(self, data):
self.list_node.next = Node()
self.list_node.next.data = data
self.list_node =self.list_node.next
self.list_size += 1
if self.head_node.data == '':
self.delete_node(1)
def delete_all_node(self):
self.head_node = None
self.list_size = 0
def delete_node(self, index):
#index start from ONE not ZERO
if index <= 0 or index > self.list_size:
raise LinkedListIndexOutOfRangeError(index)
else:
context = self.index_node(index)
if context[0] is None:
self.head_node = context[2]
elif context[2] is None:
context[0].next = None
else:
context[0].next = context[2]
self.list_size -= 1
def insert_node(self, index, data):
if index < 1 or index > self.list_size:
raise LinkedListInsertError(index, self.list_size)
elif index == 1:
node = Node()
node.data = data
node.next = self.head_node
self.head_node = node
else:
context = self.index_node(index)
node = Node()
node.data = data
context[0].next = node
node.next = context[1]
self.list_size += 1
def index_node(self, index):
if index <= 0 or index > self.list_size:
raise LinkedListIndexOutOfRangeError(index)
else:
if index == 1:
return None, self.head_node, self.head_node.next
head_node = self.head_node
node = head_node
for i in range(index - 1 - 1 ):
node = head_node.next
head_node = node
if node.next.next is not None:
return node, node.next, node.next.next
else:
return node, node.next, None
def search(self, keyward):
print("key:" + keyward)
ret = []
node = self.head_node
index = 1
while True:
try:
print(node.data)
if keyward in node.data:
ret.append(index)
node = node.next
except AttributeError as e:
print("break")
break
index+=1
return ret
def replace(self, keyward, new_word):
ret = []
node = self.head_node
index = 1
while True:
try:
if keyward in node.data:
strinfo = re.compile(keyward)
node.data = strinfo.sub(new_word, node.data)
ret.append(index)
node = node.next
except AttributeError as e:
break
index+=1
return ret
def __str__(self):
ret = ''
head_node = self.head_node
for i in range(self.list_size):
ret += head_node.data + '\n'
head_node = head_node.next
return ret
#File IO
class FileManager(object):
def __init__(self):
super(FileManager, self).__init__(self)
@staticmethod
def dump_to_file(filename, data):
with open(filename, 'w') as file:
file.write(data)
@staticmethod
def read_from_file(filename):
try:
with open(filename, 'r') as file:
content = file.read()
except IOError as e:
print(e)
return None
else:
return content
@staticmethod
def open_file(filename):
try:
file = open(filename , 'r')
except IOError as e:
pass
file = open(filename, 'w')
return file
#Editors
class Editor(object):
def __init__(self, filename = None):
self.filename = filename
self.file_handler = None
self.content = ''
self.buffer = LinkedList()
self.init_editor()
self.build_list()
self.show_content()
self.show_command_helper()
self.user_input()
def show_content(self):
if self.filename is None:
cprint('head_line', 'unnamed file')
else:
cprint('head_line', self.filename)
node = self.buffer.head_node
lineno = 0
if self.buffer.list_size >= 1:
while True:
try:
lineno+=1
cprint('content', str(lineno)+ ': ' + node.data)
node = node.next
except AttributeError as e:
cprint('head_line', 'END OF FILE')
print('\r')
return
else:
self.show_space()
return
def cmd_handler(self, input):
cmds = input.split(' ')
if cmds[0] == 'insert' or cmds[0] == 'i':
try:
self.insert_opt(int(cmds[1]), ' '.join(cmds[2:]))
except IndexError as e:
print('you need input the complete command')
exit(0)
elif cmds[0] =='delete' or cmds[0] =='d':
try:
self.delete_opt(int(cmds[1]))
except IndexError as e:
self.delete_all_opt()
elif cmds[0] =='quit' or cmds[0] == 'q':
self.quit_opt()
elif cmds[0] =='print' or cmds[0] =='p':
try:
self.print_opt(int(cmds[1]))
except IndexError as e:
self.print_all_opt()
elif cmds[0] =='read' or cmds[0] =='r':
self.read_opt(cmds[1])
elif cmds[0] =='write' or cmds[0] =='w':
self.write_opt(cmds[1])
elif cmds[0] =='h':
self.show_content()
self.show_command_helper()
self.user_input()
elif cmds[0] =='g':
self.search_opt(cmds[1])
elif cmds[0] =='s':
self.replace_opt(cmds[1], cmds[2])
else:
self.show_content()
self.show_command_helper()
self.user_input()
def quit_opt(self):
self.save_to_file()
exit(0)
def replace_opt(self, keyward, new_word):
val = self.buffer.replace(keyward, new_word)
for i in val:
node = self.buffer.index_node(i)[1]
print(str(i) + ":" + node.data + '\n')
self.show_content()
self.show_command_helper()
self.user_input()
def search_opt(self, keyward):
val = self.buffer.search(keyward)
for i in val:
node = self.buffer.index_node(i)[1]
print( str(i)+":" + node.data +" \n")
self.show_content()
self.show_command_helper()
self.user_input()
def delete_all_opt(self):
self.buffer.delete_all_node()
self.show_content()
self.show_command_helper()
self.user_input()
def read_opt(self, filename):
self.buffer = LinkedList()
self.content = ''
self.filename = filename
self.init_editor()
self.build_list()
self.show_content()
self.show_command_helper()
self.user_input()
def write_opt(self, filename):
self.filename = filename
self.save_to_file()
self.show_content()
self.show_command_helper()
self.user_input()
def insert_opt(self, lineno, data):
try:
self.buffer.insert_node(lineno, data)
except LinkedListInsertError as e:
print(e)
self.show_content()
self.show_command_helper()
self.user_input()
def print_all_opt(self):
self.show_content()
self.show_command_helper()
self.user_input()
def print_opt(self, lineno):
try:
context = self.buffer.index_node(lineno)
except LinkedListIndexOutOfRangeError as e:
print(e)
return
else:
print(context[1].data)
self.show_content()
self.show_command_helper()
self.user_input()
def delete_opt(self, lineno):
try:
self.buffer.delete_node(lineno)
except LinkedListIndexOutOfRangeError as e:
print(e)
self.show_content()
self.show_command_helper()
self.user_input()
def user_input(self):
ret = input('please input command:\n')
self.cmd_handler(ret)
def init_editor(self):
if self.filename is not None:
self.open_file()
try:
self.content = self.file_handler.read()
except IOError as e:
self.content = ''
finally:
self.file_handler.close()
self.file_handler = None
def build_list(self):
if self.content != '':
temp_buffer = self.content.split('\n')[:-1]
self.buffer.build_from_list(temp_buffer)
def open_file(self):
self.file_handler = FileManager.open_file(self.filename)
def load_file(self):
if self.filename:
self.content = FileManager.read_from_file(self.filename)
if self.content is None:
print("open file error , file does not exists of something wrong !")
exit(1)
def show_command_helper(self):
cprint('helper', INSERT_CMD_HELPER)
cprint('helper', DELETE_CMD_HELPER)
cprint('helper', PRINT_CMD_HELPER)
cprint('helper', QUIT_CMD_HELPER)
cprint('helper', 'r/read lename')
cprint('helper', 'w/write lename')
cprint('helper', 'p/print num')
cprint('helper', 'd/delete num')
cprint('helper', 'q/quit for quit')
cprint('helper', 'h for help')
cprint('helper', 'i for insert')
def show_space(self):
for i in range(5):
print('\n')
def save_to_file(self):
content = ''
if self.file_handler is None:
print("saveing")
self.file_handler = open(self.filename, 'w')
node = self.buffer.head_node
while True:
try:
content += node.data + '\n'
node = node.next
except AttributeError as e:
break
self.file_handler.write(content)
self.file_handler.close()
#utils
def cprint(flag, text):
if 'head_line' == flag:
print(text)
elif 'content' == flag:
print(text) #+ '\n'
elif 'helper' == flag:
print(text) #+ '\n'
#Tests
def LinkedListTest():
list = LinkedList("linked list 1");
for i in range(2, 11):
list.add_node("lisked list " + str(i))
print(list)
list.delete_node(1)
list.delete_node(1)
print(list)
def main(argv):
editor = Editor(argv[1])
#LinkedListTest()
if __name__ == '__main__':
main(sys.argv)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment