• Row of objects: for loop creates only 2 rows out of 5

    From modelling.data@gmail.com@21:1/5 to All on Sat Nov 14 09:14:05 2015
    Hello!

    I have written a post regarding the same program.

    I have an issue with the easiest part of it, and I don't see
    my mistake: the for loop in the BRICKS FUNCTION doesn't create
    5 rows of bricks, but only 2, albeit the amount of columns is correct
    (all bricks are perfectly aligned within 10 columns). The program
    prints out only 2 rows of bricks.

    I understand that this program implies the availability of Stanford
    Portable Library, and that without this library you can't compile
    the program. But I hope that because all functions have descriptive
    names, you will understand what the desired outcome.

    If "=" is a brick, then the outcome should look like this:

    = = = = = = = = = =
    = = = = = = = = = =
    = = = = = = = = = =
    = = = = = = = = = =
    = = = = = = = = = =

    I get only first two rows out of five.


    // standard libraries
    #include <stdio.h>

    // Stanford Portable Library
    #include <spl/gevents.h>
    #include <spl/gobjects.h>
    #include <spl/gwindow.h>

    // height and width of game's window in pixels
    #define HEIGHT 600
    #define WIDTH 400

    // number of rows of bricks
    #define ROWS 5

    // number of columns of bricks
    #define COLS 10

    // horizontal space between bricks
    #define HS 10
    #define VS 10

    // brick size
    #define BRWIDTH 29
    #define BRHEIGHT 15

    void initBricks(GWindow window);

    int main(void)
    {
    // instantiate window
    GWindow window = newGWindow(WIDTH, HEIGHT);

    initBricks(window);

    return 0;
    }

    /** BRICKS FUNCTION **/
    void initBricks(GWindow window)
    {
    double x = 10;
    double y = VS * 5;

    for (int i = 0; i < ROWS; i++)
    {
    for (int j = 0; j < COLS; j++)
    {
    GRect brick = newGRect(x, y, BRWIDTH, BRHEIGHT);
    add(window, brick);

    x = x + BRWIDTH + HS;
    }

    x = 10;
    y = BRHEIGHT + VS;
    }
    }

    Thank you!

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From modelling.data@gmail.com@21:1/5 to All on Sun Nov 15 00:10:05 2015
    <snip>
    You should provide a makefile along with your program! Otherwise, how
    can we know how to compile it, what options you used, and how to run it?

    Yes, I understand it, that is why I have added a comment saying I understand that it wouldn't be possible to compile the program without SPL headers.
    I am new not only to Objective C, but to programming in general. I follow
    a free online course, that gives broad information, and I read books on my
    own and do some exercises. Therefore, I have not yet learned how to create makefiles. I am very thankful to you for the version you posted, though
    at this moment it look too cryptic from me. I have not yet learned debugging either.

    Here is the makefile I used, but if yours is different, then obviously
    we will have different results, and I won't be able to debug your
    program.


    Also, you have a bug in your initBricks(), you set y to a constant in
    the loop. Therefore all the new bricks beyond the first two rows will be displayed on the second row.

    Thank you very much - I am ashamed that I missed such an easy bug. Indeed,
    this one caused the problem. I have forgotten to add one tiny + sign before
    = one.


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Pascal J. Bourguignon@21:1/5 to modelling.data@gmail.com on Sat Nov 14 22:47:02 2015
    modelling.data@gmail.com writes:

    Hello!

    I have written a post regarding the same program.

    I have an issue with the easiest part of it, and I don't see
    my mistake: the for loop in the BRICKS FUNCTION doesn't create
    5 rows of bricks, but only 2, albeit the amount of columns is correct
    (all bricks are perfectly aligned within 10 columns). The program
    prints out only 2 rows of bricks.

    By the way, you will have noticed in my makefile the debug-bricks target
    which runs your program with the environment variable JBETRACE set to
    true. This allows you to see the traffic sent and received on the pipe
    by your program (but you don't see what happens on the other side of the
    pipe, data written in the pipe buffer is not necessarily read by the
    other side). Nonetheless, this let you see what happens with the GUI
    when you have doubts about what you program does.

    You should be able to set it on and off using putenv(3):
    putenv("JBETRACE=true");
    putenv("JBETRACE=false");
    if you want to trace only parts of your program.


    Secondly, one big problem of batch programming environment such as the
    usual C compilers, is that you don't see what's in your variables during execution or debugging. Granted, you could run a debugger, but gdb or
    ldb are low level debuggers, and while you may be able to see what's in
    a variable or a data structure, it's rather difficult, and there are all
    kinds of exception (notably when optimization levels are higher than 0
    (notice the -g -O0 options I use to compile). Therefore, a very common
    and useful technique while debugging, is to add to your program a lot of
    logs displaying the values of your variables.

    Adding a single line such as:

    /** BRICKS FUNCTION **/
    void initBricks(GWindow window)
    {
    double x = 10;
    double y = VS * 5;

    for (int i = 0; i < ROWS; i++)
    {
    for (int j = 0; j < COLS; j++)
    {

    /*PJB-DEBUG*/printf("i=%i j=%i x=%f y=%f w=%f h=%f\n",i,j,x, y, BRWIDTH, BRHEIGHT);

    GRect brick = newGRect(x, y, BRWIDTH, BRHEIGHT);
    add(window, brick);

    x = x + BRWIDTH + HS;
    }

    x = 10;
    y = BRHEIGHT + VS;
    }
    }

    would allow you to easily see what one problem was. Notice the
    /*PJB-DEBUG*/ comment. You can easily search and replace them to
    //PJB-DEBUG to disable such lines, and use:

    sed -i -e /PJB-DEBUG/d bricks.c

    to remove them entirely once your program works.

    --
    __Pascal Bourguignon__ http://www.informatimago.com/
    “The factory of the future will have only two employees, a man and a
    dog. The man will be there to feed the dog. The dog will be there to
    keep the man from touching the equipment.” -- Carl Bass CEO Autodesk

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From modelling.data@gmail.com@21:1/5 to All on Sun Nov 15 00:12:30 2015
    <snip>
    for (int i = 0; i < ROWS; i++)
    {
    for (int j = 0; j < COLS; j++)
    {

    /*PJB-DEBUG*/printf("i=%i j=%i x=%f y=%f w=%f h=%f\n",i,j,x, y, BRWIDTH, BRHEIGHT);

    GRect brick = newGRect(x, y, BRWIDTH, BRHEIGHT);
    add(window, brick);

    x = x + BRWIDTH + HS;
    }

    x = 10;
    y = BRHEIGHT + VS;
    }
    }

    would allow you to easily see what one problem was. Notice the
    /*PJB-DEBUG*/ comment. You can easily search and replace them to
    //PJB-DEBUG to disable such lines, and use:

    sed -i -e /PJB-DEBUG/d bricks.c

    to remove them entirely once your program works.
    Thank you for your advice. I will implement it.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Pascal J. Bourguignon@21:1/5 to modelling.data@gmail.com on Sat Nov 14 22:24:59 2015
    modelling.data@gmail.com writes:

    Hello!

    I have written a post regarding the same program.

    You should provide a makefile along with your program! Otherwise, how
    can we know how to compile it, what options you used, and how to run it?

    Here is the makefile I used, but if yours is different, then obviously
    we will have different results, and I won't be able to debug your
    program.



    I have an issue with the easiest part of it, and I don't see
    my mistake: the for loop in the BRICKS FUNCTION doesn't create
    5 rows of bricks, but only 2, albeit the amount of columns is correct
    (all bricks are perfectly aligned within 10 columns). The program
    prints out only 2 rows of bricks.

    Indeed, it does. However, I remark that it exits and the window
    displayed by the JavaBackEnd stays up.

    Therefore I would infer that there's a bufferization problem: you have
    to leave the connection open enough time for the data to be actually
    sent and received by the JavaBackEnd. The unix kernel probably drops
    the data that's in the pipe when the writer process is killed or exits.

    One way to ensure that the JavaBackEnd has read everything you sent, is
    to actually implement what would be normal in a GUI application: an
    event loop. If you wait for a mouse-down event on the window, then you
    will ensure that all you sent has been received.

    Also, you have a bug in your initBricks(), you set y to a constant in
    the loop. Therefore all the new bricks beyond the first two rows will be displayed on the second row.


    [pjb@kuiper localhost:10.0 spl]$ make -f bricks.mk run-bricks
    cc -g3 -O0 -std=c99 -std=c11 -o bricks.o -c bricks.c
    cc -g3 -O0 -std=c99 -std=c11 -o bricks bricks.o -lcs -lm -lobjc CLASSPATH=/usr/local/lib/spl.jar ./bricks
    C-c C-c
    Interrupted: exiting.
    bricks.mk:14: recipe for target 'run-bricks' failed
    make: *** [run-bricks] Interrupt

    [pjb@kuiper localhost:10.0 spl]$

    Here are my files:

    ------------------------------------------------------------------------ #!/bin/sh
    # This is a shell archive (produced by GNU sharutils 4.14).
    # To extract the files from this archive, save it to some FILE, remove
    # everything before the '#!/bin/sh' line above, then type 'sh FILE'.
    #
    lock_dir=_sh18948
    # Made on 2015-11-14 22:23 CET by <pjb@kuiper>.
    # Source directory was '/home/pjb/src/miscellaneous/spl'.
    #
    # Existing files will *not* be overwritten, unless '-c' is specified.
    #
    # This shar contains:
    # length mode name
    # ------ ---------- ------------------------------------------
    # 379 -rw-r--r-- bricks.mk
    # 1527 -rw-r--r-- bricks.c
    #
    MD5SUM=${MD5SUM-md5sum}
    f=`${MD5SUM} --version | egrep '^md5sum .*(core|text)utils'`
    test -n "${f}" && md5check=true || md5check=false
    ${md5check} || \
    echo 'Note: not verifying md5sums. Consider installing GNU coreutils.'
    if test "X$1" = "X-c"
    then keep_file=''
    else keep_file=true
    fi
    echo=echo
    save_IFS="${IFS}"
    IFS="${IFS}:"
    gettext_dir=
    locale_dir=
    set_echo=false

    for dir in $PATH
    do
    if test -f $dir/gettext \
    && ($dir/gettext --version >/dev/null 2>&1)
    then
    case `$dir/gettext --version 2>&1 | sed 1q` in
    *GNU*) gettext_dir=$dir
    set_echo=true
    break ;;
    esac
    fi
    done

    if ${set_echo}
    then
    set_echo=false
    for dir in $PATH
    do
    if test -f $dir/shar \
    && ($dir/shar --print-text-domain-dir >/dev/null 2>&1)
    then
    locale_dir=`$dir/shar --print-text-domain-dir`
    set_echo=true
    break
    fi
    done

    if ${set_echo}
    then
    TEXTDOMAINDIR=$locale_dir
    export TEXTDOMAINDIR
    TEXTDOMAIN=sharutils
    export TEXTDOMAIN
    echo="$gettext_dir/gettext -s"
    fi
    fi
    IFS="$save_IFS"
    if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null
    then if (echo -n test; echo 1,2,3) | grep n >/dev/null
    then shar_n= shar_c='
    '
    else shar_n=-n shar_c= ; fi
    else shar_n= shar_c='\c' ; fi
    f=shar-touch.$$
    st1=200112312359.59
    st2=123123592001.59
    st2tr=123123592001.5 # old SysV 14-char limit
    st3=1231235901

    if touch -am -t ${st1} ${f} >/dev/null 2>&1 && \
    test ! -f ${st1} && test -f ${f}; then
    shar_touch='touch -am -t $1$2$3$4$5$6.$7 "$8"'

    elif touch -am ${st2} ${f} >/dev/null 2>&1 && \
    test ! -f ${st2} && test ! -f ${st2tr} && test -f ${f}; then
    shar_touch='touch -am $3$4$5$6$1$2.$7 "$8"'

    elif touch -am ${st3} ${f} >/dev/null 2>&1 && \
    test ! -f ${st3} && test -f ${f}; then
    shar_touch='touch -am $3$4$5$6$2 "$8"'

    else
    shar_touch=:
    echo
    ${echo} 'WARNING: not restoring timestamps. Consider getting and
    installing GNU '\''touch'\'', distributed in GNU coreutils...'
    echo
    fi
    rm -f ${st1} ${st2} ${st2tr} ${st3} ${f}
    #
    if test ! -d ${lock_dir} ; then :
    else ${echo} "lock directory ${lock_dir} exists"
    exit 1
    fi
    if mkdir ${lock_dir}
    then ${echo} "x - created lock directory ${lock_dir}."
    else ${echo} "x - failed to create lock directory ${lock_dir}."
    exit 1
    fi
    # ============= bricks.mk ==============
    if test -n "${keep_file}" && test -f 'bricks.mk'
    then
    ${echo} "x - SKIPPING bricks.mk (file already exists)"

    else
    ${echo} "x - extracting bricks.mk (text)"
    sed 's/^X//' << 'SHAR_EOF' > 'bricks.mk' &&
    all: bricks
    X
    LIBS=-lcs -lm -lobjc
    CFLAGS=-g3 -O0 -std=c99 -std=c11
    X
    %.o:%.m;cc $(CFLAGS) -o $@ -c $^
    %.o:%.c;cc $(CFLAGS) -o $@ -c $^
    X
    bricks.o:bricks.c
    bricks:bricks.o
    X cc $(CFLAGS) -o $@ $^ $(LIBS)
    X
    run-bricks:bricks
    X CLASSPATH=/usr/local/lib/spl.jar ./bricks
    X
    debug-bricks:bricks
    X JBETRACE=true CLASSPATH=/usr/local/lib/spl.jar ./bricks
    X
    clean:
    X -rm -rf bricks *.dSYM *.o
    X
    SHAR_EOF
    (set 20 15 11 14 22 22 21 'bricks.mk'
    eval "${shar_touch}") && \
    chmod 0644 'bricks.mk'
    if test $? -ne 0
    then ${echo} "restore of bricks.mk failed"
    fi
    if ${md5check}
    then (
    ${MD5SUM} -c >/dev/null 2>&1 || ${echo} 'bricks.mk': 'MD5 check failed'
    ) << \SHAR_EOF
    08f3fc95e6ba9bb115154029c5351a2d bricks.mk
    SHAR_EOF

    else
    test `LC_ALL=C wc -c < 'bricks.mk'` -ne 379 && \
    ${echo} "restoration warning: size of 'bricks.mk' is not 379"
    fi
    fi
    # ============= bricks.c ==============
    if test -n "${keep_file}" && test -f 'bricks.c'
    then
    ${echo} "x - SKIPPING bricks.c (file already exists)"

    else
    ${echo} "x - extracting bricks.c (text)"
    sed 's/^X//' << 'SHAR_EOF' > 'bricks.c' &&
    // standard libraries
    #include <stdio.h>
    #include <signal.h>
    // Stanford Portable Library
    #include <spl/gevents.h>
    #include <spl/gobjects.h>
    #include <spl/gwindow.h>
    #include <spl/platform.h>
    X
    // height and width of game's window in pixels
    #define HEIGHT 600
    #define WIDTH 400
    X
    // number of rows of bricks
    #define ROWS 5
    X
    // number of columns of bricks
    #define COLS 10
    X
    // horizontal space between bricks
    #define HS 10
    #define VS 10
    X
    // brick size
    #define BRWIDTH 29
    #define BRHEIGHT 15
    X
    void initBricks(GWindow window);
    X
    bool done=false;
    bool interrupted=false;
    void sigint(int signal){
    X interrupted=true;
    X done=true;}
    X
    void eventLoop(){
    X while(!done){
    X GEvent e=getNextEvent(MOUSE_EVENT);
    X if(e!=0){
    X if(getEventType(e)==MOUSE_CLICKED){
    X done=true;}
    X freeEvent(e);}}}
    X
    int main(void)
    {
    X signal(SIGINT,sigint);
    X signal(SIGQUIT,sigint);
    X GWindow window = newGWindow(WIDTH, HEIGHT);
    X initBricks(window);
    X eventLoop();
    X if(interrupted){
    X printf("\nInterrupted: exiting.\n");
    X fflush(stdout);}
    X exitGraphicsOp();
    X return 0;
    }
    X
    /** BRICKS FUNCTION **/
    void initBricks(GWindow window)
    {
    X GRect brick;
    X double y = VS * 5;
    X for (int i = 0; i < ROWS; i++)
    X {
    X double x = 10;
    X y = y + BRHEIGHT + VS;
    X for (int j = 0; j < COLS; j++)
    X {
    X brick = newGRect(x, y, BRWIDTH, BRHEIGHT);
    X add(window, brick);
    X
    X x = x + BRWIDTH + HS;
    X }
    X
    X }
    }
    SHAR_EOF
    (set 20 15 11 14 22 16 45 'bricks.c'
    eval "${shar_touch}") && \
    chmod 0644 'bricks.c'
    if test $? -ne 0
    then ${echo} "restore of bricks.c failed"
    fi
    if ${md5check}
    then (
    ${MD5SUM} -c >/dev/null 2>&1 || ${echo} 'bricks.c': 'MD5 check failed'
    ) << \SHAR_EOF
    2b8bed01642279076e0076c052d83adf bricks.c
    SHAR_EOF

    else
    test `LC_ALL=C wc -c < 'bricks.c'` -ne 1527 && \
    ${echo} "restoration warning: size of 'bricks.c' is not 1527"
    fi
    fi
    if rm -fr ${lock_dir}
    then ${echo} "x - removed lock directory ${lock_dir}."
    else ${echo} "x - failed to remove lock directory ${lock_dir}."
    exit 1
    fi
    exit 0
    ------------------------------------------------------------------------

    --
    __Pascal Bourguignon__ http://www.informatimago.com/
    “The factory of the future will have only two employees, a man and a
    dog. The man will be there to feed the dog. The dog will be there to
    keep the man from touching the equipment.” -- Carl Bass CEO Autodesk

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From modelling.data@gmail.com@21:1/5 to All on Tue Nov 17 07:30:46 2015
    <snip>

    Thank you very much for your help! I do appreciate it: studying
    on my own is a challenge, given lack of prior programming experience.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Pascal J. Bourguignon@21:1/5 to modelling.data@gmail.com on Sun Nov 15 21:40:58 2015
    modelling.data@gmail.com writes:

    <snip>
    You should provide a makefile along with your program! Otherwise, how
    can we know how to compile it, what options you used, and how to run it?

    Yes, I understand it, that is why I have added a comment saying I understand that it wouldn't be possible to compile the program without SPL headers.
    I am new not only to Objective C, but to programming in general. I follow
    a free online course, that gives broad information, and I read books on my own and do some exercises. Therefore, I have not yet learned how to create makefiles. I am very thankful to you for the version you posted, though
    at this moment it look too cryptic from me. I have not yet learned debugging either.

    Makefile are really simple really.

    Basically, they allow you to indicate the dependency graph between
    files, in the form:

    target : source…
    <TAB> command

    or as an extension too:

    target : source… ; command

    You can also define variables:

    VAR=VALUE

    We can also specify default commands using patterns:

    %.o:%.m;cc $(CFLAGS) -o $@ -c $^

    is an example of such a pattern.

    make knows a default set of patterns to compile simple programs.
    There are some targets that don't correspond to files; they're called
    phony targets, you can declare you own with:

    .PHONY:: target…

    all, clean are some of the default phony targets. The difference
    between normal targets, is that they're not intended to generate files,
    but instead will try to make their dependencies, and command everytime
    they're invoked.

    That's all there is to it.

    So, to run-bricks, we need the program bricks; to compile the program
    bricks we need the object file bricks.o and to compile the object file
    bricks.o we need the source file bricks.c. This is expressed simply as:

    run-bricks:bricks
    bricks:bricks.o
    bricks.o:bricks.c

    As such, make would provide default rules, but I wanted to provide my
    own rules, so I defined the pattern rule %.o:%.m to indicate how to
    compile bricks.c into bricks.o, and I provided explicit commands to
    indicate how to link bricks.o into bricks, and how to run the bricks
    command for the phony target run-bricks.

    There are extensions, in eg. GNU make, (which actually make it turing
    complete, and allowed somebody to implement a lisp in GNU make), you can
    find the GNU make documentation online.


    all: bricks

    LIBS=-lcs -lm -lobjc
    CFLAGS=-g3 -O0 -std=c99 -std=c11

    %.o:%.m;cc $(CFLAGS) -o $@ -c $^
    %.o:%.c;cc $(CFLAGS) -o $@ -c $^

    .PHONY::run-bricks debug-bricks

    bricks.o:bricks.c
    bricks:bricks.o
    cc $(CFLAGS) -o $@ $^ $(LIBS)


    run-bricks:bricks
    CLASSPATH=/usr/local/lib/spl.jar ./bricks

    debug-bricks:bricks
    JBETRACE=true CLASSPATH=/usr/local/lib/spl.jar ./bricks

    clean:
    -rm -rf bricks *.dSYM *.o



    Here is the makefile I used, but if yours is different, then obviously
    we will have different results, and I won't be able to debug your
    program.


    Also, you have a bug in your initBricks(), you set y to a constant in
    the loop. Therefore all the new bricks beyond the first two rows will be
    displayed on the second row.

    Thank you very much - I am ashamed that I missed such an easy bug. Indeed, this one caused the problem. I have forgotten to add one tiny + sign before
    = one.

    Just remember to use printf to display your variables when you're
    debugging.


    --
    __Pascal Bourguignon__ http://www.informatimago.com/
    “The factory of the future will have only two employees, a man and a
    dog. The man will be there to feed the dog. The dog will be there to
    keep the man from touching the equipment.” -- Carl Bass CEO Autodesk

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)