2010-12-06 9 views
0

ちょっとこれは私のCSクラスの宿題のために持っていたクラスの1つで、今は私はPythonで遊んでいます。私は、Pythonでクラスを設計する方法を学びたいので、このクラスを実装したいと考えています。これは比較的ストレートなクラスです。ヘルプをいただければ幸いです。Pythonでクラスを実装する

#include <iostream> 
#include <string> 
#include <fstream> 
#include <cstdlib> 
#include <ctime> 
#include <sstream> 
#include <vector> 
#include <cmath> 

using namespace std; 

int num_flights=0 ; 
const int Columns_Total = 14; /*the total columns are 14 for each flight*/ 


class Flight 
{ 
public: 
Flight(); 
void major_calc(string& filename,ifstream& is,string& line, ofstream& os); 
    void print (ofstream& os); 

private: 
vector<vector <double> > store; 
int num_lines; 
double avg_wind_speed; 
double avg_height; 
double avg_tempr; 
double std_dev_speed; 
double std_dev_height; 
double std_dev_tempr; 

    }; 

Flight::Flight() 
{ 

} 

    void Flight::major_calc(string& filename,ifstream& is, string& line, ofstream& os) 
    { num_lines=0; 

vector <double> single_line; /* Vector to one test line of a flight*/ 
vector <double> flight_height; /* Vector stores the heights associated with all the test lines for a particular flight*/ 
vector <double> flight_wind_speed; /* Vector stores the wind speeds associated with all the test lines for a particular flight*/ 
vector <double> flight_tempr; /* Vector stores the temperatures associated with all the test lines for a particular flight*/ 

while(getline(is,line)) 
{ 
if (line.substr(0,3) == "ACM") /* Checks a new flight */ 
{ 
    num_flights++; 
    os << line << endl; 
    return ; 

} 
else 
{ 
    istringstream iss(line,istringstream::in); /* Reading the string*/ 
    double FieldInfo; 
    num_lines++; /* updating the counter*/ 
    for (int n=0; n<14; n++) 
    { 
     iss >> FieldInfo; 
     single_line.push_back(FieldInfo); 
    } 

    store.push_back(single_line); 

    flight_height.push_back(single_line[4]); /* Updates the height vector with the value from a particular test line*/ 
    flight_wind_speed.push_back(single_line[3]); /* Updates the wind speed vector with the value from a particular test line*/ 
    flight_tempr.push_back(single_line[8]);/* Updates the temperature vector with the value from a particular test line*/ 

} 

    single_line.clear(); /* Empties the single line vector so it can be used again*/ 

} 


double temp1=0; /* temporary variables used to calculate the average height, average speed and average temperature*/ 
double temp2=0; 
double temp3=0; 

for (int i=0; i< flight_height.size();i++) 
{ 
    temp1+= flight_height[i]; 
    temp2+= flight_wind_speed[i]; 
    temp3+= flight_tempr[i]; 
} 

avg_height= temp1/(flight_height.size()); 
avg_wind_speed= temp2/(flight_wind_speed.size()); 
    avg_tempr= temp3/(flight_tempr.size()); 


double sqr=2.0; /* Temporary variables used to calculate std deviation associate with the speed, height and the temperature*/ 
double temp4=0; 
double temp5=0; 
double temp6=0; 

for (int i=0; i< flight_height.size();i++) 
{ 
    temp4+= pow((flight_height[i]-avg_height),sqr); 
      temp5+= pow((flight_wind_speed[i]-avg_wind_speed),sqr); 
      temp6+= pow((flight_tempr[i]-avg_tempr),sqr); 
} 

std_dev_height= sqrt(temp4/flight_height.size()); 
std_dev_speed= sqrt(temp5/flight_wind_speed.size()); 
    std_dev_tempr= sqrt(temp6/flight_tempr.size()); 
    } 

    void Flight::print (ofstream& os) 
    { 
os<<"printing the results out"<<endl;   /* Printing out all the values*/ 
os<<"avg speed: "<<avg_wind_speed<<"knots"<<endl; 
os<<"avg height: "<<avg_height<<"feet"<<endl; 
os<<"avg tempr: "<<avg_tempr<<"celcius"<<endl; 
os<<"std dev in height: "<<std_dev_height<<"knots"<<endl; 
os<<"std dev in speed: "<<std_dev_speed<<"feet"<<endl; 
os<<"std dev in temperature: "<< std_dev_tempr<<"celcius"<<endl; 
os<<"The number of lines "<< num_lines<<endl; 

} 


    int main() 
    {   
string filename; 
    string line; 
cout<<"Enter the filename"<<endl; 
cin>>filename; 
ifstream is; 
    is.open(filename.c_str()); /*open the file*/ 
bool FileDoesntExist = is.fail(); 

if(FileDoesntExist) /*checks if the file exists*/ 
{ 
cout << "File doesn't exist" << endl; 
exit(1); 
} 

string fileout = filename.substr(filename.rfind(".")+1,filename.length()) + ".log"; /*making the ouput file */ 
ofstream os (fileout.c_str()); 

vector <Flight> complete; 
while(!is.eof()) 
{ 
    Flight test; 
    while(getline(is,line)) 
    { 
     test.major_calc(filename,is,line,os); 
     test.print(os); 
    } 
    complete.push_back(test); 
} 


return 0; 

}

+5

それは「比較的単純クラス」だとして、おそらくあなたはPythonでそれを自分で書いてみてください可能性があり、特定の問題が発生したときに質問してください。誰かがあなたのためにPythonですべてのことを書き直すことを期待するのはちょっとだと思います。 –

+0

私は全体を書き直したことは一度も言わなかった...私はちょうど周りのものを変更する方法のヒントがほしいので、私はそれをPythonで実装することができます。あなたが間違ったメッセージを受け取った場合はごめんなさい。 – dawnoflife

+0

それにもかかわらず、Python * first *でクラスを作成しようとするともっと多くのことを学び(より良い回答を得ることになります)、 。 – jalf

答えて

1

、私はあまりにも、この時のショットを取ると思います考え出し。私は物事を少し並べ替えました。私は、違ったやり方でやり遂げることができるものに対するコメントを感謝します。

import math 
import os 

def avg_dev(arr): 
    """ 
    Calculate mean and standard deviation on an array of values 

    @param arr Array of values 
    """ 
    if len(arr)==0: 
     return 0.0, 0.0 
    else: 
     avg = float(sum(arr))/len(arr) 
     dev = math.sqrt(sum([(i-avg)**2 for i in arr])) 
     return avg,dev 

class Flight: 
    """ 
    Class wraps data about a single flight 
    """ 
    def __init__(self, txt): 
     """ 
     Initialize flight information 

     @param txt List of strings containing per-flight data 
        First row is header, beginning with 'ACM'; 
        remainder are space-delimited columnar data 
     """ 

     self.flightName = txt[0][3:].strip() 
     self.numLines = len(txt)-1 

     height = [] 
     wind = [] 
     temp = [] 
     for ln in txt[1:]: 
      data = ln.split() 
      height.append(float(data[4])) 
      wind.append(float(data[3])) 
      temp.append(float(data[8])) 

     self.avg_height,  self.std_dev_height = avg_dev(height) 
     self.avg_wind_speed, self.std_dev_speed = avg_dev(wind) 
     self.avg_temp,  self.std_dev_temp = avg_dev(temp) 

    def __str__(self): 
     return """Results for %s: 
Speed: avg %f, stddev %f 
Temp: avg %f, stddev %f 
Height: avg %f, stddev %f 

""" % (
      self.flightName, 
      self.avg_wind_speed, self.std_dev_speed, 
      self.avg_temp, self.std_dev_temp, 
      self.avg_height, self.std_dev_height) 


class Flights: 
    """ 
    Container class for multiple flights expressed in a single log file 
    """ 
    def __init__(self, fname): 
     """ 
     Read a flight log file 

     @param fname Name of the log file 
     """ 
     self.filename = fname 
     self.flight = [] 

     inf = file(fname, 'r')   
     txt = [] # per-flight data buffer 
     for ln in inf.readlines(): 
      if ln[:3]=='ACM': # found start of new record 
       if len(txt)>0: # flush buffer 
        self.flight.append(Flight(txt)) 
       txt = [] 
      txt.append(ln) 
     if len(txt)>0:   # clear buffer 
      self.flight.append(Flight(txt)) 
     inf.close() 

    def __iter__(self): 
     return self.flight.__iter__() 

def main(): 
    fname = raw_input("Enter the filename: ") 

    try: 
     # read flight data 
     flight = Flights(fname) 
    except IOError: 
     print "File doesn't exist" 
     sys.exit(1) 

    logname = os.path.splitext(fname)[0] + ".log" 
    logf = file(logname, 'w') 
    for f in flight: 
     logf.write(str(f)) 
    logf.close() 

if __name__=="__main__": 
    main() 

し、それをプレイしたい人の、偽造インテスト用入力ファイル用:

ACM The first flight record 
1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 13.0 14.0 
1.1 2.1 3.1 4.1 5.1 6.1 7.1 8.1 9.1 10.1 11.1 12.1 13.1 14.1 
ACM The second flight 
1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 13.0 14.0 
1.1 2.1 3.1 4.1 5.1 6.1 7.1 8.1 9.1 10.1 11.1 12.1 13.1 14.1 
1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 13.0 14.0 
1.1 2.1 3.1 4.1 5.1 6.1 7.1 8.1 9.1 10.1 11.1 12.1 13.1 14.1 
ACM Third flight 
1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 13.0 14.0 
1.1 2.1 3.1 4.1 5.1 6.1 7.1 8.1 9.1 10.1 11.1 12.1 13.1 14.1 
1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 13.0 14.0 
2

トランジションを作るために知っておく必要がありますいくつかのもの:ここでは、コードのですPythonで

  • が、あなたは、クラス内の初期化を行います__init__()と呼ばれる方法(Flight()の代わりに、またはクラス本体自体)
  • すべてのinsta PythonでNCEメソッドは、クラスをwithingからクラスのインスタンス変数を参照するには、引数
  • としてselfを取る、あなたはPythonではself.var
  • を使用し、Java等、C++とは異なり、クラスの可視性をほとんど制御があります属性、(あなたがそれを先頭にアンダースコアを与えることができても、それがガイドラインではなく、コンパイラによって強制何か)あなたがパブリックまたはプライベートの事を宣言することはできませんので

EDIT

他のいくつかのどのように書くのかについてのメモC++ i n Python:

  • Pythonではstd::vectorのようなものは必要ありません。必要に応じて拡大縮小することができるリストを使用するだけで、あらゆるタイプのオブジェクトを含むことができ、索引付けやスライスが可能であり、常に多数の素晴らしいメソッドを利用できます。私はあなたが知っていると確信しているとして、Pythonは動的型付けされ
  • ので、あなたはC++で行うこれらの型宣言のすべてがメインのために過去
0

のものを()私はこのイディオムが好きclass-- :

class Flight(object): 
    # class defined here 

if __name__ == '__main__': 
    # main func defined here 

そして、あなたはユニットテスト/コマンドラインで実行することにより、モジュールを実行することができます:熱狂的なアマチュアとして

python flight.py 
+0

ありがとう)。私が得続けるエラーの1つは「予期しないインデント」です。本当にわからない理由 – dawnoflife

+0

ええ、重要な空白に慣れるには時間がかかります。私はすべてのブロック(クラス、defs、ifsなど)が同じインデントレベルを持つ必要があることを知っていると確信しています。私は一貫性のためにタブを4つのスペースに展開するためにエディタ(vim)を設定し、インデント用のタブのみを使用します。 – Hollister