Parkzeit und Parkgebühren

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
__blackjack__
User
Beiträge: 13111
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Tunc0: Du hast das mit dem gezeigten Code sicher nicht geschafft, weil der falsche Ausgaben liefert. Es sind immer Keine Kosten für alles unter oder gleich zwei Stunden und 2€ sonst, egal wie lange man geparkt hat. Zudem fordert die Aufgabe das der Benutzer die Zeit in Minuten und nicht in Stunden angeben soll.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Tunc0
User
Beiträge: 5
Registriert: Dienstag 30. Oktober 2018, 17:04

Habe es nun so gemacht dass die Minuten ausgegeben werden, aber wenn man beispielsweise 2,5 Stunden angibt also 2.5, welches 150 min wären kommen falsche kosten, wie müsste ich es verändern



while(True):
print("Geben sie ihre vorraussichtlichen Parkstunden ein: ")
stunden = float(input())
print("Info: bis 2h - kostenlos, ansonsten 2€/h, max. 30€")
minuten = stunden * 60

if stunden <= 2:

print("Glückwunsch! Sie müssen nichts bezahlen.")
print("Ihre Parkdauer beträgt", stunden*60,"min")

elif stunden > 17:
print("Ihre Kosten betragen 30€")
print(stunden*60,"min")

else:
kosten = stunden * 2 - 4

print("Ihr Kosten betragen "+str(kosten)+"€")
print("Ihre Parkdauer beträgt", stunden*60,"min")
Benutzeravatar
__blackjack__
User
Beiträge: 13111
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Tunc0: Die Eingabe ist immer noch in Stunden. Die *Eingabe* soll aber laut Aufgabenstellung in *vollen Minuten* sein.

Ansonsten ist die Formel ganz offensichtlich falsch. Du müsstest die also so ändern, das sie richtige Ergebnisse liefert.

Wenn etwas am Anfang oder Ende von jedem Zweig in einem ``if``/``elif``/``else``-Konstrukt steht, dann ist das eine Verletzung des DRY-Prinzips (Don't Repeat Yourself). Die Ausgabe der Parkdauer kann man *einmal* *danach* in den Code schreiben.

Man kann das ganze auch ohne ``if``/``elif``/``else`` in eine einzige Berechnung packen. Hier mal in Ruby, damit ich Dir die Hausaufgaben nicht so ganz komplett löse. :-)

Code: Alles auswählen

#!/usr/bin/env ruby
FEE_PER_HOUR = 2
MAX_FEE = 30

def main
  puts "Bitte die Parkdauer in Minuten angeben:"
  minutes = gets.to_i
  hours = (minutes / 60.0).ceil
  parking_fee = [[hours - 2, 0].max * FEE_PER_HOUR, MAX_FEE].min
  puts "Die Parkgebühr für #{hours} Stunde(n) beträgt #{parking_fee}€."
end

main if __FILE__ == $PROGRAM_NAME
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Tunc0
User
Beiträge: 5
Registriert: Dienstag 30. Oktober 2018, 17:04

Ich habe es versucht zu machen wie du es in ruby gemacht hast, aber kommen trotzdem falsche kosten, woran liegt es?

kostenprostunde = 2
maximalekosten = 30

minuten = int(input("Bitte die Parkdauer in Minuten angeben:"))
stunden = (minuten / 60)
parkkosten = (stunden - 2) * kostenprostunde
print("Die Parkgebühr für", stunden,"Stunden(n) beträgt", parkkosten)
__deets__
User
Beiträge: 14541
Registriert: Mittwoch 14. Oktober 2015, 14:29

Was heißt denn “falsche Kosten”? Es hilft uns, wenn deine fehlerbeschreibungen etwas aussagekräftiger sind.

Und ich sehe gleich mehrere Ursachen. Was ist denn zb 123 Minuten durch 60? Und was passiert, wenn die Stunden kleiner 2 sind?
Benutzeravatar
__blackjack__
User
Beiträge: 13111
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Wenn die Ruby-Lösung zu High-Level war, hier mal ein Ansatz in MIPS-Assembler: :mrgreen:

Code: Alles auswählen

.data

minutes:
	.word 121

.text
	lw	$a0, minutes
	
	li 	$t0, 60			# $t0 = commenced hours
	div 	$a0, $t0
	mflo	$t0
	mfhi	$t1
	sgt	$t1, $t1, $zero
	add 	$t0, $t0, $t1

	subi	$t0, $t0, 2		# $t0 = billable hours
	bge	$t0, $zero, more_than_two_hours
	move	$t0, $zero
more_than_two_hours:

	li	$t1, 2			# $v0 = total parking fee
	mul	$v0, $t0, $t1
	
	li	$t0, 30			# $v0 = capped to max parking fee
	ble	$v0, $t0, not_over_max
	move	$v0, $t0
not_over_max:
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
pixewakb
User
Beiträge: 1412
Registriert: Sonntag 24. April 2011, 19:43

Die nachfolgende Lösung gefällt mir noch nicht, aber sie funktioniert. Die Integration der Variablen (Gebühr pro Stunde, Freie Parkdauer usw.) könnte man sicher noch machen...

Code: Alles auswählen

def parking_fee(minutes):
    if minutes < 2 * 60:
        return 0.0
    else:
        fee = ( ((minutes - 2 * 60) // 60) + (1 if minutes % 60 != 0 else 0) ) * 2
        if fee > 30:
            return 30.0
        else:
            return fee


print(parking_fee(60 * 4.0))
Benutzeravatar
__blackjack__
User
Beiträge: 13111
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Auf meinem alten HP48 Taschenrechner liesse sich eine Funktion `pfee` so schön knapp ausdrücken:

Code: Alles auswählen

« 60 / CEIL 2 - 0 MAX 2 * 30 MIN » 'pfee' STO
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Ist das Problem dank der Community nun gelöst? :')
Benutzeravatar
DeaD_EyE
User
Beiträge: 1021
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Ja, natürlich..
Hätte auch noch einen Ansatz, der den anderen ähnelt.

Code: Alles auswählen

def calc_parking(duration):
    free = 2 * 60
    if duration <= free:
        return 0.0
    elif duration > free:
        duration -= free
        return min(30, math.ceil(duration / 60) * 2.0)
Jetzt fehlt nur noch ein netter Docstring, der das Beschreibt was die Funktion macht und unit tests ^^

Was mir immer wieder auffällt, dass viele versuchen alles in einer Funktion zu erschlagen. Berechnungen durchführen und formatierten Text ausgeben z.B.
Teilt es auf. Eine Funktion rechnet und eine andere Funktion gibt den berechneten Wert der ersten Funktion formatiert aus. So kann man ggf. die erste
Funktion zur Berechnung der gebühren im Programm an anderer Stelle verwenden.
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

@Dead_Eye: wenn in einer elif-Bedingung das genaue Gegenteil der if-Bedingung steht, nimmt man else. Bei Dir fehlt z.B. der else-Block, so dass man beim Lesen gar nicht weiß, was da dann passieren soll, bzw. warum die Funktion in diesem Fall None zurückgibt.

Code: Alles auswählen

def calc_parking_fee(duration, free_fee=4, max_fee=30):
    return max(0, min(max_fee, math.ceil(duration / 60.) * 2 - free_fee))
Benutzeravatar
__blackjack__
User
Beiträge: 13111
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Mal Benutzerinteraktion und Berechnungen getrennt. Als Bash-Skript. :-)

Code: Alles auswählen

#!/bin/bash
readonly FreeHours=2
readonly FeePerHour=2
readonly MaxFee=30

MinutesToHours() {
    local minutes=$1
    local hours
    hours=$((minutes / 60))
    ((minutes % 60)) && ((hours++))
    echo "$hours"
}

CalculateParkingFee() {
    local hours=$1
    local fee=0
    [[ hours -gt FreeHours ]] && fee=$(((hours - FreeHours) * FeePerHour))
    [[ fee -gt MaxFee ]] && fee=$MaxFee
    echo "$fee"
}

Main() {
    local minutes
    local hours
    local fee
    read -r -p "Parkzeit in Minuten: " minutes
    hours=$(MinutesToHours "$minutes")
    fee=$(CalculateParkingFee "$hours")
    echo "Die Parkgebühr für $hours Stunde(n) beträgt $fee €."
}

[[ ${BASH_SOURCE[0]} = "$0" ]] && Main "$@"
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Antworten