Letzter Index in einer Schleife (out of range)

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Benutzeravatar
snafu
User
Beiträge: 6741
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Hier mal basierend auf `collections.deque()`:

Code: Alles auswählen

from collections import deque

ROMAN_TO_INT = {
    'M': 1000, 'CM': 900, 'D': 500, 'CD': 400, 'C': 100, 'XC': 90,
    'L': 50, 'XL': 40, 'X': 10, 'IX': 9, 'V': 5, 'IV': 4, 'I': 1
}

def get_int(romans):
    result = 0
    buf = deque(maxlen=2)
    for char in romans:
        buf.append(char)
        if len(buf) == 2:
            value = ROMAN_TO_INT.get(buf[0] + buf[1])
            if value is None:
                value = ROMAN_TO_INT[buf.popleft()]
            else:
                buf.clear()
            result += value
    if buf:
        # One item remaining in `buf`
        result += ROMAN_TO_INT[buf.pop()]
    return result
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

Mit re:

Code: Alles auswählen

#!/usr/bin/env python3
# coding: utf-8

import re

scan = re.Scanner([
    ('CM', 900),
    ('CD', 400),
    ('XC', 90),
    ('XL', 40),
    ('IX', 9),
    ('IV', 4),
    ('M', 1000),
    ('D', 500),
    ('C', 100),
    ('L', 50),
    ('X', 10),
    ('V', 5),
    ('I', 1),
]).scan

def main():
    values, invalid = scan(input('Please enter a roman number: '))
    if invalid:
        print('invalid input:', invalid)
    else:
        print('The corresponding decimal number is', sum(values))

if __name__ == '__main__':
    main()
Zum Beispiel:[codebox=bash file=Unbenannt.bsh]Please enter a roman number: MMXVI
The corresponding decimal number is 2016[/code]
In specifications, Murphy's Law supersedes Ohm's.
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

die bisherigen Lösungen prüfen alle nicht die korrekte Konstruktion der Zahlen

Code: Alles auswählen

ROMAN_DIGITS = [
    ('M', 1000, 0),
    ('CM', 900, 3),
    ('D', 500, 1),
    ('CD', 400, 1),
    ('C', 100, 0),
    ('XC', 90, 3),
    ('L', 50, 1),
    ('XL', 40, 1),
    ('X', 10, 0),
    ('IX', 9, 3),
    ('V', 5, 1),
    ('IV', 4, 1),
    ('I', 1, 0),
]

def convert_roman(roman):
    result = 0
    skip = 0
    for digit, value, newskip in ROMAN_DIGITS:
        if skip > 0:
            skip -= 1
        else:
            while roman.startswith(digit):
                result += value
                roman = roman[len(digit):]
                if newskip:
                    skip = newskip
                    break
    if roman:
        raise ValueError("invalid roman number")
    return result
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

Dann so: :mrgreen:

Code: Alles auswählen

#!/usr/bin/env python3
# coding: utf-8

import re

scan = re.Scanner([
    ('M+', lambda s, t: len(t) * 1000),
    ('CM(?!M|C|D)', 900),
    ('D(?!M|CM|CD|D)', 500),
    ('CD(?!M|C|D)', 400),
    ('C{1,3}(?!M|C|D)', lambda s, t: len(t) * 100),
    ('XC(?!M|C|D|X|L)', 90),
    ('L(?!M|C|D|XC|XL|L)', 50),
    ('XL(?!M|C|D|X|L)', 40),
    ('X{1,3}(?!M|C|D|X|L)', lambda s, t: len(t) * 10),
    ('IX(?!M|C|D|X|L|V|I)', 9),
    ('V(?!M|C|D|X|L|IX|IV|V)', 5),
    ('IV(?!M|C|D|X|L|V|I)', 4),
    ('I{1,3}(?!M|C|D|X|L|V|I)', lambda s, t: len(t)),
]).scan

def main():
    values, invalid = scan(input('Please enter a roman number: '))
    if invalid:
        print('invalid input:', invalid)
    else:
        print('The corresponding decimal number is', sum(values))

if __name__ == '__main__':
    main()
Beispiele:[codebox=bash file=Unbenannt.bsh]$ python3 roman_numerals.py
Please enter a roman number: MMXVI
The corresponding decimal number is 2016
$ python3 roman_numerals.py
Please enter a roman number: MMXVIIII
invalid input: IIII
$ python3 roman_numerals.py
Please enter a roman number: CMCMCM
invalid input: CMCMCM[/code]
In specifications, Murphy's Law supersedes Ohm's.
Nachbar
User
Beiträge: 24
Registriert: Sonntag 10. Juli 2016, 08:12

Mir ist in BlackJacks Lösung diese Zeile aufgefallen:

Code: Alles auswählen

result = i = 0
Ist das gleichbedeutend mit

Code: Alles auswählen

result = 0
i = 0
? Falls ja, ist das eine übliche Form der Variableninitialisierung in Python?
Benutzeravatar
snafu
User
Beiträge: 6741
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ja, es ist gleichbedeutend. Es ist IMHO eine Stilfrage, ob man dieses Konstrukt zum Einsatz bringt.
Antworten