<div dir="ltr"><div>''' traduce numeri romani ,in decimali e viceversa '''</div><div><br></div><div>#from copy import copy</div><div>import unittest</div><div><br></div><div>num_romani = 'MDCLXVI'</div><div><br></div><div># ammessi è un dizio con:</div><div># chiave = lettera, valore una tupla con:</div><div>#        (  valore decimale,</div><div>#           num_romani ammessi nel precedente,</div><div>#           num_romani ammessi successivi</div><div>#<span class="" style="white-space:pre">                    </span>ordine importanza scala valori</div><div>ammessi = { 'alfa'<span class="" style="white-space:pre">   </span>:1001,</div><div><span class="" style="white-space:pre">                     </span>'M'<span class="" style="white-space:pre">               </span>:1000,</div><div><span class="" style="white-space:pre">                     </span>'D'<span class="" style="white-space:pre">               </span>: 500,</div><div><span class="" style="white-space:pre">                     </span>'C'<span class="" style="white-space:pre">               </span>: 100,</div><div><span class="" style="white-space:pre">                     </span>'L'<span class="" style="white-space:pre">               </span>:  50,</div><div><span class="" style="white-space:pre">                    </span>'X'<span class="" style="white-space:pre">               </span>:  10,</div><div><span class="" style="white-space:pre">                    </span>'V'<span class="" style="white-space:pre">               </span>:   5,</div><div><span class="" style="white-space:pre">                    </span>'I'<span class="" style="white-space:pre">               </span>:   1}</div><div><br></div><div>def controllaLegalita(numax):</div><div><span class="" style="white-space:pre">       </span>''' torna None se condizioni di errore</div><div><span class="" style="white-space:pre">         </span>il valore decimale se corretto</div><div><span class="" style="white-space:pre">     </span>'''</div><div><span class="" style="white-space:pre">    </span>if numax == "": return # caso della stringa vuota</div><div><br></div><div><span class="" style="white-space:pre">       </span>global stoppa</div><div><span class="" style="white-space:pre">      </span>global num</div><div><br></div><div><span class="" style="white-space:pre">        </span>num = numax.upper()</div><div><span class="" style="white-space:pre">        </span># contiene la stringa in caratteri romani</div><div><span class="" style="white-space:pre">  </span># il metodo di stringa .upper() ritorna laicita</div><div><span class="" style="white-space:pre">    </span># la medesima stringa in numeri maiuscoli</div><div><br></div><div><span class="" style="white-space:pre"> </span># <span class="" style="white-space:pre">        </span>scoP = 'alfa'</div><div><span class="" style="white-space:pre">      </span># indica il valore massimo nello sconto</div><div><span class="" style="white-space:pre">    </span># ricorda che quando un valore è usato come sconto</div><div><span class="" style="white-space:pre">        </span># non può più essere usato come valore in aggiunta:</div><div><span class="" style="white-space:pre">      </span># es: se MCM -> non ammesso MCMC</div><div><span class="" style="white-space:pre">        </span># altrimenti sarebbe ammesso anche MCCM</div><div><span class="" style="white-space:pre">    </span># quindi un valore usato come aggiunta non può più</div><div><span class="" style="white-space:pre">       </span># essere usato come sconto.</div><div><br></div><div><span class="" style="white-space:pre">       </span># <span class="" style="white-space:pre">        </span>adjP = 'alfa'</div><div><span class="" style="white-space:pre">      </span># indica il valore massimo in aggiunta</div><div><span class="" style="white-space:pre">     </span># sia con bloP che con adjP impostati così non si</div><div><span class="" style="white-space:pre"> </span># sbaglia altrimenti nel primo passaggio</div><div><span class="" style="white-space:pre">   </span># si esclude tutto e bisognerebbe riscrivere</div><div><span class="" style="white-space:pre">       </span># il codice per gestire tutte le eccezioni relative</div><div><span class="" style="white-space:pre">        </span>#   adjPP = 'alfa' è il backup per gli sconti</div><div><br></div><div><span class="" style="white-space:pre">   </span>#   diFila = 0</div><div><span class="" style="white-space:pre">    </span># mantiene un contatore (counter abbeviato ctr in</div><div><span class="" style="white-space:pre">  </span># gergo) al numero di caratteri inseriti di</div><div><span class="" style="white-space:pre">        </span># fila -> max 3</div><div><br></div><div><span class="" style="white-space:pre">        </span>#   valorD = 0</div><div><span class="" style="white-space:pre">    </span># mantiene il conto del valore decimale complessivo</div><div><span class="" style="white-space:pre">        </span># da tornare per la stampa ed il test_parto_da_qui</div><div><br></div><div><br></div><div><span class="" style="white-space:pre">       </span># qui si sistema scoP:</div><div><span class="" style="white-space:pre">     </span>if len(num) > 1 and ammessi[num[0]] < ammessi[num[1]]:</div><div><span class="" style="white-space:pre">               </span>scoP = num[1]</div><div><span class="" style="white-space:pre">              </span>if stoppa == num:</div><div><span class="" style="white-space:pre">                  </span>zz = stoppa</div><div><span class="" style="white-space:pre">        </span>else:</div><div><span class="" style="white-space:pre">              </span>scoP = 'alfa'</div><div><br></div><div><span class="" style="white-space:pre">     </span>scoP = 'alfa'</div><div><span class="" style="white-space:pre">      </span>adjPP = adjP = 'alfa'</div><div><br></div><div><br></div><div><span class="" style="white-space:pre">    </span>diFila = valorD = 0</div><div><br></div><div><span class="" style="white-space:pre">       </span>for pos,  car in enumerate(num):</div><div><span class="" style="white-space:pre">          </span>''' fa la scansione di tutta la stringe in num per sottoporla</div><div><span class="" style="white-space:pre">                  </span>ad esame di correttezza</div><div><span class="" style="white-space:pre">            </span>'''</div><div><span class="" style="white-space:pre">            </span># for pos,  car in enumerate(num):</div><div><span class="" style="white-space:pre">                </span># abbiamo avuto sia posizione che carattere,</div><div><span class="" style="white-space:pre">               </span># -> enumerate un iterabile torna</div><div><span class="" style="white-space:pre">               </span># la posizione e l'elemento</div><div><span class="" style="white-space:pre">            </span># in quella posizione</div><div><br></div><div><span class="" style="white-space:pre">             </span>if car not in num_romani:</div><div><span class="" style="white-space:pre">                  </span># non esiste in romano:</div><div><span class="" style="white-space:pre">                    </span>if stoppa == num:</div><div><span class="" style="white-space:pre">                          </span>zz = stoppa</div><div><span class="" style="white-space:pre">                        </span>return</div><div><br></div><div><span class="" style="white-space:pre">            </span>if ammessi[adjP] >= ammessi[car]:</div><div><span class="" style="white-space:pre">                       </span># adjP => car. Ok. Caso semplice:</div><div><span class="" style="white-space:pre">                       </span># sono ammessi IN AGGIUNTA solo valori minori/eguali dell'ultimo</div><div><span class="" style="white-space:pre">                       </span># qui si gestisce il caso del minore</div><div><span class="" style="white-space:pre">                       </span># valore inserito IN AGGIUNTA: ok MMCC e MMCM no MMCCM</div><div><span class="" style="white-space:pre">                     </span># Per ovviare al primo inserimento nel primo giro è</div><div><span class="" style="white-space:pre">                       </span># adjP = 'alfa', valore fittizio massimo</div><div><span class="" style="white-space:pre">                   </span>'''</div><div><span class="" style="white-space:pre">                    </span>a0 = ammessi[car]</div><div><span class="" style="white-space:pre">                  </span>a1 = ammessi[scoP]</div><div><span class="" style="white-space:pre">                 </span>a2 = ammessi[adjPP]</div><div><span class="" style="white-space:pre">                        </span>a3 = ammessi[adjP]</div><div><span class="" style="white-space:pre">                 </span>a4 = ammessi[car]</div><div><br></div><div><span class="" style="white-space:pre">                 </span>if stoppa == num:</div><div><span class="" style="white-space:pre">                          </span>zz = stoppa</div><div><span class="" style="white-space:pre">                        </span>a0 = scoP</div><div><span class="" style="white-space:pre">                  </span>a1 = ammessi[scoP]</div><div><span class="" style="white-space:pre">                 </span>a2 = ammessi[scoP]</div><div><span class="" style="white-space:pre">                 </span>a3 = ammessi[scoP]</div><div><span class="" style="white-space:pre">                 </span>a4 = ammessi[car]</div><div><span class="" style="white-space:pre">                  </span>'''</div><div><span class="" style="white-space:pre">                    </span>if ammessi[scoP] <= ammessi[car]:</div><div><span class="" style="white-space:pre">                               </span># ma sono ammessi IN AGGIUNTA solo valori minori dell'ultimo</div><div><span class="" style="white-space:pre">                           </span># valore inserito COME SCONTO: ok MCML e CXCV no CXCX</div><div><span class="" style="white-space:pre">                              </span># Per ovviare al primo inserimento nel primo giro è</div><div><span class="" style="white-space:pre">                               </span># adjP = 'alfa', valore fittizio massimo</div><div><span class="" style="white-space:pre">                           </span>if stoppa == num:</div><div><span class="" style="white-space:pre">                                  </span>zz = stoppa</div><div><span class="" style="white-space:pre">                                </span>return</div><div><br></div><div><span class="" style="white-space:pre">                    </span># ok, tutto bene, aggiorno i valori di adjP a quello inserito:</div><div><span class="" style="white-space:pre">                     </span># if ammessi[adjP] == ammessi[car]:</div><div><span class="" style="white-space:pre">                        </span>if adjP == car:</div><div><span class="" style="white-space:pre">                            </span># caso inserimento eguale all'ultimo</div><div><span class="" style="white-space:pre">                           </span># controllo la fila:</div><div><span class="" style="white-space:pre">                               </span>if car in 'DLV':</div><div><span class="" style="white-space:pre">                                   </span># fanculo perché non si possono duplicare DLV:</div><div><span class="" style="white-space:pre">                                    </span>if stoppa == num:</div><div><span class="" style="white-space:pre">                                          </span>zz = stoppa</div><div><span class="" style="white-space:pre">                                        </span>return</div><div><br></div><div><span class="" style="white-space:pre">                            </span>if diFila == 2:</div><div><span class="" style="white-space:pre">                                    </span># non vi possono essere più di tre num_romani eguali di fila</div><div><span class="" style="white-space:pre">                                      </span># ricorda che il conteggio parte da 0</div><div><span class="" style="white-space:pre">                                      </span>if stoppa == num:</div><div><span class="" style="white-space:pre">                                          </span>zz = stoppa</div><div><span class="" style="white-space:pre">                                        </span>return</div><div><span class="" style="white-space:pre">                             </span># ed incremento il contatore</div><div><span class="" style="white-space:pre">                               </span>diFila +=1</div><div><span class="" style="white-space:pre">                 </span>else:</div><div><span class="" style="white-space:pre">                              </span># spezzo la fila per ricominciare da zero:</div><div><span class="" style="white-space:pre">                         </span>diFila = 0</div><div><br></div><div><span class="" style="white-space:pre">                        </span>adjPP = adjP # se dopo avrò uno sconto dovrò riaggiornare adjP!</div><div><span class="" style="white-space:pre">                  </span>adjP  = car</div><div><br></div><div><span class="" style="white-space:pre">                      </span>if stoppa == num:</div><div><span class="" style="white-space:pre">                          </span>zz = stoppa</div><div><br></div><div><br></div><div><span class="" style="white-space:pre">                      </span>valorD += ammessi[car]</div><div><br></div><div><span class="" style="white-space:pre">                    </span>continue</div><div><br></div><div><span class="" style="white-space:pre">          </span># resta adjP < car e l'if sotto non è necessario:</div><div><span class="" style="white-space:pre">          </span># if ammessi[adjP][1] > ammessi[car][1]:</div><div><span class="" style="white-space:pre">                </span># ovvio che siamo di fronte ad una richiesta di sconto.</div><div><span class="" style="white-space:pre">            </span># che fa riferimento al valore precedente</div><div><span class="" style="white-space:pre">          </span>'''</div><div><span class="" style="white-space:pre">            </span>ATTENZIONE QUI SOTTO ALLA DIFFERENZA TRA adjP e adjPP</div><div><span class="" style="white-space:pre">              </span>sostanzialmente:</div><div><span class="" style="white-space:pre">           </span>adjP<span class="" style="white-space:pre">      </span>-> aggiunto precedente</div><div><span class="" style="white-space:pre">          </span>adjPP<span class="" style="white-space:pre">     </span>-> aggiunto prima del precedente</div><div><span class="" style="white-space:pre">                </span>'''</div><div><span class="" style="white-space:pre">            </span>if stoppa == num:</div><div><span class="" style="white-space:pre">                  </span>zz = stoppa</div><div><span class="" style="white-space:pre">                </span>if ammessi[adjPP] < ammessi[car]:</div><div><span class="" style="white-space:pre">                       </span># sono ammessi SCONTABILI solo valori minori o eguali</div><div><span class="" style="white-space:pre">                      </span># dell'ultimo valore inserito IN AGGIUNTA, in questo caso:</div><div><span class="" style="white-space:pre">                     </span># ammessi[adjPP][1]</div><div><span class="" style="white-space:pre">                        </span># quindi: ok MCM e CXC no CXCM</div><div><span class="" style="white-space:pre">                     </span># Per ovviare al primo inserimento nel primo giro è</div><div><span class="" style="white-space:pre">                       </span># adjPP = 'alfa', valore fittizio massimo</div><div><span class="" style="white-space:pre">                  </span>if stoppa == num:</div><div><span class="" style="white-space:pre">                          </span>zz = stoppa</div><div><span class="" style="white-space:pre">                        </span>return</div><div><br></div><div><span class="" style="white-space:pre">            </span>if not(ammessi[car]//10 <= ammessi[adjP] < ammessi[car]//2):</div><div><span class="" style="white-space:pre">                 </span># sono ammessi sconti solo eguali o superiori</div><div><span class="" style="white-space:pre">                      </span># ad un decimo del valore da scontare</div><div><span class="" style="white-space:pre">                      </span># e minori della metà dello stesso</div><div><span class="" style="white-space:pre">                        </span>if stoppa == num:</div><div><span class="" style="white-space:pre">                          </span>zz = stoppa</div><div><span class="" style="white-space:pre">                        </span>return</div><div><br></div><div><span class="" style="white-space:pre">            </span># sono ammessi IN SCONTO solo valori minori dell'ultimo</div><div><span class="" style="white-space:pre">                </span># valore inserito IN AGGIUNTA, in questo caso: ammessi[adjPP][1]</div><div><span class="" style="white-space:pre">           </span># quindi: ok MCM e CXC no CXCM</div><div><span class="" style="white-space:pre">             </span># Per ovviare al primo inserimento nel primo giro è</div><div><span class="" style="white-space:pre">               </span># adjPP = 'alfa', valore fittizio massimo</div><div><br></div><div><span class="" style="white-space:pre">         </span>if ammessi[adjPP] < ammessi[adjP]:</div><div><span class="" style="white-space:pre">                      </span># sono ammessi SCONTI solo valori minori</div><div><span class="" style="white-space:pre">                   </span># dell'ultimo valore inserito IN AGGIUNTA, in questo caso:</div><div><span class="" style="white-space:pre">                     </span># ammessi[adjPP]</div><div><span class="" style="white-space:pre">                   </span># quindi: ok MCM e CXC no CXCM</div><div><span class="" style="white-space:pre">                     </span># Per ovviare al primo inserimento nel primo giro è</div><div><span class="" style="white-space:pre">                       </span># adjPP = 'alfa', valore fittizio massimo</div><div><span class="" style="white-space:pre">                  </span>if stoppa == num:</div><div><span class="" style="white-space:pre">                          </span>zz = stoppa</div><div><span class="" style="white-space:pre">                        </span>return</div><div><br></div><div><span class="" style="white-space:pre">            </span># aggiorno i valori:</div><div><span class="" style="white-space:pre">               </span>valorD += ammessi[car] -2 * ammessi[adjP]</div><div><span class="" style="white-space:pre">          </span># adjP due volte perché una era stata caricata prima di sapere che</div><div><span class="" style="white-space:pre">                </span># era da scontare.</div><div><br></div><div><span class="" style="white-space:pre">                </span>scoP = adjP</div><div><span class="" style="white-space:pre">                </span>adjP = car</div><div><span class="" style="white-space:pre">         </span># ignoriamo adjPP: qui non interessati al valore dello sconto</div><div><span class="" style="white-space:pre">              </span>diFila = 2 # non si può inserire un MCM</div><div><br></div><div><span class="" style="white-space:pre">          </span>continue</div><div><br></div><div><span class="" style="white-space:pre">  </span>return valorD</div><div><br></div><div>def parto_da_qui(nome):</div><div><span class="" style="white-space:pre">       </span>global stoppa</div><div><span class="" style="white-space:pre">      </span>a = ''</div><div><span class="" style="white-space:pre">     </span>#while True:</div><div><span class="" style="white-space:pre">               </span>#a = input("un numero romano or 'fine' ?")</div><div><span class="" style="white-space:pre">               </span>#if a == 'fine':</div><div><span class="" style="white-space:pre">           </span>#<span class="" style="white-space:pre"> </span>break</div><div><span class="" style="white-space:pre">      </span>a = controllaLegalita(nome)</div><div><span class="" style="white-space:pre">        </span>print(a)</div><div><br></div><div><span class="" style="white-space:pre">  </span>return a</div><div><br></div><div><br></div><div>def parto_da_qui(nome):</div><div><span class="" style="white-space:pre">   </span>global stoppa</div><div><span class="" style="white-space:pre">      </span>a = ''</div><div><span class="" style="white-space:pre">     </span>#while True:</div><div><span class="" style="white-space:pre">               </span>#a = input("un numero romano or 'fine' ?")</div><div><span class="" style="white-space:pre">               </span>#if a == 'fine':</div><div><span class="" style="white-space:pre">           </span>#<span class="" style="white-space:pre"> </span>break</div><div><span class="" style="white-space:pre">      </span>a = controllaLegalita(nome)</div><div><span class="" style="white-space:pre">        </span>print(a)</div><div><br></div><div><span class="" style="white-space:pre">  </span>return a</div><div><br></div><div>def int_to_roman(input):</div><div>    """ Convert an integer to a Roman numeral. """</div><div><span class="" style="white-space:pre">  </span># questa funzione l'ho trovata in rete qui l'ho solo adattata:</div><div><span class="" style="white-space:pre">     </span># <a href="https://www.safaribooksonline.com/library/view/python-cookbook/0596001673/ch03s24.html">https://www.safaribooksonline.com/library/view/python-cookbook/0596001673/ch03s24.html</a></div><div><br></div><div>    ints = (1000, 900,  500, 400, 100,  90, 50,  40, 10,  9,   5,  4,   1)</div><div>    nums = ('M',  'CM', 'D', 'CD','C', 'XC','L','XL','X','IX','V','IV','I')</div><div>    result = []</div><div>    for i in range(len(ints)):</div><div>        count = int(input / ints[i])</div><div>        result.append(nums[i] * count)</div><div>        input -= ints[i] * count</div><div>    return ''.join(result)</div><div><br></div><div><br></div><div><br></div><div>class perTest(unittest.TestCase):</div><div><br></div><div><span class="" style="white-space:pre">       </span>global stoppa</div><div><span class="" style="white-space:pre">      </span>stoppa = 'i'</div><div><span class="" style="white-space:pre">       </span>stoppa = stoppa.upper()</div><div><span class="" style="white-space:pre">    </span>def test_parto_da_qui(self):</div><div><br></div><div><span class="" style="white-space:pre">              </span>for j in range(1, 4000):</div><div><span class="" style="white-space:pre">                   </span>rom = (int_to_roman(j))</div><div><span class="" style="white-space:pre">                    </span>print(j,  rom)</div><div><span class="" style="white-space:pre">                    </span>self.assertEqual(j, parto_da_qui(rom))</div><div><br></div><div>if __name__ == '__main__':</div><div><span class="" style="white-space:pre">   </span>unittest.main()</div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div></div>