Tag: tools

Resources for Artists: Be More Productive

We’ve all been there, needing that extra nudge to actually get something good done. Twitter and Facebook can suck you into a vortex and never let you go. We, as artists, need inspiration, tools, resources, and help with things we may not do so well (like social media marketing).

The good folks over at Creative Shrimp have put together a wonderful, catch-all list of 19 Useful Resources to Help You Get More Productive at Art. I use several of these regularly. You should really check it out.

Series: Building a Data Manager

I decided to extract some core classes I’ve used in several of my projects into their own package, a data-manager. DataManager is a container that does exactly what it says: manages item data for things like configuration settings. It also handles dot notation and exceptions. It should:

  1. Be stupid simple and lean — no extra features or code
  2. Create, Retrieve, Update, Delete and confirm/deny single items or complex items (array)
  3. Allow for fallback values if get() no item
  4. Handle deeply nested items through dot-notation (this.one.here)
  5. Be super extendable super easily

I worked for a few hours and cranked out exactly what I needed using Test Driven Development. You can use the Manager freely from github or composer. But, I wanted to share my process. This series will lead you through, step-by-step, the entire creation workflow for a php composer package using Test Driven Development. This is great for beginners who want to see TDD in practice.

You can see the finished version of this tutorial at chrismichaels84/data-manager/tree/tutorial-part-3 or use the finished, feature-complete, supported DataManager at chrismichaels84/data-manager.

Series Contents

  1. Setting Up – Define our goals and get our skeleton in place
  2. Features and Contracts – Define our API and get some core functionality
  3. Dot Notation – Dig deep into array structures (one.two.three)

Building a Data Manager Part III: Dot Notation

This post is part of a series aimed at beginning PHP coders. Follow step-by-step from ground zero to build a simple data manager.

You can see the finished version for the first part at chrismichaels84/data-manager/tree/tutorial-part-3 or use the finished, feature-complete, supported DataManager at chrismichaels84/data-manager

Setting UpFeatures and ContractsDot Notation


In the previous posts, we build a data manager from scratch using Test Driven Development. There are two features we have left to implement: deeply nested values via dot notation and throwing exceptions as needed. You can review the source code and lessons for the earlier bits, but this tutorial should stand on its own fairly well.

Dot notation is a common convention for getting at values that are deeply rooted in multidimensional arrays. The best way to show this is to show it.

$array = [
    'michael' => [
        'family' => [
            'sisters' => [
                'oldest' => 'Alicia',
                'youngest' => 'Erika'
            ]
        ],
        'favorites' => [
            'color' => 'purple',
            'foods' => ['tacos', 'pasta', 'all the bad for you stuff']
        ]
    ],
    'other' => 'value'
];

// array.michael.family.sisters.oldest returns Alicia
// array.michael.family returns sisters array
// array.michael.favorites.foods returns my favorite foods
// array.other returns value

With dot notation, we can easily dig deep into our Manager object. We want to be able to Create, Retrieve, Update, and Delete using dot notation. So, let’s get cracking.

Step Thirteen: Creating Our Tests

In this case, I want to create all of our tests at once so we know exactly what we’re getting into. I am sure we will create some private helper methods that we will reuse and it’s always good to have an overview of what will happen.

According to our API checklist, this is what’s left:

$manager->add('namespace.item', $item);
$manager->exists('namespace.name'); // also has()
$manager->get('namespace.item', $fallback);
$manager->remove('namespace.name');

And we’ll do it in that order. As we learned in the last post, set() is the same as add() and has() is the same as exists(). Looks like four tests to me.

We also have to be careful of false positives. If we add an item “one.two.three” it will create an item with that name without actually nesting arrays, so most of the tests will pass. To get by this, we will verify the entire contents of the manager in every test.

public function testAddNestedItems()
{
    $manager = new Manager();
    $manager->add('one.two.three', 'three-value');
    $manager->add('one.two.four.five', 'five-value');
    $manager->add('one.six', ['seven' => 'seven-value']);
    $manager->add('one.six.eight', 'eight-value');
    $manager->add('top', 'top-value');

    $expected = [
        'one' => [
            'two' => [
                'three' => 'three-value',
                'four' => [
                    'five' => 'five-value'
                ],
            ],
            'six' => [
                'seven' => 'seven-value',
                'eight' => 'eight-value'
            ]
        ],
        'top' => 'top-value',
    ];
    $actual = $manager->getAll();

    $this->assertEquals($expected, $actual, 'failed to add nested items');
}

public function testCheckExistenceOfNestedItems()
{
    $manager = new Manager();
    $manager->add('one.two.three', 'three-value');

// Always match against full contents
    $expected = ['one' => ['two' => ['three' => 'three-value']]];
    $actual = $manager->getAll();
    $this->assertEquals($expected, $actual, 'failed to add nested items');

    $this->assertTrue($manager->exists('one.two.three'), 'failed to confirm existence of a nested item');
    $this->assertFalse($manager->exists('one.two.no'), 'failed to deny existence of a nested item');
}

public function testGetNestedItems()
{
    $manager = new Manager();
    $manager->add('one.two.three', 'three-value');

// Always match against full contents
    $expected = ['one' => ['two' => ['three' => 'three-value']]];
    $actual = $manager->getAll();
    $this->assertEquals($expected, $actual, 'failed to add nested items');

    $this->assertEquals('three-value', $manager->get('one.two.three'), 'failed to get a single item');
}

public function testRemoveNestedItems()
{
    $manager = new Manager();
    $manager->add('one.two.three', 'three-value');
    $manager->add('one.two.four', 'four-value');

    // Always match against full contents
    $expected = ['one' => ['two' => ['three' => 'three-value', 'four' => 'four-value']]];
    $actual = $manager->getAll();
    $this->assertEquals($expected, $actual, 'failed to add nested items');

    $manager->remove('one.two.three');
    $manager->remove('does.not.exist');

    $this->assertTrue($manager->exists('one.two.four'), 'failed to leave nested item in tact');
    $this->assertFalse($manager->exists('one.two.three'), 'failed to remove nested item');
}

Great! All our tests fail or error. (Wow, that sounds weird).

Let’s Talk About Nested Arrays

Before we dive into modifying nested arrays, lets look at how we use loops to navigate nested arrays. When given a string like “this.is.my.dot.notation” what we are really wanting to do is loop through a given array 5 times, changing our location in the array by one step. So, on the first loop we go to $array[‘this’] and then to $array[‘this’][‘is’] and so on.

The best way to achieve this is to use php references from variables. What this does is allow two variables to point to the exact same bit of data. You modify one, you modify the other. For instance,

$loc = &$this->items['this']['is']['my'];

does not set $loc to the value of that array ([‘dot’ => [‘notation’]]). Instead, $loc now refers to or points to or aliases that array.

Knowing that, we can navigate through our deeply nested items using a foreach in this basic way:

$alias = "one.two.three";
$loc = &$this->items;
foreach (explode('.', $alias) as $step) {
    if (isset($loc[$step])) {
        $loc = &$loc[$step];
    }
}

We are going to modify this basic control structure (and use a while loop variant) to do all of our nesting. Note that even if an alias does not have a dot (and therefore refers to the top level), the loop will still execute once. That means we don’t need to check if an alias is nested. We can just treat all aliases as nested and the method will return the correct value.

Step Fourteen: Adding Nested Items

Let’s get our feet wet. Our add() method now is

public function add($alias, $item = null)
{
    // Are we adding multiple items?
    if (is_array($alias)) {
        foreach ($alias as $key => $value) {
            $this->add($key, $value);
        }
        return $this;
    }

    // No, we are adding a single item
    $this->items[$alias] = $item;

    return $this;
}

We want to leave adding multiple items the same. If it ain’t broke, don’t fix it. We’ll use our foreach loop to replace $this->items[$alias] = $item

// No, we are adding a single item
$loc = &$this->items;
foreach (explode('.', $alias) as $step) {
    $loc = &$loc[$step];
}
$loc = $item; // remember that $loc now refers to the right place in the nested items array

First, we set a temporary location variable to refer to our items array. Second, we loop through that items array “x” times, depending on how deep the alias is nested. At each loop, we change the $loc variable to refer to the new level. Finally, we simply set final location (which refers to the items array) to the correct value. Viola!

For now, comment out the other three tests, run phpunit, and watch everything pass.

Step Fifteen: Check the Existence of Nested Items

Since we are going to want to check the existence of things before we get or remove them (in order to avoid “index not found” errors), let’s whip this one out first.

Our current exists() method is pretty simple:

public function exists($alias)
{
    return (isset($this->items[$alias]));
}

We want to cycle through the array in the same way we did for add(). It’s good practice to return early, so we can return false if at any time we run into a nonexistent item. We return true at the end.

public function exists($alias)
{
    $loc = &$this->items;
    foreach (explode('.', $alias) as $step) {
        if (!isset($loc[$step])) {
            return false; // returning early so the loop ends
        } else {
            $loc = &$loc[$step];
        }
    }
    return true;
}

This passes our second test, and breaks no other tests. Well done.

Step Sixteen: Getting a Nested Item

Right now we’re looking at

public function get($alias, $fallback = null)
{
    $exists = $this->exists($alias);
    if (!$exists && !is_null($fallback)) {
        return $fallback;
    } elseif (!$exists) {
        throw new ItemNotFoundException();
    }

    return $this->items[$alias];
}

Let’s break this down logically. We have three ways any attempted get() can go

  1. The item does exist. Return the value
  2. The item does not exist, but we have a fallback. Return the fallback
  3. The item does not exist, and there is no fallback. Throw an error.

This is the perfect time for an if, elseif, else statement. When it comes time to return the value if it exists, we will use the same foreach structure as we did to add.

// Check for existence
$exists = $this->exists($alias);

// The item does exist, return the value
if ($exists) {
    $loc = &$this->items;
    foreach (explode('.', $alias) as $step) {
        $loc = &$loc[$step];
    }
    return $loc;

// The item does not exist, but we have a fallback
} elseif ($fallback !== null) {
    return $fallback;

// The item does not exist, and there is no fallback
} else {
    throw new ItemNotFoundException();
}

 Step Seventeen: Remove a Nested Value

That brings us to the last of our CRUD for nested values. I’ll be honest. This one stumped me for a moment. I tried a simple foreach, found that foreach was going through ALL the items in the . I googled it and found Laravel’s Array Helpers which led me to this solution:

public function remove($alias)
{
    $loc = &$this->items;
    $parts = explode('.', $alias);

    while (count($parts) > 1) {
        $step = array_shift($parts);
        if (isset($loc[$step]) && is_array($loc[$step])) {
            $loc =& $loc[$step];
        }
    }

    unset($loc[array_shift($parts)]);
}

Here, we iterate over the alias array, but don’t hit the very last member.

Now all of our tests pass. We can refactor with joy because anything we change that will break something causes phpunit to throw a fit.

A Little Polish

There are just two more things I would like to do. First, add a constructor so you can populate the manager at instantiation.

First a test.

public function testPopulateAtInstantiation()
{
    $expected = ['one' => ['two' => ['three' => 'three-value']]];
    $manager = new Manager($expected);

    $this->assertEquals($expected, $manager->getAll(), 'failed to populate array at construction');
}

And to make it pass

public function __construct(array $items = [])
{
    $this->items = $items;
}

All done!

And that, my friends, is that. We have a fully featured Manager, well tested, and ready for the world. Add in some docblocks and refactor to you hearts content. See the full version at http://github.com/chrismichaels84/data-manager. There are different branches. The “master” is the up-to-date version with new features. Tutorial branches are married to these tutorials.

Cheers!

Building a Data Manager Part II: Features and Contracts

This post is part of a series aimed at beginning PHP coders. Follow step-by-step from ground zero to build a simple data manager.

You can see the finished version for the first part at chrismichaels84/data-manager/tree/tutorial-part-2 or use the finished, feature-complete, supported DataManager at chrismichaels84/data-manager

Setting Up – Features and Contracts – Dot Notation


Last time, we started building a simple data manager for things like configuration settings (or any kind of collection, really). Our feature goals were:

  • Create, Retrieve, Update, and Delete single items or complex items (array)
  • Get all items as an array
  • Clear all items
  • Confirm or deny that an item exists in its collection
  • Handle deeply nested items through dot-notation (this.one.here)
  • Throw exceptions as needed, or fail silently based on configuration
  • Allow for fallback values if get() no item

We set up a repository, defined our API, created an interface, and implemented the first feature (add and get a single item) using Test Driven Development. If you don’t remember, check it out!

Now we are going to implement the rest of the basic features and begin checking things off of our api list. We can actual check some things off now!

//$manager = new MichaelsDataManager();
//$manager->add('name', $item);
$manager->add(['name' => $item, 'name2' => $item2]);
$manager->add('namespace.item', $item);
//$manager->get('name');
$manager->get('namespace.item');
$manager->get('doesntexist', 'fallback');
//$manager->getAll();
$manager->set('name' $newValue);
$manager->set(['name1' => $newValue1, 'name2' => $newValue2]);
$manager->clear();
$manager->remove('name');
$manager->remove('namespace.name');
$manager->has('item'); // true or false
$manager->exists('item'); // same as above

Basic C.R.U.D.

Step Six: Add Multiple Items at Once

Let’s tack line 3 of the above code. It should be simple enough to add an array of items. While we’re at it, lets start adding different kinds of data, just to be on the safe side.

First, the test

public function testAddMultipleItemsAtOnce()
{
    $manager = new Manager();
    $manager->add([
        'objectTest' => new StdClass(),
        'closureTest' => function () {
            return true;
        },
        'stringTest' => 'value'
    ]);

    $items = $manager->getAll();

    $this->assertArrayHasKey('objectTest', $items, 'Array Items does not have key `objectTest`');
    $this->assertArrayHasKey('closureTest', $items, 'Array Items does not have key `closureTest`');
    $this->assertArrayHasKey('stringTest', $items, 'Array Items does not have key `stringTest`');
}

When we run “phpunit”, we get an errors. Let’s make the tests pass by fixing DataManager.php

public function add($alias, $item = null)
{
    // Are we adding multiple items?
    if (is_array($alias)) {
        foreach ($alias as $key => $value) {
            $this->add($key, $value);
        }
        return $this;
    }

    // No, we are adding a single item
    $this->items[$alias] = $item;

    return $this;
}

All this does is check if we are adding at array of items, and sends it back through the same method for each item to add.

Run “phpunit” and we are golden.

Step Seven: Confirm or deny that an item exists

Let’s do this one in two tests: First check to see if it confirms the existence of an item:

public function testReturnTrueIfItemExists()
{
    $manager = new Manager();
    $manager->add('test', 'value');

    $this->assertTrue($manager->exists('test'));
}

And then confirm that an item doesn’t exist:

public function testReturnFalseIfItemDoesNotExist()
{
    $manager = new Manager();

    $this->assertFalse($manager->exists('test'));
}

Create this method in DataManagerTest.php and run the unit test. It should fail. Yep. To make it pass, were just going to return the result of isset()

public function exists($alias)
{
    return (isset($this->items[$alias]));
}

All green. Good job. See how easy this actually is? Since we also have a has() method, lets just point it to exists().

public function has($alias)
{
    return $this->exists($alias);
}

Step Eight: Allow for fallback values

If we try to get an item that doesn’t exist, right now it would throw an error. I want to be able to provide a fallback value if my item doesn’t exist, so I know I’ll get a default value.


$manager->get('doesntexist', 'fallback');

Like always, we write the test first so that it fails or errors:

public function testCanProvideFallbackValue()
{
    $manager = new Manager();
    $manager->add('one', 'one-value');

    $actual = $manager->get('two', 'default-value');

    $this->assertEquals('default-value', $actual, 'failed to return a fallback value');
}

We get an undefined index error. That’s what we expect. There is no index for ‘two’. Let’s make it pass using the exists() method we’ve already made.

public function get($alias, $fallback)
{
    if (!$this->exists($alias) && $fallback) {
        return $fallback;
    }

    return $this->items[$alias];
}

Well that was interesting. We made that test pass, but we broke another test. in testGetSingleItem() we use $manager->get() and don’t provide a fallback. But $fallback is required. This is why we write automated tests. It may have taken me months to come across that bug.

Let’s fix it so all our tests pass. We want fallback to be optional, so we’ll set it to null by default.

public function get($alias, $fallback = null)
{
    if (!$this->exists($alias) && !is_null($fallback)) {
        return $fallback;
    }

    return $this->items[$alias];
}

Bam! Green! Let’s move on.

If we do not have a fallback value, we should throw an exception.

Test:

/**
 * @expectedException MichaelsManagerItemNotFoundException
 */
public function testThrowsExceptionIfItemNotFound()
{
    $manager = new Manager();
    $manager->get('doesntexist');
}

Updated get() method:

public function get($alias, $fallback = null)
{
    $exists = $this->exists($alias);
    if (!$exists && !is_null($fallback)) {
        return $fallback;
    } elseif (!$exists) {
        throw new ItemNotFoundException();
    }

    return $this->items[$alias];
}

And of course, we have to create ItemNotFoundException.php inside of src.

namespace MichaelsManager;

class ItemNotFoundException extends Exception
{

}

Step Nine: Updating a Value

We have the C and R from CRUD. Let’s take on the U – Update. What we want is


$manager->set('name' $newValue);

$manager->set(['name1' => $newValue1, 'name2' => $newValue2]);

So, let’s write our tests.

public function testUpdateSingleItem()
{
    $manager = new Manager();
    $manager->add('item', 'original-value');
    $manager->set('item', 'new-value');

    $this->assertEquals('new-value', $manager->get('item'), 'failed to update a single item');
}

public function testUpdateMultipleItems()
{
    $manager = new Manager();
    $manager->add('item', 'original-value');
    $manager->add('item2', 'other-original-value');
    $manager->set(['item' => 'new-value', 'item2' => 'other-new-value']);

    $this->assertEquals('new-value', $manager->get('item'), 'failed to update first item');
    $this->assertEquals('other-new-value', $manager->get('item2'), 'failed to update second item');
}

From previous experience, we know that set() requires 2 arguments, but in the second test we only provide one. So, we will get an error. We will fix this the same way as before.

Actually, this is all identical to what we’ve done before, right? We’re just going to create or update an index in an array. Why don’t we cheat and just point to the add() method? It can’t hurt to try. We don’t want to copy and past the code because it may change in the future and we don’t want to change it twice.

public function set($alias, $item = null)
{
    return $this->add($alias, $item);
}

Everything is GREEN. Kudos to us for saving ourselves some work.

Step Ten: Remove An Item

We don’t want to use the word delete, because it can be reserved and cause weird bugs. So we want to remove individual items and we want to clear the entire manager. Let’s remove a single item first. We know our test will fail before we create the method, so I’m going to do both at the same time for brevity.

Test:

public function testRemoveItem()
{
    $manager = new Manager();
    $manager->add([
        'one' => 'one',
        'two' => 'two'
    ]);

    $manager->remove('one');

    $items = $manager->getAll();

    $this->assertArrayNotHasKey('one', $items, 'failed to remove `one`');
    $this->assertArrayHasKey('two', $items, 'failed to leave `two` intact');
}

Method in DataManager. When doing this, we want to

  1. Check if the item exists at all
  2. Remove it if it does
public function remove($alias)
{
    if ($this->exists($alias)) {
        unset($this->items[$alias]);
    }
}

Let’s look at this code for a second. We use the already created exists() method. If it does exist, then we pop the item out of the array and delete it. When it comes time to return, I used a short syntax for the if statement that says “if $removed exists) then return it, otherwise, return false”. Remove won’t exist unless we removed something.

Step Eleven: Clear the Entire Manager

As a last helper, it would be nice to totally empty the manager. This should be easy.

Test:

public function testClear()
{
    $manager = new Manager();
    $manager->add([
        'one' => 'one',
        'two' => 'two'
    ]);

    $manager->clear();

    $items = $manager->getAll();

    $this->assertEmpty($items, "Failed to empty manager");
}

Code:

public function clear()
{
    $this->items = [];
    return $this;
}

Checking Our Progress

What can we safely check off now?

//$manager = new MichaelsDataManager();
//$manager->add('name', $item);
//$manager->add(['name' => $item, 'name2' => $item2]);
$manager->add('namespace.item', $item);
//$manager->get('name');
$manager->get('namespace.item');
//$manager->get('doesntexist', 'fallback');
//$manager->getAll();
//$manager->set('name' $newValue);
//$manager->set(['name1' => $newValue1, 'name2' => $newValue2]);
// $manager->clear();
//$manager->remove('name');
$manager->remove('namespace.name');
//$manager->has('item'); // true or false
//$manager->exists('item'); // same as above

Wow, that’s everything except the namespaced dot-notation which we will tackle next time.

Step Twelve: Abiding By a Contract

So, for good measure, let’s implement an interface. This is important because it allows others to create interchangeable classes. I will discuss this more later, but it’ a really good habit. We’ll have to modify what we created earlier. If your editor won’t extract an interface, the easiest thing to do is copy and past the class into the new file and then remove all the code. Leave your docblocks!

And that is all for now. All that is left is to implement the namespacing feature and handle missing items, and then publish out work to the world! See you later.

Building a Data Manager Part I: Setting Up

This post is part of a series aimed at beginning PHP coders. Follow step-by-step from ground zero to build a simple data manager.

You can see the finished version for the first part at chrismichaels84/data-manager/tree/tutorial-part-1 or use the finished, feature-complete, supported DataManager at chrismichaels84/data-manager

Setting UpFeatures and ContractsDot Notation

I decided to extract some core classes I’ve used in several of my projects into their own package, a data-manager. DataManager is a container that does exactly what it says: manages item data for things like configuration settings. It also handles dot notation and exceptions. It should:

  1. Be stupid simple and lean — no extra features or code
  2. Create, Retrieve, Update, Delete and confirm/deny single items or complex items (array)
  3. Allow for fallback values if get() no item
  4. Handle deeply nested items through dot-notation (this.one.here)
  5. Be super extendable super easily

I worked for a few hours and cranked out exactly what I needed using Test Driven Development. You can use the Manager freely from github or composer. But, I wanted to share my process. This series will lead you through, step-by-step, the entire creation workflow for a php composer package using Test Driven Development. This is great for beginners who want to see TDD in practice.

Getting Started

Step One: Create a new Repository

I like to start directly from Github. Login and create a new repository. I named my data-manager (chrismichaels84/data-manager), gave it an MIT License, and a Composer .gitignore. Though it doesn’t matter, We’re about to override all this.

Next, clone your repository locally so you can edit it more easily. I use PHP Storm 8.2, but Github’s program and Sublime Text works just as well. I’m going to assume you know how to do this. If not Github’s bootcamp is the perfect place to start.

Step Two: Create the Skeleton

I’m a big fan of being lazy. If someone else has done it, I’m gonna steal it if I can, lol. In this case, the League of Extraordinary Packages has done it right and wants us to steal it. The League is a collective of php coders who share their work. Some really good work that is held to the highest standards. They have a skeleton repo that gets all the boilerplate for a kick-ass composer package. It’s also a good idea to take a look at the PHP Package Checklist.

Clone the skeleton repo (don’t just download the zip file). Now, you can copy everything in the skeleton to your manager project. Overwrite anything that’s already there.

With a little tweaking, customize this skeleton:

  1. I don’t use scrutinzer, so I delete that file
  2. Work through the .MD files to change names, authors, and such. You can leave the badges at the top of the README.md file alone for now.
  3. Update composer.json to your awesome project.

Test Driven Development

Skip this if you’re familiar with the TDD workflow.

It is important to do things right the first time so you don’t have to do them right the second time. That’s what test driven development is all about. For the beginner (and even the advanced user), I know that phrase can sound scary, like your adding a ton of work. Plus terms like mock, stub, dummy, and acceptance are defined a million different ways — never consistently. I feel your pain.

TDD is simply writing automated tests for every feature of your package so that as you change things in the future, you can make sure you didn’t break something along the way. We all test, even if you just pull it up in the browser and put it through its paces. The problem with that is, you will miss something and a bug will creep in. These automated tests will tell you exactly what has gone wrong every step of the way. And, once you write a good test, you shouldn’t have to rewrite or rexecute it unless you make sweeping changes to the package.

You also ensure that you don’t write any extra code. You only test what you need and only code to pass the test. The basic process is:

  1. Describe the feature
  2. Make it Red: Write a test for that feature. This test will fail because you haven’t actually coded yet.
  3. Make it Green: Write the least amount of code possible to make that test pass.
  4. Refactor with complete safety. The test will fail if you break something.
  5. Repeat for each feature.

You’ll see what I mean as we plow through. Check out Laracasts or this article for great getting started lessons.

Make a Plan

I start every project by creating a PROPOSAL.md file where I figure out exactly what it is I want to do. My goals and what features I want. In this case:

  • Create, Retrieve, Update, and Delete single items or complex items (array)
  • Get all items as raw array
  • Clear all items
  • Confirm or deny that an item exists in its collection
  • Handle deeply nested items through dot-notation (this.one.here)
  • Allow for fallback values if get() no item

Step Three: Work Out Your Basic API

I also like to sketch out a basic API for the class (usually in the proposal):

$manager = new MichaelsDataManager();
$manager->add('name', $item);
$manager->add(['name' => $item, 'name2' => $item2]);
$manager->add('namespace.item', $item);
$manager->get('name');
$manager->get('namespace.item');
$manager->get('doesntexist', 'fallback');
$manager->getAll();
$manager->set('name', $newValue);
$manager->set(['name1' => $newValue1, 'name2' => $newValue2]);
$manager->clear();
$manager->remove('name');
$manager->remove('namespace.name');
$manager->has('item'); // true or false
$manager->exists('item'); // same as above

While we’re at it, let’s extract it to an interface to src/DataManagerInterface.php and docblock everything.

Give Me Some Code, Already!

I hear you. We are finally ready to start coding. It may seem like a lot, but all this preliminary stuff is important, will make our lives so much easier, and will get faster with practice.

Step Four: Write and Fail Your First Test

Inside “/tests” create “DataManagerTest.php”

namespace MichaelsManagerTest;

class DataManagerTest extends \PHPUnit_Framework_TestCase
{
    public function testMyFirstFeature()
    {
        $this->assertTrue(true);
    }
}

Be sure to change the namespace!

Before we can run this, we need to make sure we have PHPUnit installed. It couldn’t be easier. Open up composer.json. It should already be added under “require”. If it is, then run “composer update” from the project directory in your terminal.

Once PHPUnit is installed, we can run “phpunit” from the terminal.

All is great! Except we don’t want it to be. Remember we actually want to fail our first test. It passes because we aren’t actually testing anything. Let’s change that.

namespace MichaelsManagerTest;
use MichaelsManagerDataManager as Manager;

class DataManagerTest extends PHPUnit_Framework_TestCase
{
    public function testAddSingleItem()
    {
        $manager = new Manager();
        $manager->add('alias', 'value');

        $this->assertArrayHasKey('alias', $manager->getAll(), 'Array Items does not have key `alias`');
        $this->assertEquals('value', $manager->get('alias'), 'Failed to get a single item');
    }
}

Here, we are testing a few things. First, we create a new Manager instance. Then, we try to add a string called “alias” with a value “value”. We test to see if that has worked by getting all the values from the Manager and making sure “alias” is one of them and then trying to get “alias” by itself and ensuring that the value is correct.

We are actually test 3 of our API methods: “add(), getAll(), and get()”.

Give it a whirl! Run phpunit”. What? Fatal error? Of course, we haven’t actually created the DataManager class.

Create “DataManager.php” inside “/src” with our three testable methods that do nothing right now. Don’t implement any interfaces quite yet.

namespace MichaelsManager;

/**
 * Manages Basic Items
 *
 * @package MichaelsMidas
 */
class DataManager
{
    public function add($alias, $item)
    {
        return $this;
    }

    public function get($alias)
    {
        return false;
    }

    public function getAll()
    {
        return [];
    }
}

Now when we run this test, it will not give us any errors, but it will fail. That’s actually what we want!

Step Five: Pass Your First Test

Alright, let’s make DataManager do something. Remember, we are trying to do the least amount possible to make this one test pass.

  1. Start by creating a protected property called $items and set it to an array.
  2. Inside add(), simply append the desired item to $this->items
  3. Inside get(), return $this->items[$alias];
  4. Inside getAll() return $this->items;

So, your DataManager class looks like:

namespace MichaelsManager;

/**
 * Manages Basic Items
 *
 * @package MichaelsMidas
 */
class DataManager
{
    protected $items = [];

    public function add($alias, $item)
    {
        $this->items[$alias] = $item;
        return $this;
    }

    public function get($alias)
    {
        return $this->items[$alias];
    }

    public function getAll()
    {
        return $this->items;
    }
}

And viola! When we run “phpunit” our tests are green. We have successfully managed some data. Don’t forget to DocBlock your methods.

You can see the finished version for the first part at https://github.com/chrismichaels84/data-manager/tree/tutorial-part-1 or use the finished, feature-complete, supported DataManager at https://github.com/chrismichaels84/data-manager

From here on, we are just going to repeat this project until all our goals are complete and our API is functional including dot notation. Hope to see you next time!

Using Digital Storytelling in e-Learning

In an attempt to gather some of the foremost research in transformational storytelling and innovative curriculum design, I offer this article from eLearn Magazine. This article discusses how creativity and innovation can enhance e-learning systems based on digital storytelling. It goes as far as to propose a story creation model called “movement-oriented design” (MOD)  for systematically developing effective digital stories, in conjunction with story creation principles articulated by Robert McKee, a Hollywood guru of script writing.

Read the original here.


Some Highlights:

Digital Storytelling
With advancements in digital audio and video capture technology and editing software, digital storytelling is becoming a part of modern life, making it easier to create innovative e-learning content presented as digital stories. Such innovative content can not only make courses more attractive, but can also lead to deep learning.

Some of the new pedagogical models based on storytelling include: story-centred curriculum, proposed by Roger Schank (2007), and scenario-based curriculum development, suggested by Ray Bareiss & Sukhjit Singh (2007). The common theme that permeates these pedagogical models is: “learning through stories.”

Stories have been used as educational medium since prehistoric times as they encapsulate four crucial aspects of human communication: information, knowledge, context, and emotions (Norman, 1993). Embedding stories as digital media, i.e., digital storytelling, is therefore not only desirable, but almost essential for producing engaging e-learning content . . .

e-Learning and Digital Storytelling
E-learning systems that just transform the traditional educational content (for example, books or lecture notes) into digital media are not successful; because, e-learning content that presents only facts and figures can loose the learners attention more easily than a good lecturer, who can capture the learners’ attention with personal charisma. With e-learning content, the lack of personal connection (with a real teacher) can be overcome by creating “educational stories” that embody good storytelling principles.

Good storytelling principles have been articulated by the masters of storytelling since Aristotle. These principles can also be applied to develop good educational stories. To capture and maintain the learner’s interest, a story’s narrative must connect with the learner’s emotions and create emotional movement. Any learning that happens with a story, especially one that provides an emotionally moving experience, is much more persistent, and therefore, easy to recall.

McKee Principles
Robert McKee, the Hollywood guru of film script writing has articulated principles for creating effective stories (McKee, 1998). A subset of these “McKee Principles” can be applied for creating good educational stories as well. To achieve emotional movement, McKee proposes five stages for designing the “spine” of a story: 1) inciting incident, 2) progressive complications, 3) crisis, 4) climax, and 5) resolution.

Movement Oriented Design
Movement Oriented Design (MOD) is a framework proposed by the author for creating contextualized stories, that is, stories that work in a given context, for example e-learning (Sharda(2), 2007). MOD views every temporal presentation as a story. From a MOD perspective, even this article is a story. Every good story should have three clearly identifiable components: a beginning, a middle, and an end; called Begin (B), Middle (M), and End (E) in the MOD terminology.

The most fundamental element of the MOD methodology is a Movement, which is defined as a micro story with clearly identifiable begin, middle, and end components. A good beginning should entice the user, wanting to find out more. The middle should be used to deliver the essential educational content, and the end should conclude the story unit. Wherever possible, the end of one story unit should build a link to the next. A story unit that does not have all three components (B, M, E) will most likely be ineffective. When creating e-learning content, often the authors overload it with useful information without linking these with an effective narrative; consequently the learners’ interest wanes.


Read the rest here.

Storytelling With WordPress

In trolling the vast interwebs for research, I found several great resources to create storytelling websites using the popular (and free) web-software, WordPress. For those that don’t know, WordPress is a mini-content-management system that runs about 20% of all the websites in the internet. It’s totally free, made by community volunteers, open source (so you can modify it), and very easy to use. Usually, it makes websites, but the links below give tips on transforming that website into an interactive story. Enjoy!


WordPress Storytelling – A great introduction with examples of how people are using WordPress to tell stories.

Storytelling in WordPress – Another showcase of WordPress stories.

Immersive Storytelling – The next step, how to get started.

A DIY Guide to WordPress Storytelling – Another step by step guide. Very readable. Great people over at WPMU.

The Aesop Story Engine – A great tool to get you started. Does a lot of the technical stuff for you. Easy to use.

Building Stories Using a Multimedia Storyteller – Another tool that gives you more control, but is a little more tech-y.

Enjoy!

Seven Resources for Educational Games

I discuss educational stories a lot, but that story may take many forms. One of the most powerful is through educational games. Here is a simple list of ways to get you started created engaging games for an educational purpose.

Do It Yourself

  1. How to make Art and Craft Games
  2. Make Fun Quizzes and Games
  3. Educational Games on Pintrest
  4. ClassTools: A huge resource of games and curriculum
  5. Sharendipity: makes it possible for students and teachers to quickly create and share simple video games
  6. PurposeGames: free service that allows users to create custom games, share games, and play games
  7. W2L: Thousands of online educational games

More From Free4Teachers.com

Personalized Instruction in the Classroom

This post is part of a mini-series introduction to Individual Differences in Instruction and Storytelling. I lay the groundwork for deeper adventures in Differentiated Instruction, Learning Styles, Personalized Stories, and the like.

Check out the rest of the series.

Now that we have looked at the theories and concepts behind differentiated instruction, let’s see what it looks like in the classroom itself. I am not a classroom teacher, so I will rely on the best. Scholastic Publishers has a fantastic resources for teachers. This article was excerpted from the Scholastic Professional title, Differentiating Reading Instruction, by Laura Robb and can be found at http://www.scholastic.com/teachers/article/what-differentiated-instruction.

I have taken a few excerpts  to give the gist of the article, but I highly recommend you read the original.


 Step Inside The Classroom

“So what does differentiated reading instruction look like? I invite you to step inside my eighth-grade classroom at the beginning of my reading workshop. After a brief warm-up exercise, and a read aloud for enjoyment, I introduce an essential component of my approach to differentiated reading instruction “” the teaching read aloud. To be certain that I am reaching every student in my class, I use the read aloud to model how I apply reading strategies and to show students how to use questioning, discussion, and writing to build comprehension and new understandings while reading (Beck & McKeown, 1997, 2006; Robb, 2000, 2003). In fact, the read aloud has become the common mentor or teaching text for my students, and a primary teaching tool. In addition, I use it as a catalyst to raise students”™ awareness of issues and to build background knowledge.

Read More

Powered by WordPress & Theme by Anders Norén

%d bloggers like this: