Python Cowsay API Cartoon Tutorial

Python Cowsay API Cartoon Tutorial

Python Cowsay API Cartoon Tutorial

We’ve long been interested in online web application ideas that end up with a half decent cartoon the user can create, and share, themselves. “Half decent” becomes “fully decent” with a user who has a great imagination. And so, onto yesterday’s Python Cowsay API Primer Tutorial‘s start with interfacing to the great cowsay Python API / Command-line tool we access via the PHP exec method conduit to our AlmaLinux Apache/PHP/MySql Linux web server, today we’ve extended that …

  • “proof of concept” thinking … onto …
  • cartoon creation “smarts” … starting with (also egged on here by mobile platform problems with monospaced fonts, it seems like)
  • allowing a tabular display of our cowsay components … into …
  • table cells horizontally aligned (and so, less vulnerable to monospacing inaccuracies) … also allowing …
  • within any table cell there is a topmost th table cell wording part above a cowsay character td cell lower part …
  • “half decent” looking via static CSS
    <?php echo ”

    <style>
    margin: 0 0 0 0;
    padding: 0 0 0 0;
    tr { vertical-align: top; }
    td { vertical-align: top; }
    th { vertical-align: top; }

    * { font-family:'Courier New',Courier,monospace; }
    .img-hor { // thanks to https://stackoverflow.com/questions/32875695/flip-mirror-an-image-horizontally-vertically-with-css
    -moz-transform: scaleX(-1);
    -o-transform: scaleX(-1);
    -webkit-transform: scaleX(-1);
    transform: scaleX(-1);
    filter: FlipH;
    -ms-filter: 'FlipH';
    }
    .img-ver { // thanks to https://stackoverflow.com/questions/32875695/flip-mirror-an-image-horizontally-vertically-with-css
    -moz-transform: scaleY(-1);
    -o-transform: scaleY(-1);
    -webkit-transform: scaleY(-1);
    transform: scaleY(-1);
    filter: FlipV;
    -ms-filter: 'FlipV';
    }

    .glow {
    -webkit-animation: glow 1s linear infinite alternate;
    -moz-animation: glow 1s linear infinite alternate;
    animation: glow 1s linear infinite alternate;
    }

    /* Thanks to https://www.w3schools.com/howto/tryit.asp?filename=tryhow_css_glowing_text */

    @-webkit-keyframes glow {
    from {
    box-shadow: 0 0 3px #fff, 0 0 5px #fff, 0 0 37px #e60073, 0 0 9px #e60073, 0 0 11px #e60073, 0 0 13px #e60073, 0 0 15px #e60073;
    }

    to {
    box-shadow: 0 0 24px #fff, 0 0 6px #ff4da6, 0 0 8px #ff4da6, 0 0 10px #ff4da6, 0 0 12px #ff4da6, 0 0 14px #ff4da6, 0 0 16px #ff4da6;
    }
    }

    th[id$='0'] {
    background: rgba(224,240,240,0.6); //#e0f0f0;
    }

    th[id$='1'] {
    background: rgba(225,241,241,0.6); //#e1f1f1;
    }

    th[id$='2'] {
    background: rgba(226,242,242,0.6); //#e2f2f2;
    }

    th[id$='3'] {
    background: rgba(227,243,243,0.6); //#e3f3f3;
    }

    th[id$='4'] {
    background: rgba(228,244,244,0.6); //#e4f4f4;
    }

    th[id$='5'] {
    background: rgba(229,245,245,0.6); //#e5f5f5;
    }

    th[id$='6'] {
    background: rgba(230,246,246,0.6); //#e6f6f6;
    }

    th[id$='7'] {
    background: rgba(231,247,247,0.6); //#e7f7f7;
    }

    th[id$='8'] {
    background: rgba(232,248,248,0.6); //#e2f2f2;
    }

    th[id$='9'] {
    background: rgba(233,249,249,0.6); //#e9f9f9;
    }

    td[id$='0'] {
    background: rgba(240,240,240,0.3); //#f0f0f0;
    text-shadow:-1px 1px 1px #ff2d90;
    }

    td[id$='1'] {
    background: rgba(241,241,241,0.3); //#f1f1f1;
    text-shadow:-1px 1px 1px #ff2d91;
    float: bottom;
    }

    td[id$='2'] {
    background: rgba(242,242,242,0.3); //#f2f2f2;
    text-shadow:-1px 1px 1px #ff2d92;
    }

    td[id$='3'] {
    background: rgba(243,243,243,0.3); //#f3f3f3;
    text-shadow:-1px 1px 1px #ff2d93;
    }

    td[id$='4'] {
    background: rgba(244,244,244,0.3); //#f4f4f4;
    text-shadow:-1px 1px 1px #ff2d94;
    }

    td[id$='5'] {
    background: rgba(245,245,245,0.3); //#f5f5f5;
    text-shadow:-1px 1px 1px #ff2d95;
    }

    td[id$='6'] {
    background: rgba(246,246,246,0.3); //#f6f6f6;
    text-shadow:-1px 1px 1px #ff2d96;
    }

    td[id$='7'] {
    background: rgba(247,247,247,0.3); //#f7f7f7;
    text-shadow:-1px 1px 1px #ff2d97;
    }

    td[id$='8'] {
    background: rgba(248,248,248,0.3); //#f8f8f8;
    text-shadow:-1px 1px 1px #ff2d98;
    }

    td[id$='9'] {
    background: rgba(249,249,249,0.3); //#f9f9f9;
    text-shadow:-1px 1px 1px #ff2d99;
    }

    table tbody tr:first-child {
    background: transparent; //#f6f6e6;
    }
    </style>

    “; ?>
    … and then …
  • whenever new cell content happens padding-top adding CSS Javascript DOM nuanced display logic via …
    <?php echo ”

    function paddingtopit() {
    var maxtwo=0, thistwo=0;
    var thhs=[], tdhs=[], it=0;
    var thdids=[];
    //trthtd1
    //trtdtd1
    var tds=document.getElementsByTagName('td');
    for (it=0; it<tds.length; it++) {
    if (('' + tds[it].id).indexOf('trtdtd') != -1) {
    if (('' + tds[it].style.paddingTop).replace(/^null/g,'').replace(/^undefined/g,'').trim() != '') {
    tds[it].style.paddingTop='0px';
    }
    }
    }
    for (it=0; it<tds.length; it++) {
    if (('' + tds[it].id).indexOf('trtdtd') != -1) {
    tdhs.push(eval('' + tds[it].getBoundingClientRect().height));
    thdids.push('' + tds[it].id);
    }
    }
    var ths=document.getElementsByTagName('th');
    for (it=0; it<ths.length; it++) {
    if (('' + ths[it].id).indexOf('trthtd') != -1) {
    thhs.push(eval('' + ths[it].getBoundingClientRect().height));
    thistwo=eval(thhs[it] + tdhs[it]);
    if (thistwo > maxtwo) { maxtwo=thistwo; }
    }
    }
    for (it=0; it<tdhs.length; it++) {
    thistwo=eval(thhs[it] + tdhs[it]);
    if (thistwo < maxtwo) {
    document.getElementById(thdids[it]).style.paddingTop='' + eval(maxtwo - thistwo) + 'px';
    }
    }
    }

    “; ?>
    … so that …
  • cartoons present with “speech bubble” wording aligned to the top in our “cells” (ie. th contenteditable=true editable wording on top of td horizontal flip (double click) and/or vertical flop (right click) editable lower part) with those characters aligned to the bottom

… in our changed “third draft” Cartoon creation and email sharing capable PHP web application you can also try below.


Previous relevant Python Cowsay API Primer Tutorial is shown below.

Python Cowsay API Primer Tutorial

Python Cowsay API Primer Tutorial

We discovered an interesting Open Source Python API / Command-line tool called cowsay which we installed up at our AlmaLinux web server via …


pip install cowsay

… with an integration purpose in mind, so thanks. Before many readers’ time indeed, but some may remember those cute banner printouts that told you who owned the next printout on a spooling “crude graphics” printout in the late 70’s … well cowsay encapsulates those heady days (and who can forget punch cards)?! Before integration, though, we want to test it via a new PHP supervisor on exec method Linux command line interfacings to cowsay.

So we started, with this “first draft” getting places and then this “second draft” with a little more sophistication to leave the day with this interfacer

If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.

This entry was posted in eLearning, Event-Driven Programming, Tutorials and tagged , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *