Esercizi stilistici in Python

From Sistemi Operativi
Jump to navigation Jump to search

trace.py:

#!/usr/bin/env python3

def trace(f):
  def strtuple(x):
    return "("+str(x[0])+")" if len(x)==1 else str(x)
  def g(*x):
    print('| ' * trace.indent + '/-- ', f.__name__, strtuple(x), sep='')
    trace.indent += 1
    value = f(*x)
    trace.indent -= 1
    print('| ' * trace.indent + '\-- ', 'return', repr(value))
    return value
  return g
trace.indent=0
 
def memoize(f):
  cache = {}
  def g(*x):
    if x not in cache:
      cache[x] = f(*x)
    return cache[x]
  return g

istr2num (c'e' un bug nel francese, da trovare e risolvere):

#!/usr/bin/env python3
# 
#   istr2num.py
#
#   multi language string 2 number conversion
#   
#   Copyright 2014 Renzo Davoli University of Bologna - Italy
#   
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License along
#   with this program; if not, write to the Free Software Foundation, Inc.,
#   51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
#
import sys

class num:
        def __init__(self,n):
                self.val=n

class mul(num):
        pass

class onemul(mul):
        pass

class plus():
        pass

class times():
        pass

class numlanguage():
        def __init__(self):
                self.dict={}
        def __setitem__(self,s,op):
                self.dict[s]=op
                for l in range(len(s)-1,0,-1):
                        if s[:l] in self.dict:
                                break
                        else:
                                self.dict[s[:l]]=None
                return op
        def match(self,s):
                matchlen,obj=0,None
                for l in range(1,len(s)+1):
                        if s[:l] in self.dict:
                                matchlen,obj=l,self.dict[s[:l]]
                        else:
                                break
                return matchlen,obj

def str2num(langnum,s):
        hi=lo=last=0
        lastop=None
        while s:
                if s[0] in " -\t\n":
                        s=s[1:]
                else:
                        ml,obj=langnum.match(s)
                        if obj:
                                if isinstance(obj,num):
                                        if isinstance(obj,mul):
                                                if isinstance(obj,onemul) and lo == 0:
                                                        lo = 1
                                                if (last <= obj.val or isinstance(lastop,times)) and not isinstance(lastop,plus):
                                                        hi,lo = (hi+lo)*obj.val,0
                                                else:
                                                        hi,lo = hi+lo*obj.val,0
                                                last=obj.val
                                        else: 
                                                if obj.val <= lo or isinstance(lastop,plus):
                                                        lo += obj.val
                                                else:
                                                        lo = lo*obj.val if lo else obj.val
                                        lastop=None
                                else:
                                        lastop=obj
#                               print(s[:ml],hi,lo,last,lastop)
                                s=s[ml:]
                        else:
                                return -1
        return hi+lo

def num_it():
        nl=numlanguage()
        nl["zero"]=num(0) 
        nl["uno"]=nl["un"]=nl["una"]=num(1) 
        nl["due"]=num(2) 
        nl["tre"]=num(3) 
        nl["quattro"]=num(4) 
        nl["cinque"]=num(5) 
        nl["sei"]=num(6) 
        nl["sette"]=num(7) 
        nl["otto"]=num(8) 
        nl["nove"]=num(9) 
        nl["dieci"]=num(10) 
        nl["undici"]=num(11) 
        nl["dodici"]=num(12) 
        nl["tredici"]=num(13) 
        nl["quattordici"]=num(14) 
        nl["quindici"]=num(15) 
        nl["sedici"]=num(16) 
        nl["diciassette"]=num(17) 
        nl["diciotto"]=num(18) 
        nl["diciannove"]=num(19) 
        nl["venti"]=nl["vent"]=num(20) 
        nl["trenta"]=nl["trent"]=num(30) 
        nl["quaranta"]=nl["quarant"]=num(40) 
        nl["cinquanta"]=nl["cinquant"]=num(50) 
        nl["sessanta"]=nl["sessant"]=num(60) 
        nl["settanta"]=nl["settant"]=num(70) 
        nl["ottanta"]=nl["ottant"]=num(80) 
        nl["novanta"]=nl["novant"]=num(90) 
        nl["cento"]=num(100) 
        nl["mille"]=onemul(10**3) 
        nl["mila"]=nl["migliaia"]=mul(10**3) 
        nl["milioni"]=nl["milione"]=mul(10**6) 
        nl["miliardi"]=nl["miliardo"]=mul(10**9) 
        nl["dozzine"]=nl["dozzina"]=mul(12) 
        nl["decine"]=mul(10) 
        nl["centinaia"]=mul(100) 
        nl["di"]=times() 
        nl["e"]=plus() 
        return nl

def num_en():
        nl=numlanguage()
        nl["zero"]=nl["null"]=num(0)
        nl["one"]=num(1)
        nl["two"]=num(2)
        nl["three"]=num(3)
        nl["four"]=num(4)
        nl["five"]=num(5)
        nl["six"]=num(6)
        nl["seven"]=num(7)
        nl["eight"]=num(8)
        nl["nine"]=num(9)
        nl["ten"]=num(10)
        nl["eleven"]=num(11)
        nl["twelve"]=num(12)
        nl["thirteen"]=num(13)
        nl["fourteen"]=num(14)
        nl["fifteen"]=num(15)
        nl["sixteen"]=num(16)
        nl["seventeen"]=num(17)
        nl["eighteen"]=num(18)
        nl["nineteen"]=num(19)
        nl["twenty"]=num(20)
        nl["thirty"]=num(30)
        nl["forty"]=num(40)
        nl["fifty"]=num(50)
        nl["sixty"]=num(60)
        nl["seventy"]=num(70)
        nl["eighty"]=num(80)
        nl["ninety"]=num(90)
        nl["hundred"]=num(100)
        nl["thousand"]=mul(10**3)
        nl["million"]=mul(10**6)
        nl["billion"]=mul(10**9)
        nl["trillion"]=mul(10**12)
        nl["dozen"]=mul(12)
        nl["and"]=plus()
        nl["of"]=times()
        return nl

def num_fr():
        nl=numlanguage()
        nl["zero"]=num(0)
        nl["un"]=num(1)
        nl["deux"]=num(2)
        nl["trois"]=num(3)
        nl["quatre"]=num(4)
        nl["cinq"]=num(5)
        nl["six"]=num(6)
        nl["sept"]=num(7)
        nl["huit"]=num(8)
        nl["neuf"]=num(9)
        nl["dix"]=num(10)
        nl["onze"]=num(11)
        nl["douze"]=num(12)
        nl["treize"]=num(13)
        nl["quatorze"]=num(14)
        nl["quinze"]=num(15)
        nl["seize"]=num(16)
        nl["vingt"]=num(20)
        nl["trente"]=num(30)
        nl["quarante"]=num(40)
        nl["cinquante"]=num(50)
        nl["soixante"]=num(60)
        nl["cent"]=num(100)
        nl["mille"]=onemul(10**3)
        nl["million"]=mul(10**6)
        nl["milliard"]=mul(10**9)
        nl["douzaine"]=mul(12)
        nl["et"]=plus()
        nl["de"]=times()
        return nl

def num_de():
        nl=numlanguage()
        nl["null"]=num(0)
        nl["eins"]=nl["ein"]=num(1)
        nl["zwei"]=nl["zwo"]=num(2)
        nl["drei"]=num(3)
        nl["vier"]=num(4)
        nl["fünf"]=num(5)
        nl["sechs"]=num(6)
        nl["sieben"]=num(7)
        nl["acht"]=num(8)
        nl["neun"]=num(9)
        nl["zehn"]=num(10)
        nl["elf"]=num(11)
        nl["zwölf"]=num(12)
        nl["dreizehn"]=num(13)
        nl["vierzehn"]=num(14)
        nl["fünfzehn"]=num(15)
        nl["sechzehn"]=num(16)
        nl["siebzehn"]=num(17)
        nl["achtzehn"]=num(18)
        nl["neunzehn"]=num(19)
        nl["zwanzig"]=num(20)
        nl["dreiβig"]=num(30)
        nl["dreißig"]=num(30)
        nl["vierzig"]=num(40)
        nl["fünfzig"]=num(50)
        nl["sechzig"]=num(60)
        nl["siebzig"]=num(70)
        nl["achtzig"]=num(80)
        nl["neunzig"]=num(90)
        nl["hundert"]=num(100)
        nl["tausend"]=mul(10**3)
        nl["million"]=mul(10**6)
        nl["milliard"]=mul(10**9)
        nl["und"]=plus()
        return nl

def num_es():
        nl=numlanguage()
        nl["cero"]=num(0)
        nl["uno"]=num(1)
        nl["dos"]=num(2)
        nl["tres"]=num(3)
        nl["cuatro"]=num(4)
        nl["cinco"]=num(5)
        nl["seis"]=num(6)
        nl["siete"]=num(7)
        nl["ocho"]=num(8)
        nl["nueve"]=num(9)
        nl["diez"]=num(10)
        nl["once"]=num(11)
        nl["doce"]=num(12)
        nl["trece"]=num(13)
        nl["catorce"]=num(14)
        nl["quince"]=num(15)
        nl["dieciséis"]=num(16)
        nl["diecisiete"]=num(17)
        nl["dieciocho"]=num(18)
        nl["diecinueve"]=num(19)
        nl["veinte"]=nl["veinti"]=num(20)
        nl["treinta"]=num(30)
        nl["cuarenta"]=num(40)
        nl["cincuenta"]=num(50)
        nl["sesenta"]=num(60)
        nl["setenta"]=num(70)
        nl["ochenta"]=num(80)
        nl["noventa"]=num(90)
        nl["cien"]=nl["cientos"]=num(100)
        nl["quinientos"]=num(500)
        nl["setecientos "]=num(700)
        nl["novecientos"]=num(900)
        nl["mil"]=onemul(10**3)
        nl["millón"]=nl["millones"]=mul(10**6)
        nl["billón"]=nl["billones"]=mul(10**12)
        nl["y"]=plus()
        return nl

if __name__ == "__main__":
        itnum=num_it()
        print("it",str2num(itnum,sys.argv[1]))
        ennum=num_en()
        print("en",str2num(ennum,sys.argv[1]))
        frnum=num_fr()
        print("fr",str2num(frnum,sys.argv[1]))
        denum=num_de()
        print("de",str2num(denum,sys.argv[1]))
        esnum=num_es()
        print("es",str2num(esnum,sys.argv[1]))