Elizabeth Believe it or not, I am working on that project (24 hours/week) ... the other 16 I'm sitting at a desk and earning some wages. So, a PT contract isn't a bad thing compared to $0/hour until next year; it will keep Mrs. Dale from feeling like I'm being worthless while she's at work 4 days/week.

The pet project is pretty fun. Recently selected a domain name for it, and I have started the process of content production and enlisted a friend from LONG AGO to help with that in his "spare" time....

It bears a question: given a ton of responsibilities, (e.g. you're the CEO, the programmer, the media producer, the marketing agent, and the janitor), does your preferred work style do each in turn for a few hours or a day, then on to the next task for a similar time period, or do you do one for a week or a month and then switch, for productivity's sake? Anyone have that kind of experience?

    13 days later

    NogDog - Nope... I'm hoping the old theory is correct.... AND that bots will gather that address and SPAM it.

    It's from a SPAMMER.

    @Weedpacket I never moved the spam filter into production , but I'm happy to share my findings -- if I can just remember where I put everything. IIRC, I tested two versions. One implemented a Support Vector Machine, the other an Artificial Neural Network. They mostly achieved the same results. NOTE that the filter works solely by checking the presence of absence (0 or 1 )of certain words. Intuitively, I suspect this would make the filter vulnerable to gaming somehow. It might be worthwhile to add additional signals (e.g., a 0 or 1 if the post has a link to a remote website, or if the post links to certain top level domains). The key is to have a large corpus of ham/spam examples to train the filter. The challenge is that training a filter requires a lot of number crunching and it's tricky to get PHP to do fast matrix multiplication.

    sneakyimp NOTE that the filter works solely by checking the presence of absence (0 or 1 )of certain words.

    Well, you've seen the sort of spam that has been coming through: big blocks of spurious text (sometimes in Chinese), an <img> tag so the server gets pinged when the spam is viewed, a link to some phone-list sharing site chucked in the middle. So it's not so much the absence or presence of certain words, but the overall appearance. It's weird the current spam filter is so ineffective.

      14 days later

      Do you need a copy of my "bots.php"?? ... I'm sure it's up to date, if your system timezone is set to 12 years ago. 🤣

        Although I was making a bit of a joke there, a central point of logic does exist, "consider the source." It's why RBLs exist.

          4 days later

          TIL: PHP now has a hrtime() function for when microseconds are not enough resolution (among other more technical reasons it may be advantageous in certain situations).

          PS: Where "now" means since PHP 7.3. 😁

          NogDog (among other more technical reasons it may be advantageous in certain situations).

          Like it won't suddenly jump backwards when the underlying machine decides to adjust its clock to align it with an NTP server.

            17 days later

            I think I once knew this already, then re-learned today: you can use the ?? null coalescing operator as a sort of shorthand syntax to avoid "variable does not exist" types of warnings/errors while keeping the code terser than using the ternary operator or some sort of if/else statement:

            $foo = $_COOKIE['bar'] ?? null;
            // ...instead of...
            $foo = isset($_COOKIE['bar']) ? $_COOKIE['bar'] : null;

            PS: I believe I'd like to eat something called a "cookie bar" now. 😉

              2 months later

              The ?? operator also has an assignment form, ??=, which was initially undocumented. It's handy for setting stuff that might or might not already be set.

              $option['colour'] ??= $defaults['colour'];

              If $option already has an element colour the line does nothing, but if it doesn't ... well, it does now, with the value given in $defaults['colour'].

                a month later

                Javascript has somewhat arbitrary ideas of which printable ASCII chars are "punctuation" and which are "symbols" when you use regex:

                const patterns = {
                  'LOWER' : /\p{Ll}/u,
                  'UPPER' : /\p{Lu}/u,
                  'DIGIT' : /\p{N}/u,
                  'PUNCTUATION' : /\p{P}/u,
                  'SYMBOL' : /\p{S}/u
                }
                let results = []
                for (let i=32; i<127; i++) {
                  let char = String.fromCharCode(i)
                  matches = []
                  for(let type in patterns) {
                    if (char.match(patterns[type])) {
                      matches.push(type)
                    }
                  }
                  results.push(char + ' - ' + matches.join(','))
                }
                console.log(results);

                sneakyimp

                <?php
                const patterns = [
                  'LOWER' => '/\p{Ll}/u',
                  'UPPER' => '/\p{Lu}/u',
                  'DIGIT' => '/\p{N}/u',
                  'PUNCTUATION' => '/\p{P}/u',
                  'SYMBOL' => '/\p{S}/u'
                ];
                $results = [];
                for ($i=32; $i<127; $i++) {
                  $char = chr($i);
                  $matches = [];
                  foreach(patterns as $type => $patt) {
                    if (preg_match($patt, $char)) {
                      $matches[] = $type;
                    }
                  }
                  $results[] = ($char . ' - ' . join(',', $matches));
                }
                echo join("\n", $results);

                Sure enough,

                The distinctions between some General_Category values are somewhat arbitrary for edge cases, particularly those involving symbols and punctuation.
                https://www.unicode.org/reports/tr44/#General_Category_Values

                  TIL the PHP manual comments section doesn't want you to use the word "specialised" when posting.

                    What's weird is that neither of my two previous posts bumped the thread.

                      5 days later

                      That in MySQL, you don't store a number as FLOAT if you want to compare exactly (=) or do much math with it. Since this was a price field, glad I learned before going live this month...

                      (It seems important ... I wonder if I knew that once and forgot?)

                      6 days later

                      dalecosp Not to use floats for money? Pretty important. MySQL does have a DECIMAL type, right?
                      (And lets see if this post gets counted on the front page. It's been a while...)