HOME | Python | download | ���� |
Python �ϴؿ��������֥������Ȼظ��ʤɤΤ��������ʥѥ�������Ȥ����Ȥ��Ǥ��ޤ������Τ��ᡢ
���줫������ۤȤ�ɤʤ�����ͳ�˥ץ�������ǥ����뤳�Ȥ��Ǥ��ޤ���
�����ǡ�Scheme ����Ʊ�ͤˡ��黻�Ҥ�ǡ����Ȥ��ư�����
�ġ��α黻�Ҥȡ�����������ʬΥ����ǥ��������Ѥ��ޤ���
���Υǥ�����Ǥϡ��黻�Ҥ��ɲä��Ƥ�����å����ѹ���ä���ɬ�פ�̵���Τǡ�����ץ������������߷פȤ���
ͥ��Ƥ���Ȼפ��ޤ���
�ޤ���Python ��ͥ�줿���Ȥ��ơ�
[code 1] (calc.py)
001: #!/usr/bin/env python 002: # -*- coding:euc-jp -*- 003: 004: u''' 005: Python �ǽ��ؿ�����ץ������Ǥ��� 006: ưŪ���դ��ȴؿ����֥������Ȥ�Ȥ��ȴʷ�˽ޤ��� 007: ''' 008: 009: 010: import math, re, sys, operator 011: 012: 013: 014: 015: 016: class Operator: 017: u'''�黻�Ҥ�����Υ��饹�Ǥ�''' 018: 019: # �黻�Ҥ�ͥ���١��礭��������ͥ��Ū�˷������ 020: P_CST=6 # �����ͥ���� 021: P_LHB=5 # ! ��ͥ���� 022: P_FUN=4 # �ؿ���ͥ���� 023: P_POW=3 # �߾��ͥ���� 024: P_UPM=2 # ñ��� + �� - ��ͥ���� 025: P_MD=1 # *, /, % ��ͥ���� 026: P_BPM=0 # ����� +, - ��ͥ���� 027: 028: 029: def __init__(self, name, fun, priority): 030: self.name=name 031: self.fun=fun 032: self.priority=priority 033: 034: def __call__(self, x=None, y=None): 035: return self.fun if self.is_const() else \ 036: self.fun(x) if self.is_unary() or self.is_lhb() else \ 037: self.fun(x, y) 038: 039: def __gt__(self, other): 040: u'''self �� other ���ͥ���٤��⤤�Ȥ� True ���֤�''' 041: assert other is None or isinstance(other, Operator) 042: return other is None or \ 043: self.priority > other.priority or \ 044: ( self.priority in (Operator.P_FUN, Operator.P_POW, Operator.P_UPM) and self.priority == other.priority) 045: 046: def __str__(self): 047: return self.name 048: 049: def __repr__(self): 050: return repr(self.name) 051: 052: def is_const(self): 053: return self.priority==Operator.P_CST 054: 055: def is_lhb(self): 056: return self.priority==Operator.P_LHB 057: 058: def is_upm(self): 059: return self.priority==Operator.P_UPM 060: 061: def is_func(self): 062: return self.priority==Operator.P_FUN 063: 064: def is_unary(self): 065: return self.priority in (Operator.P_FUN, Operator.P_UPM) 066: 067: def is_binary(self): 068: return self.priority in (Operator.P_POW, Operator.P_MD, Operator.P_BPM) 069: 070: 071: 072: # �ؿ� 073: 074: def is_natural(n): 075: u'''��������''' 076: return type(n) is int and n>=0 077: 078: 079: 080: def fact(n): 081: u'''����''' 082: assert is_natural(n) 083: return reduce(operator.__mul__, range(1, n+1)) if n>0 else 1 084: 085: 086: 087: def permutation(m,n): 088: u'''����''' 089: assert is_natural(m) and is_natural(n) and m>=n 090: return reduce(operator.__mul__, range(m-n+1, m+1), 1) 091: 092: 093: 094: def combination(m,n): 095: u'''�Ȥ߹�碌''' 096: assert is_natural(m) and is_natural(n) and m>=n 097: return permutation(m,n)/fact(n) 098: 099: 100: 101: 102: 103: # �黻�Ҥ�����μ��� 104: # ʸ������Ȥ����б�����ؿ���ͥ���٤Υ��ץ� �ޤ��� �б�����������ͤˤȤ롣 105: L_OP= [ \ 106: Operator('@+', operator.__pos__, Operator.P_UPM), \ 107: Operator('@-', operator.__neg__, Operator.P_UPM), \ 108: Operator('+', operator.__add__, Operator.P_BPM),\ 109: Operator('-', operator.__sub__, Operator.P_BPM), \ 110: Operator('*', operator.__mul__, Operator.P_MD),\ 111: Operator('/', operator.__truediv__, Operator.P_MD), \ 112: Operator('%', operator.__mod__, Operator.P_MD), \ 113: Operator('<<', operator.__lshift__, Operator.P_POW), \ 114: Operator('>>', operator.__rshift__, Operator.P_POW), \ 115: Operator('**', math.pow, Operator.P_POW), \ 116: Operator('^', math.pow, Operator.P_POW), \ 117: Operator('exp', math.exp, Operator.P_FUN), \ 118: Operator('log', math.log, Operator.P_FUN), \ 119: Operator('log10', math.log10, Operator.P_FUN), \ 120: Operator('sqrt', math.sqrt, Operator.P_FUN), \ 121: Operator('abs', operator.__abs__, Operator.P_FUN), \ 122: Operator('sin', math.sin, Operator.P_FUN), \ 123: Operator('cos', math.cos, Operator.P_FUN), \ 124: Operator('tan', math.tan, Operator.P_FUN), \ 125: Operator('asin', math.asin, Operator.P_FUN), \ 126: Operator('acos', math.acos, Operator.P_FUN), \ 127: Operator('atan', math.atan, Operator.P_FUN), \ 128: Operator('!', fact, Operator.P_LHB), \ 129: Operator('P', permutation, Operator.P_POW), \ 130: Operator('C', combination, Operator.P_POW), \ 131: Operator('pi', math.pi, Operator.P_CST), \ 132: Operator('e', math.e, Operator.P_CST), \ 133: ] 134: 135: # �黻�Ҥ�̾�����ˤ��ƥϥå���ɽ���� 136: H_OP=dict([(str(op), op) for op in L_OP]) 137: 138: 139: def convert_op_name(op): 140: u'''�黻�Ҥ�����ɽ��ʸ������Ѵ������֤�''' 141: 142: return ''.join([(c if c.isalnum() else '\\'+c) for c in str(op)]) + \ 143: (r'(?=\W|$)' if op.is_const() else r'(?=[\s\(])' if op.is_func() else '') 144: 145: 146: 147: # �������Ǥ�ɽ������ɽ�� 148: RE_FORM = re.compile( \ 149: r'''(?P<nest>\() | # ����� 150: (?P<num>\d+(?P<after_dot>\.\d+)?(?:[eE][+-]?\d+)?) | # ���� 151: (?P<op_name>%s) # �黻�� 152: ''' % ('|'.join([ convert_op_name(op) for op in sorted([op for op in L_OP if not op.is_upm()], key=lambda x:len(str(x)), reverse=True)]),), \ 153: re.VERBOSE) 154: 155: 156: 157: 158: # �ġ��� 159: def cons(obj, ls): 160: u'''Lisp ���ˤ��뤿��''' 161: ls.append(obj) 162: return ls 163: 164: 165: 166: def operator_position (ls): 167: u'''ls ����Ǻǽ�˷�����黻�Ҥΰ��֤��֤�''' 168: 169: tprev, term0, pos = None, None, -1 170: 171: for i, term in enumerate(ls): 172: if isinstance(term, Operator) and (term > term0 or (isinstance(tprev, Operator) and term.is_upm())): 173: term0, pos = term, i 174: tprev=term 175: 176: return term0, pos 177: 178: 179: 180: def eval_ls(ls): 181: u'''���ͤȱ黻�Ҥ���ʤ�ꥹ�Ȥ�����Ʒ�̤��֤�''' 182: 183: if operator.isNumberType(ls): return ls # ���ͤʤ餽����֤� 184: elif len(ls)==1: 185: i=ls[0] 186: return eval_ls(i() if isinstance(i, Operator) else i) # ���Ǥ����ĤΥꥹ�Ȥʤ餽�����Ф� 187: else: 188: op, pos =operator_position(ls) # �ǽ�λȤ��黻�Ҥ�õ�� 189: 190: if op.is_const(): # ��� 191: return eval_ls(cons(op(), ls[:pos]) + ls[pos+1:]) 192: 193: elif op.is_unary() and pos < len(ls)-1: # ñ��黻�� 194: return eval_ls(cons(op(eval_ls(ls[pos+1])), ls[0:pos]) + ls[pos+2:]) 195: 196: elif op.is_lhb() and pos>0: # ! 197: return eval_ls(cons(op(eval_ls(ls[pos-1])), ls[0:pos-1]) + ls[pos+1:]) 198: 199: elif op.is_binary() and 0 < pos < len(ls)-1: # ���黻�� 200: return eval_ls(cons(op( eval_ls(ls[pos-1]), eval_ls(ls[pos+1]) ), ls[0:pos-1]) + ls[pos+2:]) 201: 202: else: 203: raise RuntimeError, "invalid formmula: (%r)" % (ls,) 204: 205: 206: 207: def find_pair(s0): 208: u'''�б������Ĥ���̤�õ��''' 209: n=0 210: for i, c in enumerate(s0): 211: if c in '()': n+= (1 if c=='(' else -1) 212: if n==0: return i 213: else: 214: raise RuntimeError, "Cannot find the close parenthesis!" 215: 216: 217: 218: def read_str(str): 219: u'''ʸ������ɤ߹���ǡ����ͤȱ黻�ҤΥꥹ�Ȥ��֤�''' 220: def _iter(s, ls): 221: s=s.strip() 222: if(s): 223: obj=RE_FORM.match(s) 224: if obj and obj.group('nest'): 225: idx=find_pair(s) 226: return _iter(s[idx+1:], cons(_iter(s[1:idx], []), ls)) 227: elif obj: 228: s1=s[obj.end():] 229: if obj.group('num'): 230: return _iter(s1, cons((float if obj.group('after_dot') else int)(obj.group('num')), ls)) 231: else: 232: op_name = obj.group('op_name') 233: if op_name in '+-' and (not ls or (isinstance(ls[-1], Operator) and not ls[-1].is_lhb())): # ñ��� +/- ���̤��� 234: op_name = '@' + op_name 235: return _iter(s1, cons(H_OP[op_name], ls)) 236: else: 237: raise RuntimeError, "Cannot parse input!" 238: else: 239: return ls 240: 241: return _iter(str, []) 242: 243: 244: 245: if __name__=='__main__': 246: 247: interactive= len(sys.argv)>1 and sys.argv[1]=='-i' 248: if interactive: 249: sys.stderr.write("Available operators and constants:\n" + \ 250: ', '.join([str(op) for op in L_OP if not op.is_upm()]) + \ 251: "\nq:quit\n\n") 252: 253: while(1): 254: if interactive: sys.stderr.write('> ') 255: str=sys.stdin.readline() 256: if str: 257: str=str.rstrip() 258: if interactive and str=='q': break 259: try: 260: print eval_ls(read_str(str)) 261: except Exception, strerror: 262: print strerror 263: else: 264: break 265: 266:
$ python calc.py -i Available operators and constants: +, -, *, /, %, <<, >>, P, C, **, ^, exp, log, log10, sqrt, abs, sin, cos, tan, sin, acos, atan, !, pi, e q:quit > 4!*7+3 171 > 64>>2 16 > 3<<4 48 > sqrt sin (pi/3) 0.930604859102 > 1233333333333333333333333333333333 * 2222222222222222244444444444444 2740740740740740768148148148147599259259259259259251851851851852 > log exp 40 40.0 > q $���Τ褦�˥ѥ��������뤳�Ȥ�Ǥ��ޤ���
python calc.py < input.txt > output.txt
���̾ | �� | ���� |
---|---|---|
P_CST | 6 | �����ͥ���� |
P_LHB | 5 | ! ��ͥ���� |
P_FUN | 4 | ���Ѵؿ���ͥ���� |
P_POW | 3 | �߾��ͥ���� |
P_UPM | 2 | ñ��� + �� - ��ͥ���� |
P_MD | 1 | *, /, % ��ͥ���� |
P_BPM | 0 | ����� +, - ��ͥ���� |
ñ��� +/- ������ +/- ����̤��뤿�ᡢ ñ�������̾���� "@+", "@-" �ˤ��ޤ���
Python �Ϥ��������ʥѥ�����ब�Ĥ���������ɽ���ʤɤΥ饤�֥��䥨�顼���������¤��Ƥ��ޤ��� ���Τ���ʷ�˥ץ���������Ȥ��Ǥ��ޤ��� �ޤ����ü��åɤ��Ѥ��Ʊ黻�Ҥ��С������ɤ��뤳�Ȥˤ�ä� ľ��Ū�ˤ狼��䤹�������ɤˤʤ�ޤ���
HOME | Python | download | ���� |