Author Topic: C and C++ homework questions and answers ...  (Read 31010 times)

Offline David

  • Hero Member
  • *****
  • Posts: 647
    • View Profile
C and C++ homework questions and answers ...
« on: December 14, 2014, 05:07:40 AM »
This question is regarding a student grade type of program ...

Write a program that enters marks for any number of students, (for some semester course) ...
Calculate each student's total marks, total / total_possible * 100 (%) ... and the letter grade.
Then the class average and letter grade.
   
(The grading is:  A for 90's, B for 80's, C for 70's, D for 60's ...  but below is F)


The output could look similar to this:

Code: [Select]
# ID First Second Final Average% Grade
1 20071156      5.5 16.5 32.0 64 D
 ...
Class average for 10 students is: 72.5 (C)
       
   
Use functions where ever it might help logic flow.
« Last Edit: December 14, 2014, 05:39:45 AM by David »

Offline David

  • Hero Member
  • *****
  • Posts: 647
    • View Profile
Re: C and C++ homework questions and answers ...
« Reply #1 on: December 14, 2014, 05:28:50 AM »
A solution that uses class Student might look like this:


Code: [Select]
// studentGrades.cpp //

#include <iostream>
#include <iomanip> // re. setw... etc...
#include <string>
#include <sstream> // re ostringstream obj.
#include <vector>
#include <cctype> // re. tolower ... //

using namespace std;

const int NUM_MARKS = 3;
const int TOTAL_MARKS = 120;

const char LETTER_GRADES[] = {'F', 'D', 'C', 'B', 'A' } ;

const int FIELD = 10;
const string HEADER[] =
{
    "#", "ID", "Test 1(10)",  "Test 2(10)",  "Final(100)",
    "Total",  "Average%",  "Grade"
} ;

void showHeader()
{
    int i = 0;
    cout << setw(FIELD-7) << HEADER[i] << ' ';
    while( ++ i < 7 )
        cout << setw(FIELD ) << HEADER[i] << ' ';
    cout << HEADER[i];
}

// to handle int to string here ,,, //
template< typename T >
string toString( T val )
{
    ostringstream oss;
    oss << val;
    return oss.str();
}
// to handle both int and double input ... //
template< typename T >
T takeIn( const string& msg, T min, T max )
{
    T tmp;
    for( ; ; )
    {
        cout << msg << flush;
        if( cin >> tmp && cin.get() == '\n' &&  tmp >= min && tmp <= max  )
            return tmp;
            // else ...
        cin.clear();
        cin.sync();
        cout << "\nBad data input ... valid range is " << min << ".." << max << ":\n";
    }
}

char get_letter( double avg )
{
    int i = int( avg ) / 10 - 5;
    if( i < 0 )
        i = 0;
    return LETTER_GRADES[i];
}


class Student
{
    int id;
    double marks[NUM_MARKS];
public:
    int get_id() const { return id; }
    double get_sum() const
    {
        double s = 0.0;
        for( int i = 0; i < NUM_MARKS; ++ i )
            s += marks[i];
        return s;
    }

    friend ostream& operator << ( ostream& os, const Student& st )
    {
        double sum  = st.get_sum();
        double avg = sum / TOTAL_MARKS * 100;
        char letter = get_letter( avg );

        os << setw(FIELD) << st.id << ' ';
        for( int i = 0; i < NUM_MARKS; ++ i )
            os << setw(FIELD) << st.marks[i] << ' ';

        os << setw(FIELD) << sum << ' ' << setw(FIELD) << avg << ' ' << letter;
        return os;
    }

void takeInID()
{
        id = takeIn< int >( "Enter ID in range 1000..9999    : ", 1000, 9999 );
    }
    void takeInMarks()
{
        int i;
        for( i = 0; i < NUM_MARKS-1; ++ i )
            marks[i] = takeIn< double >( "Enter mark for test "
                               + toString( i+1 ) + " in range (0..10) : ", 0, 10 );

        marks[i] = takeIn< double >( "Enter final test mark in range (0..100) : ", 0, 100 );
    }

} ;


bool isUnique( int id, const vector< Student >& st  )
{
    for( size_t i = 0; i < st.size(); ++ i )
    if( st[i].get_id() == id )
        return false;
    // else ... if reach here ...
    return true;
}

// some handy student utilities ... ////////////////////////////////////////////
char takeInChr( const std::string& msg )
{
    std::cout << msg << std::flush;
    std::string reply;
    getline( std::cin, reply );
    if( reply.size() )
        return reply[0];
    // else ...
    return 0;
}
bool more()
{
    if( tolower( takeInChr( "\nMore (y/n) ? " ) ) == 'n' )
        return false;
    // else ...
    return true;
}
////////////////////////////////////////////////////////////////////////////////



int main()
{
    vector< Student > myStds; // get empty vector to hold each Student

    int count = 0;
    do // data entry loop ... until not more requested ...
    {
        Student st;

        for( ; ; ) // accept only ID's NOT already used ... as input ...
        {
            cout << "For myStds[" << count << "] \n";
            st.takeInID();
            if( isUnique(  st.get_id(), myStds ) )
                break; // break out NOW  ... out of *INNER for loop* ... //
            // else ... if reach here ... //
            cout << "\nThat id " << st.get_id() << " is already used ...\n";
        }
        st.takeInMarks();

        myStds.push_back( st ); // ok  ... append to vector of Students ...
        ++count;
    }
    while( more() );

   
    // ok ... show results ...

    cout << left << setprecision(1) << fixed;

    showHeader(); cout << endl;

    double sumAvgs = 0.0;
    for( size_t i = 0; i < myStds.size(); ++ i )
    {
        cout << setw(FIELD-7) << (i+1) << ' ' << myStds[i] << endl;
        sumAvgs += myStds[i].get_sum() / TOTAL_MARKS * 100;
    }

    double classAvg = sumAvgs/myStds.size();
    char letter  = get_letter( classAvg );
    cout << "\nThe class average for these " << myStds.size()
         << " students :  " << classAvg << " (" << letter << ')' << endl;
}
« Last Edit: December 14, 2014, 05:55:43 AM by David »

Offline David

  • Hero Member
  • *****
  • Posts: 647
    • View Profile
Re: C and C++ homework questions and answers ...
« Reply #2 on: December 15, 2014, 10:31:55 AM »
How to code a calender for any year?

A C++ example ...

Code: [Select]
// printCalendar.cpp //

/*
isLeapYear determines whether or not the specified year is a leap year.
This function is accurate for all years from 1582 to the present.  By
4818 A.D., there may be a different method ... because we'll be off
by about a day by then.  Maybe leave off the leap year for years that
are divisible by 4000?  Anyway, for dates before the Gregorian calendar,
this will assume that the Gregorian calendar extends backwards before
its creation; (the Julian calendar simply added a leap day every four
years and thus, spring grew later on the calendar every century ...);

Matching up to calendars before 1582 is not the concern of this author.

... The Gregorian calendar was introduced in 1582,
by 4818, our current calendar will be a day off ...
*/

#include <iostream>
#include <iomanip>

using namespace std;

//////////////////////////// j  f  m  a  m  j  j  a  s  t  n  d //
const int DAYS_N_MONTH[] = {31,28,31,30,31,30,31,31,30,31,30,31};
const char* MONTHS[] =
{
    "January","February","March","April","May","June",
    "July","August","Septempber","Octber", "November","December"
} ;
const char* LINE = "\n ===========================\n";

// returns number in range: 0..6 ///////////////////////////
//                        1..121..
int getDayNum( int year, int month, int day );

////////////////////// 0..11      0..6           false..true
void showCalendar( int month, int startDay, bool isLeap = false );
bool isLeapYear( int year );
void testCalendar( int month );
////////////////////////////////////////////////////////////

//////////////// some utilities used here  /////////////////
int takeInInt( const char* msg, int min, int max );
bool more();
////////////////////////////////////////////////////////////




int main()
{
    //testCalendar( 1 ); // feb
   
    do
    {
        int year = takeInInt( "Year for calendar: ", 1582, 4818 );

        cout << &LINE[1];

        for( int month = 0; month < 12; ++ month )
        {
            //////////////////////////////// 1..12    1..7 /////
            int dayOfWeek = getDayNum( year, month+1, 1 );
            bool isLeap = isLeapYear( year );

            ///////////// 0..11  0..6       false..true ////////
            showCalendar( month, dayOfWeek, isLeap );
            if( month < 11 ) cout << LINE;
        }
    }
    while( more() ) ;

   std::cout << "Press 'Enter' to continue ... ";
   cin.get();

}



/////////////////////// 0..11       0..6    false..true ////
void showCalendar( int month, int startDay, bool isLeap )
{
    int daysInMonth = DAYS_N_MONTH[month] + (month == 1 && isLeap);
    cout << ' ' << MONTHS[month] << endl;
    cout << " Sun Mon Tue Wed Thu Fri Sat" << endl;

    for( int day = 0; day < startDay; ++ day )
         cout << "    ";
    int lines = 1;
    for( int day = 1; day <= daysInMonth; ++ day )
    {
        cout << setw(4) << day;
        if( (day + startDay ) % 7  == 0 )
            if( day < daysInMonth )
                cout << endl, ++lines;
    }
    while( lines < 6 ) { cout << endl; ++lines; }
    cout << LINE;
}

bool isLeapYear( int year )
{
    bool isLeap = false;
    if( year % 4  == 0 )
    {
        isLeap = true;
        if( year % 100 == 0 )
        {
            if( year % 400 != 0 ) isLeap = false;
        }
    }
    return isLeap;
}

// returns an int in range: 0..6 (Zeller's Method) //
int getDayNum( int y, int m, int day )
{
    //if( m > 2 ) m -= 2; // Mar->1,Apr->2, ...,Jan->11,Feb->12 //
    //else --y, m += 10; // if Jan or Feb, then --y, m += 10   //
    //return (day + y + y/4 - y/100 + y/400 + 31*m/12) % 7;
    //return (day + y + (y>>2) - y/100 + y/400 + 31*m/12) % 7;
    const int table[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
    y -= m < 3;
    return (day + y + (y>>2) - y/100 + y/400 + table[m-1]) % 7;
}

void testCalendar( int month )
{
    cout << &LINE[1];
    for( int i = 0; i < 7; ++ i )
    {
        showCalendar( month, i ) ;
        cout << LINE;
        showCalendar( month, i, true ) ;
        cout << LINE;
    }
}


//////////////// some utilities used here  /////////////////
int takeInInt( const char* msg, int min, int max )
{
    int y;
    for( ; ; )
    {
        cout << msg << flush;
        if( cin >> y && cin.get() == '\n' && y >= min && y <= max )
            return y;
        // else ... if reach here ...
        cin.clear(); // clear any/all error flags ...
        cin.sync(); // 'flush' cin stream ...
        cout << "Input ERROR!  Valid range is " << min << ".." << max << '\n';
    }
}
bool more()
{
    cout << "\nMore (y/n) ? " << flush;
    char reply = cin.get();
    cin.sync();
    if( reply == 'n' || reply == 'N' ) return false;
    // ekse ...
    return true;
}
////////////////////////////////////////////////////////////
« Last Edit: December 15, 2014, 03:32:40 PM by David »

Offline David

  • Hero Member
  • *****
  • Posts: 647
    • View Profile
Re: C and C++ homework questions and answers ...
« Reply #3 on: December 15, 2014, 03:59:09 PM »
Now C ..


Code: [Select]
/* printCalendar.c.c. */

#include <stdio.h>

/*
isLeapYear determines whether or not the specified year is a leap year.
This function is accurate for all years from 1582 to the present.  By
4818 A.D., there may be a different method ... because we'll be off
by about a day by then.  Maybe leave off the leap year for years that
are divisible by 4000?  Anyway, for dates before the Gregorian calendar,
this will assume that the Gregorian calendar extends backwards before
its creation; (the Julian calendar simply added a leap day every four
years and thus, spring grew later on the calendar every century ...);

Matching up to calendars before 1582 is not the concern of this author.

... The Gregorian calendar was introduced in 1582,
by 4818, our current calendar will be a day off ...
*/

/*                           j  f  m  a  m  j  j  a  s  t  n  d */
const int DAYS_N_MONTH[] = {31,28,31,30,31,30,31,31,30,31,30,31};
const char* MONTHS[] =
{
    "January","February","March","April","May","June",
    "July","August","Septempber","Octber", "November","December"
} ;
const char* LINE = "\n ===========================\n";

/* returns number in range: 0..6 //////////////////////// */
int getDayNum( int year, int month, int day );

/*                     0..11      0..6           false..true */
void showCalendar( int month, int startDay, int isLeap );
int isLeapYear( int year );
void testCalendar( int month );
/* ////////////////////////////////////////////////////// */


/* ////////////// some utilities used here  ////////////// */
int takeInInt( const char* msg, int min, int max );
int more();
/* ////////////////////////////////////////////////////// */



int main()
{
    do
    {
        int year = takeInInt( "Year for calendar: ", 1582, 4818 ),
            month = 0;

        printf( &LINE[1] );

        for( ; month < 12; ++ month )
        {
            /* ///////////////////////////// 1..12    1..7 // */
            int dayOfWeek = getDayNum( year, month+1, 1 );
            int isLeap = isLeapYear( year );

            /* ////////// 0..11  0..6       false..true ///// */
            showCalendar( month, dayOfWeek, isLeap );
            if( month < 11 ) printf( LINE );
        }
    }
    while( more() ) ;

   return 0;
}



/* //////////////////// 0..11       0..6    false..true / */
void showCalendar( int month, int startDay, int isLeap )
{
    int daysInMonth = DAYS_N_MONTH[month] + (month == 1 && isLeap),
        day, lines;
    printf( " %s\n", MONTHS[month] );
    printf( " Sun Mon Tue Wed Thu Fri Sat\n" );

    for( day = 0; day < startDay; ++ day )
         printf( "    " );
    lines = 1;
    for( day = 1; day <= daysInMonth; ++ day )
    {
        printf( "%4d", day ) ;
        if( (day + startDay ) % 7  == 0 )
            if( day < daysInMonth )
                { putchar( '\n' ); ++ lines; }
    }
    while( lines < 6 ) { putchar( '\n' ); ++ lines; }
    printf( LINE );
}

int isLeapYear( int year )
{
    int isLeap = 0;
    if( year % 4  == 0 )
    {
        isLeap = 1;
        if( year % 100 == 0 )
        {
            if( year % 400 != 0 ) isLeap = 0;
        }
    }
    return isLeap;
}

/* returns an int in range: 0..6 (Zeller's Method) */
int getDayNum( int y, int m, int day )
{
    /* if( m > 2 ) m -= 2; */  /* Mar->1,Apr->2, ...,Jan->11,Feb->12 */
    /* else --y, m += 10; */  /* if Jan or Feb, then --y, m += 10   */
    /* return (day + y + y/4 - y/100 + y/400 + 31*m/12) % 7; */
    /* return (day + y + (y>>2) - y/100 + y/400 + 31*m/12) % 7; */
    const int table[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
    y -= m < 3;
    return (day + y + (y>>2) - y/100 + y/400 + table[m-1]) % 7;
}



/* ///////////// some utilities used here  ////////////// */
int takeInInt( const char* msg, int min, int max )
{
    int good, y;
    for( ; ; )
    {
        printf( msg ) ; fflush( stdout );
        good = scanf( "%d", &y );
        if( good == 1 )
        {
            if( getchar() == '\n' )
            {
                if( y >= min && y <= max )
                    return y;
            }
            else
                while( getchar() != '\n' ) ; /* 'flush' stdin ... */
        }
        else
            while( getchar() != '\n' ) ; /* 'flush' stdin ... */
               
        /* else ... if reach here ... */
        printf( "Input ERROR!  Valid range is %d..%d\n", min, max );
    }
}
int more()
{
    char reply;
    printf( "\nMore (y/n) ? " ); fflush( stdout );
    reply = getchar();
    if( reply != '\n' ) while( getchar() != '\n' ) ; /* flush stdin ... */
    if( reply == 'n' || reply == 'N' ) return 0;
    /* else ... */
    return 1;
}
/* ////////////////////////////////////////////////////// */