Liest nicht richtig aus Datei ein

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
benny.fi
User
Beiträge: 2
Registriert: Dienstag 10. Juli 2012, 11:58

hi leute
hoffe ihr könnt mir einen tipp geben, wie ich mein programm richtig zum laufen bringe...

Problem:
gegen Ende des Codes soll in der for-schleife, Daten aus einer Datei entnommen werden. In dieser Datei sind 8760 Werte für die Einstrahlung und die Temperatur enthalten. Das Programm soll nun den 1. Wert aus der Datei nehmen und die dazugehörigen Werte berechnen...dann den 2 Wert Berechnen..usw. bis 8760. Mein Programm macht dies schon richtig, allerdings nur für die Werte 1 bis 24 und dann fängt er wieder mit dem Wert 1. an und wiederholt dies bis zum Ende.

TU= Umgebungstemperatur
Gh=EInstrahlung

Hoffe dass ich es einingermaßen verständlich rübergebracht habe was ich damit meine :)


Code: Alles auswählen

import numpy as np
##
gl= 10 #geografische Länge für Ulm
gb=48.4 #geografische Breite für Ulm
LK= 4*(15-gl) #gl ist der wert für die geo länge
rho = 0.2 # Albedo
uhrzeit = np.arange(0.,24,1) #uhrzeit = np.arange(0,24,1)
tag = np.arange(1,366)
pi = np.pi
eta_ref= 0.15 #Referenzmodulwirkungsgrad aus Datenbaltt
NOCT= 45 #Nominal operation cell temperature
TEMPKOEFF= 0.004#Temperaturkoeffizient der Leistung vom Moduls
beta = 30 # Neigung des Kollektors
gamma = 0 # Ausrichtung nach Himmelsrichtung
Flaeche1= 15. # Dachflächengröße  100%

tabelle2 = file('tabelle2.csv','w')
tabelle2.write('Tag;Uhrzeit;Gt;Deklination;B-Wert;ET-Wert;WOZ;w;Alpha S;Theta Z;K t; Gdh;Gbh;P_Modul;Temperatur\n')
l_dekl = []
l_B=[]
l_ET = []
l_WOZ = []
l_w = []
l_Theta_Z =[]
l_alphas =[]
l_kt = []
l_m=[]
l_gdh=[]
l_gbh=[]
l_gh=[]
l_tu=[]
l_theta=[]
l_gt=[]
l_tc=[]
l_etamodul=[]
l_pmod=[]



def read_gh(Dateiname):
    ta, hgh = np.loadtxt(Dateiname,usecols=[4,8],skiprows=4,unpack=True)
    return ta, hgh
   
TU,Gh = read_gh('Wetterdaten_Deutschland.dat')

def Deklination (tag):
    return 23.45*np.sin(((360/365.)*(284.+tag))*(pi/180))

def B (tag):
    return 360*((tag-1)/365.)

def ET(b):
    return 229.2*(0.000075+0.001868*np.cos(b*(pi/180))-0.032077*np.sin(b*(pi/180))-0.014615*np.cos((2*b)*(pi/180))-0.040849*np.sin((2*b)*(pi/180)))
    #anstattt b*(pi/180) np.degrees(b)

def WOZ(uhrzeit,LK, ET, d):
        return 60*uhrzeit-LK+ ET


def w(WOZ):
    return ((WOZ/60)-12)*15

def Theta_Z(gb,d,w):
    return (np.arccos(((np.sin(d*(pi/180)))*(np.sin(gb*(pi/180)))+(np.cos(d*(pi/180)))*(np.cos(gb*(pi/180)))*(np.cos(w*(pi/180)))))*(180/pi))


def ALPHAs(tz):
    return 90-tz
   
   
def KT(Gh, tag,alphas):
    return Gh /(1353*(1+0.033*np.cos(((2*pi*tag)/365)*(pi/180)))*np.sin(alphas*(pi/180)))  

def m(KT):
    if KT <= 0.22:
        return 1-0.09 *KT
    elif 0.8 >= KT > 0.22:
        return 0.9511- 0.1604*KT + 4.388 *KT**2 - 16.638*KT**3 + 12.336* KT**4
    elif KT > 0.8:
        return 0.165

def Gdh(m,Gh):return m*Gh

def Gbh(Gh,gdh):return Gh-gdh    


def theta(d,gb,beta,gamma,w):
    return np.arccos(np.sin(d*(pi/180))*np.sin(gb*(pi/180))*np.cos(beta*(pi/180))-np.sin(d*(pi/180))*np.cos(gb*(pi/180))*np.sin(beta*(pi/180))*np.cos(gamma*(pi/180))+np.cos(d*(pi/180))*np.cos(gb*(pi/180))*np.cos(beta*(pi/180))*np.cos(w*(pi/180))+np.cos(d*(pi/180))*np.sin(gb*(pi/180))*np.sin(beta*(pi/180))*np.cos(gamma*(pi/180))*np.cos(w*(pi/180))+np.cos(d*(pi/180))*np.sin(beta*(pi/180))*np.sin(gamma*(pi/180))*np.sin(w*(pi/180)))*(180/pi)
   
def Gt(tz,th,gbh,gdh,beta,gh,rho):
    return (gbh/np.cos(tz*(pi/180)))*np.cos(th*(pi/180))+gdh*((1+np.cos(beta*(pi/180)))/2)+gh*rho*((1-np.cos(beta*(pi/180)))/2)


 
def T_C(kt, NOCT, TU):
   
    return (219+832* kt)*((NOCT-20.)/800.)+ TU

def ETA_modul(tc,eta_ref,TEMPKOEFF):
    return eta_ref*(1.-TEMPKOEFF*(tc-25.))


def P_Modul(etamodul, gt,Flaeche1):
    return etamodul* gt* Flaeche1


def r(s):
    return str(s).replace('.',',')
   
for i,j in enumerate(tag):
    d = Deklination(j)
    l_dekl.append(d)
    b = B(j)
    l_B.append(b)
    et = ET(b)
    l_ET.append(et)    
    for l,k in enumerate(uhrzeit):
       woz = WOZ(k,LK,et, d)
       l_WOZ.append(woz)
       W = w(woz)
       l_w.append(W)
       tz = Theta_Z(gb,d,W)
       l_Theta_Z.append(tz)
       a_s = ALPHAs(tz)
       l_alphas.append(a_s)
       kt = KT(Gh[l],j,a_s)
       l_kt.append(kt)

       M= m(kt)      
       l_m.append(M)
       gdh= Gdh(M,Gh[l])
       l_gdh.append(gdh)
       gbh= Gbh(Gh[l],gdh)
       l_gbh.append(gbh)
       th = theta(d,gb,beta,gamma,W)
       l_theta.append(th)
       gt = Gt(tz,th,gbh,gdh,beta,Gh[l],rho)
       l_gt.append(gt)

       tc= T_C(kt, NOCT, TU[l])
       l_tc.append(tc)
       etamodul= ETA_modul(tc,eta_ref,TEMPKOEFF)
       l_etamodul.append(etamodul)
       pm= P_Modul(etamodul,gt,Flaeche1)
       l_pmod.append(pm)
     
       tabelle2.write('%s;%s;%s;%s;%s;%s;%s;%s;%s;%s;%s;%s;%s;%s;%s\n' % (j,r(k),r(gt),r(d),r(b),r(et),r(woz),r(W),r(a_s),r(tz),r(kt),r(gdh),r(gbh),r(pm),r(tc)))
       
   

tabelle2.close()
 
Vielen Dank eure Bemühungen
Benutzeravatar
sparrow
User
Beiträge: 4193
Registriert: Freitag 17. April 2009, 10:28

Ohne mich durch den kruden Code gehangelt zu haben: du iterierst über Uhrzeit... und das ist bei dir eine range von 0-24
benny.fi
User
Beiträge: 2
Registriert: Dienstag 10. Juli 2012, 11:58

ja das ist ein iterationschritt...für eine Funktion benötige ich die Uhrzeit und die dazugehörige Einstrahlung oder Temperatur die ich aus der Datei eingelese.....

das programm macht folgendes:

Code: Alles auswählen

Tag  Uhrzeit        Temperatur
1      0:00                 1,1
        0:15                 2,0   
forlaufend bis 24 Uhr

2      0:00                1,1
       0:15                 2,0

Er liest den Datensatz richtig ein, aber wenn er damit dann rechnen soll, nimmt er nur die Werte 1 bis 24 und wiederholt die für alle weiteren Tage.......

Ich vermute, dass der Fehler in der 2. for-schleife liegt (genauer gesagt tc= T_C(kt, NOCT, TU[l]) wo ich mich auf das TU beziehe
BlackJack

@benny.fi: Ja da liegt *offensichtlich* das Problem. `l` nimmt halt nur Werte von 0 bis 23 an. Genau das sagst Du ja auch im Quelltext, dass das passieren soll. Wie sparrow schon anmerkte geht die innere Schleife, die `l` bei jedem Durchlauf an einen neuen Wert bindet, über die `uhrzeit`.

Die beiden `enumerate()`-Funktionen in den Schleifen am Ende sind etwas komisch weil damit eine zweite Laufvariable erzeugt wird, die synchron zur anderen läuft. Insbesondere bei `uhrzeit` haben beide den *gleichen* Wert. Das ist 100% redundant.

Ich frage mich warum Du überall `numpy`-Funktionen benutzt ohne *wirklich* `numpy` zu benutzen. Das Modul ist nicht dazu gedacht um mit Einzelwerten zu rechnen, die man dann in normale Listen steckt. Das ist langsamer, weil mehr Aufwand, als wenn man das Modul weg lässt. Das Modul ist aber eigentlich dazu da um Berechnungen auf vielen Werten zu beschleunigen — wenn man es richtig verwendet.

Werden diese ganzen Listen mit dem `l_`-Präfix im Namen eigentlich überhaupt irgendwo verwendet? Auf den ersten Blick sehe ich das nirgendwo.

Was soll die `2` bei `tabelle2`? Durchnummerieren von Namen ist in der Regel ein „code smell”.

Die Zeile in der in die Datei geschrieben wird, ist zu umständlich. Statt zig mal '%s' und ``r(name)`` hin zu schreiben hätte man das mit der `join()`-Methode auf Zeichenketten und einem Generatorausdrück kompakter schreiben können.

Für `csv`-Dateien gibt ein Modul in der Standardbibliothek.

Und Du solltest den Code der auf Modulebene ausgeführt wird und keine Konstanten definiert in eine Funktion stecken. Dann ist der auch nicht so weit verstreut.
BlackJack

@benny.fi: Ich habe mir das mit den `l_`-Listen noch einmal genauer angeschaut. Die werden tatsächlich nicht verwendet. In `l_gh` und `l_tu` werden noch nicht einmal Elemente gesteckt. Also weg damit.

Das `i` bei der äusseren Schleife wird auch nicht verwendet. Da hast Du also schon selbst gemerkt, dass es redundant ist.

Die Formatierung des Quelltextes was Leerzeichen, und teilweise auch Einrückung, angeht, ist nicht besonders konsistent. Wirf mal einen Blick in PEP 8 -- Style Guide for Python Code.

Dateien sollte man mit `open()` öffnen. `file` ist der Datentyp für Dateien und eher zum vererben bei objektorienterter Programmierung gedacht. Ausserdem bietet sich zum öffnen und schliessen von Dateien die ``with``-Anweisung an.

Die Namen sind teilweise schlecht gewählt.

Wenn man einen Kommentar braucht um eine Abkürzung oder einen absolut generischen Namen zu erklären, sollte man über einen besseren Namen nachdenken, bei dem man sich dann den Kommentar sparen kann. Das gilt insbesondere wenn der Kommentar nur aus einem Wort besteht. Bei `rho` mit dem Kommentar ``# Albedo`` hätte man zum Beispiel gleich den Namen `albedo` für den Wert nehmen können. Die Indirektion über einen „griechischen Buchstaben” macht hier keinen Sinn. Das Programm wird einfach nur geringfügig schwerer lesbar weil man immer wenn man irgend wo über `rho` stolpert und nicht weiss wofür das steht, erst einmal den Kommentar suchen muss.

Bei `uhrzeit` und `tag` wird aus dem Namen nicht ersichtlich dass nicht *eine* Uhrzeit oder *ein* Tag an den Namen gebunden wird, sondern jeweils eine Sequenz von Werten. Bei Sequenz-Objekten bietet es sich an die Mehrzahl bei der Namensgebung zu wählen. Dann kann man in einer Schleife die Einzahl für die Schleifenvariable wählen und macht das Programm so verständlicher.

Du trennst die Daten in `read_gh()` auf zwei Namen auf, die im folgenden dann aber doch wieder parallel/paarweise verwendet werden. Das macht keinen Sinn, beziehungsweise nicht wenn man das in Python-Schleifen weiterverarbeitet. Falls man `numpy` verwendet, dann würde man die beiden Spalten in den Rechnungen jeweils als *ein* Wert behandeln — da wäre dass dann wieder sinnvoll.

Die Daten sind weder durch Uhrzeit noch durch den Tag alleine indexierbar. Entweder berechnest Du den Index oder Du vermeidest Indizes für die Zugriffe komplett in dem Du einen Iterator über die Daten erstellst und am Anfang der inneren Schleife einfach immer das nächste Wertepaar anforderst.

Du hast in einem Kommentar ja selbst schon festgestellt, dass es `np.degrees()` gibt. `np.radians()` ist für die Gegenrichtung. Statt die Umwandlung von Grad in Bogenmass in jeder betroffenen Funktion und dort dann auch noch mehrfach zu machen, solltest Du die Gradangaben so früh wie möglich in das Bogenmass umwandeln. Und falls Du Gradangaben für die Ausgabe benötigst, sollten die dafür so spät wie möglich aus dem Bogenmass umgerechnet werden. Die triginometrischen Funktionen arbeiten nun mal mit Bogenmass, also sollte man nur Ein- und Ausgaben (im weitesten Sinne) in Grad haben und alles andere im Bogenmass um es einheitlich zu haben und unnötige Umrechnungen zu vermeiden.

Die Zeilenlänge sollte man auf 80 Zeichen beschränken und Berechnungen so formatieren, dass man einfacher erkennen kann was da passiert. `theta()` ist das absolute Negativbeispiel.

Mal angefangen die Vorschläge umzusetzen komme ich auf dieses Zwischenergebnis (ungetestet):

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import csv
from itertools import izip
import numpy as np

pi = np.pi


def read_gh(filename):
    return np.loadtxt(filename, usecols=[4, 8], skiprows=4, unpack=True)


def Deklination(tag):
    return 23.45*np.sin(((360/365.)*(284.+tag))*(pi/180))


def B(tag):
    return 360*((tag-1)/365.)


def ET(b):
    return (
        229.2 * (
            0.000075
            + 0.001868 * np.cos(b * (pi / 180))
            - 0.032077 * np.sin(b * (pi / 180))
            - 0.014615 * np.cos(2 * b * (pi / 180))
            - 0.040849 * np.sin(2 * b * (pi / 180))
        )
    )
    # TODO Anstatt b*(pi/180) np.degrees(b).


def WOZ(uhrzeit, LK, ET, d):
    return 60*float(uhrzeit)-LK+ ET


def w(WOZ):
    return ((WOZ/60)-12)*15


def Theta_Z(breite, d, w):
    return (
        np.arccos(
            np.sin(d * (pi / 180)) * np.sin(breite * (pi / 180))
            + (
                np.cos(d * (pi / 180))
                * np.cos(breite * (pi / 180))
                * np.cos(w * (pi / 180))
            )
        )
        * (180 / pi)
    )


def ALPHAs(tz):
    return 90-tz


def KT(Gh, tag,alphas):
    return (
        Gh / (
            1353
            * (1 + 0.033 * np.cos(((2 * pi * tag) / 365)
            * (pi / 180))) * np.sin(alphas * (pi / 180))
        )
    )


def m(KT):
    if KT <= 0.22:
        return 1-0.09 *KT
    elif 0.8 >= KT > 0.22:
        return 0.9511- 0.1604*KT + 4.388 *KT**2 - 16.638*KT**3 + 12.336* KT**4
    elif KT > 0.8:
        return 0.165


def Gdh(m,Gh):return m*Gh


def Gbh(Gh,gdh):return Gh-gdh


def theta(d, breite, beta, gamma, w):
    return (
        np.arccos(
            (
                np.sin(d * (pi / 180))
                * np.sin(breite * (pi / 180))
                * np.cos(beta * (pi / 180))
            )
            - (
                np.sin(d * (pi / 180))
                * np.cos(breite * (pi / 180))
                * np.sin(beta * (pi / 180))
                * np.cos(gamma * (pi / 180))
            )
            + (
                np.cos(d * (pi / 180))
                * np.cos(breite * (pi / 180))
                * np.cos(beta * (pi / 180))
                * np.cos(w * (pi / 180))
            )
            + (
                np.cos(d * (pi / 180))
                * np.sin(breite * (pi / 180))
                * np.sin(beta * (pi / 180))
                * np.cos(gamma * (pi / 180))
                * np.cos(w * (pi / 180))
            )
            + (
                np.cos(d * (pi / 180))
                * np.sin(beta * (pi / 180))
                * np.sin(gamma * (pi / 180))
                * np.sin(w * (pi / 180))
            )
        ) * (180 / pi)
    )


def Gt(tz, th, gbh, gdh, beta, gh, albedo):
    return (
        (gbh / np.cos(tz * (pi / 180))) * np.cos(th * (pi / 180))
        + gdh * ((1 + np.cos(beta * (pi / 180))) / 2)
        + gh * albedo * ((1 - np.cos(beta * (pi / 180))) / 2)
    )


def T_C(kt, NOCT, TU):
    return (219+832* kt)*((NOCT-20.)/800.)+ TU


def ETA_modul(tc,eta_ref,TEMPKOEFF):
    return eta_ref*(1.-TEMPKOEFF*(tc-25.))


def P_Modul(etamodul, gt,Flaeche1):
    return etamodul* gt* Flaeche1


def main():
    # Geographische Länge/Breite für Ulm.
    laenge, breite = 10, 48.4
    LK = 4 * (15 - laenge)
    albedo = 0.2
    eta_ref = 0.15      # Referenzmodulwirkungsgrad aus Datenblatt.
    NOCT = 45   # Nominal operation cell temperature.
    TEMPKOEFF = 0.004   # Temperaturkoeffizient der Leistung vom Moduls.
    kollektor_neigung = 30
    ausrichtung = 0     # Ausrichtung nach Himmelsrichtung.
    dachflaeche = 15.0
    
    with open('tabelle2.csv', 'wb') as out_file:
        writer = csv.writer(out_file, delimiter=';')
        writer.writerow(
            [
                'Tag',
                'Uhrzeit',
                'Gt',
                'Deklination',
                'B-Wert',
                'ET-Wert',
                'WOZ',
                'w',
                'Alpha S',
                'Theta Z',
                'K t',
                'Gdh',
                'Gbh',
                'P_Modul',
                'Temperatur'
            ]
        )
        
        tu_gh_values = izip(read_gh('Wetterdaten_Deutschland.dat'))
        
        for tag in xrange(1, 366):
            d = Deklination(tag)
            b = B(tag)
            et = ET(b)
            for uhrzeit in xrange(0, 24):
                tu, gh = tu_gh_values.next()
                woz = WOZ(uhrzeit, LK, et, d)
                W = w(woz)
                tz = Theta_Z(breite, d, W)
                a_s = ALPHAs(tz)
                kt = KT(gh, tag, a_s)
                
                M = m(kt)
                gdh = Gdh(M, gh)
                gbh = Gbh(gh, gdh)
                th = theta(d, breite, kollektor_neigung, ausrichtung, W)
                gt = Gt(tz, th, gbh, gdh, kollektor_neigung, gh, albedo)
                
                tc = T_C(kt, NOCT, tu)
                etamodul = ETA_modul(tc, eta_ref, TEMPKOEFF)
                pm = P_Modul(etamodul, gt, dachflaeche)
                
                writer.writerow(
                    str(s).replace('.', ',')
                    for s in [
                        tag,
                        uhrzeit,
                        gt,
                        d,
                        b,
                        et,
                        woz,
                        W,
                        a_s,
                        tz,
                        kt,
                        gdh,
                        gbh,
                        pm,
                        tc
                    ]
                )


if __name__ == '__main__':
    main()
Man sollte aber die beiden Schleifen IMHO versuchen los zu werden und `numpy` tatsächlich auch dazu benutzen wofür es gedacht ist.
Antworten