Tic Tac Toe - Demo program

by shian ⌂, Thursday, August 20, 2020, 15:58 (40 days ago)
edited by shian, Tuesday, September 01, 2020, 17:20

-- Simple demo of Tic Tac Toe game; You play against the PC.
--
-- Copy/Paste the code into text file, run it in your console
-- and see how it works... (press control-C to break)
--
-- There are 3 levels - 1 is the most easy.
-- The code demonstrates only basic programming methods (procedure,
-- function, constant, include, if..then, for/while loops, etc).
-- (I did not debug too much... so for now I hope that it works OK).
--
-- Language: Euphoria 3.1.1; by shian, 20/8/2020
 
 
include get.e       -- prompt_string(), prompt_number()
include wildcard.e  -- upper()
 
-- with trace
-- trace(1)
 
constant SCREEN = 1
constant TRUE = 1
 
-- X is you; O is the PC; ' ' is blank
constant X = 'X', O = 'O', B = ' ', BOARD_FULL = 'F', CONTINUE_PLAY = -1
 
-- position to print the board
constant BOARD_LINE = 2, PROMPT_LINE = BOARD_LINE + 12, PROMPT_COLUMN = 3
 
sequence matrix -- string-sequence of length 9 (3+3+3)
integer player  -- player can be constant X (you) or O (the PC)
integer level   -- how clever is the PC? from 1 to 3 (1=child)
                --  we could add level 4 but the code is long enough...
 
sequence your_name
 
your_name = ""  -- enter your name before first game
 
procedure print_board()
-- simple/short method to print the board
-- using a single printf() command
    position(BOARD_LINE, 1)
    printf(SCREEN,
        "\t  * TicTacToe * \n" &
        "\t     Level %d  \n" &
        "\t~~~~~~~~~~~~~~~~~\n" &
        "\t    A   B   C  \n" &
        "\t  +---+---+---+\n" &
        "\t1 | %s | %s | %s |\n" &
        "\t  +---+---+---+\n" &
        "\t2 | %s | %s | %s |\n" &
        "\t  +---+---+---+\n" &
        "\t3 | %s | %s | %s |\n" &
        "\t  +---+---+---+\n",
    level & matrix)
end procedure
 
function string_to_index(sequence column_line)
-- example: if column_line is "a3" then return index 7 in matrix
    integer col, row
 
    col = upper(column_line[1]) - ('A' - 1)
    row = column_line[2] - '1'
 
    return row * 3 + col
end function
 
procedure you_play()
    sequence s
    integer p
 
    while TRUE do
        -- erase old prompt
        position(PROMPT_LINE, PROMPT_COLUMN)
        puts(SCREEN, repeat(' ', 80))
 
        -- new prompt
        position(PROMPT_LINE, PROMPT_COLUMN)
        s = prompt_string("Enter X (example: \"b1\"): ")
 
        -- valid input?
        if length(s) = 2 and find(s[1], "abcABC") and find(s[2], "123") then
            p = string_to_index(s)
            if matrix[p] = B then
                matrix[p] = X
                return
            end if
        end if
    end while
end procedure
 
function get_triplets()
    return {
        -- lines                            -- index of triplet
        matrix[1..3],                       -- [1]
        matrix[4..6],                       -- [2]
        matrix[7..9],                       -- [3]
        -- columns
        matrix[1] & matrix[4] & matrix[7],  -- [4]
        matrix[2] & matrix[5] & matrix[8],  -- [5]
        matrix[3] & matrix[6] & matrix[9],  -- [6]
        -- diagonals \ and /
        matrix[1] & matrix[5] & matrix[9],  -- [7]
        matrix[3] & matrix[5] & matrix[7]   -- [8]
    }
end function
 
procedure pc_play()
    integer row, pos, fallback
    sequence triplets, trio
 
    if level > 1 then -- (not used by level 1)
        fallback = 0
        triplets = get_triplets()
        pos = 0
    end if
 
    -- this loop tries level 3 then level 2 (then exits to level 1)
    for le = level to 2 by -1 do
 
        if level = 3 and fallback != 2 then
            -- PC tries to win you in level 3 (i.e. "OOO")
            trio = {{B,O,O}, {O,B,O}, {O,O,B}}
            fallback = 2
        elsif level = 2 or fallback = 2 then
            -- PC tries to block you in level 2 (e.g. "XXO")
            trio = {{B,X,X}, {X,B,X}, {X,X,B}}
            fallback = 1
        end if
 
        -- this loop checks each element of the current trio
        for col = 1 to 3 do
 
            -- win/block line (row is 1,2,3 here)
            row = find(trio[col], triplets[1..3])
            if row then
                pos = (row - 1) * 3 + col
                exit
            end if
 
            -- win/block column (row is A,B,C here)
            row = find(trio[col], triplets[4..6])
            if row then
                pos = row + (col - 1) * 3
                exit
            end if
 
            -- win/block diagonal \
            if equal(trio[col], triplets[7]) then
                pos = (col - 1) * 3 + col
                exit
            end if
 
            -- win/block diagonal /
            if equal(trio[col], triplets[8]) then
                pos = (col - 1) * 3 + (3 - col + 1)
                exit
            end if
        end for -- trio
 
        -- pos is the actual index in the matrix string
        if pos then
            matrix[pos] = O
            return
        end if
 
    end for -- level
 
    -- level 1 is a simple random guess
    if level = 1 or fallback = 1 then
        while TRUE do
            pos = rand(9)
            if matrix[pos] = B then
                matrix[pos] = O
                return
            end if
        end while
    end if
end procedure
 
function check_if_game_over()
    sequence t
 
    t = get_triplets()
 
    if find(repeat(X, 3), t) then
        return X            -- your triplet wins
    elsif find(repeat(O, 3), t) then
        return O            -- PC triplet wins
    elsif not find(B, matrix) then
        return BOARD_FULL   -- no winner
    else
        return CONTINUE_PLAY
    end if
end function
 
function well_done(integer over)
    sequence prefix, suffix
    integer new
 
    prefix = "       *** GAME OVER - THE WINNER IS "
    suffix = "! ***       "
    position(PROMPT_LINE, PROMPT_COLUMN)
    if over = X then
        puts(SCREEN, prefix & "YOU !!" & suffix)
    elsif over = O then
        puts(SCREEN, prefix & "THE PC" & suffix)
    elsif over = BOARD_FULL then
        puts(SCREEN, prefix & "NOBODY" & suffix)
    end if
 
    position(PROMPT_LINE + 2, PROMPT_COLUMN)
    printf(SCREEN, "New game %s [Y,N]? ", {your_name})
    new = 0
    while new != 'Y' and new != 'N' do
        new = upper(wait_key())
        puts(SCREEN, new)
    end while
 
    return new
end function
 
procedure start_new_game()
    sequence players
 
    -- who starts the game?
    players = {X, O}
    player = players[rand(2)]
 
    -- new blank board {B,B,B, B,B,B, B,B,B}, 9 blanks
    matrix = repeat(B, 9)
 
    clear_screen()
    position(2, 3)
    level = floor(prompt_number("Enter Level [1,2,3]: ", {1, 3}))
 
    if length(your_name) = 0 then
        position(4, 3)
        your_name = prompt_string("Enter your name: ")
    end if
    clear_screen()
end procedure
 
procedure main()
    integer over, new
 
    new = 'Y'
 
    -- this is the main loop of the games
    while new = 'Y' do
        start_new_game()
        print_board()
 
        over = CONTINUE_PLAY
 
        -- this loop is for a single game
        while over = CONTINUE_PLAY do
 
            if player = X then
                you_play()
                player = O
            else -- plyaer = O
                pc_play()
                player = X
            end if
 
            print_board()
            over = check_if_game_over()
        end while
 
        new = well_done(over)
    end while
 
end procedure
 
main()
 
-- End.
 
 

Tags:
demo

Homework-1 for Really beginner in Euphoria 3 programming

by shian ⌂, Friday, August 21, 2020, 07:20 (39 days ago) @ shian
edited by shian, Friday, August 21, 2020, 07:23

1. Try to use a loop that will print the following on the console's screen (shorter is better):

1.1 print 10 x's on consecutive lines and columns:


x
 x
  x
   x
    x
     x
      x
       x
        x
         x


1.2 print 5 x's & 5 o's on consecutive lines and columns:


x
 o
  x
   o
    x
     o
      x
       o
        x
         o


1.3 print numbers from 0 to 9 on consecutive lines and columns:


0
 1
  2
   3
    4
     5
      6
       7
        8
         9


1.4 print numbers from 9 to 0 on consecutive lines and columns:


9
 8
  7
   6
    5
     4
      3
       2
        1
         0


1.5 print numbers from 9 to 0 on consecutive lines and columns - start from right column:


         9
        8
       7
      6
     5
    4
   3
  2
 1
0


1.6 print x's on consecutive lines and columns - start from right column. On the fifth line print "Euphoria":


         x
        x
       x
      x
     Euphoria
    x
   x
  x
 x
x


1.7 print numbers from 10 to 100 on consecutive lines and columns:


10
 20
  30
   40
    50
     60
      70
       80
        90
         100


1.8 print strings of x's on consecutive lines and columns:


x
 xx
  xxx
   xxxx
    xxxxx
     xxxxxx
      xxxxxxx
       xxxxxxxx
        xxxxxxxxx
         xxxxxxxxxx


1.9 print strings of "Euphoria31" on consecutive lines and columns:


E
 Eu
  Eup
   Euph
    Eupho
     Euphor
      Euphori
       Euphoria
        Euphoria3
         Euphoria31


Good Luck! This was my first homework in programming (GW-BASIC) when I was 23 years old... and as you could guess: I failed! :-D

Tags:
lesson

How computer program works?

by shian ⌂, Tuesday, August 25, 2020, 09:18 (35 days ago) @ shian
edited by shian, Wednesday, August 26, 2020, 06:38

Personal computer program works in a perfect serial order. The PC (Personal Computer) reads and executes each statement that you write one by one, from top (beginning of program) to bottom (end of program). i.e.:

 
First statement
Second statement
Third statement
...
...
...
Last statement
 


The program ends when the PC reads and executes the last statement.

To keep the program running for a long time we must create a main loop, infinite loop usually. The entire program, as large as it is, runs from within that main loop.
The main loop normally waits for an event to occur, such as user typing on the keyboard or clicking with the mouse, or other events such as Internet or system request, etc. i.e.:

 
Some local and/or global declarations
 
any statement
 
start of main loop
  statement one
  statement two
  ...
  ...
end of main loop -- (go back to the start)
 
any statement
 


To make our program more readable and maintainable we must make it MODULAR.
So the main loop is normally calling subroutines, procedures or functions. Each subroutine (routine in short) is doing something very specific, for example the function get_key() in Euphoria 3 is checking if the user typed on the keyboard - that's all it does, nothing else.

Using MODULAR programming we can create very large programs without a problem. Each routine is doing a single task, and doing it well.

To make modular programming even better we create "libraries" of related routines, such as the libraries in Euphoria 3: graphics.e, sort.e, get.e, etc; or the libraries in Lib2 (by shian): string.e, machine2.e, utf8.e, etc.

Whenever we need a routine(s) from a library we just need to include the library in our program, i.e.:

 
include sort.e
 


That is it. In the example above all routines from sort.e library are now available to our program! That is modular, readable, maintainable procedural programming.
Now you know all the ancient secrets about modular procedural programming: it's all comes down to subroutines and libraries of subroutines (which also called "modules") - nothing else.

Note:
-----
OOP (Object Oriented Programming) is based on procedural programming, but OOP is a complete monarchy system, while procedural programming is a democracy. ...That explains why many people goes for OOP - they are afraid of freedom!

OK, so where were we? Yea, main loop that calls subroutines. It looks like this:

 
any statement
 
start of main loop
  ...
  key = get_key()
  ...
  click = get_mouse()
  ...
  ...
end of main loop
 
any statement
 


Now, to make our program useful, we need "branching statements" such as if..then. for example:

 
any statement
 
start of main loop
 
  key = get_key()
 
  click = get_mouse()
  ...
 
  if key = Escape then
    exit main loop
 
  else if key = make_me_coffee then
    my_coffee = coffee_cup()
 
  else if click = bomb_icon then
    shutdown_system()
 
  else
    print "come on, do something, time is money! (as if)."
 
  end if
  ...
end of main loop
 
any statement
 


The key & click in the example above are called: variables. Variables are holding values, so for example key is holding the value that the get_key() routine returns, i.e.: key = get_key().

We must declare variables before we use them, i.e.:

 
any statement
 
integer key
sequence click
 
start of main loop
 
  key = get_key()
 
  click = get_mouse()
  ...
 
end of main loop
 
any statement
 


To make things more human we should add comments here and there which describe WHY we are doing this or that, i.e.:

 
any statement
 
integer key
sequence click
 
-- this is a comment that tells us WHY we need this loop
start of main loop
 
  key = get_key()
  click = get_mouse()
  ...
 
  if key = Escape then
    exit main loop
 
  else if key = make_me_coffee then
    my_coffee = coffee_cup() -- a comment tells us WHY we need coffee
 
  else if click = bomb_icon then
    shutdown_system()        -- a comment tells us WHY we use brutal force
 
  else
    print "come on, do something, time is money! (as if)."
 
  end if
  ...
end of main loop
 
any statement
 


In real Euphoria 3 code the above example will look similar to this:

 
-- my first program for learning Euphoria 3
-- ----------------------------------------
 
-- here I declare all constants (constant is a read-only variable)
constant TRUE = 1
constant ESCAPE = 27, MAKE_ME_COFFEE = -500, BOMB_ICON = 10
 
function coffee_cup()
   integer coffee
 
   -- some statements
   coffee = 2
 
   return coffee
end function
 
function get_my_mouse()
   integer mouse
 
   -- some statements
   mouse = 1
 
   return mouse
end function
 
procedure shutdown_system()
   -- some statements
end procedure
 
 
-- here I declare all local variables for this module
integer key, my_coffee
object click
 
clear_screen()
 
-- the main loop of my program is waiting for the user
-- to press a key or click the mouse
while TRUE do
 
  key = get_key()
 
  click = get_my_mouse()
 
  if key = ESCAPE then
    exit -- end of program, exit main loop
 
  elsif key = MAKE_ME_COFFEE then
    my_coffee = coffee_cup() -- if my_coffee = 1 then pause program for break
 
  elsif click = BOMB_ICON then
    shutdown_system()        -- in case the program gets on my nerves
 
  else
    if key != -1 then
       position(1, 1)
       puts(1, "come on, do something, time is money! (as if).")
    end if
 
  end if
 
end while
 
clear_screen()
 
-- End of program.
 

OK, to sum up, computer program is a sequence of statements that the computer executes in serial order, one by one, to accomplish some task.

Here is a real, working, Euphoria 3 program, that divides two numbers and prints the result on the screen (copy/paste to text file 'divide.ex' and run it):

 
include get.e -- prompt_number()
 
function divide(atom n1, atom n2)
  atom r 
 
  r = n1 / n2
 
  return r
end function
 
 
constant TRUE = 1, SCREEN = 1
 
atom number1, number2, result
 
clear_screen()
 
while TRUE do
  number1 = prompt_number("Enter number 1: ", {})
  number2 = prompt_number("Enter number 2 (0 = Quit): ", {})
 
  if number2 = 0 then
    exit -- exit loop to end program
  else
    result = divide(number1, number2)
    printf(SCREEN, "%g / %g = %g\n\n", {number1, number2, result})
  end if
end while
 
puts(SCREEN, "\nDone.\n")
 
-- end of program.
 

Tags:
lesson

bit, byte - what are they?

by shian ⌂, Wednesday, September 02, 2020, 10:57 (27 days ago) @ shian

Modern computers are using digital signals. :confused:

Digital signal can be either: electrical current exists or electrical current not exists in a register. So we get base-2 numeral system or binary numeral system, which uses only two symbols: typically "0" (zero) and "1" (one).

A bit is a binary number, i.e. 0 or 1. This is the only numbers that a digital equipment knows (PC, CPU, RAM, HDD, SSD, Internet, etc). But a bit can only represent 2 numbers, 0 or 1, so we must combine few bits to represent larger numbers, in modern computers a group of 8-bits, also called byte, is the basic data unit.

A byte (8-bits) can represent 256 numbers, 0 to 255. i.e. 2 to the power 8 is 256. Let's see base-10 (Decimal) and base-2 (Binary) side by side:

Dec...Binary
--------------
000...00000000
001...00000001
002...00000010
003...00000011
004...00000100
005...00000101
006...00000110
007...00000111
008...00001000
009...00001001
010...00001010
...
246...11110110
247...11110111
248...11111000
249...11111001
250...11111010
251...11111011
252...11111100
253...11111101
254...11111110
255...11111111

Everything in computers is done with units of byte (8-bits). Now, if you need larger numbers then you just combine bytes, for example 2 bytes (16-bits) can represent 65536 numbers, i.e. 2 to the power 16 is 65536; and 4 bytes (32-bits) can represent 4294967296 numbers, i.e. 2 to the power 32 is 4294967296.


Now, to convert between Binary system that the PC is using and Decimal system that people are using it's a bit tedious. Therefore the solution is to represent Binary numbers (base-2 numbers), which are extremely long, in base-16 (Hexadecimal, or hex) numeral system, since each 4-bits are corresponding to exactly 1 hexadecimal digit (0 to F). As you can see:

Dec: Bin  = Hex
--------------
00:  0000 = 0
01:  0001 = 1
02:  0010 = 2
03:  0011 = 3
04:  0100 = 4
05:  0101 = 5
06:  0110 = 6
07:  0111 = 7
08:  1000 = 8
09:  1001 = 9
10:  1010 = A
11:  1011 = B
12:  1100 = C
13:  1101 = D
14:  1110 = E
15:  1111 = F

Example:

Dec...Binary  ...Hex
--------------------
000...00000000...00
001...00000001...01
002...00000010...02
003...00000011...03
004...00000100...04
005...00000101...05
006...00000110...06
007...00000111...07
008...00001000...08
009...00001001...09
010...00001010...0A
011...00001011...0B
012...00001100...0C
013...00001101...0D
014...00001110...0E
015...00001111...0F
016...00010000...10
...
240...11110000...F0
241...11110001...F1
242...11110010...F2
243...11110011...F3
244...11110100...F4
245...11110101...F5
246...11110110...F6
247...11110111...F7
248...11111000...F8
249...11111001...F9
250...11111010...FA
251...11111011...FB
252...11111100...FC
253...11111101...FD
254...11111110...FE
255...11111111...FF

OK, so for example to convert the base-2 number 11111010 (250 in decimal) to base-16 all we need to do is group the number, from right to left, into groups of 4-bits, i.e. 1111 1010;
Now, 1010 is A, and 1111 is F, therefore 11111010 is the hex number FA. Simple.


Worth to mention a branch of algebra called Boolean algebra, it is using only the binary numbers 0 and 1. In boolean algebra 0 is FALSE and 1 is TRUE. Although boolean algebra is more useful for hardware designers rather than for software programmers - FALSE (0) and TRUE (1) are always the result of logical and relational operators in programming, and this is also very useful for logical decisions (branching statements), as well as a factor in regular math equations.


OK, to sum up:

In Euphoria 3 you will not need bits and bytes unless you are advanced programmer. So don't worry about it.

Anyway, there are high level functions in Euphoria to deal with bits: int_to_bits() and bits_to_int()

Also there are high level functions to deal with bytes: int_to_bytes() and bytes_to_int()

There are also lots of low level functions to deal with bits in Euphoria 3 (also in Lib2), such as: and_bits() and eqv_bits() or peek4u().

These low level functions can operate on a single atom (number) or on any arbitrarily (sub)sequence of atoms (numbers).

Where were we? Ha! Bits! Yea. Nice. :lookaround:


BTW, you can tell if a number is negative by the MSB (Most Significant Bit) which is the leftmost bit of a binary number: if it is 1 then the number is negative, if it is 0 then the number is positive. This method is called Two's complement. Again: unless you are advanced programmer - you don't care about it.

Tags:
bit, lesson, byte, boolean

Balance - Demo program

by shian ⌂, Sunday, September 06, 2020, 13:28 (23 days ago) @ shian

[image]You can download the Balance demo program from the Demo source programs for learning Euphoria 3. (Delete your browser's history to update the home page if needed...).


The Balance demo program demonstrates how to retrieve records from a simple colon-separated-values file, which is actually a CSV (Comma Separated Values) file that is using colon ':' instead of comma ',' to separate between fields.

The CSV database looks like this:

20120930:1100:deposit:2500
20121001:1100:rent pmt:-1400
...


The function split() from string.e in Lib2 1.41, is doing the work easily:

-- demo: BALANCE CALCULATOR, using Euphoria 3.1.1 + Lib2 v1.41
-- Version 1.10, 06/Sep/2020, shian.
 
-- demonstrates how to retrieve records from a simple colon-
-- separated-values file, ':', (text database).
 
-- In version 1.10: instead of loading *entire* database file into
-- memory we retrieve the records *one by one*, for efficiency.
 
-- Type in terminal with: edu balance.ex
-- Then run the program from the menu with: Esc-e
 
 
 
include graphics.e  -- colors
include string.e    -- Lib2: split(), val()
include machine2.e  -- Lib2: TRUE, EMPTY, pause(), iif()
 
constant DATABASE_FILE = "balance.db"
 
constant SCREEN = 1, EOF = -1
 
 
-- set screen colors
constant COLOR_NORMAL = 1,
           COLOR_PLUS = 2,
          COLOR_MINUS = 3
procedure set_color(integer color)
    bk_color(BLACK)
 
    if color = COLOR_NORMAL then
        text_color(WHITE)
    elsif color = COLOR_PLUS then
        text_color(BRIGHT_CYAN)
    elsif color = COLOR_MINUS then
        text_color(YELLOW)
    end if
end procedure
 
 
integer database_fn
database_fn = EOF -- initialize
 
-- return the *next* line from a database text file
function get_text_line(sequence file_name)
    object next_line
 
    -- open text file for reading only once on the beginning
    if database_fn = EOF then
        database_fn = open(file_name, "r")
 
        -- error?
        if database_fn = EOF then
            puts(SCREEN, "\nCannot find or open the file '" &
                            file_name & "' for reading!\n")
            pause()
            abort(1)
        end if
    end if
 
    -- get and return the next line in file
    next_line = gets(database_fn)
    if atom(next_line) then -- End of file? (EOF)
        close(database_fn)  -- close the file
        database_fn = EOF   -- set back flag that file is closed
    end if
 
    return next_line
end function
 
 
-- pause display after few lines
function press_any_key(integer line_counter)
    line_counter += 1
 
    if remainder(line_counter, 10) = 0 then
        puts(SCREEN, "Press any key to continue...")
        pause()
        puts(SCREEN, '\r') -- return cursor to column 1 in current line
    end if
 
    return line_counter
end function
 
 
-- some constants for table and formating line
constant T_WIDTH = 54,
          H_LINE = '+' & repeat('-', T_WIDTH - 2) & '+' & '\n',
     COMMON_LINE = "| %-20s | %+12.3f | %+12.3f |\n"
 
constant DELIMIT = ":\r\n"  -- colon ':', or end-of-line control characters
 
 
-- print horizontal line in table
procedure horizontal_line()
    set_color(COLOR_NORMAL)
    puts(SCREEN, H_LINE)
end procedure
 
 
-- display the balance table on the screen
procedure print_balance()
    sequence min_val, max_val, avg_val
    atom number, balance
    integer line_counter
    object line -- string-sequence or atom EOF
 
    -- initialize variables
    min_val = {0, 0}
    max_val = {0, 0}
    avg_val = {0, 0}
    balance = 0
    line_counter = 0
 
    -- print table captions
    set_color(COLOR_NORMAL)
    puts(SCREEN, mset("*** BALANCE CALCULATOR ***", T_WIDTH, ' ') & '\n')
    horizontal_line()
    printf(SCREEN, "| %-20s | %-12s | %-12s |\n",
        {mset("Use", 20, ' '), mset("Value", 12, ' '), mset("Sub Total", 12, ' ')}
    )
    horizontal_line()
 
    -- print the balance table (retrieve lines from database one by one)
    while TRUE do
        line = get_text_line(DATABASE_FILE)
        if atom(line) then
            exit    -- line is EOF (end of file)
        end if
 
        -- split line into fields, i.e. {"field1", field2", "field3", "field4"}
        line = split(line, DELIMIT)
 
        -- make sure line is valid (don't crash)
        if length(line) >= 4 then
            number = val(line[4])
            balance += number
 
            -- print line
            set_color(iif(balance < 0, COLOR_MINUS, COLOR_PLUS))
            printf(SCREEN, COMMON_LINE, {line[3], number, balance})
 
            -- update statistics
            if number  < min_val[1] then min_val[1] = number    end if
            if balance < min_val[2] then min_val[2] = balance   end if
            if number  > max_val[1] then max_val[1] = number    end if
            if balance > max_val[2] then max_val[2] = balance   end if
            avg_val[1] += number
            avg_val[2] += balance
 
            line_counter = press_any_key(line_counter)
        end if
    end while
 
    -- print table statistics & total
    horizontal_line()
    set_color(COLOR_NORMAL)
    printf(SCREEN, COMMON_LINE, {"MINIMUM:"} & min_val)
    printf(SCREEN, COMMON_LINE, {"MAXIMUM:"} & max_val)
    printf(SCREEN, COMMON_LINE, {"AVERAGE:"} & (avg_val / line_counter))
 
    horizontal_line()
    set_color(iif(balance < 0, COLOR_MINUS, COLOR_PLUS))
    printf(SCREEN, "| %-20s | %+12.3f | %12s |\n", {"TOTAL:", balance, ""})
 
    horizontal_line()
end procedure
 
 
-- start the program here
 
set_color(COLOR_NORMAL)
clear_screen()
 
print_balance()
pause()
 
 
-- end.
 

Tags:
demo

CSV Database - Demo program

by shian ⌂, Sunday, September 13, 2020, 14:27 (16 days ago) @ shian

CSV (Comma Separated Values) is a very simple text file database. Used by many applications, therefore useful for export and import data to/from other programs.

You can download the demo from here.
OK, that's the program (I can use Euphoria 3 syntax coloring!!!) :ok: :

 
-- short demo of creating and using CSV (Comma Separated Values) database.
-- in this database we store 4 fields in each line: name, gender, age, hobby.
--
-- shian, v1.00, 13/September/2020 (hopefully without bugs)
 
 
include get.e
include string.e    -- Lib2 1.41
include machine2.e  -- Lib2 1.41
 
 
-- with trace -- for debugging
 
 
-- file constants
constant FILE = "hobby.csv",    -- name of CSV database
         DELIMITER = ",",       -- delimiter string, normally a comma ','
         REPLACEMENT = ";",     -- replace delimiter in-string with another char
         NEW_LINE = "\r\n",     -- (CR+LF is the Internet standard of New-line)
         ALL_DELIMITERS = DELIMITER & NEW_LINE  -- used by split() function
 
 
 
-- append a single record to the end of the database file
procedure append_record()
    integer fn -- Euphoria's file number
    sequence name, hobby
    object gender, age
    sequence line
 
    -- trace(1) -- for debugging
 
    -- open text file for appending
    fn = open(FILE, "a")
 
    if fn = -1 then -- open error?
        puts(1, "\nCannot open '" & FILE & "' for appending!\n")
        abort(1)
    end if
 
    -- get user's input
    clear_screen()
    name   = prompt_string("Enter Name: ")
    gender = prompt_number("Enter Gender [Male = 0; Female = 1]: ", {0, 1})
    age    = prompt_number("Enter Age: ", {1, 120})
    hobby  = prompt_string("Enter Hobby: ")
 
    -- make valid strings
    name   = translate(name, DELIMITER, REPLACEMENT)
    gender = str(floor(gender))
    age    = sprintf("%g", age)
    hobby  = translate(hobby, DELIMITER, REPLACEMENT)
 
    -- append line to the CSV database and close file
    line = join({name, gender, age, hobby}, DELIMITER)
    puts(fn, line & NEW_LINE)
 
    close(fn)
end procedure
 
 
-- print all records in the database file
procedure print_records()
    integer fn -- Euphoria's file number
    object line
    integer line_number
 
    -- open text file for reading
    fn = open(FILE, "r")
 
    if fn = -1 then -- open error?
        puts(1, "\nCannot open '" & FILE & "' for reading!\n")
        abort(1)
    end if
 
    line_number = 0
 
    -- display all records in database
    while TRUE do
        line = gets(fn)
 
        if atom(line) then
            puts(1, "\nDone... ")
            pause()
            exit
        end if
 
        line_number += 1
 
        -- split line into fields,
        -- e.g. {"field1", "field2", "field3", "field4"}
        line = split(line, ALL_DELIMITERS)
 
        -- avoid crash, make sure that 4 fields exist
        if length(line) >= 4 then
 
            -- convert 0 or 1 to gender
            line[2] = iif(equal(line[2], "0"), "Male", "Female")
 
            printf(1, '\n' &
                "Line #%03d\n" &
                "=========\n" &
                "[1] Name:   %s\n" &
                "[2] Gender: %s\n" &
                "[3] Age:    %s\n" &
                "[4] Hobby:  %s\n", line_number & line[1..4])
 
            puts(1, "...\n")
            pause()
        end if
    end while
end procedure
 
 
-- main menu runs the program
procedure main_menu()
    integer choice
 
    -- put menu inside endless loop
    while TRUE do
        clear_screen()
        puts(1,
            " Hobby CSV Database\n" &
            " ******************\n\n")
 
        -- get user's choice
        choice = floor(prompt_number(
            " 0=Quit, 1=Add record, 2=Print records: ", {0, 2}))
 
        if choice = 1 then
            append_record()
        elsif choice = 2 then
            print_records()
        else
            exit -- end.
        end if
    end while
end procedure
 
 
main_menu() -- start here
 
 
-- End.
 

Tags:
Database, demo, csv

My first program in Euphoria 3.1.1 - Input & Output

by shian ⌂, Sunday, September 20, 2020, 13:51 (9 days ago) @ shian

See how easy is to write a program in Euphoria 3, using 'edu' (from Lib2)...: click here to watch video.

Tags:
demo, lesson

RSS Feed of thread
powered by my little forum