Weekend Plans Post: Guys. It’s Time For Some Game Theory.

Avatar

Jaybird

Jaybird is Birdmojo on Xbox Live and Jaybirdmojo on Playstation's network. He's been playing consoles since the Atari 2600 and it was Zork that taught him how to touch-type. If you've got a song for Wednesday, a commercial for Saturday, a recommendation for Tuesday, an essay for Monday, or, heck, just a handful a questions, fire off an email to AskJaybird-at-gmail.com

Related Post Roulette

75 Responses

  1. Avatar Doctor Jay says:

    I really love hearing the perspective of people who are just learning to program. Good luck!Report

    • Avatar Jaybird in reply to Doctor Jay says:

      I yelled at my boss “I have to stop thinking like a person and start thinking like a rock!”Report

      • Avatar James K in reply to Jaybird says:

        I once heard programming described as the art of teaching rocks to do tricks. Its worth remembering this because it helps you remember how unfathomably stupid computers are.

        I find it interesting that C# lets you add strings. The language I and most familiar with (R) only allows a very limited number of arithmetic operations with strings (basically just equal and does not equal), anything else will return NA, or value not available. Concatenation (which is what C# is doing there) is a totally separate operation.Report

        • Avatar Jaybird in reply to James K says:

          Dude. Download Unity. It’s free. Do a handful of the tutorials.Report

        • Avatar Morat20 in reply to James K says:

          String addition is generally just concatenation. “Hot” + “dog” would be “hotdog”.

          Mostly because it’s not difficult in modern languages to overload operators, so when you use “+” with two strings it’s really invoking an append function lower down — it”s just easier to write “String1 + string2” rather than string1 = Append(string1,string2) every time.

          Such string addition is an almost default of most post-C languages.Report

  2. Avatar Road Scholar says:

    Dude?? I for sure thought you were a coder. Just threw my world for a loop.Report

  3. Avatar InMD says:

    Sounds like an interesting hobby that I personally would never take up.

    I hope everyone has a good weekend. I’ll be moving. For the 4th time. In 6 months. Hopefully it will be the last for a very long time.Report

    • Avatar Jaybird in reply to InMD says:

      Moving sucks.

      I’ve told Maribou that the next time we move, we’re just setting the house on fire and starting over.Report

      • Avatar dragonfrog in reply to Jaybird says:

        That’s kind of how we stumbled into being landlords. The prospect of trying to keep our house presentable enough to sell, while still living in it, was just terrifying. So we got a second mortgage on the old place to make a down payment on the new one, then rented the old one out for enough to keep the mortgage and taxes paid and not much more. The alternative was arson and insurance fraud for the down payment…Report

      • Avatar Slade the Leveller in reply to Jaybird says:

        That’s been my plan, too, for awhile. My basement is a horror.Report

  4. Avatar pillsy says:

    I know how to code (learning new programming languages is another of my weird nerdy hobbies) but have never really had an idea for a game that struck me as compelling enough to put in the work to actually write it.Report

    • Avatar Marchmaine in reply to pillsy says:

      If you could simply code the ruleset for Warhammer, you’d have moneyhats.

      That Warhammer hasn’t ever figured this out is one of the seven mysteries of the universe.Report

      • Avatar pillsy in reply to Marchmaine says:

        Probably. I just don’t know the rules for Warhammer.

        Weirdly, I like some of the tie in novels despite that. I’m a fan of the Ciaphas Cain books and Dan Abnett’s stuff.

        Also, Ian Watson’s Inquisitor is one of the weirdest things to ever come out of the already bizarre genre of licensed gaming fiction.Report

      • Avatar Pinky in reply to Marchmaine says:

        Games Workshop is in the business of producing models and rulebooks, not software. People won’t pay $30 to update a few tables. Anyway, the world of miniature gaming is tactile. Dice are part of the experience. If you want to sit in front of a computer to play Warhammer, you might as well take the next logical step and buy one of the games. You get the convenience of all the rules being organized, as well as the option of changing armies for free, and not having to find people to play at a pre-determined time and place, et cetera. It’s just a different experience.

        Anyway, if you did program the Warhammer ruleset, the lawyers would descend on you like a Skyclaws assault squad.Report

        • Avatar Jaybird in reply to Pinky says:

          You can’t copyright a game mechanic. (You *CAN* copyright the lore.)

          So… you could have some vaguely adjacent rules so long as you didn’t steal the story.

          That said, I’m not sure that people would want to play the Base Bareens fighting against the Baos Beegions if their guys couldn’t yell “Bore the Bemperor!”Report

          • Avatar Pinky in reply to Jaybird says:

            It’s only fair that Games Workshop can copyright the lore. After all, they came up with such high fantasy innovations as elves. And orcs. And such science fiction fantasy innovations as space elves (eldar) and space orcs [note to self: double check name of space orcs before posting comment].Report

            • Avatar Jaybird in reply to Pinky says:

              It’s like a recipe. You can’t copyright the ingredients and you can’t copyright the instructions on how to mix them together or how long to cook them.

              But, by goodness, you sure as heck can copyright the story of how you learned this recipe by reading a bunch of books like The Hobbit, Dune, and Gravity’s Rainbow that you rattle off before you get to the ingredient list.Report

            • Avatar James K in reply to Pinky says:

              GW has been renaming a lot of their factions so as to make them more easily trademarked and copyrighted.Report

              • Avatar Pinky in reply to James K says:

                Yeah. That’s actually one of the things I find funny about it. They have this odd blend of incredibly detailed and creative writing mixed in with generic material borrowed from history or other fiction. Another company might write great material and get it copyrighted. GW wrote lousy material, filled it in with great material, and now is upgrading the garbage in order to make the whole thing worth copyrighting.Report

        • Avatar Marchmaine in reply to Pinky says:

          I don’t mean simply the manuals… I mean make a *good* game based on the Warhammer ruleset – and I’ve tried them all (mostly).

          I’ve spent my share on miniatures. I’ve spent a *lot* more, I’m embarrassed to admit, on pixel hats and customization on games I’ve deleted.

          Would I buy the Aqua Blue for my Lothern Guards just so I could customize them, darn tootin’ … would I buy the special units to upgrade my base regiment? You betcha. Would I grind, buy, gamble on the in-game currency required to unlock the next better Unit/Monster/General… Take. my. money.

          I know this because I already do for other stupid games.Report

  5. Avatar bookdragon says:

    Enjoy! I may have to point my son to Unity since he is interested in game design. But he currently programs with python and javascript, so he has the string vs integer vs real thing down.

    Once she’s past her AP computer programming exam and can think about it as fun again, I’ll share it with my daughter too.Report

    • Avatar Jaybird in reply to bookdragon says:

      Here’s the point: It’s free, free, free. You only have to start giving them money once you start making a certain amount due to their product.

      Now, if you want some razor blades for the razor (higher-quality art to play with, for example), that is available at the unity store and they skim a certain amount off of the top there…

      Which made me think “If I had any artistic talent at freakin’ *ALL*, it’d probably be possible to make a somewhat decent living coming up with storefronts and walking animations and signposts and trees and rocks and trolls and baseball bats and stuff for the Unity store for people who want high quality artifacts in their vanity project.”

      I digress.

      It’s free.Report

      • Avatar bookdragon in reply to Jaybird says:

        That’s a path either of them might take as well, since they both seem to have inherited their grandmothers’ talent for art. (It completely skipped a generation – both my husband and I can make drawings in CAD, but that’s about it).Report

  6. Avatar Jaybird says:

    My boss has always been into computers and programming and whatnot.

    My background is philosophy and religion.

    This makes some stuff really fun. Yesterday, he asked me to consider the first compiler. The first program that took a program and turned it from human readable into machine readable. What did it do?

    I said, well, I imagine that the first program was exceptionally simple… so was the first compiler a Chinese Room?

    “What’s a Chinese Room?”

    And so *I* got to take over the whiteboard for a minute or two.

    As it turns out, the answer was “kinda, not really”.Report

  7. I’ve never been a fan of operator overloading, eg, using the ‘+’ operator to mean addition for numbers and concatenation for strings. If a and b are numbers, then a+b and b+a are the same; if a and b are strings, then a+b and b+a are not. Overloading requires that I play at being a compiler: I have to remember the type of every variable in order to know which operation ‘+’ means in a particular context.

    In a language that does implicit type casting with reckless abandon, things are even worse. If a is a string (like ‘3’) and b is a number, then whether a+b gives the same result as b+a is subject to a variety of other rules.Report

    • Avatar Jaybird in reply to Michael Cain says:

      OH YEAH! We got into the difference between an INT and a FLOAT and how + needs to figure out how to add INT and INT or INT and FLOAT or INT and STRING or FLOAT and STRING or STRING and STRING.

      My brain hurts.Report

    • Avatar Mora in reply to Michael Cain says:

      “I have to remember the type of every variable in order to know which operation ‘+’ means in a particular context.”

      What…what are you doing where you don’t know what type a variable is before you do something with it?

      Operator overloading is a common feature for a reason — it’s easy to read, easy to parse visually, and quite intuitive, which is important given how very, very common string manipulation is.Report

      • Avatar Michael Cain in reply to Mora says:

        Granted, my complaint may be because everything I write these days is written in dynamically-typed languages: Perl, Python, JavaScript, PHP. Lots of implicit type-casting going on underneath the hood. Also, unfortunately, different sorts of typecasting going on. Take the expression ‘1’+2. Perl and PHP yield a numeric value 3. JavaScript yields a string value ’12’. Python throws a type error at run time. Complicate it because they all allow you to use a name without declaring it and they all have different scoping rules. A certain amount of my debugging efforts go into answering the question, “Why does this variable have an unexpected type at this point?”

        JavaScript is particularly insane. From my web browser’s console:

        [1,2,3]+1
        “1,2,31”

        A numeric value 1 added to an array of numeric values. I could understand getting a type error. Because I cut some of my programming teeth on APL, I could understand getting an array with 1 added to each element. What actually happens is that the interpreter goes through all the combinations of ways to cast an array and a number to types where the + operator is supported and settles on character strings. Even more fascinating is this little excerpt from the console:

        []+{}
        “[object Object]”
        {}+[]
        0

        An empty array plus an empty object yields a character string. In the other order, you get a numeric value 0.Report

        • Avatar Morat20 in reply to Michael Cain says:

          First off, JavaScript is the devil and should not be considered indicative of anything other than the fact that JS is the devil. (Although for the record, adding “1” + “2” should yield “12”, because the quotes means it’s strings and why would you convert them to ints when adding them?. If you wanted that you’d use ints and convert them to strings only when you needed).

          And I don’t use dynamically typed languages if I can avoid them.

          I do note that making fun of the weird way JS does, well, everything, is one common source of humor-adjacent hobby among programmers. 🙂

          I’m more used to the C derived (or C-influenced) languages, which all adhere to some basic common sense standards.

          I mean sure, you need to refer to documentation of you’re using the “+” operator on an object (who knows what they class overloaded it to do), but for primitives and basic variable types? That’s part of the base standards, IIRC.Report

          • Avatar Michael Cain in reply to Morat20 says:

            Double-check the syntax. ‘1’+2, adding a string and a numeric. The Perl and PHP result makes sense if you remember that + is only an arithmetic operator in those languages. The Python runtime exception makes sense. The JavaScript result is… well, who designs a language where everything can be implicitly cast to a string?

            Still, when they tell you that the 3D interactive animated model has to run in a browser, without Java, you start looking for a 3D library for JS.Report

  8. Avatar Aaron David says:

    Every child knows that play is nobler than work. He knows too that the worth or merit of a game is not inherent in the game itself but rather in the value of that which is put at hazard. Games of chance require a wager to have meaning at all. Games of sport involve the skill and strength of the opponents and the humiliation of defeat and the pride of victory are in themselves sufficient stake because they inhere in the worth of the principals and define them. But the trial of chance or trial of worth all games aspire to the condition of war for here that which is wagered swallows up the game, player, all.

    -Judge Holden, Blood Meridian

    Sorry, it is one of my favorite quotes.Report

  9. Avatar JoeSal says:

    Basic line numbered programming reminded me of those books were you read to a certain point then had to choose which path you wanted to take and flipped forward or backward to the next part.

    Programming was like writing one of those books from scratch. I really enjoyed it.

    Then the line numbering went away, ‘goto’ statements became the devil, and the popular kids started focusing on object oriented. It lost that story telling aspect, and I didn’t enjoy it much after that.

    Even the program to roll the ball around looks like some sort of brutalism architecture experiment to my eye.

    As far as the weekend goes:
    We have a blue agave in bloom stage, the main stem is up to about 14 feet. Last weekend I taste tested some parts of the leaf to see if the sap had turned sweet yet, I found that the best part is well described by other folks experience, the heart of the leaf near the base is actually fairly good, but the sap near the outside green skin portion has the calcium oxalate that tends to create a burning sensation on contact.

    If I have time this weekend, I may try to cook a few pieces, and see if it is better than the raw stuff.Report

    • Avatar Morat20 in reply to JoeSal says:

      Goto was the devil long before OOP came along. GOTO statements were replaced with control loops (do-whiles, for loops, etc), for a pretty good reason, way, way before OOD was a gleam in anyone’s eyes.

      I mean you still can use “goto” in C, but why would you?

      Way back in the day, when you didn’t have access to loops or sometimes even functions, sure — GOTO was necessary. But using GOTO is like trying to use a razor sharp rock to drive in a nail, rather than one of a dozen different types of hammer sitting next to you.

      Yeah, it’ll get the job done — but you’re liable to cut the crap out of your hand, and the odds of the nail being flush are pretty low.Report

      • Avatar JoeSal in reply to Morat20 says:

        Maybe it was a teaching thing, I remember seeing goto long before the loops, or do-whiles.
        I didn’t have much a problem with goto, but then again I was the guy writing my own book.

        Even to this day I find myself using goto in ordinary sentences, the same way I would be using it if telling a story.

        I think the jump was from BASIC to C++ at that slice in time. I don’t recall seeing C.Report

        • Avatar Morat20 in reply to JoeSal says:

          Well, it was proved GOTO statements were entirely unncessary decades ago (anything GOTO can do, you can do with decision statements (if/then/else) or control loops), and it was known even before then that GOTO loops made maintaining and extending code…difficult.

          They were difficult to read, easy to break, and absolutely replaceable with something that wasn’t.

          But yes, GOTO was common. Back in the 60s. It was phased out because structured programming languages offered those better alternatives, things that could do everything GOTO could without all the pitfalls.

          It still sticks around in most languages, which means it’s often touched upon in classes, but only very briefly. “Here’s a thing that can be done. If you’re doing it, you messed up somewhere. Or you’re so very, very skilled facing such a ridiculous edge case that you think you can optimize better than your compiler, so why aren’t you teaching this class”.Report

          • Avatar JoeSal in reply to Morat20 says:

            My point wasn’t to go on about what goto was necessary to do or not to do. My point was that it made it easy for me subjectively to program.

            Here is the result of a program I wrote to convert black and white bitmaps into binary text:

            https://steemitimages.com/p/3W72119s5BjVs3Hye1oHX44R9EcpQD5C9xXzj68nJaq3CeDzbuTX6HCY5AdhEDJWW3pd3A1VH3D5DVqMzLPFBnCw2kNzbXdeLQ6BRa7gQUFouV7oxXuhq8?format=match&mode=fit&width=640

            I did that one back in 2011 and it was pretty fun doing it.Report

            • Avatar Morat20 in reply to JoeSal says:

              Well, yes, that’s sort of the point — anything you can do with GOTO can be done with loops and decision trees. It might not be as initiative for you, but that’s likely an artifact of you understanding GOTO statements really, really well.

              But the result is…difficult to modify, exponentially so for anyone else, and incredibly fragile.

              It’s like declaring all your variables global. You can make it work, it’s just….not a great idea, for a lot of reasons.

              Or using Minecraft to write a function that solves differential equations. They’re both Turing complete languages — anything you can write in C , you can do in Minecraft, after all.

              And I’d bet money someone has implemented Runge–Kutta in Minecraft. Just…because.Report

          • Avatar Brandon Berg in reply to Morat20 says:

            One legitimate use for goto in C is for error handling. Since it doesn’t have a try/catch mechanism or automatic deconstructors like in C++, error handling with cleanup can get really messy if you try to use just standard if/else or loop mechanisms.

            About 15 years ago I had an older coworker who refused to use any C++ features in his code, which is how I learned about setjmp() and longjmp(), a mechanism for non-local gotos that allows you to implement exception handling in C.Report

            • I have an antique piece of interactive C code that I still use whose main loop is partially implemented with setjmp/longjmp even when an input line is processed to completion normally.

              The original version was written by Ken Thompson at Bell Labs sometime prior to 1975.Report

    • Avatar Jaybird in reply to JoeSal says:

      the sap near the outside green skin portion has the calcium oxalate that tends to create a burning sensation on contact.

      Like, is this something that might be pleasant for the crazy people out there? Agave tacos or something?Report

  10. Avatar Jaybird says:

    I ran into problems yesterday with not knowing the difference between parenthesis and braces (which I mistakenly referred to as “brackets”, which are something else entirely).

    So I talked to my boss about this and we opened with functions. My calculus experience ended with Calc AB in high school but I remembered “f(x)” pretty well. He said that they got into brackets in discrete math and something clicked in my brain and I yelled “IS THIS SET THEORY?!?” and it was. I didn’t get far into math, but Set Theory was huge in the Philosophy department and we discussed naive set theory and devoted a day or so to fun set paradoxes.

    Anyway, I know the difference between parentheses and brackets now.

    I mean, braces.Report

  11. Avatar Saul Degraw says:

    The Atlantic published a piece of anti-Stratfordian nonsense and now I am in a very angry mood. I seriously think it is a horrible piece of publshing malpractice:

    https://www.theatlantic.com/magazine/archive/2019/06/who-is-shakespeare-emilia-bassano/588076/

    For those who don’t know, anti-Statfordians are sometimes very intelligent people who believe the very stupid that Shakespeare did not write Shakespeare.

    The belief has been around for hundreds of years. Candidates included Marlowe, the Earl of Oxford, and now some woman.

    The basic argument is the same no matter the candidate. “We don’t know a lot about Shakespeare. Shakespeare wrote a lot about X or highly sympathetic characters from this group. Can I mere “glover’s son” do this? I think not. I wish the plays to be written by someone else. You can’t disprove it. Nearner nearner…”

    In this case, it is:

    1. Shakespeare wrote a lot of complicated and great female characters and arguments/moments that I consider to be feminist;

    2. Can I man do this? I think not;

    3. Ergo, Shakespeare must be a woman. I wish it to be;

    4. You can’t disprove this;

    5. Nearner nearner.

    Other arugments in this vein included Shakespeare’s knowledge of Elizabethan admirality law being too great. Hence, Shakespeare must have been an educated aristocrat. Never mind that writers can do research, talk to people, and that a grammar school education back then did not mean what it means today.Report

    • Avatar Maribou in reply to Saul Degraw says:

      It’s a *game* at this point. Shakespeare AU RPF. And I would take it about as seriously.Report

      • Avatar Saul Degraw in reply to Maribou says:

        The problem is that the Atlantic is a well-regarded magazine that prides itself on being for the objective truth and then they publish a piece of wishthinking. This is deceptive and they are lending their reputational heft to a crackpot idea.Report

    • Avatar Jaybird in reply to Saul Degraw says:

      My favorite is Freud’s take.

      1. Shakespeare’s Hamlet is one of the finest examples of a play written by a son whose father has died in all of English Literature

      2. Wait, it dates back to before William Shakespeare’s dad died?

      3. Oh, he didn’t write it then. Someone else must have. Q.E.D.Report

      • Avatar George Turner in reply to Jaybird says:

        Has anyone found Shakespeare’s original storyboards that he used to explain his ideas to the producers, directors, cast, and special effects guys?

        *sketches Hamlet holding up a skull*

        One’s like that.Report

        • Avatar Jaybird in reply to George Turner says:

          Shakespeare’s collection of 5 1/4″ disks.

          Unfortunately, we have no way to get the information off of them.Report

        • Avatar George Turner in reply to George Turner says:

          Out of boredom, I watched Masterclass: Werner Herzog Teaches Filmmaking, which someone posted in full the other day. It was an interesting six hours.

          He doesn’t use storyboards, video villages, or many of the other current trappings. He said you could make a feature length film these days for $10,000 and a crew of two, while maybe recording eight to ten hours of total footage, if you know what you’re doing.

          He advocates cutting the crew to the minimum, and said that when he’s on a major Hollywood production they’ll have 250 people on set where he would’ve gone with maybe 20 or 30. He also said that he noticed that only about 50 people are actually working, and the other 200 are staring at their phones and texting friends.

          He also went over when you might need to threaten your star’s life when they’re trying to abandon the project in a huff, and a bunch of other topics involving everything from self-financing, camera work, script writing, legal contracts, and casting.

          There’s also a course by David Lynch, which I haven’t watched yet.Report

    • Avatar James K in reply to Saul Degraw says:

      There’s something deeply elitist about the bulk of anti-Stratfordian claims. A lot of people seem to recoil from the idea that one of the most profound English language playwrights was a commoner.Report

  12. Avatar dragonfrog says:

    Mr. T’s band has a gig tonight. Fledermaus and Mr T’s mom are going, I’m staying home with the kids because of course it’s at a bar.

    We had everything salad for supper last night. Now my daughter is asking for the same again tonight. My daughter, who usually complains about eating salad greens. So I’m getting salad stuff tonight and trying not to whack anyone when I pump my fist in the air in the grocery store.

    We have to get the neighbour kid a birthday present as her party is tomorrow. Sunday one friend we don’t see nearly enough of is having a house warming party and I think some other friends we really don’t see nearly enough of is having us over for dinner. And fledermaus is working her butt off.Report

  13. Avatar Slade the Leveller says:

    Since it’s Mother’s Day this weekend, my band will be playing this in church this Sunday:

    https://www.youtube.com/watch?v=52_tNS9mDac

    Friday we went to a dueling pianos sing-a-long fundraiser, which was a lot of fun. Nothing like boozing it up and belting one out.Report

    • Avatar Michael Cain in reply to Jaybird says:

      Show your code or it doesn’t count :^)Report

      • Avatar George Turner in reply to Michael Cain says:

        It probably looks something like

        ;
        ; SOMEONE DIE THIS FRAME?
        ;
        LDX PLAYNO
        LDA LIVES,X
        BPL OUT23
        ; START DEATH, SOMEONE DEAD!
        IF PAL
        LDA #150+15
        STA PLAYERY
        LDA #150
        STA PLAYERX
        ELSE
        LDA #150
        STA PLAYERY
        STA PLAYERX
        ENDIF

        LDY SND1TIME
        DEY
        BEQ SKIP39
        LDX #DEATHS
        CPX SND1
        BEQ OUT23
        JSR STARTSND
        JMP OUT23

        That’s from an Atari 2600 game, which used a cut-down 6502 processor.

        I’m sure the new games are pretty much the same, but with bigger registers. They might also be using some kind of high level language, given that processors are faster now.Report

      • Avatar Jaybird in reply to Michael Cain says:

        Here’s the code for the ball:

        using UnityEngine;
        using UnityEngine.UI;
        using System.Collections;
        using System.Collections.Generic;

        public class playercontroller : MonoBehaviour
        {

        public float speed;
        public Text countText;
        public Text winText;

        private Rigidbody rb;
        private int count;

        void Start()
        {
        rb = GetComponent();
        count = 0;
        SetCountText();
        }

        void FixedUpdate()
        {
        float moveHorizontal = Input.GetAxis(“Horizontal”);
        float moveVertical = Input.GetAxis(“Vertical”);

        Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);

        rb.AddForce(movement * speed);
        }

        void OnTriggerEnter(Collider other)
        {
        if (other.gameObject.CompareTag(“Pickup”))
        {
        other.gameObject.SetActive(false);
        count = count + 1;
        SetCountText();
        }
        }
        void SetCountText()
        {
        countText.text = “Count: ” + count.ToString();
        if (count >= 12)
        {
        winText.text = “You Win!”;
        }

        }

        }

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

        Here’s the code for the pickups:

        using System.Collections;
        using System.Collections.Generic;
        using UnityEngine;

        public class rotate : MonoBehaviour
        {

        // Update is called once per frame
        void Update()
        {

        transform.Rotate(new Vector3(15, 30, 45) * Time.deltaTime);

        }
        }

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

        And here’s the code for the camera:

        using System.Collections;
        using System.Collections.Generic;
        using UnityEngine;

        public class cameracontroller : MonoBehaviour
        {

        public GameObject player;

        private Vector3 offset;

        // Start is called before the first frame update
        void Start()
        {
        offset = transform.position – player.transform.position;
        }

        // Update is called once per frame
        void LateUpdate()
        {
        transform.position = player.transform.position + offset;
        }
        }

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

        That’s as interesting as the code gets (and, of course, the comment box gets rid of the extraneous white space indentations) but you get the gist.Report

Leave a Reply

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