Projekt für die Schule

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.
peddy
User
Beiträge: 121
Registriert: Montag 30. Juni 2008, 13:51

Bei Wikipedia stimmt doch die Formel nicht bei Celsius zu Fahrenheit oder bin ich plem plem???

http://de.wikipedia.org/wiki/Grad_Celsius

Fahrenheit = TC · 1,8 + 32 liefert falsche Werte. Richtig wäre Fahrenheit = ((celsius * 9) / 5) + 32
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

peddy hat geschrieben: Fahrenheit = TC · 1,8 + 32 liefert falsche Werte. Richtig wäre Fahrenheit = ((celsius * 9) / 5) + 32
Das könnte evtl. an der Fließkommaungenauigkeit liegen? In der Shell sieht es zunächst gut aus:

Code: Alles auswählen

In [3]: from __future__ import division

In [4]: 9 / 5
Out[4]: 1.8
Je nach Genauigkeit muss man dann eben das decimal-Modul in diesem Kontext nutzen. Aber so dramatisch sollten die Unterschiede hier nicht ausfallen ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
BlackJack

@peddy: Die Abweichungen sind doch aber wohl ein Witz:

Code: Alles auswählen

In [100]: ['%.40f' % ((c*1.8+32) - (c*9./5+32)) for c in xrange(3,300,10)]
Out[100]: 
['0.0000000000000000000000000000000000000000',
 '0.0000000000000071054273576010018587112427',
 '0.0000000000000000000000000000000000000000',
 '0.0000000000000000000000000000000000000000',
 '0.0000000000000000000000000000000000000000',
 '0.0000000000000000000000000000000000000000',
 '0.0000000000000000000000000000000000000000',
 '0.0000000000000000000000000000000000000000',
 '0.0000000000000000000000000000000000000000',
 '0.0000000000000000000000000000000000000000',
 '0.0000000000000000000000000000000000000000',
 '0.0000000000000000000000000000000000000000',
 '0.0000000000000000000000000000000000000000',
 '0.0000000000000000000000000000000000000000',
 '0.0000000000000568434188608080148696899414',
 '0.0000000000000568434188608080148696899414',
 '0.0000000000000568434188608080148696899414',
 '0.0000000000000568434188608080148696899414',
 '0.0000000000000568434188608080148696899414',
 '0.0000000000000568434188608080148696899414',
 '0.0000000000000568434188608080148696899414',
 '0.0000000000000568434188608080148696899414',
 '0.0000000000000568434188608080148696899414',
 '0.0000000000000568434188608080148696899414',
 '0.0000000000000568434188608080148696899414',
 '0.0000000000000568434188608080148696899414',
 '0.0000000000000568434188608080148696899414',
 '0.0000000000001136868377216160297393798828',
 '0.0000000000001136868377216160297393798828',
 '0.0000000000000000000000000000000000000000']
Da beides mit Fliesskommaungenauigkeiten behaftet ist, ist am Ende wahrscheinlich auch beides streng genommen falsch.

Die Formel bei Wikipedia stimmt aber, denn 9/5 ist nun einmal *genau* 1,8. Das der Rechner 1.8 intern nicht exakt repräsentiert, dafür kann Wikipedia ja nix. ;-)
BlackJack

Da die Hausaufgaben die gestern abend bis heute morgen noch gemacht werden mussten, wahrscheinlich heute morgen noch schnell abgeschrieben wurden, können wir ja jetzt die Sprachvielfalt wieder aufleben lassen. So hätte ich das wohl zu meiner Schulzeit geschrieben:

Code: Alles auswählen

10 INPUT"VON";A:INPUT"BIS";B:PRINT"CELSIUS","KELVIN","FAHRENHEIT"
20 FOR C=A TO B STEP 10:PRINT C,C+273.15,C*9/5+32:NEXT
Testlauf:

Code: Alles auswählen

RUN
VON? 3
BIS? 30
CELSIUS   KELVIN    FAHRENHEIT
 3         276.15    37.4
 13        286.15    55.4
 23        296.15    73.4

READY.
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

Hier mal in Scheme:

Code: Alles auswählen

(define stdin
  (transcoded-port (standard-input-port)
                   (make-transcoder (utf-8-codec))))

(define (get-number-from-stdin msg)
  (display msg)
  (string->number (get-line stdin)))

(define (celsius->kelvin c)
  (+ c 273.15))

(define (celsius->fahrenheit c)
  (+ 32 (* c 1.8)))

(define (main)
  (let loop [(from (get-number-from-stdin "from: "))
             (to (get-number-from-stdin "to: "))]
    (unless (= from to)
      (printf "C: ~a | K: ~a | F: ~a\n"
              from
              (celsius->kelvin from)
              (celsius->fahrenheit from))
      (loop (+ from 1) to))))

(main)
Leider ist die Eingabereihenfolge beliebig, da die Reihenfolge der "assignments" in `let` beliebig ist. `let*`, das geordnete `let`, gibt's aber nicht in der "named" Form (der Name ist hier "loop"). Ich war zu faul, mir das jetzt zu bauen. Außerdem war ich zu faul, mir ein Tabellenformatierungsdings in Scheme zu basteln, und soweit ich weiß, hat die Standard Library da kein `str.xjust`-Äquivalent :-(

Code: Alles auswählen

to: 30
from: 3
C: 3 | K: 276.15 | F: 37.4
C: 4 | K: 277.15 | F: 39.2
C: 5 | K: 278.15 | F: 41.0
...
C: 28 | K: 301.15 | F: 82.4
C: 29 | K: 302.15 | F: 84.2
BlackJack

In Io:

Code: Alles auswählen

#!/usr/bin/env io
Range

Converter := Object clone do(
    name ::= nil
    factor ::= 1
    offset ::= 0
    convert := method(x, x * self factor + self offset)
    withName := method(name, self clone setName(name))
)

converters := List with(
    Converter withName("Celsius"),
    Converter withName("Fahrenheit") setFactor(9/5) setOffset(32),
    Converter withName("Kelvin") setOffset(273.15)
)

input := method(prompt, File standardInput readLine(prompt))

start := input("Von? ") asNumber
end := input("Bis? ") asNumber

converters map(name) join("; ") println
start toBy(end, 10) foreach(x,
    converters map(convert(x)) join("; ") println
)
peddy
User
Beiträge: 121
Registriert: Montag 30. Juni 2008, 13:51

BlackJack hat geschrieben:@peddy: Die Abweichungen sind doch aber wohl ein Witz:

Da beides mit Fliesskommaungenauigkeiten behaftet ist, ist am Ende wahrscheinlich auch beides streng genommen falsch.

Die Formel bei Wikipedia stimmt aber, denn 9/5 ist nun einmal *genau* 1,8. Das der Rechner 1.8 intern nicht exakt repräsentiert, dafür kann Wikipedia ja nix. ;-)
Ähhh, das ist jetzt ein wenig peinlich für mich und ich versteh im Moment auch nicht wie mir das passieren konnte, aber ich habe mich verrechnet. Da haben wir es mal wieder, dass Problem sitzt immer einen halben Meter vor dem Bildschirm :oops:
peddy
User
Beiträge: 121
Registriert: Montag 30. Juni 2008, 13:51

Dauerbaustelle hat geschrieben:Hier mal in Scheme:

Code: Alles auswählen

(define stdin
  (transcoded-port (standard-input-port)
                   (make-transcoder (utf-8-codec))))

(define (get-number-from-stdin msg)
  (display msg)
  (string->number (get-line stdin)))

(define (celsius->kelvin c)
  (+ c 273.15))

(define (celsius->fahrenheit c)
  (+ 32 (* c 1.8)))

(define (main)
  (let loop [(from (get-number-from-stdin "from: "))
             (to (get-number-from-stdin "to: "))]
    (unless (= from to)
      (printf "C: ~a | K: ~a | F: ~a\n"
              from
              (celsius->kelvin from)
              (celsius->fahrenheit from))
      (loop (+ from 1) to))))

(main)
Beim Scheme Erfinder waten wohl Klammern recht beliebt?
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Nicht schön, aber selten:

Code: Alles auswählen

import Data.List

main = do
    putStrLn "VON?"
    fromStr <- getLine
    putStrLn "BIS?"
    toStr <- getLine
    let from = read fromStr
        to = read toStr
        ss = [[c, c+273.15, c*9/5+32] | c<-[from, from+10..to]]
    putStrLn $ intercalate "\n" $ map (intercalate "\t") $ (["C", "K", "F"]:) $ map (map show) ss

Code: Alles auswählen

VON?
3
BIS?
22
C       K       F
3.0     276.15  37.4
13.0    286.15  55.4
23.0    296.15  73.4
Das Leben ist wie ein Tennisball.
BlackJack

CoffeeScript:

Code: Alles auswählen

#!/usr/bin/env coffee

delimiter = '; '

converters = [
    ['Celsius', (x) -> x],
    ['Fahrenheit', (x) -> x * 9 / 5 + 32],
    ['Kelvin', (x) -> x + 273.15],
]

printTable = (from, to, step=10) ->
    console.log (n for [n, _] in converters).join(delimiter)
    for c in [from..to] by step
        console.log (f(c) for [_, f] in converters).join(delimiter)
    null

main = ->
    values = []
    stdin = process.openStdin()
    stdin.setEncoding 'ascii'
    stdin.on 'data', (data) ->
        values.push parseInt data
        if values.length == 2
            printTable values...
            process.exit 0

main()
Kein Prompt für den Benutzer und die Eingabe ist auch etwas unschön umgesetzt, aber an der Stelle macht es einem die Standardbibliothek von node.js auch nicht besonders einfach.
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

peddy hat geschrieben:Beim Scheme Erfinder waten wohl Klammern recht beliebt?
Hm. Genauer gesagt sind Klammern die "einzige" Syntax, die es in LISP (wovon Scheme abstammt) gibt. Es gibt nur Klammer auf, Klammer zu, Namen und noch so Kram wie Strings und Zahlen und so weiter. Drum hat's da auch so viele Klammern, es gibt gar nix anderes :-P
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Dauerbaustelle hat geschrieben:Genauer gesagt sind Klammern die "einzige" Syntax, die es in LISP (wovon Scheme abstammt) gibt.
Wobei Scheme ja mehr Klammern hat als etwa Clojure.

Scheme

Code: Alles auswählen

(let ((a 23)
      (b 42))
   a)
Clojure

Code: Alles auswählen

(let [a 23
      b 42]
   a)
Mag jemand die Angabe wieder posten? Der OP hat sie ja entfernt, damit seine Lehrer sie nicht ergooglen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Leonidas hat geschrieben: Mag jemand die Angabe wieder posten? Der OP hat sie ja entfernt, damit seine Lehrer sie nicht ergooglen.
Schon ärgerlich, dass sich hinter dem Board keine wiki-artige Struktur verbirgt, die die Änderungsstände speichert.

Also aus dem Kopf heraus würde ich es mal so formulieren:

Gesucht ist ein Programm, welches nach Benutzereingabe einer Start- und einer Endtemperatur in Grad Celsius die Temperaturwerte in diesem Intervall in 10 Grad-Schritten in die Einheiten Kelvin und Fahrenheit umrechnet. Die berechneten Werte sollen tabellarisch ausgegeben werden.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

peddy hat geschrieben:Bei Wikipedia stimmt doch die Formel nicht bei Celsius zu Fahrenheit oder bin ich plem plem???
Nein, Fahrenheit selbst stimmt einfach nicht. ;) Die Definition ist einfach nur zum Weglaufen.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Hyperion hat geschrieben:Gesucht ist ein Programm, welches nach Benutzereingabe einer Start- und einer Endtemperatur in Grad Celsius die Temperaturwerte in diesem Intervall in 10 Grad-Schritten in die Einheiten Kelvin und Fahrenheit umrechnet. Die berechneten Werte sollen tabellarisch ausgegeben werden.
Ok, ich habe vermutlich die halbe Clojure-Stdlib neu implementiert, aber hier meine Lösung.

Die aktuelle Fassung sieht so aus. Da geht auch etwas Code drauf um Eingaben zu prüfen und ``->`` habe ich einfach nur verwendet weils toll ist :)

Code: Alles auswählen

(defn raw-input
  ([] (raw-input ""))
  ([prompt]
   (if (not (empty? prompt))
     (do 
       (print prompt)
       (flush)))
   (read-line)))

(defn read-number
  ([] (read-number ""))
  ([prompt]
   (let [value (raw-input prompt)
        number (try
                 (Integer/parseInt value 10)
                 (catch NumberFormatException e nil))]
    (if (not (nil? number)) number
      (do
        (println "Not a number")
        (recur prompt))))))

(defn get-range []
  (let [start (read-number "Enter start: ")
        stop (read-number "Enter stop: ")
        step 10]
    (range start (+ stop 1) step)))

(defn celsius->kelvin [temperature]
  (+ temperature 273.15))

(defn celsius->fahrenheit [temperature]
  (-> temperature
    (* 9)
    (/ 5)
    (+ 32)))

(defn convert [value]
  [value (celsius->kelvin value) (celsius->fahrenheit value)])

(defn tabellize [items]
  (doseq [[celsius kelvin fahrenheit] items]
    (printf "C: %s | K: %.2f | F: %.1f\n" celsius kelvin (float fahrenheit))))

(tabellize (map convert (get-range)))
Ich vermute mal dass diese Lösung lazy ist, aber da hab ich nicht wirklich Erfahrung wie Clojure das nun genau auswertet.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Und hier eine Ruby-Loesung. Ich war zu faul das noch in Funktionen zu verpacken. Was mich ein wenig Zeit gekostet hat war rauszufinden, dass ich call benutzen muss, um die Lambda-Funktionen dann aufzurufen; das fand ich ungewoehnlich. Anderseits kann man Klammern beim Funktionsaufruf weglassen (siehe Zeile 10) ... Und obwohl ich die Syntax von Python 2, wie man mit und ohne Zeilenumbruch printet, doof finde -- Rubys puts und print sind auch nicht besser, da vergesse ich immer, was was ist.

Code: Alles auswählen

#!/usr/bin/env ruby

rules = {
  "Celsius" => lambda { |temp| temp },
  "Farenheit" => lambda { |temp| temp * 9 / 5.0 + 32 },
  "Kelvin" => lambda { |temp| temp + 273.15 }
}

puts "Von?"
min = gets.to_i
puts "Bis?"
max = gets.to_i

(min ... max).step(10) do |temp|
  rules.each_pair { |name, func| print "#{name} %6.2f; " % func.call(temp) }
  puts
end
EDIT: Die schonen rosa Keywords im Ruby-Highlighting passen zu meinem Avatar. :)
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
Antworten