Jump to content

Barand

Moderators
  • Posts

    24,501
  • Joined

  • Last visited

  • Days Won

    818

Posts posted by Barand

  1. ... or ...

        $res = $pdo->query("SELECT Lvl
                                 , Sub
                            FROM shadd_1
                            ORDER BY Lvl DESC, Sub
                            ");
        $results = $res->fetchAll(PDO::FETCH_GROUP | PDO::FETCH_COLUMN);
        
        foreach ($results as $lvl => $arr)  {
            echo "$lvl <UL>";
            foreach ($arr as $sub)  {
                echo "<li>$sub</li>";
            }
            echo "</ul>";
        }

    FYI - the $results array (slightly simpler than the $data array in above post) looks like this..

    Array
    (
        [ULE] => Array
            (
                [0] => BASIC lug
                [1] => BASIC lug
            )
    
        [ACE] => Array
            (
                [0] => ger
            )
    
    )

     

  2. 1 hour ago, shadd said:

    how can i make sure it does not go back to start time duration on page refresh?

    Store the completion time instead of the duration. Count down until the end time is reached.

     

    1 hour ago, shadd said:

    how can i accustom it to recieve the count down duration using php variable?

    My usual method is to store a variable in a hidden input field in PHP  then access that field's value from javascript.

  3. @Psycho the PDO result/statement object is traversable whether you use query() or execute().

    The mysqli result object is traversable (when the result of a query) but the statement object as a result of execute() is not (as well as having a different set of methods to process).

    This adds to my theory that mysqli result class and statement class were developed by two teams who never spoke to one another.

    EG

    $res = $pdo->query("SELECT name FROM reindeer");
    foreach ($res as $r) {
        echo $r['name'] . "<br>";
    }

    results...

    Comet
    Cupid
    Dasher
    Vixen
    Prancer
    Dancer
    Donner
    Blitzen

     

    • Like 1
    • Haha 1
  4. Don't use "select *". Specify the columns you need.

    Then use a foreach loop, not a for loop.

    Don't embed variables in the sql string, use prepared queries with placeholders, then execute with the variables passed as parameters.

    $sql_list = "SELECT ID FROM dados_socios WHERE usuario = ? ORDER BY ID";
    $result_list = $conn->prepare($sql_list);
    $result_list->execute([$usario]);
    
    echo "<select>";
      foreach {$result_list as $row)
        echo "<option>ID: {$row['ID']}</option>";
      }
     echo "</select>";

     

    • Like 1
  5. PHP runs on the server. - Javascript runs on the client.

    On completion of the PHP it sends the page to the client where the javascript runs.

    At the time you "echo $array;" the js variable "i" does not yet exist. (Error thrown if turn on error reporting)

    By the time the javascript runs "$array" no longer exists.

    • Like 1
  6. 3 hours ago, jodunno said:

    However, i also recommend creating only two possible doors: bottom and right.

    I agree those are sufficient to define and draw the cell connections but, to be able to trace the paths through the network, it's a lot easier to know that A connects to B and also that B connects to A - that requires the top and left ones too.

    The database gave me an easy way to check for uniqueness and that I wasn't just recreating the same grid over and over.

    • Like 1
  7. Consider a student who has a maths exam at the end of each term. They score 60% in each of the first 2 terms but they are ill for the third so no score can be entered.

    If the "score" column in the result table is defined

    score int NOT NULL DEFAULT '0'

    then not inputting the score inserts a value of 0%. When the average score is calculated at the end of the year it is 40% ((60 + 60 + 0) / 3).

    On the other hand, if it is defined as

    score int

    thus allowing a NULL value if omitted, the the average is a much fairer 60% ((60 + 60) / 2).

    Consider NULL to be the absence of known value.

    Use NOT NULL when it is mandatory that a value is provided.

  8. Because your table has 8 columns but you only want to insert into 3 of them, it will attempt to insert NULL values (or the columns' specified default values) into the remaining 5.

    Therefore, if a column is specified as NOT NULL, it should have a default value if you don't always populate it when inserting a new record.

    In addition, the id column should be an auto_incremented INT value by default and also excluded from the insert.

  9. 2 hours ago, jodunno said:

    Multiple svg images is also problematic because if one shrinks the browser window then the tiles are no longer connected.

    The advantage of SVG (Scalable Vector Graphics) is that, as the name implies, they are scalable. Resizing should not separate the elements.

    Take this example svg

    <svg width='100%' viewBox='0 0 100 100' >
        <circle cx='30' cy='30' r='25' fill='#333'/>
        <circle cx='70' cy='70' r='25' fill='#333'/>
        <line x1='30' y1='30' x2='70' y2='70' stroke='#333' stroke-width='8'/>
    </svg>

    The viewBox defines the source coordinate system, the width defines the output size.  If I output the same image into two differently sized containers, the image expands to fit.

    EG

    <?php
        
        $svg = "<svg width='100%' viewBox='0 0 100 100' >
                    <circle cx='30' cy='30' r='25' fill='#333'/>
                    <circle cx='70' cy='70' r='25' fill='#333'/>
                    <line x1='30' y1='30' x2='70' y2='70' stroke='#333' stroke-width='8'/>
                </svg>
               ";
    ?>
    
    <!DOCTYPE html>                              
    <html lang='en'>
    <meta charset='utf-8'>
    <head>
    <title>Example</title>
    </head>
    <body>
        
        <div style='width:20%'>
            <?=$svg?>
        </div>
        
            
        <div style='width:50%'>
            <?=$svg?>
        </div>
    </body>
    </html>

    image.png.5288d2a1adc9dee3671af17215c05e34.png

    You just need to to create all your connected cells inside a single SVG image.

    I have been having a go at this grid problem myself and now have version which has just created 500 unique  6x5 grid maps with no circular routes and no isolated groups of cells. Each time you try to connect two cells it first verifies that it will not result in a circular path. It also verifies that all cells are reachable from any other cell. The paths through the maps are saved to a database and the path is defined as UNIQUE to ensure no repeats are saved. My grid table is like this...

    image.thumb.png.f0438863f3da637ee5f9b9fc38c36fe0.png

    Code...

    <?php
        require 'db_inc.php';
        $pdo = mdbConnect('db1');
        
        
    $invalid = 0;
    
    $num_maps_required = 500;        // if 1 is required it is displayed. If multiple they as saved to database
    $gridWidth  = 6; 
    $gridHeight = 5;
    
    
    for ($g=0; $g<$num_maps_required; $g++)   {
    
        ################################################################################
        #  BUILD THE GRID SQUARES
        ################################################################################
        // Grid settings
        $svgSize    = 100;
        $svgColor   = '#333';
    
        // Images (Icons)
        $iconExit     = '&#128274;'; // Shows a lock
        $iconMonster  = '&#129430;'; // Shows a dinosaur
        $iconStart    = '&#128578;'; // Shows a smiley
        $iconTreasure = '&#127873;'; // Shows a gift
    
        // Calculate Monsters
        $monsters = ceil($gridHeight * $gridWidth * 0.15);
    
        // Calculate Treasures
        $treasures = floor($gridHeight * $gridWidth * 0.25);
    
        // Make iconBox and shuffle
        $iconBox = array_merge(
            array_fill(0, $treasures, $iconTreasure),
            array($iconExit),
            array_fill(0, $monsters, $iconMonster),
            array($iconStart),
            array_fill(0, $gridHeight * $gridWidth - $monsters - $treasures - 2, '')
        );
        shuffle($iconBox);
    
        $cells = [];
        foreach ($iconBox as $k => $icn)  {
            $r = intdiv($k, $gridWidth);
            $c = $k % $gridWidth;
            $poss = [ $k-$gridWidth, $k-1, $k+1, $k+$gridWidth ];
            if ($r == 0) unset($poss[0]);
            if ($r == $gridHeight - 1) unset($poss[3]);
            if ($c == 0) unset($poss[1]);
            if ($c == $gridWidth - 1) unset($poss[2]);           
            $cnx = array_fill_keys($poss, 0);
            $cells[] = [ 'icon' => $icn,
                         'cnxs' => $cnx,
                         'reachable' => []
                       ];
        }
    
        ################################################################################
        #  RANDOMLY CREATE A LINK BETWEEN EACH PAIR OF ADJACENT COLUMNs AND 
        #  ONE OR TWO LINKS BETWEEN EACH PAIR OF ADJACENT ROWS.
        ################################################################################
            $rows = range(0, $gridHeight-1);
            $cols = range(0, $gridWidth-2);
            shuffle($rows);
            foreach ($cols as $c)  {
                $r = array_pop($rows);
                $s = $r * $gridWidth + $c;
                $e = $s + 1;
                connectCells($s, $e, $cells);
            }
    
            $rows = range(0, $gridHeight-2);
            $cols = range(0, $gridWidth-1);
            shuffle($cols);
            foreach ($rows as $r)  {
                for ($i=0; $i<rand(1,2); $i++)
                {
                $c = array_pop($cols);
                $s = $r * $gridWidth + $c;
                $e = $s + $gridWidth;
                connectCells($s, $e, $cells);
                }
            }
    
        ################################################################################
        #  FIND THE UNCONNECTED CELLS AND CONNECT THEM TO THEIR NEIGHBOURS
        #    --  NOTE coonectCells() CHECKS NO CIRCULAR PATH IS CREATED
        ################################################################################
    
            #  $loneCells = array_filter($cells, fn($v)=>empty(array_filter($v['cnxs'])));
            $loneCells = array_filter($cells, fn($v)=>count(array_filter($v['cnxs'])) < 2 );
            uasort($loneCells, fn($a, $b)=>rand(0,1)? -1: 1);
            foreach ($loneCells as $start => $lc)  {
                foreach ($lc['cnxs'] as $end => $v)  {
                    if (!$v )  {
                        connectCells($start, $end, $cells);
                    }
                }
            }
    
    
        ################################################################################
        #  MAP NOW GENERATED
        #  - VERIFY
        #  - SAVE THE ROUTES THROUGH THE MAZE FOR SUBSEQUENT ANALYSIS
        #  - PRINT THE MAP
        ################################################################################
    
            $cells[0]['reachable'] = [];
            findReachable(0, $cells, $cells[0]['reachable']);
            $pathLength = count($cells[0]['reachable']);
            $path = join(', ', $cells[0]['reachable']);
            if ($pathLength != $gridHeight * $gridWidth) {
                ++$invalid;
                echo "<h1>INVALID GRID MAP $invalid</h1>" ;
                echo "$pathLength cells: $path<br>";
            }
            else switch ( $num_maps_required )  {
                    case 1:  echo printMap($gridHeight, $gridWidth, $cells);
                             break;    
                    default: saveMap($pdo, $gridHeight, $gridWidth, $path, $pathLength, $cells);
                             break;
                 }
    
    }
    
    ################################################################################
    #   FUNCTIONS
    ################################################################################
    
        function saveMap(PDO $pdo, $gridHeight, $gridWidth, $path, $pathLength, &$cells)
        {
            $pdo->beginTransaction();
            try {
                $stmtg = $pdo->prepare("INSERT IGNORE INTO grid (height, width, path, path_length) VALUES (?, ?, ?, ?)");
                $stmtgc = $pdo->prepare("INSERT INTO grid_cell (grid_id, cell_no, icon) VALUES (?, ?, ?)");
                $stmtcnx = $pdo->prepare("INSERT INTO cell_cnx (grid_id, from_cell, to_cell) VALUES (?, ?, ?)");
                                                   
                $stmtg->execute( [ $gridHeight, $gridWidth, $path, $pathLength ] );
                $grid_id = $pdo->lastInsertId();                                                                                                    #TODO grid_cell table, cell_cnx table
                
                foreach ($cells as $cno => $cl)  {
                    $stmtgc->execute( [ $grid_id, $cno, $cl['icon'] ] );
                    
                    foreach ($cl['cnxs'] as $k => $v)  {
                        if ($v && $k > $cno)  {
                            $stmtcnx->execute( [ $grid_id, $cno, $k ] );
                        }
                    }
                }
                
                $pdo->commit();
            }
            catch(PDOException $e) {
                $pdo->rollBack();
                throw $e;
            }
        }
    
        /**
        * Recursively searches all possible paths through the maze from start 
        * and stores new reachable cells in array
        * 
        * @param int $from   starting cell
        * @param array pointer $cells  cells array
        * @param array pointer $reachable  all reachable cells
        */
        function findReachable($from, &$cells, &$reachable)
        {
            foreach ($cells[$from]['cnxs'] as $k => $v)  {
                if ($v) {
                    if (!in_array($k, $reachable))  {
                        $reachable[] = $k;
                        findReachable($k, $cells, $reachable);
                    }
                }
            }
        }
    
    
        function connectCells($start, $end, &$cells)
        {
            $cells[$end]['reachable'] = [];
            findReachable($end, $cells, $cells[$end]['reachable']);
            #
            # if cell is already reachable then connecting to it would result in a circular path
            #
            if (in_array($start, $cells[$end]['reachable'])) {
                return 0;
            }
            $cells[$start]['cnxs'][$end] = 1;   
            $cells[$end]['cnxs'][$start] = 1;
            return 1;   
        }            
    
        function printMap ($rows, $cols, &$cells)
        {
            $cellSize = 80;
            $cellBgd  = '#333';
            $wid = $cols * $cellSize;
            $ht  = $rows * $cellSize;
            $ix = 10;
            $iy = 10;
            $cx = $cy = $cellSize/2;
            $isz = $cellSize - 20;
            $ty = 47;
            $ty2 = $cellSize - 14;
            
            $svg = "<svg width='$wid'  viewBox='0 0 $wid $ht'>
                    <rect x='0' y='0' width='$wid' height='$ht' fill='linen'  />
                    ";
            foreach ($cells as $k => $cell) {
                $transx = $k % $cols * $cellSize;
                $transy = intdiv($k, $cols) * $cellSize;
                $sColor = count(array_filter($cell['cnxs']))==1 ? '#aaa' : $cellBgd;
                $svg .= "<g transform='translate($transx, $transy)' >
                        <rect x='$ix' y='$iy' width='$isz' height='$isz' rx='8' ry='8' fill='$cellBgd' stroke='$sColor' stroke-width='2'/>
                        ";
                foreach ($cell['cnxs'] as $c => $connected)  {
                    if ($c > $k && $connected)
                        switch ($c - $k)  {
                            case 1:      $svg .= "<path d='M $cx $cy h $cellSize' stroke='$cellBgd' stroke-width='10' />\n"; break;
                            case $cols:  $svg .= "<path d='M $cx $cy v $cellSize' stroke='$cellBgd' stroke-width='10' />\n"; break;
                        }
                }      
                $svg .= "<text x='$cx' y='$ty' font-size='24px' fill='#FFF' text-anchor='middle'>{$cell['icon']}</text>
                         <text x='$cx' y='$ty2' font-size='12px' fill='#FFF' text-anchor='middle'>$k</text>
                        </g>
                        ";
            }
                        
            $svg .= "</svg>\n";
            return $svg;
        }
    ?>

    The next step is to be able to select a stored grid map from the DB and display it.
     

  10. My code...

    <!DOCTYPE html>                              
    <html lang='en'>
    <meta charset='utf-8'>
    <head>
    <title>Example</title>
    <style type="text/css">
        body {
            font-family: verdana, sans-serif;
            font-size: 12pt;
            padding: 20px;
        }
        h2 {
            font-variant: small-caps;
            text-align: center;
        }                                   
        .chapter {
            width: 100%;
            margin-top: 20px;
            margin-bottom: 20px;
            border-bottom: 5px solid blue;
            text-align: center;
        }
        .head-text {
            display: inline;
            padding: 0 10px;
            background-color: white;
            font-family: gabriola, cursive;
            font-size: 20pt;
            font-style: italic;
            font-weight: 600;
            position: relative;
            top: +26px;
        }
        p {
            text-align: justify;
            line-height: 22px;
        }
    </style>
    </head>
    <body>
    <h2>Book 3</h2>
    <div>
        <div class='chapter'>
            <div class='head-text'>
                Caput vigesimum septimum
            </div>
        </div>
    
            <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas porttitor congue massa. 
            Fusce posuere, magna sed pulvinar ultricies, purus lectus malesuada libero, sit amet commodo 
            magna eros quis urna.
            </p>
    
            <p>Suspendisse dui purus, scelerisque at, vulputate vitae, pretium mattis, nunc. Mauris eget 
            neque at sem venenatis eleifend. Ut nonummy. Fusce aliquet pede non pede. Suspendisse 
            dapibus lorem pellentesque magna. Integer nulla. Donec blandit feugiat ligula. Donec hendrerit, 
            felis et imperdiet euismod, purus ipsum pretium metus, in lacinia nulla nisl eget sapien. 
            Donec ut est in lectus consequat.
            </p>
    
        <div class='chapter'>
            <div class='head-text'>
                Epilogus
            </div>
        </div>
    
            <p>Nunc viverra imperdiet enim. Fusce est. Vivamus a tellus. Pellentesque habitant morbi 
            tristique senectus et netus et malesuada fames ac turpis egestas. Proin pharetra nonummy 
            pede. Mauris et orci. Aenean nec lorem. In porttitor. Donec laoreet nonummy augue.
            </p>
    </div>
    </body>
    </html>

    image.png.c1ed3993d05be31e162071e180bfb2fe.png

  11. 2 hours ago, shadd said:

    $theme='b|||c|||d|||e|||f|||g|||h|||i|||j,'
    which i explode like so:
    $sub=explode(',',$theme);

    Why explode on comma when they too are delimited by '|||' ?

     

    2 hours ago, shadd said:

    each element in theme string corresponds to an id in the string above

    If that is the case (although your example says otherwise) then you can use array_combine() to store the related values

    EG

    $p_id = "1.1.51|||1.1.51.2|||1.1.51.3|||1.1.51.4|||1.1.51.5|||1.1.51.6|||1.1.51.7|||1.1.51.8|||1.1.51.9";
    $theme = 'b|||c|||d|||e|||f|||g|||h|||i|||j';
    
    $i = explode('|||', $p_id);
    $t = explode('|||', $theme);
    
    $result = array_combine($i, $t);
    
    foreach ($result as $id => $theme)   {
        echo "$id : $theme <br>";
    }

    giviing

            1.1.51 : b 
            1.1.51.2 : c 
            1.1.51.3 : d 
            1.1.51.4 : e 
            1.1.51.5 : f 
            1.1.51.6 : g 
            1.1.51.7 : h 
            1.1.51.8 : i 
            1.1.51.9 : j 
    

     

  12. Perhaps...

    $a = explode(',', '1.1.51,1.1.51.10,1.1.51.2,1.1.51.3,1.1.51.4,A,1.1.52'); 
    echo 'original <pre> ' . print_r($a, 1) . '</pre>';
    
    sort($a);
    echo 'after sort() <pre> ' . print_r($a, 1) . '</pre>';
    
    natsort($a);
    echo 'after natsort() <pre> ' . print_r($a, 1) . '</pre>';

    giving...

    original
     Array
    (
        [0] => 1.1.51
        [1] => 1.1.51.10
        [2] => 1.1.51.2
        [3] => 1.1.51.3
        [4] => 1.1.51.4
        [5] => A
        [6] => 1.1.52
    )
    after sort()
     Array
    (
        [0] => 1.1.51
        [1] => 1.1.51.10
        [2] => 1.1.51.2
        [3] => 1.1.51.3
        [4] => 1.1.51.4
        [5] => 1.1.52
        [6] => A
    )
    after natsort()
     Array
    (
        [0] => 1.1.51
        [2] => 1.1.51.2
        [3] => 1.1.51.3
        [4] => 1.1.51.4
        [1] => 1.1.51.10
        [5] => 1.1.52
        [6] => A
    )

     

  13. Try a ...

    <html>
      <head>
        
      </head>
      <body>
        
      </body>
    </html>

    ... structure instead of your pick'n'mix approach to the documant sections.

    (And why was this posted in PHP Coding Help forum?)

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.