A Beggar's Blog

BACKGROUND

Windows Presentation Foundation (WPF) applications divide documents into two different categories, "Flow Documents" and "Fixed Documents".

The Flow document class is a document that is optimized for viewing an readability in which ease of reading is the primary function of the document. It works a little like HTML in which you can add block level and inline level child elements in to the document in order to achieve a document layout that automatically resizes and reflows based on the medium that is viewing the content.

DESCRIPTION

This post goes over what it takes to roate images in your flow document so you don't have to explicitly lay our your flow document in landscape orientation for full page size images.

PROBLEM

I had been asked to work on a WPF based application for a client that would print a report of information gained based on user selections.

Reports in the application include all of the tabulated data for each "Installation" slection as well as the image that is linked to that installation. These images are based on CAD drawings, and so they need to be as large as possible in order to fully express all of the detail that is required to view all of the intricacies of the image.

Image controls are, in essense, UIElements, which are not allowed to be added to the "top level" of a flow document. We require use of a BlockUIContainer class to put any UIElement controls in our flow document.

This snippet shows how to insert any UIElement into a flowdocument. The image below shows the application output.

Click here to see the code

As you can see, we've got an image in our flow document. It's on the page in a portrait-style orientation, though, so we're not using the full page when outputting our image. This isn't good for printing as we would like to have as much information displayed from our image as possible.

So, what if we rotate our image? You first may think about rotating the Image control in place after we set our source. The method of performing this rotation is shown below, and the picture after code is the application output.

Click here to see the code

So now we've rotated our image, but there's a big problem. The image itself is out of the view of the Flow Document! So if rotating the image control in our BlockUIContainer isn't the correct solution, what other solutions do we have?

Well, there is one more way in which we could rotate our image. We could provide a TransformedBitmap operation on our BitmapImage, essentially rotating the image before our FlowDocument has a chance to deal with it and work its paginating magic. The code used to supply a TransformedBitmap is below. And the image below the code is the output.

Click here to see the code

Aha! As you can see we have a fully rotated image that has been successfully processed by the FlowDocument paginator and margin handling. What you see on the preview is what you should see on the document, if you so choose to print it.

Let me know if this blog helped you out by posting a comment below. It's always good to hear feedback if it ever comes.

I had been wanting to create a couple of projects with the Vue.js JavaScript framework and, being the neat freak that I am, I wanted to make sure that I was linting my script code within the single file component.

So, I installed the SublimeLinter-jshint plugin on my Sublime text editor, went to a local .vue file that I had been building, and saw this

Somethings not right, and it's not allowing jshint to lint my single file component's scripts. I eventually was able to find a fix for the issue, but it took a little bit of research. Lucky you, I have included the solution below.Note: This is a snippet of the contents of my SublimeLinter.sublime-settings file that is made to look like the full file.

SublimeLinter.sublime-settings


{
    "linters": {
        "jshint": {
            "selector": "source.js, text.html.vue",
            "args": ["--extract=auto"]
        }
    }
}

Going into the details

As you can see, the code above is shown to be the SublimeLinter settings file that you can get to by opening up your sublime package manager search window, typing in something like "sublime linter settings", and then you should be able to open it up. Below I explain why we're actually feeding those arguments within the SublimeLinter.sublime-settings file.

*Note: I tried to make this solution work through a a .sublime-project file, but I was only able to make it work the way I wanted through using the current method given. Please let me know if you are able to make it work through a sublime-project file as that would be very helpful.

  • linters

    This setting tells the SublimeLinter package of extra parameters (i.e. like argument flags that you would give on a CLI of the module) you want the linter to consier. We are using jshint so in order to change the default behavior of jshint, we input our jshint parameter.
    For more information about this parameter, please go to the documentation

  • selector

    This setting tells jshint what source to be active on. This works off of the given scope that Sublime Text uses. For example, if you make a .vue single component file, put your cursor anywhere in the file, and go to Sublime Options Bar -> Tools -> Developer -> "Show Scope Name" you should see a scope of text.html.vue on top. From what I gather, that seems to be the overall scope of the filetype. Note: I'm not 100 sure, but the scope may be obtained from the syntax highlighting package that I have for vue single file components. So, if that's the case, make sure to install vue-syntax-highlight through your Sublime Text package manager.

    Once the selector is properly configured, you should see this

    So now jshint is reading the file, but it doesn't know what to do with that template tag. I don't blame it, because it's not really javascript or anything. The next option will help with this error

  • args

    This setting gives what can be considered command line arguments to the jshint runtime on sublime. The arg that we're using is called extract, which is documented here. We're setting it to auto because it is necessary for our needs. Basically, jshint is told to either extract the JavaScript out of a script tag within the html file, or if that fails, just run the linter over the whole file (i.e. as you would a .js file). This is necessary because I need to edit my Node.js backend webpack code as well as my .vue single file components, and I want both types linted.

After you correctly enable all of these options, jshint should be working on your Vue.js single file component! Oh no, it looks like I'm not as good a coder as I thought I was...

As an aside, this method is actually not very favored, even by the owner of the jshint repository! This means that every single use case might not work properly using the same config that I am using. So please, code on your own preferences

Card games to us humans are notoriously simple. Computers don’t really know much about card games, though. Without any instruction, computers can live their whole pitiful life without playing a single card game, so cherished by us humans. How sad.

Well, I’m sympathetic to my computer, so I chose for it to have a better life; to give it the ability to play the simple card game, Go Fish! Go Fish is a game that has some very easy to follow rules and regulations, with several variations that can be added along the way. The base rules of the game consist of these main points (taken from Wikipedia):

  • Players are dealt FIVE cards from a standard 52-card deck, or SEVEN if there are four or fewer players.
  • The remaining cards consist of the deck that the players will draw from for the remainder of the game.
  • A player whose turn it is to play asks another player for a card of a particular face value
  • The player who was asked must hand over all cards of that rank, if possible.
  • If the player who was asked does not have any of the face value cards in their hand, the player tells the asking player “Go Fish!”
  • The player who asked must draw a card from the deck.
  • If a player who asks for cards gets their cards through another player, or if they draw it from the deck after they make a bad guess, they get to go again. If not, it is the next player’s turn
  • When any player at any time has all four cards of one face value, it forms a trick, and the cards must be placed down on the playing table
  • When all sets of cards have been laid down in tricks, the game ends
  • The player with the most tricks wins!

Since I’m new to programming, I knew this would be a whole new experience for me. I hadn’t had the gumption or know-how to start a project like this before, but I knew that applying basic object oriented programming principles would help me get to the bottom of solving this problem. To start things off, I asked myself: “What is an object in a game of Go Fish?”. It’s not surprising what I came up with.

  1. Engine – An engine is necessary to handle how the game’s different parts will interact with each other
  2. Deck – The players will interact with the deck
  3. Card – Every deck is filled with cards, which the player will also interact with in their specific hands
  4. Player – The player of the actual game. Split into two categories:
    1. HumanPlayer – Humans control this type of player
    2. Bot – Since Go Fish isn’t fun without any friends, Players can fill the game up with some computer friends that will take the place of real friends

What else needs to be in there? Nothing? Oh, okay. Yeah… Well it looks like everything that is needed for the base functionality of a card game is there, now all I have to do is actually start to make the classes up. My next post will go over the Card and Deck class, how those two relate to each other, and how they each are built.

Lately, I've been volunteering on a WordPress project for a client with another developer. We're using LifterLMS; a plugin to handle the internal operations of the course, but the front-end is lacking for my needs. Our course has lots of audio files, some of which have file sizes greater than 8MB. We want a course that's accessible to everyone, even people who are learning on their phone. If they're not on WiFi, we're going to be killing their data with high quality files.

So here's the mission:

  • If the user is on a computer or tablet (on an average basis, connected to WiFi) serve the original quality audio file
  • If the user is on a phone, serve the same audio file at a reduced bitrate. 32 Kbps to be exact. Sorry audiophiles, but having a 16MB size file compress down to 2MB is nice.

The only draw to this process is that we have to store the high and low quality files on the server in the WP-Uploads folder. It's alright if we use more of our data storage. The final chore to make this a reality would be a JavaScript that would only run if the user is on a `Lesson` page.

So, first of all, I had to enqueue the script that I would be using in the `functions.php` file for my theme:

function dynamicScriptLoad() {
    // Using `is_page` causes an error
    if (is_page()) {
        if (is_lesson()) {
            wp_enqueue_script('audioServe', get_stylesheet_directory_uri() . '/js/dynamicAudioServe.js', array(), 1.0)
        }
    }
}
add_action('wp_enqueue_scripts', 'dynamicScriptLoad')

I was running into a wall, and the code wasn't running like I thought it would. The error came out to be the is_page() conditional call being used before is_lesson() conditional. Just using is_lesson() was fine enough.

function dynamicScriptLoad() {
    if (is_lesson()) {
        wp_enqueue_script('audioServe', get_stylesheet_directory_uri() . '/js/dynamicAudioServe.js', array(), 1.0)
    }
}

Anyway, now I could get to work on the JavaScript. I could use CSS with the addition of an .active class to dynamically change the `display` property. If we don't pre-load the audio files, then I'll still be able to have close to the same amount of data savings between phone usage and desktop usage. I whipped up a really quick script from there:

window.onload = function() {
	var smallFiles = document.getElementsByClassName('mobile-audio');
	var largeFiles = document.getElementsByClassName('desktop-audio');
	var smallView = true;
	if (screen.width > 736) {
		smallView = false;
	}

	if (smallView) {
		for (var i = 0; i < smallFiles.length; i++) {
			console.log(smallFiles[i])
			smallFiles[i].class = smallFiles[i].classList.add('active');
		}
	}
	else {
		for (var i = 0; i < largeFiles.length; i++) {
			largeFiles[i].class = largeFiles[i].classList.add('active');
		}
	}
}

This script looks at the screen.width of the device that is viewing the page, and adds the active class to all the DOM elements that also have the mobile-audio class, if screen.width < 736px, and vice versa if the width is over.

I was pretty happy with myself. Not only had I seen a well put-together job posting on Reddit, but I actually got a DM back, asking about my e-mail, and when to contact me! I've only been completely passionate about web development for about 9 Months now, and the fact that my resume looked good enough to potential employers for them to contact me back really made me feel like I was really going somewhere with my work. This turned out to be the wrong feeling that I should have had.

A week or two later, I was finally able to talk to the guy that contacted me about the opportunity. He was really nice during the interview, and he also let me know of the biggest thing that I needed to work on, which was my Data-Structure/Algorithm knowledge. I felt so dumb when I was asked even a simple question on the basics; "What is an abstract class, and why are these classes used instead of ?". My voice broke, my hands got sweaty, the volume of my voice got lower;

"Well, ummm... uhhhh... I mean...". I eventually got close to being right, but I wasn't really correct. I then learned that abstract classes are used to be inherently changed to fit a specific guideline, which, I know, is a very vague answer.

So, being the person that I am, I researched what the correct answer would be, and I found out that most of the general things that I'm doing with web development right now involves tons of abstraction, It's like I'm living in an abstract world and I never even knew about it!

In an abstract class (at least in Java programming) there can be a mix of regular and abstract methods. The regular methods are applied to every other subclass that extends the parent class, but abstract methods must be implemented specifically for that subclass. For example: Birds (the abstract class) can sing, but a Blue Footed Booby's (a class that inherits the 'Birds' class) song is going to be different from a general bird song. So, the Blue Footed Booby class would need an implementation of its own 'sing' class to be able to sing its own song.

I didn't know this during the interview, though, so I left the call pretty disheartened at the state of ignorance that I was in. But, life goes on, and so does the never-ending struggle of learning. So, sooner rather than later, I'm going to dive deep into data structures and algorithms and probably never come back after that point :). It will be a hard struggle for sure, but there was never was anything worth doing that wasn't hard at first.