Wednesday, 28 August 2013

Find The Mean & Standard Deviation of a Group of Numbers.

My girlfriend is a dietitian, she is taking another supplementary course or something. I don't know what the course is, I'm guessing. She is in another city and almost done with the course and only has to submit her papers for approval.
Yesterday she sent me some data she had collected. Her professor had asked her to:
1. Find The Mean & Standard Deviation of some of the data she had collected.
2. Type them out in 2 decimal places. (She sent me this "3.2821 .45588 how can I write these in 2 decimal places?")
3. Put the Plus-Minus sign before them.

She wanted to know how to do those.

As you can see from the fact that number #2 confuses her, she's almost as bad at math as I am. It's only because I was learning C that I knew 2 decimal places means ignore the numbers after 2 digits. so it would be 3.28 and .45 for 3.2821 .45588 respectively.

Number 3 is easy enough, the Plus-Minus sign can be found in the character map on any Windows system (Start>All Programs>Accessories>System Tools>Character Map on Windows 7), also, the character code for that character is 241.
So if she was typing in the character in MS Word, she would have to hold down the Alt key, type in 241 on the Num-Pad (doesn't have to be Num-Pad for Laptops), and let go of the Alt key and find ± (Incidentally, you can use that to type in any of the ASCII characters).

I was a bit confused on #1. I didn't know what Mean & Standard Deviation meant. She led me to a page:
http://www.mathsisfun.com/data/standard-deviation-formulas.html

She also told me she had a lot of data to find the Mean and SD for. So I wrote a little program that will solve it for her if she inputs the numbers.

As usual, just copy paste into Code::Blocks and press F9 to run the program.

Sample:


Code:

#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <math.h>

int get_key(void);

main()
{
    int loop,key,x,limit;
    float input[50],TotalInput1=0,TotalInput2=0,mean1,mean2,diff1[10],diff2[10],variance,median;
    char in[50][50];

    system("mode 158,77");

    printf("Enter your values (upto 50). Press Enter after each. Press F1 to calculate. Esc to exit\n");

    for(loop=0;loop<50;loop++)
    {
        x=0;
        while(x<10)
        {
            key=get_key();
            if((key<58 && key>47) || key==46 && x<10)
            {
                printf("%c",key);
                in[loop][x]=key;
                x++;
            }
            else if(key==13 && x>0)
            {
                in[loop][x]='\0';
                printf("\n");
                break;
            }
            else if(key==315) //f1
            {
                in[loop][x]='\0';
                system("cls");
                for(x=0;x<loop;x++)
                {
                    input[x]=atof(in[x]);
                    printf("%f\n",input[x]);
                }
                limit=loop;
                for(loop=0;loop<limit;loop++)
                {
                    TotalInput1=TotalInput1+input[loop];
                }
                mean1=TotalInput1/limit;
                for(loop=0;loop<limit;loop++)
                {
                    diff1[loop]=(input[loop]-mean1)*(input[loop]-mean1);
                }
                for(loop=0;loop<limit;loop++)
                {
                    TotalInput2=TotalInput2+diff1[loop];
                }
                mean2=TotalInput2/limit;
                for(loop=0;loop<limit;loop++)
                {
                    diff2[loop]=(diff1[loop]-mean2)*(diff1[loop]-mean2);
                }
                variance=(float)1/limit*TotalInput2;

                /*now find the sq root of variance. That is the mean.*/
                median=sqrt(variance);
                printf("You entered %i digits.\nTheir Mean(%c) =%f\nStandard Deviation(%c)=%f\n",limit,230,mean1,229,median);
                getch();
                system("cls");
                printf("Enter your values (upto 50). Press Enter after each. Press F1 to calculate. Esc to exit\n");
                break;
            }
            else if(key==8 && x>0)
            {
                printf("\b \b");
                x--;
            }
            else if(key==27)
            {
                system("mode 80,25");
                return 0;
            }
        }
    }
}

int get_key(void)
{
    int c = getch();
    switch (c)
    {
      case 0:   return getch()+256;
      case 224: return getch()+512;
    }
    return c;
}


Monday, 26 August 2013

Let Us C Chapter 1 Exercise I-b

Q. The distance between two cities (in km.) is input through the keyboard. Write a program to convert and print this distance in meters, feet, inches and centimeters.

I'm doing these exercises so that I have something to do with C. I didn't use doubles or %.2f  because they haven't been taught in chapter 1.

Code:

#include <stdio.h>

main()
{
    float Distance,Meters,Feet,Inches,Centimeters;

    printf("Enter the distance in Kilometers: ");
    scanf("%f",&Distance);

    Meters=Distance*1000; //1 km=1000 meters
    Feet=Distance*3280.84; //1 km= 3280.84 Feet
    Inches=Distance*39370.1; // 1 km= 39370.1 Inches
    Centimeters=Distance*100000; //1 km= 100000 Centimeters

    printf("%f km/s in:\n\nMeters= \t%f\nFeet= \t\t%f\nInches= \t%f\nCentimeters= \t%f\n",Distance,Meters,Feet,Inches,Centimeters);
    return 0;
}

Let Us C Chapter 1 Exercise I-a

Q. Ramesh's basic salary is input through the keyboard. His dearness allowance is 40% of basic salary, and house rent allowance is 20% of basic salary. Write a program to calculate his gross salary.

I'm doing these exercises so that I have something to do with C. I didn't use doubles or %.2f  because they haven't been taught in chapter 1.

Code:

#include <stdio.h>

main()
{
    float BasicSalary,DAllowance,HRAllowance,temp;

    printf("Enter Ramesh's Basic Salary: ");
    scanf("%f",&BasicSalary);

    /**Calculate 1% of salary*/
    temp=BasicSalary/100;

    /**Assign Dearness Allowance (40%) and House Rent Allowance (20%)**/
    DAllowance=temp*40;
    HRAllowance=temp*20;

    /**display**/
    printf("Ramesh's Dearness Allowance is: %f\n",DAllowance);
    printf("Ramesh's House Rent Allowance is: %f\n\n",HRAllowance);

    printf("Ramesh's Total Salary is: %f\n",BasicSalary+DAllowance+HRAllowance);

    return 0;
}

Following are simplifications of this program:

#include <stdio.h>

main()
{
    float BasicSalary,GrossSalary;

    printf("Enter Ramesh's Basic Salary: ");
    scanf("%f",&BasicSalary);

    GrossSalary=BasicSalary+(BasicSalary*.6);

    printf("Ramesh's Gross Salary is= %f",GrossSalary);
}


OR

#include <stdio.h>

main()
{
    float BasicSalary,GrossSalary;

    printf("Enter Ramesh's Basic Salary: ");
    scanf("%f",&BasicSalary);

    GrossSalary=BasicSalary*1.6;

    printf("Ramesh's Gross Salary is= %f",GrossSalary);

}


Sunday, 25 August 2013

A Plane Shooting. ASCII Game Simulation.

2 Posts down, the asterisk pyramid thing got me thinking about space war games on the NES and ATARI systems I played as a kid.

This program draws a plane (many would disagree that it is a plane). The Spacebar key will "shoot", Left-Right keys will move the plane. Escape will end the program.

Since there are no nifty sounds that can be created, I had to use the Beep() function, which I recently picked up. Making the sound slows the program down. If you want, comment out the "Beep(100000-l,25);" line and un-comment the loop before it. The "bomb" will move faster. You can control its speed by increasing or decreasing the 5000000 in there.

The screen will be re-sized in the beginning, if it does not fit your screen, right click on the head of the program screen (The DOS screen), choose properties, go to the font tab. You can re-size your screen (which does not affect the display) there. 8X8 with Raster Font will work on most PCs and Laptops.

As with any program that has gotoxy; this program also needs myconstdwin.h be added,

SAMPLE:




Code:
#include <myconstdwin.h>

void print_lame_plane(int x,int y);
void erase_lame_plane(int x,int y);

void shoot_missile(int x,int y);

void main()
{
    system("mode 158,77");
    int key,x=80,y=73;

    print_lame_plane(x,y);
    while(1)
    {
        key=get_key();
        if(key==587 && x>2) //left
        {
            erase_lame_plane(x,y);
            x--;
            print_lame_plane(x,y);
        }
        else if(key==589 && x<154) //left
        {
            erase_lame_plane(x,y);
            x++;
            print_lame_plane(x,y);
        }
        else if(key==32)
        {
            shoot_missile(x,y);
        }
        else if(key==27)
        {
            system("mode 80,25");
            break;
        }
    }
    return 0;
}

void shoot_missile(int x,int y)
{
    printf("\a");
    int loop,l=1;
    for(;y>1;y--)
    {
        //for(loop=0;loop<5000000;loop++);
        Beep(100000-l,25);
        printf("");
        gotoxy(x,y-1);
        printf("%c",153);
        gotoxy(x,y);
        if(y!=73)
        {
            printf("  ");
        }
        l+=100;
        if(y==2)
        {
            gotoxy(x,y-1);
            printf("  ");
            gotoxy(x,y-1);
            printf("BOOM!");
        }
    }
}

void print_lame_plane(int x,int y)
{
    gotoxy(x,y);
    printf("%c",219);
    gotoxy(x-2,y+1);
    printf("%c%c%c%c%c",223,223,219,223,223);
    gotoxy(x,y+2);
    printf("%c",219);
    gotoxy(x-1,y+3);
    printf("%c%c%c",223,219,223);
}

void erase_lame_plane(int x,int y)
{
    gotoxy(x,y);
    printf("  ");
    gotoxy(x-2,y+1);
    printf("      ");
    gotoxy(x,y+2);
    printf("  ");
    gotoxy(x-1,y+3);
    printf("     ");
}

int get_key()
{
    int c = getch();
    switch (c)
    {
      case 0:   return getch()+256;
      case 224: return getch()+512;
    }
    return c;
}

Saturday, 24 August 2013

Keyboard Navigating DOS Shell Style

Sometimes you might want to break out of the old "Enter number to change...", "Enter item to delete...".

This program demonstrates creation of a menu that can be navigated with the arrow keys, somewhat similar to THIS.
You can delete an item if user presses "Delete" (595), edit it if user hits "Enter" (13). No, no it doesn't work in this program, just saying :P

This program requires that you have the myconstdwin.h header file.

User enters three names (Which would have been four, but Kenny is poor), and then any one may be highlighted using the arrow keys.

SAMPLE:


CODE:

#include <myconstdwin.h>

void hl(int y);
void dl(int y);

char names[3][20];

void main()
{
    int loop,y,key;
    for(loop=0;loop<3;loop++)
    {
        printf("Enter name %i: ",loop+1);
        gets(names[loop]);
        printf("%s\n",names[loop]);
    }

    system("cls");
    gotoxy(0,5);
    printf("press UP or Down to navigate, or Esc to exit\n");

    gotoxy(0,0);
    for(loop=0;loop<3;loop++)
    {
        printf("Name #%i: %s\n",loop+1,names[loop]);
    }

    y=1;
    for(;;)
    {
        hl(y);
        key=get_key();
        if(key==592) //down
        {
            if(y==1 || y==2)
            {
                dl(y);
                y++;
                hl(y);
            }
            else
            {
                dl(y);
                y=1;
                hl(y);
            }
        }
        else if(key==584) //up
        {
            if(y==2 || y==3)
            {
                dl(y);
                y--;
                hl(y);
            }
            else
            {
                dl(y);
                y=3;
                hl(y);
            }
        }
        else if(key==27) //ESC
        {
            system("cls");
            break;
        }
    }
}

void hl(int y)
{
    gotoxy(0,y-1);
    SetColorAndBackground(15,9);
    printf("Name #%i: %s\n",y,names[y-1]);
    SetColorAndBackground(8,0);
}
void dl(int y)
{
    gotoxy(0,y-1);
    printf("                                   ");
    gotoxy(0,y-1);
    printf("Name #%i: %s\n",y,names[y-1]);
}

int get_key()
{
    int c = getch();
    switch (c)
    {
      case 0:   return getch()+256;
      case 224: return getch()+512;
    }
    return c;
}

Draw An Asterisk (*) Half Pyramid

I have seen this problem around the internet, and maybe in hard copy somewhere. I decided to write my version of it. The idea is to draw a half pyramid of asterisks (I had to google that to find how it's spelled, always thought it was ASTERIX, like the comic book character) depending on the number user enters.

User must enter a number, greater than 0, up to 21, and it will draw the half pyramid. I have tried to explain the logic in the comments as best as I can.

The program isn't as long as it looks, the comments make it longer.

Sample:




Code:

#include <stdio.h>

void main()
{
    int input,counter,loop;

    printf("Enter a number (Greater than 0 up to 21): ");
    scanf("%i",&input);
    counter=input; /*Whatever user enters is also saved in "counter"*/

    if(input<=21 && input >0) /*make sure its a valid input*/
    {
        /*let the lines be drawn until "input", which is used to count the
        number of spaces to be drawn is not 0*/
        while(input>0)
        {
            /*Draw spaces, the first line of spaces is equal to the
            number the user input*/
            for(loop=0;loop<input;loop++)
            {
                printf(" ");
            }
            /*then draw the asterisks. Since at the first line, when we want only one
             "*", counter-input will be zero since counter=input, we specify the
             condition number to be "counter+1 minus input" which is 1, so at least one "*"
             is drawn*/
            for(loop=0;loop<counter+1-input;loop++)
            {
               printf("*");
            }
            /*go to new line after every line of spaces and asterisk/s are done*/
            printf("\n");
            /*reduce the "input" (number of spaces) by 1.*/
            input--;
        }

    }
    else
    {
        printf("Invalid Input");
    }
}

Incidentally, when I was writing this code, one of my compiles in the middle produced this. Reminded me of the background in old space war kind of games. The output varies somewhat depending on the number you input:

#include <stdio.h>

void main()
{
    int input,loop;

    printf("Enter a number (21 or less, greater than 0): ");
    scanf("%i",&input);

    if(input<=21 && input >0)
    {
        while(input>0)
        {
            for(loop=0;loop<input-1;loop++)
            {
                printf(" ");
            }
            printf("*");
        }
    }
}

Thursday, 15 August 2013

Find Windows Username

Sometimes we might need to find the Windows Username during program execution. I personally needed this for saving files to the desktop. In Windows 7, the path to the desktop is C:\users\SystemSpecificUsername\desktop.
You might need it for a myriad of other reasons. I found this in a forum where I think someone was looking for a solution to this, he found it himself then posted it for all to see (Here is the original thread). Anyway, hope you find a use for it.

This function accepts a char sent to it and writes the current username into it.

This program will print the username of the current user on a Windows system.

#include <stdio.h>
#include <windows.h>

void username(char *u);
#define INFO_BUFFER_SIZE 32767

void main()
{
    char name[20];

    username(name);
    printf("%s",name);
}

void username(char *u) //this function rewrites a char with the username of the windows user.
{
    char *c;
  TCHAR  infoBuf[INFO_BUFFER_SIZE];
  DWORD  bufCharCount = INFO_BUFFER_SIZE;

  bufCharCount = INFO_BUFFER_SIZE;
  GetUserName(infoBuf,&bufCharCount);
      c=&infoBuf[0];
      while(*c!='\0')
        {
            *u=*c;
            u++;
            c++;
        }
        *u='\0';
}


Tuesday, 13 August 2013

Pointers As I Understand Them

Pointers can be hard to work with. I still have a lot to learn, but here are somethings that have let me "wing it" for the moment. I'll try to explain what I know about pointers as simply as possible. I figure you'll need to use it for a while before you become familiar with them, if you aren't already.

A pointer stores an ADDRESS of another variable. So it points to that other variable.

Lets say your name is 'Zed'. You want to be a pointer. You must declare this by saying *Zed. From now everybody knows, and thinks of you as a pointer (Address Holder).

It's like if you held a piece of paper with a friend's address...you are the pointer...someone who doesn't know where your friend lived would come to you, you would read out the address and they would go there. Your friend is the value, you are the pointer.

*Zed' would indicate "The person whose address is with  Zed" . This means your friend. The program would find your friend in this case.
'Zed' indicates you. The program would find you in this case.


A pointer is declared like this: int *pointer_name

Whenever I see '*test' in a program I say to myself "The value at the address stored in 'test'".
When I see 'test' in that same program, if I know test has been declared as a pointer, I think "The address stored in 'test'"
If I see "&test" that would be the "address of the pointer 'test'", but it's unlikely I'll come across that unless there's a **test1 (Pointer to a pointer) involved, but that's another can of worms for another day.

From what I understand, a memory location has three characteristics:
1. The Address (Always Exists)
2. The Name (When we declare it, we give it a name)
3. The Value (Is a random number unless we assign it)

Example:

#include <stdio.h>

main()
{
    int test; //declare

    test=1; //assign
    printf("%i",test);
}

The program:
1. Declares an int naming it 'test'
2. Test is given a value of 1.
3. The value is printed.

For the duration of the program, the variable 'test' had three characteristics:
1. An Address
2. A name ('Test')
3. A value. (Random number that happened to be sitting in the memory location until we said test=1, from there on in, 'test' held the integer 1).

Lets take a look:

#include <stdio.h>

main()
{
    int test;

    printf("%i is the random number in 'test' before it is assigned\n",test);

    test=1;
    printf("%i is now the number we assigned to it",test);
}

We can view the address of a variable by adding '&' before it.

#include <stdio.h>

main()
{
    int test;

    printf("%i is the address of the variable 'test'\n",&test);
}

Notice in the printf statement, we didn't say 'test', rather we said '&test', so we got the address of the variable test.

We can store this address in a pointer:

#include <stdio.h>

main()
{
    int int1,*ptr;

    int1=5000;

    ptr=&int1; //give THE ADDRESS of int1 to the pointer. This MUST be done before the pointer is used

/**Here the program looks at the variable stored in 'ptr', the program knows that this is an address because
of the *, so it goes to that address, and displays the value there**/
    printf("Value at address ptr (*ptr) %i\n\n",*ptr);

/**Here the program looks at the variable stored in 'ptr' and shows it to us**/
    printf("Value stored in ptr (This will be the same as the address of int1) (ptr) %i\n\n",ptr);

/**The program goes to 'int1', gets the ADDRESS of the location and displays it. This location is an area in
your computers memory**/
    printf("Address of int1 (&int1) %i\n\n",&int1);

/**Finally, the program goes to 'int1' pulls out the value there, and prints it**/
    printf("Value stored in int1 (int1) %i\n\n",int1);

/**change the value at address ptr from 5000 to 3000. Here the program goes to
the address stored in 'ptr' (which is the location of 'int1') and puts a 3000 into it.
We can say the program puts 3000 into 'int1'. This is the same as saying int1=3000, except
here we send the program to ptr which has the address of int1, and then it comes to that address
and puts the value there.**/
    *ptr=3000;

    printf("Value at address ptr (*ptr) after *ptr is re-assigned %i\n\n",*ptr);
    printf("Value stored in int1 (int1) after *ptr is re-assigned %i\n\n",int1);
}



So simply remember:
A Pointer MUST be initialized (IE Initially, before it is used, It must be assigned an address otherwise your program will fail).

Whenever you see '*test' in a program say to yourself "The value at the address stored in 'test'".
When you see 'test' in that same program, and if you know test has been declared as a pointer, think "The address stored in 'test'"
If you see "&test" ,if you know test has been declared as a pointer, that would be the "address of the pointer 'test'".


________________________________________________________
EDIT:
WHY USE POINTERS?
This question bothered me for a long while a few months back before I used them. Why use pointers at all? Global variables (Variables declared outside any function) might suffice.
Since I'm still somewhat new to C, I use a lot of global variables in my big program (Yes, I only have one), but sometimes, using pointers seems to be the only way to keep things coherent and sensible.

I cannot show you a demo program to tell you how useful they are, it would still not convince an unbeliever :D, but trust me, you'll use them eventually....and thank God for them too. In fact, I don't think a person can retain much of this unless s/he is writing a program and suddenly finds him/herself unable to do something, then they see they can do it with pointers.
Interest can only be generated in something if it is needed.

Anyhow, here is a program that uses a couple of pointers sent to a function, if you really want to check it out:
http://zhukovc.blogspot.com/2013/08/draw-calendar-for-user-defined-month.html

I never learnt about pointers until I saw it can change values across functions, and that was exactly what I needed for a program I was writing. Then it seemed a little more interesting...and even easier...

Break Down of myconstdwin.h : Gotoxy, Change text & Background Colour, Move Dos Window.

The file myconstdwin.h, and how to use it can be found here.

It allows you to do three things:
1. Move the cursor to any part of the screen (gotoxy(x,y))
2. Change the text/background colour of the DOS screen (SetColorAndBackground(text,background))
3. Move the DOS window (movewin(Horizontal,Vertical))

1. Move Cursor: When you want to send the cursor to a certain place, use this function. X is for column (horizontal space) and y is for row (vertical space).

#include <myconstdwin.h>

main()
{
    gotoxy(5,15);
    printf("Press any key....");
    getch();

    //go back and erase what's printed
    gotoxy(5,15);
    printf("                    ");

    //print final message at same spot
    gotoxy(5,15);
    printf("Thanks!");
    getch();
}

2. Change the Text Or Background Colour: When you tire of the old Grey and Black, you can specify what colour you want the text or background to be. For a short program that tells you what number is what colour click HERE.

#include <myconstdwin.h>

main()
{
    SetColorAndBackground(12,0); //red
    gotoxy(5,15);
    printf("Press any key....");
    getch();

    //go back and erase what's printed
    gotoxy(5,15);
    printf("                    ");

    //print final message at same spot
    gotoxy(5,15);
    printf("Thanks!");
    getch();
    SetColorAndBackground(8,0); //back to grey
}

You can set the entire background colour to what you want by setting it once and "cls"ing the screen...like so

#include <myconstdwin.h>

main()
{
    SetColorAndBackground(15,2); //15=Bright white text, 2=dull green background
    system("cls");
    printf("Background is set....");
    getch();
}

Sample output:



You can also colour parts of the screen if you use this with the gotoxy function. Here is a sample:



#include <myconstdwin.h>

main()
{
    int loop;

    system("mode 88,30");
    SetColorAndBackground(8,12);
    for(loop=0;loop<5;loop++)
    {
        gotoxy(5,15+loop);
        printf("          ");
    }

    SetColorAndBackground(8,9);
    for(loop=0;loop<5;loop++)
    {
        gotoxy(15,15+loop);
        printf("          ");
    }

    SetColorAndBackground(8,10);
    for(loop=0;loop<5;loop++)
    {
        gotoxy(5,20+loop);
        printf("          ");
    }

    SetColorAndBackground(8,11);
    for(loop=0;loop<5;loop++)
    {
        gotoxy(15,20+loop);
        printf("          ");
    }
    getch();
    SetColorAndBackground(8,0);
}

3. Move the window: You can specify x and y to where you want the window to be. This is in case you use the DOS "Mode x,y" command to resize the screen and want to DOS window to appear at the top left corner of the screen (or anywhere else for that matter).
The following program will slowly move the DOS window across you screen, first horizontally, then vertically...

#include <myconstdwin.h>

main()
{
    int x,loop;

    system("mode 88,30"); //don't worry, i put this here as a demo to re-size the screen, remove if you want
    printf("Changing the value of x moves the window thus\n");
    for(loop=0;loop<300;loop++)
    {
        movewin(loop,1);
        //provide a slight pause
        for(x=0;x<5000000;x++);
    }
    printf("Press any key....\n");
    getch();

    printf("Changing the value of y moves the window thus\n");
    for(loop=0;loop<300;loop++)
    {
        //the window will move back to 1 because it's set back to 1 now.
        movewin(1,loop);
        //provide a slight pause
        for(x=0;x<5000000;x++);
    }
}

//You do not need to include the following lines if you are using C::B 12.11
void movewin(int x, int y)
{
    HWND hWnd=GetConsoleWindowNT();
    MoveWindow(hWnd,x,y,800,400,TRUE);
}

Notice that I had to rewrite these in the program even if it is in the header file:

void movewin(int x, int y)
{
    HWND hWnd=GetConsoleWindowNT();
    MoveWindow(hWnd,x,y,800,400,TRUE);
}

EDIT:This has been fixed with C::B 12.11

If I don't, it gives me an error sometimes. I don't know why. I'll update it here once I figure it out.

Old Compiler Or New?

This program tells you what compiler you are using. If it is a new compiler, __STDC__ (note there are 2 underscores before and after STDC making a total of 4 underscores) is set to 1.
K&R C was the first version of C before ANSI C came along. The old version is supposedly dead, so we probably will never encounter in in our noob C travels, but this program is one of those things that are "Good To Know"...

#include <stdio.h>

main()
{
    if(__STDC__==1)
    {
        printf("ANSI C);
    }

    else
    printf("K&R");
}

Saturday, 10 August 2013

The Database Completed

When I first started writing this blog, I mentioned that my target was to write my friend a Database program to manage his shop.

On June 1, 2013, based on a program to draw lines, I fiddled around to produce a far cry from a Word Processor. I posted it here in this blog (Click Here To Check It Out).
That night I pulled an all-nighter and ended up with another program (Click Here To Check Out The Improvement).

Since then I have been working on it from time to time, finally today, I think I finished it and my friend can use it. I still have something to add to it, but it is pretty much done. Here is what the program does:

Password protected with 1 Master Administrator and 99 other addable users, either Admins or Users.

1. It has a help menu that explains where user can do what.

2. Daily sales entry, amount sold is subtracted from Inventory file. As user enters item ID or name, when the matches are 10 or less, the results are displayed dynamically, decreasing as user enters more characters. User can press enter when the result is 1 and the item is added to shopping cart.
User can assign discounts as an amount by entering an amount, or by percentages by adding % at the end of the digits entered. The discount may be for a particular item or a bulk discount on the total.

3. User can search sales for one particular item. The user specifies the "From" and "To" date, results may be saved to a document that is saved on the desktop. Details include the name of the item, item ID, sale Date and Time, username of seller, selling price, (and if user is admin profit made on the sale is also shown).

4. User can enter one particular day and save the sales data to a doc file on the desktop.

5. I'm particularly pleased about this one. User can specify a date. It is taken as the start date for a week sales graph displayed. User can manually enter the amount for this or the Year graph.

6. The inventory menu allows user to input the name of items in stock, amount available, sale price, buying price etc. Sl. number is automatically assigned and a unique item ID is created for that item.
User can delete items by highlighting a particular item and pressing the delete key.
User can also enter a "Warn At" amount which will cause the program to display a warning of low stock when the amount reaches the "Warn At" amount.

7. User accounts allow users to change their passwords. Only Master Admin can change usernames (to prevent someone from messing up inventory or sales by changing name and changing back)

All the data files are encrypted.

What I want to add is an "Orders" option. My friend accepts customized orders for marriages, functions, he will print leaflets (with a traditional twist), make you bookmarks etc.
Although I haven't thought this through yet, I'm thinking it will hold the customers name, phone number and address, order date, delivery date, number of items and a decent length of item information (a discription so to speak...like 500 chars).

I do feel I have come some way since I entered my first programs. I will improve this program since I know there are bound to be some bugs I haven't noticed. Since this was a work in progress as I learnt more and more, I came across many instances of "I wrote this wrong back then" but having to stick with it because changing it would mean a lot more work. But bad code or no, I got it working, and it's not like I'm going to submit it to a professor or anything. I'm not even posting it here, so the legions of critics we meet everyday online, hiding behind texts and texts of keyboard bravado wont get a crack at it. :D

And my friend is getting an application customized to his needs for free, I know he will not complain.

I'm still far from done with C programming, I am very interested in graphics, I'll look into that pretty soon.

I would share the code for AIM (that's what I am calling it....Accounts & Inventory Management) but it is too long, 10382 lines to be precise.

Friday, 9 August 2013

Why Programming Is Difficult Initially

Since I started this blog, the stats tell me that I have an all time view of 1300+. This is not something I anticipated, but I guess it is nice to have people viewing your blog.

I have been scratching at Windows Programming for a while now and I have to admit it is a lot more difficult than I thought.

But drawing a comparison between C and Windows, I think C is a bit more difficult to learn.
The problem seems to be in the way the lessons are presented.

I do not understand one word of what is explained in tutorials. The technical jargon thrown at me is overwhelming. This may be simple stuff for people who have a teacher explaining things to them, classmates who can help, people who have mastered other languages and "Handle to the programs executable" is second nature to them and when they read it they go "Ah! I see".

The reason I could even learn a bit of C is because I started with C For Dummies (Vol 1), and Dan Gookin is one heck of an author. He never forgot for the entirety of the book that I would not not understand if he said "It will return NULL." and left it there. But every time he presented a new term, he takes some time to explain it in simple terms. His site has a regular supply of short and interesting programs (http://www.c-for-dummies.com/cfordummies/).

Even when we have learnt a new technical word, it takes some time for it to become second nature. Like right now, if someone told me about a program "No, that is not the entire program, it is only the function", I probably would know what he meant, but back when I had just learnt it, if I heard the same lines, it would take me some thinking to figure out what he meant.

So I think, the reason people think programming is hard is only because the lessons presented are put in words too difficult for laymen to understand. Heck, if I can make the computer say "Hello World" anybody can.

Draw A Calendar For User Defined Month

This is an extension of THIS program. This time, instead of just telling you the number of days and the first day in a given month, it will also draw a small calendar.

This requires that you include the header myconstdwin.h (Click on the name to find out how to create and use the header).

Please note that among the integers sent to the function
void draw_calendar(int year,char month[15],int start_day,int num_of_days,int x,int y); 
it accepts 2 integers x and y. They are used for the gotoxy co-ordinates. Meaning you can specify where on the output screen(the black DOS screen) the calendar will be drawn. You can send it different months and different co-ordinates to draw the calender for, say, an entire year too.




Here is the code. It's pretty long especially because of the grid :

#include <strings.h>
#include <myconstdwin.h>

void find_days(int month,int year,int *dates,int *day);
void draw_calendar(int year,char month[15],int start_day,int num_of_days,int x,int y);

main()
{
    int month,year,num_of_days,first_day;
    char day[10],month_char[15];

    printf("Enter Month (1 for Jan, 2 for Feb etc.):");
    scanf("%i",&month);
    printf("Enter Year:");
    scanf("%i",&year);
    find_days(month,year,&num_of_days,&first_day);

    switch(first_day)
    {
    case 1:
        strcpy(day,"Sunday");
        break;
    case 2:
        strcpy(day,"Monday");
        break;
    case 3:
        strcpy(day,"Tuesday");
        break;
    case 4:
        strcpy(day,"Wednesday");
        break;
    case 5:
        strcpy(day,"Thursday");
        break;
    case 6:
        strcpy(day,"Friday");
        break;
    case 7:
        strcpy(day,"Saturday");
        break;
    }

    switch(month)
    {
    case 1:
        strcpy(month_char,"January");
        break;
    case 2:
        strcpy(month_char,"February");
        break;
    case 3:
        strcpy(month_char,"March");
        break;
    case 4:
        strcpy(month_char,"April");
        break;
    case 5:
        strcpy(month_char,"May");
        break;
    case 6:
        strcpy(month_char,"June");
        break;
    case 7:
        strcpy(month_char,"July");
        break;
    case 8:
        strcpy(month_char,"August");
        break;
    case 9:
        strcpy(month_char,"September");
        break;
    case 10:
        strcpy(month_char,"October");
        break;
    case 11:
        strcpy(month_char,"November");
        break;
    case 12:
        strcpy(month_char,"December");
        break;
    }
    printf("It has %i days and the first day is a %s (%i)",num_of_days,day,first_day);
    draw_calendar(year,month_char,first_day,num_of_days,2,3);
    getch();
    return 0;
}

void find_days(int month,int year,int *dates,int *day)
{
    int leap_year,loop;
    int loop_day=2,loop_month=1,loop_year=1900,day_limit=31; //day is at 2 because it will start at monday etc.

    while(1)
    {
        /**First, if the month is 2 (february) find if the year is a leap year*/
        if((loop_year%4==0 && loop_year%100!=0) || (loop_year%400==0))
        {
            leap_year=1;
        }
        else
        {
            leap_year=0;
        }

        /**set up the months, with dates going up**/
        if(loop_month==1 || loop_month==3 || loop_month==5 || loop_month==7 || loop_month==8 || loop_month==10 || loop_month==12)
        {
            if(loop_month==month && loop_year==year)
            {
                *dates=31;
                *day=loop_day;
                break;
            }
            for(loop=0;loop<31;loop++)
            {
                loop_day++;
                if(loop_day==8)
                {
                    loop_day=1; //sunday
                }
            }
            loop_month++;
        }
        else if(loop_month==4 || loop_month==6 || loop_month==9 || loop_month==11)
        {
            if(loop_month==month && loop_year==year)
            {
                *dates=30;
                *day=loop_day;
                break;
            }
            for(loop=0;loop<30;loop++)
            {
                loop_day++;
                if(loop_day==8)
                {
                    loop_day=1; //sunday
                }
            }
            loop_month++;
        }
        else if(loop_month==2)
        {
            if(loop_month==month && loop_year==year)
            {
                if(leap_year==1)
                {
                    *dates=29;
                }
                else
                {
                    *dates=28;
                }
                *day=loop_day;
                break;
            }
            for(loop=0;loop<28+leap_year;loop++)
            {
                loop_day++;
                if(loop_day==8)
                {
                    loop_day=1; //sunday
                }
            }
            loop_month++;
        }
        if(loop_month==13)
        {
            loop_year++;
            loop_month=1;
        }
    }
}

void draw_calendar(int year,char month[15],int start_day,int num_of_days,int x,int y)
{
    int loop,a,b,c;
    char day[7][10]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};

/**First Line**/
    gotoxy(x,y);
    printf("%c",218);
    for(loop=0;loop<27;loop++)
    {
        printf("%c",196);
    }
    printf("%c",191);

/**Second Line**/
    gotoxy(x,y+1);
    printf("%c",179);
    printf("%s, %i",month,year);
    gotoxy(x+28,y+1);
    printf("%c",179);

/**3rd Line**/
    gotoxy(x,y+2);
    printf("%c",195);
    for(loop=0;loop<7;loop++)
    {
        printf("%c%c%c%c",196,196,196,194);
    }
    printf("\b \b");
    printf("%c",180);

/**4Th line**/
    gotoxy(x,y+3);
    printf("%c",179);
    for(loop=0;loop<7;loop++)
    {
        printf("%s%c",day[loop],179);
    }
    printf("\b \b");
    printf("%c",179);

/**5th Line**/
    gotoxy(x,y+4);
    printf("%c",195);
    for(loop=0;loop<7;loop++)
    {
        printf("%c%c%c%c",196,196,196,197);
    }
    printf("\b \b");
    printf("%c",180);

/**6th line. If first day is 1, it would be x+2, 2 would be x+6 etc.**/
    for(loop=0;loop<=28;loop+=4)
    {
        gotoxy(x+loop,y+5);
        printf("%c",179);
    }

/**7th line**/
    for(loop=0;loop<=28;loop+=4)
    {
        gotoxy(x+loop,y+6);
        printf("%c",179);
    }

/**8th Line**/
    gotoxy(x,y+7);
    printf("%c",195);
    for(loop=0;loop<7;loop++)
    {
        printf("%c%c%c%c",196,196,196,197);
    }
    printf("\b \b");
    printf("%c",180);

/**9th line. If first day is 1, it would be x+2, 2 would be x+6 etc.**/
    for(loop=0;loop<=28;loop+=4)
    {
        gotoxy(x+loop,y+8);
        printf("%c",179);
    }

/**10th line**/
    for(loop=0;loop<=28;loop+=4)
    {
        gotoxy(x+loop,y+9);
        printf("%c",179);
    }

/**11th Line**/
    gotoxy(x,y+10);
    printf("%c",195);
    for(loop=0;loop<7;loop++)
    {
        printf("%c%c%c%c",196,196,196,197);
    }
    printf("\b \b");
    printf("%c",180);

/**12th line. If first day is 1, it would be x+2, 2 would be x+6 etc.**/
    for(loop=0;loop<=28;loop+=4)
    {
        gotoxy(x+loop,y+11);
        printf("%c",179);
    }

/**13th line**/
    for(loop=0;loop<=28;loop+=4)
    {
        gotoxy(x+loop,y+12);
        printf("%c",179);
    }

/**14th Line**/
    gotoxy(x,y+13);
    printf("%c",195);
    for(loop=0;loop<7;loop++)
    {
        printf("%c%c%c%c",196,196,196,197);
    }
    printf("\b \b");
    printf("%c",180);
/**15th line. If first day is 1, it would be x+2, 2 would be x+6 etc.**/
    for(loop=0;loop<=28;loop+=4)
    {
        gotoxy(x+loop,y+14);
        printf("%c",179);
    }

/**16th line**/
    for(loop=0;loop<=28;loop+=4)
    {
        gotoxy(x+loop,y+15);
        printf("%c",179);
    }

/**17th Line**/
    gotoxy(x,y+16);
    printf("%c",195);
    for(loop=0;loop<7;loop++)
    {
        printf("%c%c%c%c",196,196,196,197);
    }
    printf("\b \b");
    printf("%c",180);
/**18th line. If first day is 1, it would be x+2, 2 would be x+6 etc.**/
    for(loop=0;loop<=28;loop+=4)
    {
        gotoxy(x+loop,y+17);
        printf("%c",179);
    }

/**19th line**/
    for(loop=0;loop<=28;loop+=4)
    {
        gotoxy(x+loop,y+18);
        printf("%c",179);
    }

/**20th Line**/
    gotoxy(x,y+19);
    printf("%c",192);
    for(loop=0;loop<7;loop++)
    {
        printf("%c%c%c%c",196,196,196,193);
    }
    printf("\b \b");
    printf("%c",217);

/**The lines for the calendar have been drawn. Now Start putting in the numbers**/
    a=1;
    c=1;
    b=start_day;
    for(loop=x+2;loop<=x+26;loop+=4)
    {
        gotoxy(loop,y+5);
        if(b<=c)
        {
            printf("%i",a);
            a++;
        }
        c++;
    }

    /**Second line of numbers**/
    for(loop=x+2;loop<=x+26;loop+=4)
    {
        gotoxy(loop,y+8);
            printf("%i",a);
            a++;
    }

    /**Third Line Of Numbers**/
    for(loop=x+2;loop<=x+26;loop+=4)
    {
        gotoxy(loop,y+11);
            printf("%i",a);
            a++;
    }

    /**Fourth Line Of Numbers**/
    for(loop=x+2;loop<=x+26;loop+=4)
    {
        gotoxy(loop,y+14);
            printf("%i",a);
            a++;
    }

    /**Fifth Line Of Numbers**/
    for(loop=x+2;loop<=x+26;loop+=4)
    {
        gotoxy(loop,y+17);
        if(a<=num_of_days)
            printf("%i",a);
            a++;
    }

    /**If all the dates did not fit into the grid. Like say in Jan1,2011
    Go back to first line of numbers and fit them in there.**/
    if(a<num_of_days)
    {
        for(loop=x+2;loop<=x+26;loop+=4)
        {
        gotoxy(loop,y+5);
        if(a<=num_of_days)
            printf("%i",a);
            a++;
        }
    }
}



Thursday, 8 August 2013

A Sudoku Grid

My next task with the database program is to draw a grid for a calendar.

As I was considering how to go about this, I remembered that I once wrote a program to draw a Sudoku grid. This was inspired by some lectures I was listening to on YouTube (Yes I am taking my C hobby seriously ^_^. This is a link to one of the lectures, they are great: (https://www.youtube.com/watch?v=Rxvv9krECNw).

The program does not actually need you to declare the functions first. So you do not have to include the lines:

void draw_sudoku(void);
void firstLine(void);
void middleLine(int r);
void middleJointSmall(void);
void middleJoint(void);
void lastLine(void);

But if you don't, although the program will compile and run, it will give you a bunch of warnings. No warning is better than a warning...so....

On execution, it will resize the DOS screen, draw the grid, wait for keypress, resize the screen back to default and exit. Here is a sample..


Here is the code:

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>


void draw_sudoku(void);
void firstLine(void);
void middleLine(int r);
void middleJointSmall(void);
void middleJoint(void);
void lastLine(void);

int a,b,c,d;

main()
{
    system("Mode 47,29");
    draw_sudoku();
    system("Mode 80,22");
    return(0);
}

void draw_sudoku(void)
{
    firstLine();
    middleLine(2);
    middleJointSmall();
    middleLine(2);
    middleJointSmall();
    middleLine(2);
    middleJoint();
    middleLine(2);
    middleJointSmall();
    middleLine(2);
    middleJointSmall();
    middleLine(2);
    middleJoint();
    middleLine(2);
    middleJointSmall();
    middleLine(2);
    middleJointSmall();
    middleLine(2);
    lastLine();
    getch();
}

void firstLine(void)
{
    //Beginning of first line
    printf("%c",201);

    for(a=0;a<3;a++)
    {
        for(b=0;b<3;b++)
        {
            for(c=0;c<4;c++)
            {
                printf("%c",205);
            }
            printf("%c",209);
        }
        printf("\b%c",203);
    }
    printf("\b%c\n",187);

}

void middleLine(int r)
{
    //Beginning of second and third line.

    for(a=0;a<r;a++)
    {
        printf("%c",186);
        for(b=0;b<3;b++)
        {
            for(c=0;c<3;c++)
            {
                for(d=0;d<4;d++)
                {
                    printf(" ");
                }
                printf("%c",179);
            }
            printf("\b%c",186);
        }
    printf("\b%c\n",186);
    }
}
void middleJoint(void)
{
    //Beginning of third line
    printf("%c",204);

    for(a=0;a<3;a++)
    {
        for(b=0;b<3;b++)
        {
            for(c=0;c<4;c++)
            {
                printf("%c",205);
            }
            printf("%c",216);
        }
        printf("\b%c",206);
    }
    printf("\b%c\n",185);
}

void middleJointSmall(void)
{
    printf("%c",199);

    for(a=0;a<3;a++)
    {
        for(b=0;b<3;b++)
        {
            for(c=0;c<4;c++)
            {
                printf("%c",196);
            }
            printf("%c",197);
        }
        printf("\b%c",215);
    }
    printf("\b%c\n",182);
}

void lastLine(void)
{
    printf("%c",200);

    for(a=0;a<3;a++)
    {
        for(b=0;b<3;b++)
        {
            for(c=0;c<4;c++)
            {
                printf("%c",205);
            }
            printf("%c",207);
        }
        printf("\b%c",202);
    }
    printf("\b%c\n",188);
}





The First Day of a Month And The Number of Days In It

Yesterday, I was writing about finding a leap year. I included it in my main program, yesterday, and expanded a bit further based on the fact that 1st January, 1900 was a Monday.
It's a function that will accept 4 integers:
1. Month (in int form 1 for January, 2 for February etc.)
2. Year
3. Another Int 1
4. Another int 2.

After it runs, "Another Int 1" will contain the number of days in that month,
"Another Int 2" will contain the first day of that month (1=Sunday, 2=Monday...etc)

I needed this function to draw the calender for a month the user specifies. Here's the function used in a simple program (NOTE: Please make sure you are trying to compile the file as a .C file and NOT .CPP. The program will not compile as a .CPP file).

#include <stdio.h>
#include <strings.h>

void find_days(int month,int year,int *dates,int *day);

main()
{
    int month,year,num_of_days,first_day;
    char day[10];

    printf("Enter Month (1 for Jan, 2 for Feb etc.):");
    scanf("%i",&month);
    printf("Enter Year:");
    scanf("%i",&year);
    find_days(month,year,&num_of_days,&first_day);

    switch(first_day)
    {
    case 1:
        strcpy(day,"Sunday");
        break;
    case 2:
        strcpy(day,"Monday");
        break;
    case 3:
        strcpy(day,"Tuesday");
        break;
    case 4:
        strcpy(day,"Wednesday");
        break;
    case 5:
        strcpy(day,"Thursday");
        break;
    case 6:
        strcpy(day,"Friday");
        break;
    case 7:
        strcpy(day,"Ssturday");
        break;
    }

    printf("It has %i days and the first day is a %s",num_of_days,day);
}

void find_days(int month,int year,int *dates,int *day)
{
    int leap_year,loop;
    int loop_day=2,loop_month=1,loop_year=1900,day_limit=31; //day is at 2 because it will start at monday etc.

    while(1)
    {
        /**First, if the month is 2 (february) find if the year is a leap year*/
        if((loop_year%4==0 && loop_year%100!=0) || (loop_year%400==0))
        {
            leap_year=1;
        }
        else
        {
            leap_year=0;
        }

        /**set up the months, with dates going up**/
        if(loop_month==1 || loop_month==3 || loop_month==5 || loop_month==7 || loop_month==8 || loop_month==10 || loop_month==12)
        {
            if(loop_month==month && loop_year==year)
            {
                *dates=31;
                *day=loop_day;
                break;
            }
            for(loop=0;loop<31;loop++)
            {
                loop_day++;
                if(loop_day==8)
                {
                    loop_day=1; //sunday
                }
            }
            loop_month++;
        }
        else if(loop_month==4 || loop_month==6 || loop_month==9 || loop_month==11)
        {
            if(loop_month==month && loop_year==year)
            {
                *dates=30;
                *day=loop_day;
                break;
            }
            for(loop=0;loop<30;loop++)
            {
                loop_day++;
                if(loop_day==8)
                {
                    loop_day=1; //sunday
                }
            }
            loop_month++;
        }
        else if(loop_month==2)
        {
            if(loop_month==month && loop_year==year)
            {
                if(leap_year==1)
                {
                    *dates=29;
                }
                else
                {
                    *dates=28;
                }
                *day=loop_day;
                break;
            }
            for(loop=0;loop<28+leap_year;loop++)
            {
                loop_day++;
                if(loop_day==8)
                {
                    loop_day=1; //sunday
                }
            }
            loop_month++;
        }
        if(loop_month==13)
        {
            loop_year++;
            loop_month=1;
        }
    }
}



Wednesday, 7 August 2013

Find Leap Year Program

I'm now completely into the database program (8k+ lines of code now), that's why I don't have much to post these days, because I'm not writing any short programs.

The feature I'm trying to put in right now is that the user will enter 2 dates and the program does something with them (displays information based of the sales between those dates).

The program needs to know how many days are in between, so if the user entered dates spans more than 365 days, I have to figure out leap years so that the number of days are accurate.

So I sat down to write a program I could use as a function. The program would accept a year and return if it is a leap year or not.

I remembered googling something to the effect of  "how to tell if a year is a leap year" once, & saved the answer I found in a notepad file. But I forgot the formula, and I was not up for finding that notepad file, so I googled it again.

HERE is what I found. Based on the best answer to the question there, I wrote a program. Here it is:

#include <stdio.h>
#include <stdlib.h>

main()
{
    int year,leap=0;

    system("cls");
    printf("Enter year, 0 to exit: ");
    while(1)
    {
        leap=0;
        scanf("%i",&year);
        if(year==0)
        {
            break;
        }
        if(year%4==0)
        {
            if(year%100==0)
            {
                if(year%400==0)
                {
                    printf("Year is a leap year!\n");
                    leap=1;
                }
                else
                {
                    leap=0;
                }
            }
            else
            {
                printf("Year is a leap year!\n");
                leap=1;
            }
        }
        if(leap==0)
        {
            printf("Year is NOT a leap year!\n");
        }
        printf("Enter year, 0 to exit: ");
    }
    return(0);
}

But when I was trying to save it as "LeapYear.c", the autocomplete showed me another file called "LeapYear.cpp". So I checked it out. Here it is:

#include <stdio.h>

main()
{
    int year;

    printf("Enter a year: ");
    scanf("%i",&year);

    if((year%4==0 && year%100!=0) || (year%400==0))
    {
        printf("%i is a leap year.",year);
    }
    else
    {
        printf("%i is not a leap year.",year);
    }
}

The second one is much shorter.
Since I decided to post it here, I found the Notepad file, here is the explanation on finding out if a particular year is a leap year.

Check if the year is divisible by 4.
If not, it is not a leap year.

If it is divisible by 4, then:
Check if the year is divisible by 400, if it is, it is a leap year.
Check if the year is divisible by 100, if it is, it is not a leap year.

Otherwise, it is a leap year.

I found that on a page in Yahoo Answers, but I cannot find that page right now.

Anyway, I may try to include a calendar displayed in a grid so that it is easier for the user to choose dates. If I do, I will write a smaller program based on that and post it next.