0

Hey this is one of the classes that I had for homework in my cs class and now i'm playing around with python. I want to learn how to design classes in python and would like to implement this one. It's a relatively straight forward class. Help would be appreciated. Here's the code:

#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;

}

3
  • 5
    As it's a "relatively straight forward class" perhaps you could try writing it in Python yourself and ask a question when you have a specific problem. I think it's a bit much to expect someone to re-write the whole thing in Python for you. Commented Dec 6, 2010 at 16:13
  • I never said to re-write the entire thing...I just want tips on how to change stuff around so I can implement it in python. i'm sorry if you got the wrong message Commented Dec 6, 2010 at 16:16
  • nevertheless, you're going to learn a lot more (and receive better answers), if you try to write the class in Python first, and then ask here when you get stuck. Commented Dec 6, 2010 at 16:34

4 Answers 4

3

Python Tutorial, §9, "Classes"

Sign up to request clarification or add additional context in comments.

Comments

2

Some things you will need to know to make the transition:

  • In Python, you do the initialization of a class in a method called __init__() (instead of Flight(), or in the class body itself)
  • All instance methods in Python take self as an argument
  • To refer to an instance variable in a class from withing the class, you use self.var
  • In Python, unlike Java, C++, etc., there's little control over visibility of class attributes, so you can't declare things public or private (though you can give it a leading underscore, but that's a guideline, not something enforced by the compiler)

EDIT

A few other notes on how you'd write that C++ in Python:

  • There's not need for anything like std::vector in Python. We just use lists, which can be expanded and shrunk as we need, can contain objects of any type, can be indexed and sliced, and have a number of great methods available at all times.
  • As I'm sure you know, Python is dynamically typed, so all of those type declarations you do in your C++ class-- a thing of the past

Comments

1

As an enthusiastic amateur, I figured I'd take a shot at this too. I've rearranged things a bit; I'd appreciate any comments on things which could be done differently/better.

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()

and for those who want to play with it, a faked-in test input file:

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

Comments

0

For the main() I like this idiom:

class Flight(object):
  # class defined here

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

Then you can unit test/run the module by running on the command line:

python flight.py

2 Comments

thanks :). one of the errors that I keep getting is the "unexpected indent". not really sure why
Yeah, getting used to the significant whitespace takes time. I'm sure you know that all blocks (classes, defs, ifs, etc.) should have the same indent level. I set my editor (vim) to expand tabs to 4 spaces for consistency, and then only use tabs for indents.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.