⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 calc.py

📁 Urwid is a Python library for making text console applications. It has many features including fluid
💻 PY
📖 第 1 页 / 共 2 页
字号:
			last_op = None		else:				last_cell = self.walker.get_cell(i-1)			x = last_cell.get_result()						if x is not None and focus_cell.op is not None:				x = OPERATORS[focus_cell.op]( x, 					focus_cell.get_value() )			focus_cell.set_result(x)				for cell in self.content[i+1:]:			if cell.op is None:				x = None			if x is not None:				x = OPERATORS[cell.op]( x, cell.get_value() )			if cell.get_result() == x:				return False			cell.set_result(x)		return True		def create_child( self, letter ):		"""Return (parent cell,child column) or None,None on failure."""		f, (i, sub) = self.walker.get_focus()		if sub != 0: 			# f is not an edit widget			return None, None		cell = self.walker.get_cell(i)		if cell.child is not None:			raise CalcEvent, E_new_col_cell_not_empty		if cell.edit.edit_text:			raise CalcEvent, E_new_col_cell_not_empty		child = CellColumn( letter )		cell.become_parent( child, letter )		return cell, child	def is_empty( self ):		"""Return True if this column is empty."""		return len(self.content)==1 and self.content[0].is_empty()		def get_expression(self):		"""Return the expression as a printable string."""				l = []		for c in self.content:			if c.op is not None: # only applies to first cell				l.append(c.op)			if c.child is not None:				l.append("("+c.child.get_expression()+")")			else:				l.append("%d"%c.get_value())						return "".join(l)	def get_result(self):		"""Return the result of the last cell in the column."""				return self.content[-1].get_result()				class HelpColumn(urwid.BoxWidget):	help_text = [		('title', "Column Calculator"),		"",		[ "Numbers: ", ('key', "0"), "-", ('key', "9") ],		"" ,		[ "Operators: ",('key', "+"), ", ", ('key', "-"), ", ",			('key', "*"), " and ", ('key', "/")],		"",		[ "Editing: ", ('key', "BACKSPACE"), " and ",('key', "DELETE")],		"",		[ "Movement: ", ('key', "UP"), ", ", ('key', "DOWN"), ", ",			('key', "LEFT"), ", ", ('key', "RIGHT"), ", ",			('key', "PAGE UP"), " and ", ('key', "PAGE DOWN") ],		"",		[ "Sub-expressions: ", ('key', "("), " and ", ('key', ")") ],		"",		[ "Columns: ", ('key', COLUMN_KEYS[0]), " and ", 			('key',COLUMN_KEYS[1]), "-", 			('key',COLUMN_KEYS[-1]) ],		"",		[ "Exit: ", ('key', "Q") ],		"",		"",		["Column Calculator does operations in the order they are ",			"typed, not by following usual precedence rules.  ",			"If you want to calculate ", ('key', "12 - 2 * 3"), 			" with the multiplication happening before the ",			"subtraction you must type ", 			('key', "12 - (2 * 3)"), " instead."],		]			def __init__(self):		self.head = urwid.AttrWrap(			urwid.Text(["Help Column ", ('key',"?")],				layout = CALC_LAYOUT),			'help')		self.foot = urwid.AttrWrap( 			urwid.Text(["[text continues.. press ",			('key',"?"), " then scroll]"]), 'helpnote' )		self.items = [urwid.Text(x) for x in self.help_text]		self.listbox = urwid.ListBox(urwid.SimpleListWalker(self.items))		self.body = urwid.AttrWrap( self.listbox, 'help' )		self.frame = urwid.Frame( self.body, header=self.head)		def render( self, (maxcol, maxrow), focus=False):		head_rows = self.head.rows( (maxcol,) )		if "bottom" in self.listbox.ends_visible( 			(maxcol, maxrow-head_rows) ):			self.frame.footer = None		else:			self.frame.footer = self.foot		return self.frame.render( (maxcol, maxrow), focus)		def keypress( self, size, key ):		return self.frame.keypress( size, key )		class CalcDisplay:	palette = [		('body','white', 'dark blue'),		('edit','yellow', 'dark blue'),		('editfocus','yellow','dark cyan', 'bold'),		('key','dark cyan', 'light gray', ('standout','underline')),		('title', 'white', 'light gray', ('bold','standout')),		('help', 'black', 'light gray', 'standout'),		('helpnote', 'dark green', 'light gray'),		('colhead', 'black', 'light gray', 'standout'),		('event', 'light red', 'black', 'standout'),		('confirm', 'yellow', 'black', 'bold'),		]		def __init__(self):		self.columns = urwid.Columns([HelpColumn(), CellColumn("A")], 1)		self.col_list = self.columns.widget_list		self.columns.set_focus_column( 1 )		self.view = urwid.AttrWrap( self.columns, 'body' )		self.col_link = {}	def main(self):		self.ui = Screen()		self.ui.register_palette( self.palette )		self.ui.run_wrapper( self.run )		# on exit write the formula and the result to the console		expression, result = self.get_expression_result()		print "Paste this expression into a new Column Calculator session to continue editing:"		print expression		print "Result:", result	def run(self):		"""Update screen and accept user input."""		self.ui.set_mouse_tracking()		size = self.ui.get_cols_rows()		self.event = None		while 1:			# draw the screen			view = self.view			if self.event is not None:				# show the event too				view = urwid.Frame( view, 					footer=self.event.widget() )			canvas = view.render( size, focus=1 )			self.ui.draw_screen( size, canvas )						# wait until we get some input			keys = None			while not keys: 				# this call returns None when it times out				keys = self.ui.get_input()							# handle each key one at a time			for k in keys:				if urwid.is_mouse_event(k):					event, button, col, row = k					view.mouse_event( size, event, button,						col, row, focus=True )					continue							if k == 'window resize':					# read the new screen size					size = self.ui.get_cols_rows()					continue									elif k in ('q','Q'):					# exit main loop					return								# handle other keystrokes				try:					self.wrap_keypress( size, k )					self.event = None				except CalcEvent, e:					self.event = e				def wrap_keypress(self, size, key):		"""Handle confirmation and throw event on bad input."""				try:			key = self.keypress(size, key)					except ColumnDeleteEvent, e:			if e.letter == COLUMN_KEYS[1]:				# cannot delete the first column, ignore key				return						if not self.column_empty( e.letter ):				# need to get two in a row, so check last event				if not isinstance(self.event,ColumnDeleteEvent):					# ask for confirmation					raise e			self.delete_column(e.letter)					except UpdateParentEvent, e:			self.update_parent_columns()			return				if key is None:			return		if self.columns.get_focus_column() == 0:			if key not in ('up','down','page up','page down'):				raise CalcEvent, E_invalid_in_help_col				if key not in EDIT_KEYS and key not in MOVEMENT_KEYS:			raise CalcEvent, E_invalid_key % key.upper()			def keypress(self, size, key):		"""Handle a keystroke."""				# let the view try to handle it first		key = self.view.keypress( size, key )		if key is None: 			return			if key.upper() in COLUMN_KEYS:			# column switch			i = COLUMN_KEYS.index(key.upper())			if i >= len( self.col_list ): 				raise CalcEvent, E_no_such_column % key.upper()			self.columns.set_focus_column( i )			return		elif key == "(":			# open a new column			if len( self.col_list ) >= len(COLUMN_KEYS):				raise CalcEvent, E_no_more_columns			i = self.columns.get_focus_column()			if i == 0: 				# makes no sense in help column				return key			col = self.col_list[i]			new_letter = COLUMN_KEYS[len(self.col_list)]			parent, child = col.create_child( new_letter )			if child is None:				# something invalid in focus				return key			self.col_list.append(child)			self.set_link( parent, col, child )			self.columns.set_focus_column(len(self.col_list)-1)				elif key == ")":			i = self.columns.get_focus_column()			if i == 0:				# makes no sense in help column				return key			col = self.col_list[i]			parent, pcol = self.get_parent( col )			if parent is None: 				# column has no parent				raise CalcEvent, E_no_parent_column						new_i = self.col_list.index( pcol )			self.columns.set_focus_column( new_i )		else:			return key		def set_link( self, parent, pcol, child ):		"""Store the link between a parent cell and child column.				parent -- parent Cell object		pcol -- CellColumn where parent resides		child -- child CellColumn object"""		self.col_link[ child ] = parent, pcol		def get_parent( self, child ):		"""Return the parent and parent column for a given column."""		return self.col_link.get( child, (None,None) )		def column_empty(self, letter):		"""Return True if the column passed is empty."""				i = COLUMN_KEYS.index(letter)		col = self.col_list[i]		return col.is_empty()				def delete_column(self, letter):		"""Delete the column with the given letter."""				i = COLUMN_KEYS.index(letter)		col = self.col_list[i]				parent, pcol = self.get_parent( col )		f = self.columns.get_focus_column()		if f == i:			# move focus to the parent column			f = self.col_list.index(pcol)			self.columns.set_focus_column(f)				parent.remove_child()		pcol.update_results(parent)		del self.col_list[i]				# delete children of this column		keep_right_cols = []		remove_cols = [col]		for rcol in self.col_list[i:]:			parent, pcol = self.get_parent( rcol )			if pcol in remove_cols:				remove_cols.append( rcol )			else:				keep_right_cols.append( rcol )		for rc in remove_cols:			# remove the links			del self.col_link[rc]		# keep only the non-children		self.col_list[i:] = keep_right_cols				# fix the letter assigmnents		for j in range(i, len(self.col_list)):			col = self.col_list[j]			# fix the column heading			col.set_letter( COLUMN_KEYS[j] )			parent, pcol = self.get_parent( col )			# fix the parent cell			parent.edit.set_letter( COLUMN_KEYS[j] )	def update_parent_columns(self):		"Update the parent columns of the current focus column."		f = self.columns.get_focus_column()		col = self.col_list[f]		while 1:			parent, pcol = self.get_parent(col)			if pcol is None: 				return			changed = pcol.update_results( start_from = parent )			if not changed: 				return			col = pcol							def get_expression_result(self):		"""Return (expression, result) as strings."""				col = self.col_list[1]		return col.get_expression(), "%d"%col.get_result()			class CalcNumLayout(urwid.TextLayout):	"""	TextLayout class for bottom-right aligned numbers with a space on	the last line for the cursor.	"""	def layout( self, text, width, align, wrap ):		"""		Return layout structure for calculator number display.		"""		lt = len(text) + 1 # extra space for cursor		r = (lt) % width # remaining segment not full width wide		linestarts = range( r, lt, width )		l = []		if linestarts:			if r:				# right-align the remaining segment on 1st line				l.append( [(width-r,None),(r, 0, r)] )			# fill all but the last line			for x in linestarts[:-1]:				l.append( [(width, x, x+width)] )			s = linestarts[-1]			# add the last line with a cursor hint			l.append( [(width-1, s, lt-1), (0, lt-1)] )		elif lt-1:			# all fits on one line, so right align the text			# with a cursor hint at the end			l.append( [(width-lt,None),(lt-1,0,lt-1), (0,lt-1)] )		else:			# nothing on the line, right align a cursor hint			l.append( [(width-1,None),(0,0)] )		return l					def main():	"""Launch Column Calculator."""	global CALC_LAYOUT	CALC_LAYOUT = CalcNumLayout()		urwid.web_display.set_preferences("Column Calculator")	# try to handle short web requests quickly	if urwid.web_display.handle_short_request():		return		CalcDisplay().main()if '__main__'==__name__ or urwid.web_display.is_web_request():	main()

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -