Syntax

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.
Antworten
alex1401
User
Beiträge: 8
Registriert: Mittwoch 18. Oktober 2017, 11:28

Hallo,
Ich hab folgende Aufgabe (und Problem)
ich soll ein Programm schreiben, welches das metrische System ins angloamerikanische System konvertiert.
und zwar Meter und Centimeter und Inches und Foot.
soweit bin ich bisher gekommen, aber wenn ich das Programm laufen lasse mit Beispiel:
0...für cm
100... value (welcher wert konvertiert gehört)
2... für inches

dann bekomme ich als ergebnis "h" was 1. für Feet ist und 2. kein Wert sondern eine Variable ist.
kann mir da jemand helfen oder sagen wo der fehler liegt:

Code: Alles auswählen

import sys
import math

print "Please select input unit type:"
print "0: centimeters"
print "1: meters"
print "2: inches"
print "3: feet"
i = input()

print "Please specifcy the value"
w = input()

print "Please specificy the unit to convert to"
print "0: centimeters"
print "1: meters"
print "2: inches"
print "3: feet"
t = input()

if i == 0:
	if t in range(2):
		k = w*2,54
		print "k"
	if t in range(3):
		h = w/30,48
		print "h"

elif i == 1:
	if t in range(2):
		q = w*39,37
	print "q"
	if t in range(3):
		e = w*3,28084
	print "e"
			
elif i == 2:
	if t in range(0):
		r = w/2,54
	print "r"
	if t in range(1):
		z = w/39,37
	print "z"
			
elif i == 3:
	if t in range(0):
		u = w*30,48
	print "u"
	if t in range (1):
		o = w*0,3048
	print "o"				
			
vielen dank im voraus
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

Der Fehler ist, dass Du den String "h" ausgibst. Und ich bin mir sicher, dass Du nicht genau weisst, was die range()-Funktion macht und dass in Python 2 input() vermieden und statt dessen raw_input() verwendet werden sollte. Auch brauchst Du weder sys noch math.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@alex1401: sys und math werden importiert aber nicht verwendet. Die Zeilen kannst Du also löschen. Variablennamen sollten aussagekräftig sein; i, w, t oder k sind das nicht. Bei `input_unit_type` könnte jeder an jeder Stelle im Programm gleich sagen, für was die Variable steht, ohne lange nach der Zuweisung suchen zu müssen. In Python2 sollte man `input` nicht benutzen. Wenn Du eine Zahl willst schreibst Du `input_unit_type = int(input())`. Ich weiß nicht, was Du denkst, was "t in range(2)" macht, aber eine Zeile davor zeigst Du schon, wie man richtig vergleicht. Wie in den meisten Programmiersprachen, gilt die englische Zahlennomenklatur 2.54. `w*2, 54` ist ein Tuple mit zwei Werten w*2 und 54. Viele Fälle behandelst Du gar nicht, was das Programm mit keiner Ausgabe beantwortet. Da weiß der Nutzer also nicht, ob oder was er falsch gemacht hat.

Statt jeden Fall einzeln auszuprogrammieren, solltest Du nach einer allgemeinen Formel suchen. Hier böte es sich an, für jede Längeneinheit den Umrechnungsfaktor zu einer gemeinsamen Basis (z.B. Meter) zu speichern und je nach Auswahl die passenden Faktoren rauszusuchen.
alex1401
User
Beiträge: 8
Registriert: Mittwoch 18. Oktober 2017, 11:28

Ich arbeite eigentlich mit Python 3 (oder sollte ich zumindest)^^.
Das mit in range versteh ich wirklich nicht ganz genau aber das war der einzige weg wie ich das Programm zum laufen bekommen hab. Davor hatte ich eine while true Schleife, welche die Angaben immer wieder wiederholt hat.
Hab jetzt aber mal das mit dem print geändert und es kommt zwar ein wert, aber leider funktioniert das Programm so gar nicht wie ich es eigentlich will..
alex1401
User
Beiträge: 8
Registriert: Mittwoch 18. Oktober 2017, 11:28

aber wo genau liegt jetzt der fehler? von der logik her sollte es ja funktionieren. nur beim sprung t_input zu "if i == 0" funktioniert es nicht. bin echt schon am verzweifeln. sollte ich es mit einem dictionary versuchen? :roll:
jedes mal wenn ich dann zB einge "2" damit es in inches konvertiert, bleibt die 2 im cdm stehen und das programm ist beendet...

Code: Alles auswählen

print "Please select input unit type:"
print "0: centimeters"
print "1: meters"
print "2: inches"
print "3: feet"
i = raw_input()

print "Please specifcy the value"
w = raw_input()

print "Please specificy the unit to convert to"
print "0: centimeters"
print "1: meters"
print "2: inches"
print "3: feet"
t = input()

if i == 0:
	if t == 2:
		k = w*2.54
		print k
	if t in range(3):
		h = w/30.48
		print h

elif i == 1:
	if t in range(2):
		q = w*39.37
	print q
	if t in range(3):
		e = w*3.28084
	print e
			
elif i == 2:
	if t in range(0):
		r = w/2.54
	print r
	if t in range(1):
		z = w/39.37
	print z
			
elif i == 3:
	if t in range(0):
		u = w*30.48
	print u
	if t in range (1):
		o = w*0.3048
	print o			
			
sebastian0202
User
Beiträge: 168
Registriert: Montag 9. Mai 2016, 09:14
Wohnort: Berlin

Was für ein type wird denn von der Funktion raw_input zurückgegeben?
Und mit welchem type vergleichst du bei deiner IF-Funktion?
__deets__
User
Beiträge: 14529
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du musst bei der Verwendung von raw_input die Typwandlung selbst vornehmen - das hat Sirius3 aber auch erwaehnt.

Code: Alles auswählen

unit = int(raw_input())
Schlechte Namen hast du uebrigens immer noch. Mehrzeilige prints kann man auch mit

Code: Alles auswählen

print("""Dies 
ist 
ein 
Text 
ueber 
mehrere 
Zeilen""")
machen.
Benutzeravatar
miracle173
User
Beiträge: 127
Registriert: Samstag 6. Februar 2016, 00:28

alex1401 hat geschrieben:...
Wenn du Pythone Code posten willst, solltest du nicht

Code: Alles auswählen

[code]

[/code]
verwenden, das du erhälst, wenn du in der Hilfe den "Code"-Buton drückst. sondern du solltest

Code: Alles auswählen

[Codebox=python file=Unbenannt.py]

[/Codebox]
verwenden. Das erhälst du, ennd du in der Hilfe im Drop-Down-Menü "Code auswählen" das Item "PY" auswählst.

Hier ist der Unterschied ist leicht zu sehen:
Hier ''code":

Code: Alles auswählen

if hallo:
    print("hallo world")
else:
    print("end")
und hier "codebox":

Code: Alles auswählen

if hallo:
    print("hallo world")
else:
    print("end")
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Eine Lösung ohne Eingabevalidierung könnte so aussehen:

Code: Alles auswählen

CONVERSIONS = [
    ('centimeters', 1),
    ('meters', 100),
    ('inches', 2.54),
    ('feet', 30.48),
]

def ask_unit(prompt):
    print prompt
    for num, (name, _) in enumerate(CONVERSIONS):
        print "{}: {}".format(num, name)
    return int(raw_input("> "))

def main():
    from_unit = ask_unit("Please select input unit type: ")
    value = float(raw_input("Please specify the value: "))
    to_unit = ask_unit("Please specify the unit to convert to: ")
    converted_value = value / CONVERSIONS[from_unit][1] * CONVERSIONS[to_unit][1]
    print "{:.3f} {} -> {:.3f} {}".format(
        value, CONVERSIONS[from_unit][0],
        converted_value, CONVERSIONS[to_unit][0],
    )
    
if __name__ == '__main__':
    main()
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Wobei man den Zugriff auch sprechender gestalten könnte, wenn man bei CONVERSIONS mit namedtuple() arbeitet oder entsprechende Wörterbücher einsetzt:

Code: Alles auswählen

from collections import namedtuple

Unit = namedtuple('Unit', 'name factor')

CONVERSIONS = [
    Unit('centimeters', 1),
    Unit('meters', 100),
    Unit('inches', 2.54),
    Unit('feet', 30.48),
]

# alternativ (mit mehr Aufwand)
CONVERSION_DICTS = [
    {'name': 'centimeters', 'factor': 1},
    {'name': 'meters', 'factor': 100),
    ...
]

def ask_unit(prompt):
    print prompt
    for num, unit in enumerate(CONVERSIONS):
        print "{}: {}".format(num, unit.name)
    return int(raw_input("> "))
 
def main():
    src = ask_unit("Please select input unit type: ")
    value = float(raw_input("Please specify the value: "))
    dst = ask_unit("Please specify the unit to convert to: ")
    converted = value / CONVERSIONS[src].factor * CONVERSIONS[dst].factor
    print "{:.3f} {} -> {:.3f} {}".format(
        value, CONVERSIONS[src].name,
        converted, CONVERSIONS[dst].name,
    )
   
if __name__ == '__main__':
    main()
Oder direkt auf dem Unit-Objekt arbeiten:

Code: Alles auswählen

def ask_unit(prompt):
    print prompt
    for num, unit in enumerate(CONVERSIONS):
        print "{}: {}".format(num, unit.name)
    num = int(raw_input("> "))
    return CONVERSIONS[num]
Zudem sollte noch eine Fehlerbehandlung bei ungültigen Eingaben mit rein...
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@snafu: NamedTuple sind immer wieder eine Freude.

Mit Fehlerbehandlung:

Code: Alles auswählen

from collections import namedtuple
 
Unit = namedtuple('Unit', 'name factor')
 
CONVERSIONS = [
    Unit('centimeters', 1),
    Unit('meters', 100),
    Unit('inches', 2.54),
    Unit('feet', 30.48),
]
 
def ask_unit(prompt):
    while True:
        print prompt
        for num, unit in enumerate(CONVERSIONS):
            print "{}: {}".format(num, unit.name)
        try:
            return CONVERSIONS[int(raw_input("> "))]
        except (ValueError, IndexError):
            pass
        print "Invalid input"
        
def ask_value(prompt)
    while True:
        try:
            return float(raw_input(prommpt))
        except ValueError:
            pass
        print "Invalid input"
 
def main():
    from_unit = ask_unit("Please select input unit type: ")
    value = ask_value("Please specify the value: ")
    to_unit = ask_unit("Please specify the unit to convert to: ")
    converted = value / from_unit.factor * to_unit.factor
    print "{:.3f} {} -> {:.3f} {}".format(
        value, from_unit.name,
        converted, to_unit.name,
    )
   
if __name__ == '__main__':
    main()
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Wobei ich das pass ja weg gelassen und direkt dort das print eingesetzt hätte...
Antworten