Thursday, June 3, 2010

โปรแกรม เรื่องสั้น (ต่อ(ต่อ))

เป็นโปรแกรมการเคลื่อนที่ทางเดียว กากฯก็ได้ แต่เคลื่อนที่ทางเดียว ดังนั้น กระสุนก็ใช้ได้ เพราะมันก็สูตรเดียวกัน ที่นำมาให้ชม ก็เป็นต้นฉบับ ที่ สับมิด ไปเมื่อวานนี้แล้ว ฉบับสุดท้าย

จากต้นฉบับนี้, filename.w,หากใช้ FreeBSD จริง จะมีคำสั่ง cweave
นี้อยู่ ก็เรียกมาใช้กับแฟ้มนี้ แล้วจะมีผลลัพธ์ออกมาด้วยแฟ้มชื่อเดียวกัน แต่จะลงท้ายด้วย .tex
% cweave filename.w

ก็ให้สั่งต่อไปด้วย
% pdftex filename.tex

ก็จะได้แฟ้ม filename.pdf ออกมาเป็น คู่มือการใช้งาน แต่อย่างที่บอกไว้ มันเป็นภาษาอังกฤษ ซึ่งเป็นข้อจำกัดของ TeX เขา และในคำสั่งแรก ถ้าเปลี่ยนจาก cweave เป็น ctangle ก็จะได้แฟ้ม filename.c ซึ่งนำไป compile ด้วย C compiler แล้วให้ executable program ออกมา ทำงานได้ ซึ่งก็ได้บอกไว้ชัดเจนแล้วในแฟ้มคู่มือ ที่ได้มา

ถ้าคิดว่าจะนำไปใช้บ้าง ก็คัดลอกไป ตามที่เห็นน่ะ แล้วไปดัดแปลงเอาเอง

แปลกตรงที่หน้าสารบัญ เขากลับสร้างมาหลังสุด ใครตอบถูกว่า ทำไม จะให้รางวัล

@* SGM programming for one dimensional movement.
This is SGM-6M-PROG-1d final
release.
This release adds command line arguments to ease, or to speed up,
users and also add some features to the programme with hope to meet specifications
and to enhance previous release such as crafting a system dependent in order
to get a relatively system independent softwares


@ Beginning with this release, assumptions have to be clearly stated here
that speed is a constant value.
Additionally, plotting graphs will
be done by other utilities, called gnuplot, available around the net.

Plotting graph by gnuplot within process is quite problematics one.
Data file
used in script for plotting can not be deferred, it must be specified directly.
Since
gnuplot command {\bf plot '{\it datafile}\/'} requires that {\it datafile}\/ is
{\it datafile}\/, the content is merely data for plotting and nothing more.


@ Now that let us imagine this programme should have the command, which is
an executable computer programme compiled from c source file, of the form,
within this release as either

{\bf sgm-6m-prog-1d -s filename}

\noindent or

{\bf sgm-6m-prog-1d -d filename}

\noindent whereas filename contains data for either speed or distant needed in
calculation for the main programme.
Moreover, {\bf filename} can be any
name but {\it jotawski\/}, {\it jotawski\/} is used for datafile mentioned
above, yes {\bf plot '{\it datafile}\/'} is actually
{\bf plot '{\it jotawski\/}'}.


@ Let us step forward a little bit into detail about |filename|
mention in the previous section.
Firstly, the format of data
in |filename| is a number of x,y pair which is an integer number,
and followed by x,y pair themselves, in floating point number.
The number of pairs of (x,y) is equal to the first number given, for example

{\bf 3} $\leftarrow$ {\it number of x,y pair\/,integer, followed by 3 lines of (x,y) pair}

{\bf 0.5,12.0} $\leftarrow$ {\it x,y pair itself separated by comma\/, floating point}

{\bf 1.8,20.0} $\leftarrow$ {\it x,y pair itself separated by comma\/, floating point}

{\bf 2.2,25.0} $\leftarrow$ {\it x,y pair itself separated by comma\/, floating point}


@ Secondly, for the x,y pairs themselves, the first one, x--value, is always time.
The second one, y--value, can be either distant or speed depending on what is needed.
If this programme is called with the first form, {\bf sgm-6m-prog-1d -s filename},
it is clearly that y--value is a distant.
Option s, --s, means speed is needed
so that distant has to be given.
There is no secret in the forest.


@ The output is a dot png file.
It is a portable network graphics format file which
is avaiable for further modification and the name is, as expected, |jotawski.png|.
For interested users, on how to get this file, please have a look at command file |jotawski.cmd|.
You can edit and play around with this command file safely.
Have fun.


@* Our problem layout, in KISS, is as follow.

@^sgm-6m-prog-1d-v1@>
@c

/*- Copyright (c) 2010 pirat sriyotha, aka jotawski
* All rights reserved.
* TBA meat of license.
*/
@<Global Variables@>@/
@<Header files@>@/
@<GNUPlot Script create@>@/
@<main@>
@ Header files and global variables are defined here.
At this moment,
only anticipated one are listed.


@<Header files@>=
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>


@ Global variables in this programme.

@<Global Variables@>=
char *programme; /* this file */
char *filename; /* filename from command line */
@* Entry point to the programme, |main| function.
|C| is nothing but function of
operating system which has main function as an entry point.

@<main@>=
main (argc,argv)
int argc; /* the number of arguments on the \UNIX/ command line */
char **argv; /* the arguments themselves, an array of strings */
{@/
@<Local variables for main@>@/
programme=argv[0];@/
@<Startup@>@/
if(status != OK)@/
exit(status);@/
@<Do calculation and plot graphs via |fork()|@>@/
@<CleanUp@>@/
exit(status);@/
}@/


@ The rest will explain the whole story from |main| down to
the last curly brace of this function.


@ Some local variables needed as in the first version are |speed|,
|distant|, |time| and |interval|.
They are all float data type
except the last one which is integer.
|x| and |y| are pointers to
float which will be used for real calculation and passing to gnuplot().

@<Local variables for main@>=
float *x, *y, *px, *py;
float speed, distant, time;
int interval;


@ More to come is a kind of file pointers type, |FILE *fp|, which
will hold informations relevant to data in input file.
This is really
the good side of writing softwares in more than one release since I have just
realized that |fp| is needed here at the moment of writing
and so inserted immediately.

@<Local ...@>=
FILE *fp;
@ Some preparations such as allocation of memories for filename,
define status for global use and so on are defined here, in global variables section.


@d OK 1
@d OPEN_FILE 2
@d USAGE 3
@d NO_ROOM 4


@ |status| is a local variable for main and initially set to |OK|.
The other integers are for command line parsing using system function |getopt(3)|.
|sflag| is used to indicate
that speed has been selected.
|interactive| is to indicate that we enter a child process
and doing something manually overthere and must be used with option s or option d.

@<Local ...@>=
int status=OK;
int sflag, interactive, ch;


@* Startup code.
This startup codes are just checked for calling syntax, memories allocation.
@<Start...@>=
if (argc == 1) {
fprintf(stderr,"usage: %s -[[i]s|[i]d] data-filename\n", programme);
status= USAGE;
} else {
if ( (filename = (char *)malloc(80)) == NULL) {
status = NO_ROOM;
} else {
@<Getoption@>
}
}


@ |errno| is needed at this point.
Get options is nothing
but services from system funtion.
@<Header files@>=
#include <errno.h>


@ |getopt(3)|, one of many functions from system services
@<Getoption@>=
sflag = 0;
interactive=0;
while ((ch = getopt(argc, argv, "is:d:")) != -1) {
switch (ch) {
case 'i':@/
interactive = 1;@/
break;@/
case 's':
if ((fp = fopen(optarg, "r")) == NULL) {
fprintf(stderr,"%s: %s: %s\n",programme, optarg, strerror(errno));
status = OPEN_FILE;
}
sflag = 1;
strcpy(filename,optarg); /* for later used */
break;
case 'd':
if ((fp = fopen(optarg, "r")) == NULL) {
fprintf(stderr,"%s: %s: %s\n",programme, optarg, strerror(errno));
status = OPEN_FILE;
}
strcpy(filename,optarg); /* for later used */
break;
case '?':@/
default:@/
fprintf(stderr,"usage: %s -[[i]s|[i]d] data-filename\n%s\n", programme,
strerror(errno));
status = USAGE;
break;
}
}
@ This part of task is to read in x,y data from filename,
doing gnuplot via forking the process to show the graph.
System funtion
wait() is needed in order to bring back the task to main() and
end with status from main.

@<Do calculation ...@>=
@<Reads in input@>@/
@<Acquire rooms for x and y@>@/
@<Scan input file for x and y@>@/
@<Real calculation for variable in question@>@/
@<Fork and wait@>


@ Reads in input consisting of two parts, number of interval
has to be read in first.
Later on, continue reading in data
into |double *x, *y| after we prepare rooms for them.
@<Reads in input@>=
fscanf(fp,"%d\n", &interval);


@ Acquire rooms for |double *x, *y| need to check for status and so
a place for saved status is needed here.
We use ch for this purpose.
@<Acquire rooms for x and y@>=
/* ch = status; saved status, i havefound that it is unnecessary to save */
if((x = (float *)malloc(interval*sizeof(float))) == NULL) {
free((char *)filename);@/
fclose(fp);@/
status = NO_ROOM;@/
}@/
if((y = (float *)malloc(interval*sizeof(float))) == NULL) {
free((char *)filename);@/
free((float *)x);@/
fclose(fp);@/
status = NO_ROOM;@/
}@/
if(status != OK)@/ /* if error occur in any case we stop here */
exit(status);@/
/* status = ch; see above for reason to remove.
restore saved status */


@ Scan input data into array of x and y.
@<Scan input file for x and y@>=
px = x;@/
py = y;@/
for(ch = 0; ch < interval; ch++)@/
fscanf(fp,"%f,%f\n", px++,py++);


@* Real calculation.
@<Real calculation for variable in question@>=
fclose(fp);@/
if ((fp = fopen("jotawski","w")) == NULL) {@/
status = OPEN_FILE;@/
fprintf(stderr,"open file probelm\n");@/
exit(status);@/
}@/
if(sflag) {@/ /* do calcuate speed from time and distant */
printf("speed");@/
for (ch=0, *px=0.0; ch<interval-1;ch++){
time = (*(x+ch+1)) - (*(x+ch));
distant = (*(y+ch+1)) - (*(y+ch));
speed = distant / time;
*px += speed;
fprintf(fp,"%f %f\n",*(x+ch), speed);
}
printf(" average : %f\n", *px/(interval-1));
/* number of interval used are interval - 1
* number of time, distant pairs are also interval -1
* speed(i) i=0,1,2,...,interval-1
* time(i) are to be calculated and print into 'jotawski' for plotting
* average speed is shown as label.
*/
fclose(fp);@/
CreateGnuPlot("Speed", fp, interactive);@/
} else {@/
printf("distant: opening file for output.\n");@/
for (ch=0; ch<interval; ch++){@/
time = *(x+ch);@/
speed = *(y+ch);@/
distant = speed * time;@/
fprintf(fp,"%f %f\n",time,distant);@/
}@/
fclose(fp);@/
CreateGnuPlot("Distant", fp, interactive);@/
}@/


@* Process control.
This program utilizes process control, via |fork()| and |wait()|,
instead of a single once through and die program normally written by others.


@ For wait() to be called properly sys/types.h and sys/wait.h must
be included.
@<Header ...@>=
#include <sys/types.h>
#include <sys/wait.h>


@ |fork()| and |wait()| are also now available.
|jotawski.cmd| is a set of gnuplot
commands.
An example is

set terminal png nocrop medium

set xrange [*x:*(x+interval-1)]

plot y

@<Fork and wait@>=
if((fork()) == 0) {@/ /* child process */
if (interactive)@/ /* load command inside gnuplot */
execlp("/usr/local/bin/gnuplot","/usr/local/bin/gnuplot",(char *)0);@/
else@/
execlp("/usr/local/bin/gnuplot","/usr/local/bin/gnuplot","jotawski.cmd",(char *)0);@/
} else {@/ /* parent, this programme */
wait(&sflag);@/
}


@* |gnuplot()| function.
Subroutine or funtion to create gnuplot script.
@<GNUPlot Script create@>=
void CreateGnuPlot(char *yasuko, FILE *fp, int interactive)@/
{
fp = fopen("jotawski.cmd","w");@/
fprintf(fp,"set terminal png nocrop medium\n");@/
if(!interactive)@/
fprintf(fp,"set output 'jotawski.png'\n");@/
fprintf(fp,"set key top left\nset key box\n");@/
fprintf(fp,"set ylabel \"%s\" center\n", yasuko);@/
fprintf(fp,"set xlabel \"time\"\n");@/
fprintf(fp,"set style data linespoints\n");@/
fprintf(fp,"set title \"SGM 6m plot 1 dimension\"\n");@/
fprintf(fp,"plot 'jotawski' title \"%s\"\n", yasuko);@/
fclose(fp);@/
}@/
@* Cleanup task.
A must for every programmes.
@<Clean...@>=
free((char *)filename);@/
free((double *)x);@/
free((double *)y);
/* fclose(fp); this has been closed already*/


@ Now that |main()| gain control back from child and die here afterward.


@ The final remaining loose end is to extract and compile programme written
from this file and get executable computer code,\,{\it{sgm-6m-prog-1d-v1\/}},
which is quite simple from four commands below.

The first two lines for executable commputer code and the last two
lines for producing a pretty print output of this manual,\,{\it sgm-6m-prog-1d-v1r0.pdf}.

\% ctangle sgm-6m-prog-1d-v1r0.w

\% cc -o sgm-6m-prog-1d-v1r0 sgm-6m-prog-1d-v1r0.c -lc

\% cweave sgm-6m-prog-1d-v1r0.w

\% pdftex sgm-6m-prog-1d-v1r0.tex


@* System requirement.
This \.{CWEB} programme, \.{sgm-6m-prog-1d-v1r0.w},
is developed on FreeBSD and has copyrighted in BSD style.
As in the first
submitted report, if one of us were interested in FreeBSD, here is some descriptions over
this operating system.



FreeBSD wmc.tint.or.th 8.0-RELEASE FreeBSD 8.0-RELEASE
\#2: Mon Apr 12 15:08:05 ICT 2010

root@@wmc.tint.or.th:/usr/obj/usr/src/sys/HARIPOONCHAI i386


@ This program require x--window system as graphic displaying tools
and gnuplot, a general purposes plotting utilities from GNU project,
for helping in displaying cute graphs and c compiler to compile
source code.
Project management and editing tools like leo is
heavily used in this task.
The unix--like operating system
such as FreeBSD is used to host the whole story finally.

All softwares mentioned above are free and are bundled with FreeBSD,
one need to even manually install x--window and gnuplot from ports tree though.
And
once they are in place, they are availble forever for every one.


@ Installation of operating system and applications are beyond the scope of this report.
But if anyone are interested in such a task, please feel free to contact to the author or
directly go to http://www.FreeBSD.ORG
@* Notes from the author.
This task is an inspiration of
the deputy secretary general of TINT about the computer programming
for the institute, he has foreseen that there is no development
in this field when the institute has been born since BE 2549.
As mention in
the first report that this kind of task can be used in managment of
radioactive liquid wastes treatment as well.
On the author look, the most
application is to calculate the amount of air flow from any stack in the
direction of wind, which in turn, the exposure rate associated with
polluted air can be assess, even very roughly though.

It is likely that a few computer interest groups for such a particular task as
safety assessments, in house development and so on will be formed
in the near future.
This will helps TINT comes up with some innovations
and is capable of competetion with other countries.
@* Index.

โดยเนื้อแท้แล้ว มึน กับงานนี้มากเลย มาสั่งให้เขียนโปรแกรม v = s/t แค่นี้ ยังนึกไม่ออก จะเอาไปทำอะไร เลยบ่นออกมาใน
@* Notes from the author นั่นแหละ

แต่เอาเถอะ หวังว่า ที่คาดหวังไว้ จะเป็นจริงได้ ก็พอแล้ว
i wishes that my dreams become true.

8 comments:

Anonymous said...

สวัสดีครับคุณลุง
เมื่อวานมีโอกาส
ได้เรียนวิชาบัญชีมา
มึนมากเลยครับ
หัวฟูเลย(จากเดิมที่ฟูอยู่แล้ว^-^)
จากไวน์

มะขาม said...

บัญชีมา
อันนี้ วิชาใหม่ เน้าะ ฮิฮิ
๔-๖ ที่ผ่านมา ไป อ.ท่าใหม่ เมืองจันทบุรี โรงเรียนบ้านจ้าวหลาว ไปช่วย ไปสร้าง ไปบำรุงสาระพัดสิ่งให้กับ เด็กนักเรียน ที่นั่น

ขอบใจมากมากน่ะครับ ที่ยังไม่ลืม และแวะมาทักทายกัน

Anonymous said...

เอ๋...ตอนปี1ถ้าผมจำไม่ผิด
ผมก็เคยไปคล้ายๆกับค่ายอาสาพัฒนา
ที่โรงเรียนบ้านจ้าวหลาวเหมือนกันครับ
ผมว่าเด็กที่นั่นน่ารักนะครับแต่ยังขาดแคลน
อะไรหลายๆอย่างอีกเยอะนะครับ

แต่ที่ผมชอบเป็นพิเศษ^-^
ก็ตอนที่เด็กๆเลิกเรียนน่ะครับ
พวกเด็กๆจะนำจักรยานที่พอจะมีกัน
มาต่อแถวแล้วเลิกเรียนพร้อมกัน
คุณครูก็จะปล่อยกลับบ้านเป็นแถวๆไป

ดูแล้วก็นึกถึงไว้เด็กที่ยังคงมีความสดใส
อยู่ในตัว
จากไวน์

dekdar said...

มีนกับข้อสอบที่ลุงให้

ต้องไล่ไปอ่านตั้้งแต่ต้นแล้วล่ะ

เข้ามาตามหารูป ๆ สาว ๆ มีบ้างอ่ะป่าวคับ อิอิ

เล่าบรรยการให้ฟังหน่อย ได้ไหมครับ ลุง ..(เด็กอยากฟังอ่ะ)

มะขาม said...

ฮาาาาาาาาา
รอรูปเหมียนกัลลลลล

ขอบใจน่ะ ที่แวะมาเยี่ยม

มะขาม said...

ถึงน้องไวน์
ใช่ครับ ทารก สดใสน่ารัก ร่าเริงตลอด
ผมให้เขาได้น้อยเหลือเกิน รู้สึกอย่างนั้นน่ะ

คงต้องหาทางไปช่วยทารกทั้งหลายอีกที บางที อาจจะขอเป็น พ่อทูนหัว สักคน

Anonymous said...

อ่า....สาวที่ไหนครับพี่บัชคุณลุง
แนะนำให้ผมบ้างซิ^-^
อิๆผมรักทุกคนเลย จุ๊บ จุ๊บ ^+^
จากไวน์

มะขาม said...

แน้
นั่นน่ะซี เน้าะ
แต่ก็มี สาวๆแถวนั้น น่ารักไปหมด อิอิ

ขอบใจน่ะครับ


View My Stats