Merl's Blog

Raising up Flags

There comes a time in life when you need to raise up some flags. Maybe it’s the smart time to surrender, maybe there is trouble ahead, or maybe you need your data to load in correctly.

This is about the latter.

I was working on a pesky bug, when entering a page from a specific route the functionality was slightly off. I wanted a graph to display everyone, however sometimes it would only display the user, which would be me in this case.

After digging around, I was able to discover the reason as to why that was the case.

It was displaying all the users! It just so happens that sometimes the first load includes only me as the complete user list. Wait a minute that’s not right.

It is great that JS is able to multitask, however asynchronous events can cause unexpected behavior. So what is the solution?

read more

Readability

There are many reasons to refactor. Often times it is to follow best practices, and sometimes it is because we want our code to be understandable.

I will say I took some time to understand this code the first time I saw it.

(let [unfocused? (and (seq @focus) 
                      (not ((set @focus) item))
                      (contains? (set (map :kind @focus)) (:kind item)))]
  ;; rest of the code
)

Let’s go over what each part does shall we?

(seq @focus) This is a clever way to see if `@focus` list is empty or not. If it is empty it will return nil,  which means unfocused is false. 

(not ((set @focus) item))

This one was not nearly as clear for me. I see that the list @focus is turned into a set, but I had no idea a set could be a function in clojure. Sets can be used to check for membership. So if item is in the set then it will return the item, and if it is not in the set it will be nil. not reverse the outcome

All in all, if the item is in @focus then unfocused? is false.

Finally

 (contains? (set (map :kind @focus)) (:kind item))

Whatever object is in focus will have a :kind. We can get all the kinds of objects are in focus and place it in a set.

Now we just see if the item in question has the same :kind as the :kind of objects in @focus.

All of these tell us if the item is in @focus or not.

Now this is the refactoring to try and make this clearer to future readers.

(defn unfocused? [focus item]
  (and (seq @focus)
       (not-any? #{item} @focus)
       (some #{(:kind item)} (map :kind @focus))))

Every part does the same thing but now I think it is more readable.

Until next time.

Best,

Merl

read more

Branches

Branches in git can be very useful, but you need to be careful with them.

I have been using another branch away from out main branch. It has worked well because we are working on a major update and doing what we need to there.

The problem is that I did some work that is not related to that update in that branch. I made 2 new useful commits in the branch instead of main.

I was digging around trying to find ways to move the commits over. Rebasing and merging are a no-go because the project itself isn’t ready. I found Cherry-picking, I have done this before and was planning on doing it again. Why not?

I will just move the 2 commits over no problem!

But, what about when we need to rebase the whole branch unto our main one …

That means that we will move over the 2 commits again a long with everything else?

This could cause problems.

Well, this is a lesson learned.

Only work on the same project for a particular branch, and stay on main as much as possible. because it might be a while before I get to move those commits over.

Best,

Merl

read more

Restart

“Have you tried turning it off and on again?”

These are the famous words spoken by anyone who has worked with electronics before.

So why would this logic not work in software?

I was in the process of adding new features and refactoring old code.

This was wonderful. Everything was going peachy, until I came across this one test.

See we had 2 navigation bars, the first was the real deal that had everything we needed. Search bar, menus, people updates, the works.

Then on another newer page we had a very simple version of that, with just the title.

As time went on the simpler version was getting the same features as the first one minus the search bar. Of course some of these buttons and features lead to you to different places.

So refactoring had to be done to replace the simpler bar with the first bar.

I came across a test that needed the simpler bar’s functionality, I made sure I rendered the navigation bar perfectly but the test was failing, thinking it was in the first page.

I tried all the many tricks I have learned throughout my time in Internal Dev. Finally I learned that I had to reset the DOM.

Seriously? It was working great with all the many other tests we had but for some reason I need to reset the DOM here.

OK. So there you go, sometimes you gotta just restart.

Best,

Merl

read more

Spikes

What are spikes? They are ways to learn about a project, a new system, or a story you want to complete.

They are very useful when you have many unknowns.

I wish I had known about this in the beginning, so I could have used these when I was learning something absolutely new.

The problem is you do learn about what you will work on, but it is hard to gauge how much is perfectly accurate.

Even right now I will be looking at multiple options and then decide which way to move forward in a story.

The end of the spike is supposed to be an estimate for the real story.

It is a wonderful tool, that is super helpful. I just hope when I do these my estimates are good and I can complete this new project.

Best,

Merl

read more

Complicated Tests

Recently I have been working on fixing a few challenging bugs. They have been challenging because they only exist in very specific conditions.

This makes it challenging to test!

How do you test this when normally you just make one component and test that. But now you need to make 2 different components. The reason why you need 2 components is because of how they interact with each other that produces this bug.

The wise thing I learned was that instead of rendering these 2 components, which would never happen in production.

You should go to a higher level where these 2 components are made “naturally” and in production and then test there.

That last sentence was what helped me move forward and actually create meaningful tests.

Tests

I did come across a test that tested me as a person.

I wrote this and I am ashamed. See a test should ideally be small and only test a few things. So I need to split it up.

I also had another problem that was mainly solved once I did split this up.

The problem was that clicking on Sam should have had specific events happening. I should not have selected Frodo, however this test could not pass.

Again the problem was it was doing too much and the other problem is that I had the click inside the let statement.

read more

Logs

Why logs?

Well, sometimes you come across a log in code. You turn it over and what do you find? A bunch of nasty bugs.

This happened to me recently. Now here is the issue, I have been working on part of this codebase before, so I can’t claim innocence, nor can I blame it on anyone else.

Story

Small personal story, when I was 23. Not very wise or domesticated I lived with my sibling and their spouse. They were very generous, and kind. I was young but foolish.

The point of this is to show that at that time when there was an issue, I would say not my fault and move on. Whether it be dishes, or some other sor tof problem.

My brother-in-law was a marine, not active but had been in the marines some time. He kept telling me, it doesn’t matter the cause it is now everyone’s responsibility to fix the problem.

As an immature person, this is tough to hear and tough to actively learn.

Obviously now I am incredibly wise, just kidding. Only slightly less immature.

Back to bugs

What I am trying to say is that regardless if I created them I need to fix them, because I am part of the system now, and it is my duty to do so.

With that being said it is taking a long time to complete. However, since our reputation is on the line I must complete it.

Best,

Merl

read more

Search Bars

Search bars, I have completed a few.

Now that I was tasked with completing a few more it should be pretty easy right?

Well, it should have been, but I like to make problems. It’s something I’ve been good at since I was young.

The problem was I began making a search bar where there was a shared component. Because of this when I would play around in local host I was unsure which bar was being displayed since the search bar would appear in the exact same place, just different pages.

For some reason, when I was playing around I wasn’t sure which menu was popping up. because this menu which the search bar would be a part of was finicky.

So what did I have to do with the shared menu that was finicky, I stopped sharing the menu between the different pages. Not permanently!

Since I was having such difficulty, I took the code out of the shared menu function and did it the long way.

I made the menus again in the large component, and then I added the search bar.

Once I finally got it working, I moved the shared code over into it’s proper function, like it was initially.

I suppose the lesson for today is that sometimes like a mechanic you need to move the part you are working on to another place to have a better understanding of what is going on.

Best,

Merl

read more

Clicking on links

The story I have been working on is clicking on links that have been signed off on an iteration.

The problem was when we sign off on an iteration, we disable the text. Since it is disabled you can’t do anything with it. This is a problem because we want to click on any link.

read more

Fixing Old Code

It finally happened. I have been looking up to my mentor for some time. For good reason, he is a very intelligent and wise mentor.

There have been refactorings or changes made to his code before. Obviously working on this legacy code that we do we have to make changes constantly.

This is the first time I have had to make changes because I could make it better!

This is like when I play golf and I drive the ball it further than my friend, who happens to be very talented at the sport. It rarely happens, but when it does I let it be known!

I am not sure If I can display the code below. But basically There was an entire doc listener for a small draggable component. Because of this everytime someone clicked the document, it would rerender lots of parts of the page.

Now that I moved the doc listener to just the button, the page no longer re-renders after every click!

A small but effective change!

Best,

Merl

read more

Client Wants

The heart wants what the heart wants but so does the client.

Not necessarily. I learned today that it is tough to anticipate what the client wants even when it comes to cold data.

We have 2 reports and one of the problems was that I was unsure what average meant.

We have completed points, pending points, total iterations, iterations without stories in them. So what is average points per iteration?

Especially for an individual craftsman.

If a craftsman jumps from project to project then if you look at one project the craftsman may not look very efficient.

Let’s say we have this information for me.

Total points complete: 21.25
Pending points: 6.00
All iterations: 8
Iterations I was in: 7

So how do you find the average? Which one of these is correct, and or what other combination will be correct?

Avg = Total completed points / number of iterations the member is part of a story

3.04 = 21.25 / 7

As opposed to:

Avg = total points / every week

3.40 = 27.25 / 8

It depends what the client wants, and I had to ask and make sure I knew what the client wanted.

It turns out they want it to be

Avg = Total Completed points / every iteration

2.66 / 21.25 / 8

It struck me as odd as something as concrete as I thought average to be, could still be up to interpretation.

Best,

Merl

read more

Talking to Clients

This is always happening, but I mean for IPM which hasn’t happened yet.

What do I mean? Maybe it is the simple developer in be, but sometimes I question what the client wants.

We added this “implicit owner” to a story, this means they are not an owner/member but can complete a task in a story.

This is when my mind starts thinking, why not make them an owner if they are part of the story?

For right now this is what the client wanted but it has it’s bugs.

Because there is an implicit owner, and not a real one that shows up in the maps about a story, there are bugs that are starting to arise.

For example, the way we display information about an individual is dependent on them being a member of a story.

This meant that the data was not accurately displaying what a craftsman had done in a story, if they were an implicit member. This happened in both the reports, and the points total dropdown menu.

This is not good, the data should show what you have done!

I was able to follow the trail of code and limit the filtering system for an individual to include points from tasks of which a person is not a member in the story.

My whole idea is, if the venn diagram of implicit owners and owners is becoming a circle, what is the point?

Regardless of what I think, the client wants what the client wants.

Best,

Merl

read more

Talking to Designers

When implementing a new design, and you have questions about functionality, talk to your designer!

This is what I learned this week! I had been making changes to the design of our productivity report. Everything was going well, but I noticed we removed a very important bar filled with navigation.

Now, my first instinct was to move the functionality of the bar to the new design. This was definitely a challenge but I was able to accomplish this. However from the previous tests there were about 3 tests that were driving me mad.

Because I could not get them to pass with removing the important nav bar and implementing the functionality to the new design.

It worked but a few tests couldn’t handle it. I tried and I tried to make it work, but to no avail.

I reached out for some help and I was given the advice to talk to the designer. So I did…

She told me to bring the bar back because we will make changes to it later on.

Had I done this in the first place I could have saved myself so much time!

Lesson learned.

Best,

Merl

read more

No Perfect System

There is no perfect system, that is life right? Essentially the second law of thermodynamics? No perpetual motion machines possible.

Ok maybe that was a stretch but the main point is we are trying are best.

We have a point system where we get paid based off what we complete. Most of the time this goes against us because we tend to underestimate how long it will take to accomplish our tasks. When I say it goes against us, I mean the company and the individual developer. We typically underestimate the potential problems that can arise, and that somtimes leads us to trouble. As in, the work that we want to accomplish, may take us longer than we had initially anticipated.

However, based off our system, we still manage to be more productive than other companies. This is based on our client’s demands which continue to rise for our services.

I guess the part of the system I wanted to talk about was bugs.

Every system will have them, and we pride ourselves on rarely having them and also fixing them for free. This means there is incentive to write great code so we don’t have to fix bugs. This does mean that the company doesn’t get paid if we are busy working on an ugly bug.

Here is the thing, any private business that works for profit will always have the same problem. It is more lucrative to move forward than to fix problems/bugs from the past.

Maybe it is working on a system that has been written by apprentices, but there seems to be more of these things popping up.

The problem, is it is tough to fix a bug someone else made because if you spend a lot of time on it, it can make you seem “unproductive”. Thankfully for apprentices we do have a little caveat where if it is not your bug, then you can get points for it.

There it is, just write code without bugs. Simple as that.

Best,

Merl

read more

Similar Functionality

I had a task I had to complete today. Of course there were wonderful tests involved, this time they were very straight forward.

The challenge was how to incorporate the previous code into my new feature. See the great thing about not duplicating code is that many places can use the same functionality, the challenge is when you want to have some sort of specifications.

In this case I want to display the project name of a story in a particular page. But only in this page, nowhere else.

My first thought was to pass in a boolean, or some flag from our intended location all the way through to the code that is called upon many times.

I knew from the beginning I did not like this solution. First, I would have to pass in an extra parameter to about 4 different functions, and now I would have to add a falsy to many more places these functions are called.

Again this was a solution, and it would work, but there has to be a better way.

It took me some time but I found that this page I wanted to display in was already doing something similar. This new page was basically “read-only” so some of the previous functionality was not present.

Primarily the drag and drop for each story!

This meant that similar information had been passed through, and now I needed to collect it where I wanted it and display the functionality that I intended.

Now I know, look for similar behaviour in the page I want to add functionality and take from there, instead of adding in a barely useful boolean.

Best,

Merl

read more

Tests Again

It seems like I have been having back luck recently on tests.

This time instead of being on the backend it was on the front end.

I had to allow a way to have multiple dropdowns displayed at the same time. Usually the dropdowns are only open one at a time.

The fix was actually quite simple. I removed the reagent listener and was able to add the functionality that I wanted.

However, a test to display the new functionality was almost impossible.

Since I removed the listener it was hard to stray click and therefore display that a stray click would still leave the dropdowns open.

After stumbling and bumbling. After a long time.

I found something that kind of worked. I was not able to make a test to display the functionality, but I was able to make a test to display the removal of the previous functionality.

I made sure that the listener no longer existed in the test, therefore providing some indirect evidence that it works as intended.

A very simple code fix followed by a tough test. Oof

Best,

Merl

read more

Estimates and tests

For the past few months I have learned it is great to give yourself a cushion on estimates because you never know what will pop up as a problem. And you may want to refactor.

The reason why I bring this up is because of the story we have been working on. Allowing a way to save a particular filter. As in if you want to display certain combinations of projects and members.

This has been tough because we have to display it in the front end and call the back end as well.

Not having worked in the backend as much it has been eye-opening.

First the backend tests are so much faster. Instead of the front end compiling it has been a quick check.

Next is the backend test code is not the same as the front end. This was after much time was spent trying to incorporate the front end db test code. Certain different namespaces had to be called to do the same thing.

This is showing me that certain times the tests are harder to write that the production code itself.

Which I suppose can be a good thing because this forces you to understand your code better and make your code testable.

Along with those testing difficulties there might need to be a refactor of some of the code but because we did not give ourselves enough time, then that might be some debt we pay back later.

Maybe I will write about it then.

Lesson for today and months. Give yourself some cushion.

Best,

Merl

read more

Alphabetize

One of the last tasks was to alphabetize the projects and the users.

This was initially simple, but it became slightly complicated and even buggy.

I know ‘why’ would I ever write buggy code?

Well I didn’t obviously, the bugs came from the system before me.

First solution

This was straight forward, just sort by their names. Duh!

So I did

;this is what I had initially
(defn some-component []
      (let [projects (get-projects user)
            users    (user-by-projects projects)]))

;so I did what I had to
(defn some-component []
      (let [projects (sort-by :name (get-projects user))
            users    (sort-by :name (user-by-projects projects))]))

Ok, problem solved! Blog post over …

But it is not.

First error

Well, maybe you knew this, but I didn’t. This sorts upper and lower case letters differently.

This means to a casual person, this is not really sorted since it is case-sensitive. This is no bueno.

Second Fix!

Ok, now I knew this and found a way to make sure this was not case sensitive.

(defn some-component []
      (let [projects (sort-by (comp string/lower-case :name) (get-projects user))
            users    (sort-by (comp string/lower-case :name) (user-by-projects projects))]
       
       )
      )

This works because string/lower-case Converts string to all lower-case.

Error 2

Remember when I said I didn’t write buggy code? Well, after pushing I noticed this page would crash …

Why?

Well after experimenting and looking at the error messages, I noticed that string/lower-case was causing the error, for some reason a nil value was being passed into projects and users.

I have no idea where they sare coming from, but they are passing through. So the last and final fix ..

Finally

If nil is being passed through, remove it!

read more

Email too

This just shows I need to dig more.

Before I get into that reasoning, my task was to be able to make a search bar that searched for names and also email addresses. Since some of our projects are so large it is easier to search by a company name.

Initially this was daunting, how in the world do I display an email much less search for it?

Display

Well this part was not too bad. Because we code so well we have a “loop” for each member being displayed, now I just had to get their email and dis play it next to their name.

read more

Search bar

One of the cool things I have been tasked with is adding a search bar.

I have seen this before to an extent. I would say this a little more challenging because there is more to be done also.

I would say once you know the pieces it is not to bad to install a new search bar.

First I would add in a new Input component where you want the search bar to be, and you need to create a Ratom to keep track of what you are searching for

In the input you can place something like this to check for a change in the search bar

:on-change   #(reset! search-query (wjs/e-text %))}

Then be have a reagent tracker that compares the projects we have with the projects we want.

(defn some-fn []
      (let [search-query (reagent/atom "")
            filtered-projects (reagent/track #(sfilter-by-name @search-query projects))]
           
           [:Input
            {:value       @search-query
             :on-change   #(reset! search-query (wjs/e-text %))}]

           (for-all [project (if (str/blank? @search-query) projects @filtered-projects)]
                    [:li#-projects])))

Hew you can see that changing the search query will also filter the projects.

And if the search query is not empty. Then it will display the projects that have been filtered.

Before going into this, it seemed challenging. But now, it’s not too bad.

Best,

Merl

read more

Tough updates

This is really not the best title, but I wasn’t sure what to say.

The story was to help update part of a modal. See this is the part where we can manually change the estimate of a story, or voting in poker could change the value of the story’s estimate.

So you can see there are 2 ways to accomplish the same thing.

Initially we have the focus on the manual input of estimate.

(let [estimate        (reagent/atom (formatc/f->s (:estimate @current) 2))]
     
    (fn [_ _ _]
   
         (merge
          {:type      "number"
           :value     @estimate
           :on-blur   #(update-estimate! estimate original current new? frozen?)
           :on-change ccc/noop}
          (when-not frozen?
            {:on-change    #(edit-estimate estimate %)
             :on-key-press (partial forms/tab-on-enter-to "#-iteration-dropdown" {})
             :placeholder  "0.00"}))))

This is kind of what it looked like. You could edit the estimate from the modal and be ok.

However, if you wanted to vote in poker and see the update. It was impossible. You would have to close out of the modal and open it again to see the update.

The fix for this was tough. How could I manually update the estimate value as well as change once the poker value came in?

Wrong turns

Initially I tried making estimate a track, but since we reset! the atom we wouldn’t be able to do this functionality anymore. So estimate must stay an atom.

Next, I tried not allowing a change unless estimate and the poker estimate were different. But I kept falling into 2 different traps.

Either, I could manually change the estimate value, and it wouldn’t update. Or it would update from poker, but I wouldn’t be able to manually change the value in the modal.

read more

New Servers

I have heard this sage old wisdom and took it to heart. Deploy to production in the middle of the week, so if there are any errors you are ready to fix them! There are other reasons of course.

I follow similar rules also, if you want a haircut or anything you want to be done well, get it “early” in the week when the workers are fresh. And if you want something done quickly and not necessarily well, go on a Friday afternoon. For example, say you need someone to approve your paperwork most people will be ready to get to the weekend and are efficient with their time.

So early to middle of the week is a good time to push to production.

However, our IPM is on Friday. We also begin our stories afterwards, and have a few commits by then. And when Tuesday comes around we forgot exactly what is what. If there are any migrations, then our memory isn’t so good.

Even though we are ready to fix things on Tuesday, there are potentially more problems to be had the later we hold off from pushing to production.

So it is in our best interest to push to production as quickly as possible. So everything is fresh in our minds, and if we need to fix a problem we are more aware of the code we have written.

Push to production often, and it won’t be that big of a deal when you do. Kind of like make changes to your code often, because if you hold off from making changes then it takes a lot of effort and becomes a big deal when you do.

Best, Merl

read more

Next Week

I recently talked about the Weekly page, and since it is new I am certain this will not be the last time.

One of the new changes we wanted was to make it also display next week.

Of course all the weeks before are present, along with last week and this week, but I need to help highlight next week. We do this to help display the stories that are in progress, or stashed away for later.

Slowly but surely I think I am getting more comfortable on the front end. I need to hone my skills on the back end a little more to be well-rounded.

Regardless I am working on this now.

I had to find the place where the weeks were chosen and how they were.

JS/Date.

One thing I noticed is the time is measured interestingly. Of course, it makes sense that the time should be precise and in a manner that is readable to computers but the first time you see it, it is strange.

2024-07-31T17:13:00.000Z

What? Of course, it turns in to something readable like this

2024-07-31, 17:13

It is important to keep this type of format or else nothing will work.

(defn starts-within-one-week? [time]
      (->> 7
           time/days
           (time/after (time/now))
           (time/before? time))) 

(defn some-fn []
  (let [weeks (filter starts-within-one-week? sorted-weeks )]))

There were other fixes as well, but this was the major one to help complete this whole idea.

Weekly, I am learning about you.

Best,

Merl

read more

Signed-Off?

Recently I had to make a story to differentiate when a story was signed off or not.

We , when I say we I mean another apprentice, helped create a new weekly page. This helps see what an individual, or multiple individuals are doing on a week to wee basis. This is across different projects.

Now stories are in progress, some are complete, and some are complete and have signed off iterations.

Currently there is only a visible difference in this page for completed stories and in progress ones.

It was up to me to help create the difference between completed stories and signed-off ones.

The great thing about a large system like we have is there are often solutions lying around we just need to grab them.

Solution

In this case I think I found one. We already have classes that help change the texture of an item frozen.

This is what we do to iterations when they are complete. However this only shows up on the Projects page, and frozen is given to the top layer and passed down everywhere else. Again this is in the projects page, so it doesn’t carry over to the Weekly page.

Now I just have to make sure a story card will be frozen when the iteration it is a part of is signed-off on.

:class (str class
            (when (= :frozen state) " frozen"))

Of course I had to find the location to do this, and of course I had to find a way to get the state in general.

This was basically the simple solution that I was able to come up with.

Another one bites the dust.

Best,

Merl

read more

Removing your features

This is a new experience for me. A feature I have worked tirelessly for, is now gone!

Ok maybe it is not that dramatic. I do have the propensity to mildly hoard. When I first started hiking, I just used running shoes. I kept those puppies even though I could put one hand through the sides of both shoes simultaneously, since I had worn out most of the material. Don’t worry, this is mainly for sentimental things.

What is more sentimental than your code? It did not exist before, now you created it. But I guess we are like potters. Or my idea of a potter. We can make the beautiful clay pots, but if it is not necessary I can recycle the material and make something new.

I supposed, like life code is always changing. And I can’t get hung up on my previous code.

Best,

Merl

read more

Discipline is important

Ok, I knew this. I would say for the last couple of weeks I have not been as consistent with my TDD as I have usually been.

This has been very evident the past 2 days. I was able to install the new features I wanted, but there was this functionality that I wanted to install.

The small features were relatively easy to install. I did have some commented out code, but all is well, or so I thought.

Now it came to the new features I wanted to implement. I was having a hard time doing this.

Throughout the code there were several atom maps that were called. I tried using one map for this new feature. I tried the other. I tried a combination.

Now this combination helped me get close to what I wanted for my expected behaviour.

It was not close enough however.

So I made a small change …

And I got stuck in a loop for hours, not knowing where my mess began because I had lots of commented out code, and just a mess everywhere.

I finally remembered to use TDD.

This helped me get rid of all my commented out code because now I could rely on my tests.

This finally helped me solve my feature problem as well.

It always goes back to the fundamentals.

Best,

Merl

read more

Unlabeled Stories

Today has been my toughest day during Internal Development.

It is my fault alone, and I will explain later why this is.

Goal

Let me do a quick syniposis of the previous problem I faced.

I was trying to make a new checkbox in the dropdown menu for labels in our Productivity Report. This checkbox was Unlabeled Stories and it should select the stories that are complete and unlabeled, as well as have the ability to join the other filtering of labels you so well choose.

Seems easy, and it might be for some. But today was not that day for me.

Problems

There were a few problems that reared their ugly head.

First is design was tough to implement and make the html look nice.

Second was when you unselected all of the labels the report will produce the unlabeled stories. this is strange behavior. Ideally if no labels are selected there should be no data showing up.

Third, throughout the code there are 2 maps that are continuously referenced. And they both contain a lot of similar information, some even identical information.

And lastly, my own fault. I was not using TDD which caused me to write some spaghetti code and prevented me from moving forward smoothly.

Progress

TDD was the way forward, and boy was it ever.

I recently got into the bad habit of finding a solution first then commenting out the code and writing tests for it.

Hopefully my confessions won’t come back to hurt me.

So I got rid of my spaghetti code and began the process. It was slow but I was able to solve the problems I had slowly but surely. It got to the point where finally I had the functionality I wanted.

Some Solutions

I solved the third problem that I mentioned above because instead of calling the convoluted maps that were referenced I just created a new reagent-atom and referenced that.
It might have been better to find a solution using the maps, but I tried and I tried and this was the simplest solution.

Next, I was able to solve most of problem 2. Now that I had tests that I could trust, I could help cleanup a lot of what I had written.

And now that I referenced 1 atom instead of finicky maps, this helped me make Unlabeled stories flexible. As well as making sure the Clear button also clears everything, including this new textbox.

So I was able to clean up almost everything, and add the new functionality that I wanted.

The problem is the new functionality changes an if statement into a cond, and now many tests break and I am unsure how to fix them. The local host seems to be working perfectly, but some unrelated tests are becoming challenging to fix.

Maybe this will be my next post. Sadly this story is becoming longer than was originally estimated. I need to communicate with my clients in order to let them know one story will be incomplete this week.

read more

Add Clear

Today is another great day because i get to work on the productivity page!

I have worked with this before but I need to learn more about how dropdowns work, and that is what I will be doing.

Besides what I mentioned I need to work on fitting the sandbox design to the actual page.

Design

From what I have heard, it is probably best to begin on this first. So that any changes made after you fit the design, will not change the design.

It would be a mistake to complete the functionality and have to go back so it fit the new look.

Well, I tried to fit the new design and I got stuck.

Adding Funtionality

Now I had to add the Clear button. For memberss there is an All Members checkbox at the top, this toggles between all members and none.

However, there needs to be a clear and baby blue button to highlight these wonderful capabilities. Implementing this was not so back.
The tests were ok themselves.

Now I had to do this for our labels. But fight I had to make a checkbox similar to All Members but as All Labels, this way this new checkbox behaves the same way.

Also I can’t add a Clear if I don’t have an All checkbox.

Problems

What I did above was relatively simple but it did take some time to implement, test, and refactor.

However I began looking into what needs to be done next. Which is add a new checkbox that has interesting funcitonality.

This checkbox is Unlabelled Stories. This contains completed stories that have no labels. This does not fall under All Labels because it has none.

Now this new checkbox should provide those stories along with the previous capabilites of playing with the other labels.

This will be a post for tomorrow.

Until then…

Best,

Merl

read more

Simple Fix

In todays story I was tasked with limiting information that was present. See the information was duplicating.

Now this seems easy, but it was slightly challenging.

We created a new page called weeks that keeps track of how much work you do per week. This is similar to our iterations but this is based on a literal week, rather than an iteration week.

The distinction is a real week starts on sunday, where as an iteration week can begin on any weekday.

So this means iterations go between regular weeks. So initially the stories got duplicated. It seemed like someone dis twice the work.

We want to be accurate, so I have to fix that.

I dug into the code and I noticed that the stories were called based on iteration.

I used print statements to try and figure out what everything was, and what everything contained.

Plan

My plan was to get the stories, which have no date, and find the iteration in each story. Then since each iteraiton has the start and end dates on it, I will only pass in the stories that have iterations that end on before the end of this new week display.

This works because it only focuses on the end, and therefore will only be displayed once.

My plan was to filter the stories and iteration based on the week.

Bad Idea

This was a bad idea because the solution was much simpler. I forgot to look into how the stores were called in the first place.

The stories were called on their dates, but called on the beginning of the iteration and the end of one.

So now all I had to do was delete the first call on the iteration and only focus on the end of there iteration.

read more

Renaming Functionality

One of the major lessons I learned today was how to talk to clients.

That is something I have prided myself on. Working as a teacher for a long time, allows you the ability to converse with many different types of people.

Not just that it provides the skill to convey challenging ideas to those that don’t understand them so well.

One of the parts I was looking forward to was speaking to clients. Having a calm and jovial nature has been my forte for quite sometime.

One thing that I learned, is that it is important to make sure your code matches what the client knows.

Explanation

What I mean by this, is we have something called tasks in our stories. These tasks help us break up the story and provide valuable information. Now in the code these are not called tasks, these are called todos.

This may not seem like a major problem, but when a developer looks at the todos for multiple days, then the todos stick in their mind.

Now when a dev talks to the client, they will talk about todos. But the client doesn’t what a todo is.

The client knows what a task is though.

Lesson

It is important that your code and what your clients knows are consistent. This way both you and your client can speak the same language. And there is now confusion when you communicate.

So now I am off to change todos to tasks.

Best,

Merl

read more

Deleting Code

Deleting code can be relieving, it can also cause a little bit of anxiety.

I say this for me in my situation.

I was tasked with deleting legacy code that was not functional anymore. It had a purpose, it served it’s purpose but something else was written that performed better.

Now is the time to get rid of the legacy code throughout the project.

In some ways this very easy.

Easy

The way this is easy is buy going to the file the code is located in, and start deleting the main part of the code.

With the wonderful IDEs that we have now, it is very easy to see code that is not being used. So if I delete a function it is easy to find a trail that was dependent on it.

So I just comb through the file, it’s tests, and I delete until I cannot CMD + F anything with the name of the functionality I am deleting.

Medium

The medium part was making sure the schema did not depend on it, or did not break if the code was deleted or changed.

Hard

The hard but not so hard part is making sure nothing is in the database.

The process is called migration, so I need to make a file that will delete the code from the database.

The code is quite simple, however what makes this difficult is that many things can go wrong just by working on the database.

The other parts that can go wrong if you don’t migrate well is your new servers won’t go up.

That is what makes this challenging. The fact that if you don’t do this correctly, there will be major consequences later.

Best,

Merl

read more

Familiarity

One of the best feelings so far has been recalling something I have done before.

It is fun learning something new, but learning takes lots of effort. So it is nice sometimes to do something you have done before in order to hone your skills.

read more

Confetti Bomb 3

The last and final piece of the confetti bomb was for it to actually explode.

Like I’ve said before once you have good code it becomes easy to continue building.

This was the perfect case for that statement. Maybe you remember my previous code?

(defmethod -create-confetto :bomb [_ center-x center-y] 
    (let [max-radius 50
          radius     (rand-between 0 max-radius)
          angle      (rand-between 0 (* 2 Math/PI))
          delta-x    (* radius (Math/cos angle))
          delta-y    (* radius (Math/sin angle))
          now        (performance-now)]
       (merge-confetto {:last-time       now
                        :start-time      now
                        :kind            :bomb
                        :transform       {:position     {:x (+ center-x delta-x) :y (+ center-y delta-y)}
                                          :velocity     {:x 0 :y 0}
                                          :acceleration {:x 0 :y 0.1}}
                        :max-ball-radius max-radius
                        :ball-radius     radius})))

Since the positions x and y are relative to the center, their velocities should be as well!

read more

Confetti Bomb 2

Part 2 of confetti madness. I suppose that isn’t true since I have worked on confetti a lot. But this series is about the confetti bomb.

Problem

The bomb has to appear in the center and grow. The great part is, a ball is in the center, now to make it seem like it grows.

The problem is that the all the confetti is rendered at the same time so there is now way to be able to create them separately.

Hmmm…

Trouble

My golden hammer has been randomization. This has worked very well especially in this project.

Will it be my answer again?

Well, I tried it, and it did not work very well. Like I said it was supposed to appear then grow. With the randomness it was difficult to control the timing of the appearance, as well as the location the confetti would appear.

Steps

I am sure there was a possible way to finish the task with randomness but it would not have been elegant.

What the solution was to render the confetti at the same time, but have them be invisible and appear slowly. giving the affect of growing.

Of course it was mention the confetti bomb has to grow, but it should not grow indefinitely. There are limited confetti. So it should take roughly a second for the bomb to go from appearing to exploding.

Therefore the key and value :invisible? true was added to the bomb confetto map.

Solution

As you know, the bomb of many confetti looks like a circle with many confetto with in it. the idea was to change the map to :invisible? false and displaying the individual confetto.

The way it was done was to find the ration of the elapsed-time / time-limit (again the time limit was ~ 1 second), and compare that ratio to the ratio of the random-radius-length / maximum-possible-radius of a particular confetto.

Then if the time-ratio is greater than or equal to the radius-ratio then it will become visible.

Essentially normalizing the ratios and displaying them.

Code

(defmethod -update-confetto :bomb [{:keys [invisible? ball-radius max-ball-radius 
                                           start-time last-time] :as confetto}]
  (when-not (sparkle-has-landed? sparkle)
    (let [now          (performance-now)
          time-ratio   (/ (- now start-time) (time/seconds 1))
          radius-ratio (/ ball-radius max-ball-radius)
          visible?     (or (not invisible?) (>= time-ratio radius-ratio))]
      (merge sparkle
             {:last-time  now
              :invisible? (not visible?)}))))

Now you didn’t see them, now you do.

Best,

Merl

read more

Confetti Bomb

FBI please do not place me on a watchlist, at least not any more.

This is to add to the confetti drop and confetti cannon “celebrations”. It seems like I will be a part of making a confetti library.

Set Up

The idea was to make confetti accumulate at the center of the screen in the shape of a ball. This ball grows to a point where it explodes and rains down virtual confetti.

How

That is the most interesting part. How to do this?

The good thing about writing good code previously is that you can easily add to it. Open-Closed Principle!

Turns

There was brainstorming how to begin. Initially the thought was to find the center of the screen, which is the correct thought.

Next is to create a circle of confetti in the middle.

This is where the turns came in. I thought creating a radius and then adding a random x value from -r to r, and a random y value from -y to y. Genius!

But wait, this would make a square not the circle desired. There were other twists and turns but finally I came to the …

Solution

Now came the flood of previous math classes. Namely the unit circle.

Using the center point, bring in theta and radius. Find a random angle from 0 to 2 * pi. And find a random number between 0 to r. Then you can find the x & y components and add it to the center point.

read more

Float Values

Have you ever had any bugs because of floats before?

I just had my first one and I hope I don’t get many of them.

Setup

Originally and proudly I help make a feature to sort and display points. The bars which displayed the points also had to be relative in size to each other.

I will not show everything but I will show where the problem was.

read more

Independence Day

I would say there is not much to report today. Fridays are usually spent in many meetings and company bonding events.

I do look forward to these days however, sometimes It can be tough to be productive.

This week especially because many people were out, and also the meetings had to be moved around and there was a lot of playing things by ear.

I was able to refactor a few things and begin working on a bug that was found recently.

I will probably write about this later.

Any who, I hope y’all have a good day today.

Best,

Merl

read more

Switching Between Pages

Today was one of those good days when I learned something new, and it was kind of straightforward.

The Problem

The task was to fix a bug between a productivity page and the project. Both are connected to each other and have buttons that can send you from one page to another.

Let’s say we begin on the project page, I can click the specific button, and it can send me to the productivity page. Now, if I am on the productivity page and I click the respective button I can go back to the project page.

This is where it gets spicy. Going from the productivity page back causes problems. So I had to dig around.

Digging

Honestly the rest wasn’t too bad.

The project page maintained the url of the productivity page which is what cause the problems.

Solution

Now I had to find a way add a href, so I can set the url to the project url.

After searching where to place it and which functions can help me do this, I added this to the code:

read more

Returning Accurately

For most of these problems I feel once the solution is found it becomes so clear in hindsight. I guess you could say that about basically most things in life, but especially here.

Before I mention the problem let me tell you the situation.

I have a Modal 1 that leads to other modals, let me only focus on Modal 2. Modal 1 is the first one of this page and it can lead to other places or just cancel and return to the regular screen. This all works perfectly. Next, when in Modal 2 this again has particular functionality and has the button Cancel as well.

The problem is the Cancel button in Modal 2 returns to the regular screen instead of Modal 1.

Ok how to fix this?

Initially I tried various functions that seemed like they would work. Something Install-Previous, and other similar functions but nothing worked.

It was until I deeply looked into how Modal 1 was called. I had to find a way to replicate it while using different functions because I was in a different location.

After learning this, I wrote my tests. And then I made sure to implement what I needed to.

The funny part was my parameters were slightly off so I was having interesting behaviour. It took me a while to figure out how to correctly place my parameters so it would work How I wanted it to.

Now it is all good.

Best,

Merl

read more

Exams

As a teacher and former student this word brings back many memories.

Currently, I am in the process of making sure others have the opportunity to take an exam.

The first episode does not display the exam meant for it. This means our apprentices and clients can’t take it.

It is my duty to make sure everyone with an account can complete it. But they need to see it first.

One of my great tools to use now is CMD + Shift + F. I can inspect whatever element I want and then find it in the code base.

This is what I have been doing but specifically for this I looked at the exam button and the ones below it.

I found their location and logic.

Most of those buttons: “Exam” “Download” “Extras” and so on had 2 pieces of logic.

Display
1. If element exists
2. If the user has permission to ___

That’s it.

So what I did was find out how episode 1 was classified as. Since it was a free episode, it was available to everyone.

The solution was to identify how it was free and to add it to the permissions.

Once I did that, the problem was solved. Just another day solving problems.

Best,

Merl

read more

Pushing to Prod

I am unsure if I should share this information. But I will anyway.

I was unsure if I should push our changes to production recently.

Without getting too specific, there were some changes that were made that were technically sound. Everything worked perfectly.

However, some new functionality may not have been intuitive to our users so there was hesitancy.

What if next week, our users don’t know how to use our new stuff!

That would be a problem.

Also this was Friday night and there was pressure to push.

However, I decided not to.

One, it seemed like I needed a “higher up” to provide more guidance. This feels wise on my part.

And, if for some reason something broke, I would not want to spend the whole weekend fixing this without help.

Another wise decision.

So until Monday I wait!

Best,

Merl

read more

Rendering Error

I was tasked with fixing a bug that happened when duplicating a story. While duplicating itself work ed fine, and even canceling the duplicate panel functioned as expected, a strange render error appeared when clicking away from the duplicate panel.

After some debugging, I realized the problem stemmed from how we handled estimates in our stories. These estimates needed to be numbers, but for input purposes, we treated them as strings. This constant swapping between strings and numbers was causing the render error.

Whenever the duplicate panel came up and was clicked away from, the mismatched data types would cause the rendering to fail.

To resolve this, I needed to limit the conversion between strings and numbers to a very specific part of the code. By doing this, I ensured that the estimates retained their intended functionality without causing render errors.

By centralizing the conversion logic, I kept the data consistent and avoided the render errors that were previously occurring.

Ok it was really others and myself, but this is my blog so I take all the credit.

Best,

Merl

read more

Searching

Today I worked on adding new functionality. I wanted to enhance the search functionality so that pressing CMD + F or CTRL + F would take users directly to our search bar, instead of the browser’s default search. Pressing it again would switch back to the browser search.

I learned a lot, specifically that if you have good coders before you certain things become easy, like knowing if it was Mac-OS or not

(defn key-mod? [e]
      (if (private-library/mac-os?)
        (private-library/o-get e "metaKey")
        (private-library/o-get e "ctrlKey")))

That is how I differentiated between the machines.

Next was to check which F it was, and to make sure even if someone was in caps lock, it would not affect this fucntionality.

(defn f-key? [e]
      (#{"F" "f"} (private-library/o-get e "key")))

Then I checked if we were in the search bar or not

(defn inactive-element? [id]
  (not= id (private-library/node-id (private-library/active-element))))

Now is the combo of all of them

read more

Clicking

I encountered when creating a new story and trying to add members right after. This bug was particularly tricky because it only appeared under specific conditions.

read more

Simple Solutions

All though there were multiple problems I solved today. I would like to say my initial problem was much simpler thant I expected.

Being new to this system but also web development in general has made me cautious with my estimations.

As well I should be cautious, my name and my team are relying on me fulfilling my word. And I need to add in how long it takes to learn this new part of the code I haven’t seen before.

It just so happens this story was to remove a button from a location. I was unsure where this was, or what functionality this was connected to.

When I finally found it it was a quick and simple fix.

Of course I had to change the tests a little bit but I literally just had to remove the button.

The once thing is I did want to leave a little extra padding to the end so I did

 [:li.margin-left-0.padding-right-plus-5
                (new-story-bar-button plan-view?)]
 [:li.margin-left-0.padding-right-plus-2]

Ta da!

Long story short, write good code so people later can make changes easily!

Best,

Merl

read more

Edge Cases

Today, I want to share how I dealt with some tricky edge cases in my project where I adjust bar lengths based on completed points. The goal was to ensure that even members with zero completed points still have a small highlight, similar to a mercury thermometer. However, I ran into an interesting problem.

When the max story points were large, I noticed an issue: someone with zero completed points had a bigger bar than someone with very few (but greater than zero) completed points. This was clearly not what I wanted.

Solution

To fix this, I adjusted my code. Here’s the updated version:

(defn calculate-percentages [total-points max-points]
      (-> (formatc/coerce-float (/ total-points max-points) 2)
          (max starting-decimal)
          make-percentage))

(defn normalize-to-min-width [{:keys [percent-complete completed-points total-points]} max-points]
      (let [starting-percentage? (= (make-percentage starting-decimal) percent-complete)
            normalized-zero-value (min total-points (* starting-decimal max-points))]
           (if (and starting-percentage? (zero? completed-points))
             (calculate-percentages normalized-zero-value total-points)
             percent-complete)))

By tweaking the code, I ensured that members with very few completed points still get a fair representation. This way, the bars are more accurate and intuitive.

That’s all for now! Keep coding and stay tuned for more updates.

Best,

read more

Adjusting Bars

Today, I’m sharing how I tackled another part of my sorting project: adjusting the lengths of the bars representing members’ points. The goal was to scale the bars according to the largest individual total points, which I call max points. Plus, even if the completed points are zero, a small portion of the bar is still highlighted, similar to a mercury thermometer.

I needed to adjust the bar lengths based on the largest individual total points and ensure that even zero completed points still show a small highlight. Here’s how I did it.

Calculating Max Points

First, I found the maximum total points from the sorted stats.

(def max-points (apply max (map :total-points sorted-stats)))

This gives us the largest individual total points, which we use to scale the bars.

Functions for Percentage and Normalization

I wrote some functions to handle percentages and normalization. This way, I avoid repeating code and keep things neat.

(defn make-percentage [decimal]
      (str (* 100 decimal) ".00%"))

(def starting-decimal (/ storyc/starting-percentage 100))

(defn calculate-percentages [total-points max-points]
      (let [calculated-decimal (formatc/coerce-float (/ total-points max-points) 2)
            decimal (if (zero? total-points) starting-decimal calculated-decimal)]
           (make-percentage decimal)))

Next, I normalized the width of the bars to ensure even zero completed points have a highlight.

(defn normalize-width [percent-complete completed-points total-points max-points]
      (let [starting-percentage? (= (make-percentage starting-decimal) percent-complete)
            normalized-zero-value (* starting-decimal max-points)]
           (if (and starting-percentage? (zero? completed-points))
             (calculate-percentages normalized-zero-value total-points)
             percent-complete)))
read more

Sorting Members

Today, I had an interesting task: sorting members by their completed points, and then by their total points if needed. It was a fun little challenge that involved filtering, mapping, and sorting data using Clojure. Let’s jump into it!

The Task

I needed to sort members based on two things:

Here’s how I tackled this with some Clojure magic.

The Functions

First up, I needed a function to gather the completion stats for each item.

(defn completion-stats [associated? entity-kind stories item]
      (let [stories (filter (partial associated? item) stories)
            completed-stories (filter storyc/complete? stories)
            owner (storyc/get-owner (first stories))
            completed-points (completed-points entity-kind owner item completed-stories)
            stats (storyc/completion-stats stories completed-points item)]
           (assoc stats :item item)))

This function grabs the completion stats for a given item, filters stories associated with the item, calculates completed points, and puts together the stats.

Next, I made a function to filter and sort these stats.

(defn filtrate-stats [associated? entity-kind focus filtrate stories]
      (let [items (or (seq (filter (partial kindc/kind= entity-kind) @focus)) filtrate)]
           (->> (map #(completion-stats associated? entity-kind stories %) items)
                (ccc/rsort-by (juxt :completed-points :total-points)))))

This one filters items based on their kind, maps each item to its completion stats, and then sorts them by completed points and total points.

read more

Confetti Cannon

Today is the day I hopefully finish the Confetti stories. It was fun initially learning about dropping the confetti, and it has been fun beginning to implement the kinematic equations as well.

Now it has been time to combine those. As was just mentioned initially, there was code to just drop the confetti, and it would flip and sway back and forth like it was in the wind.

I just made it so the ball of confetti made a parabolic motion. Now was the time to find a way to simulate a cannon.

Randomness in Velocities

To begin, all the confetti started in the same place and had the same path.

What I did was add a little bit of randomness. Meaning I had a velocity in the x and y in mind, so I allowed variance around that number that I had in mind.

Since each confetto is created separately, each one can have it’s separate and specific velocities. Since each x and y velocity are different per confetto, this means each one will have a separate launch angle.

Randomness in Acceleration

Next I did the same thing for acceleration. After changing the velocities, they still all had the same curve after launch, So I had a range in mind for the acceleration to be, and each confetto would have it’s similar but distinct acceleration.

Now every confetto will have a different launch angle and trajectory.

Simulate Air resistance.

This was hard in thought to accomplish but easy once imagined.

Like I mentioned before I had a swaying drop for each confetto. So I decided to use that!

Randomness is our friend.

Each confetto has a map, and so I added a boolean :drop false in there. Then I added functionality, if the confetto is dropping then it will stay dropping.

What does dropping mean?

This is where I got clever. If it is flying(not dropping) then it follows the trajectory, if :drop true then it will behave like it did before I made any changes.

It will “sway in the wind” in a sinusoidal manner. I did however add a small bit of the initial x-velocity, so it would keep moving slightly in the original x direction that it was before and not just stop horizontally.

read more

Using Physics

Now my time has come. I will finally use my Master’s in Physics for a private company.

Never mind that this is to simulate a virtual cannon that shoots confetti when someone accomplishes their weekly goals.

This is what I have trained for!

Displacement (yf-yi) - how far the confetti travels.
Velocity (vf, vi) - the speed and direction of the confetti.
Acceleration (a) - the change in velocity (in our case, due to gravity).
Time (t) - the duration of the confetti’s flight.

These are the components we need to understand the kinematic equations.

𝑣𝑓=𝑣i+𝑎𝑡
y𝑓=yi+𝑣i𝑡+1/2*𝑎*𝑡^2

Playing around with my makeshift cannon these are the equations I will need to use in order to create parabolic motion.

I will say this was somewhat easy with a bump in the road.

The equations themselves were relatively easy to implement themselves, however when I began placing the formulas something happened.

First off, it was tough to get the signs and the constants right. In a screen the 0 is the top of the screen and the bottom is the height of the screen. Not the biggest deal but without writing anything down this caused a little obstacle.

read more

Working in Pairs

Working in pairs has its benefits, and a few minor cons.

Let’s list the minor cons first. I would say, I need to work on my typing ability as a whole along with spelling. So if someone is pairing with me, they might have the thought that they can type better. Next if someone switched from place to place very quickly it might be challenging to understand where the wanted code is located.

There are probably more, but off the top of my head those are the 2 cons.

The pros are that, you are a think tank. You can brainstorm and bounce ideas off each other to come to a correct solution. This works well for fixing bugs. It is easier to diagnose the problem when you have a few smart people working together.

The other part, I enjoy social interactions, so it is a bit fun to work with someone than it is to be solo in your place with just your cat to keep you company.

At least this way you can have a virtual human call where you can connect with others.

Now that I think of it there can be cons in the sense where, people may disagree with a solution. However, that comes with being around people in general.

All in all, I am pleased to be working on projects now, with others.

Best,

Merl

read more

Reading Requirements

Reading is a tremendous skill in life. Writing is one of the most important inventions of our civilization.

The ability to place information down, and refer to it later is a wonderful concept. Especially once you learn of the fragility of the human memory.

With all of this being said it is important to read what is said for the requirements.

Myself and a friend lost time because we didn’t continually refer to the tasks we had to accomplish.

Hidden in the tasks was a way to solve what we were looking for.

My personal experice was to have something fall at the same rate. I got lost in the concept that I interpreted the task to have everything fall at the same time not rate.

So I fixed it so everything fell at the same time, regardless of how large a screen was present.

However, the real task was to make sure everything fell at the same consistent rate. So I had to go back and make changes. Had I done this earlier, I would have had more time to work on my other tasks.

Lesson learned, read more carefully.

Best,

Merl

read more

Fixing Randomness

Today I had the wonderful task of fixing what I thought was a bug.

Maybe it can still be classified as a bug, but I came to a different understanding. The idea is that the time it takes for something to fall is inconsistent.

There were 2 problems that I potentially noticed.

One was a potential lag that caused the inconsistency. This could be due to the kind of machine that is present, or how much memory is used up at the time by the machine.

Next is that different-sized screens cause a different time for the object to fall. This is because the code is built on constants not the screen size.

I decided to fix the latter, in hopes that it could fix both situations.

It was mildly challenging to figure out what exactly to change and how, in relation to the height. But eventually I did.

Now the trouble was testing this. I realize I should have done this backwards but testing time is tricky.

I decided to create a function that was recursive until the object fell. Then I would find the difference in time between the start and the end of the fall.

Then I used different heights and passed them through the new function. I placed these times in a list and then I checked the largest difference.

Since time is measured in millis, I decided to give a 10 ms cushion but everything still passed.

One more Story is complete baby. On to the next.

Best,

Merl

read more

Whack a Code

This is the first week working on a large code base that was made by others.

It is great code, the problem is there is a lot of it and I don’t know any of it.

I as tasked with changing the style of a presentation on data. I was able to accomplish this but like always I had to test that it worked.

I don’t just have to test that it works, I have to go back and fix the tests that I just made fail because of this new code that presents data differently.

In doing so I had to learn about the database and how everything was stored so I could test correctly. This is wild, there is so much going on, it is a mountain of information.

Now I was able to change part of the code, in order to make the broken test pass and make the system more robust. This however broke more tests, many more tests.

This began the process of whack-a-code. for almost a full day, this cycle of fixing and breaking continued.

It was a great eye opener.

It is definitely best to be a boy scout and fix whatever you see. The bad part is it may take time to fix the mess you see. Also, if you do a great job initially, then hopefully someone won’t have to clean up your mess.

Best,

Merl

read more

Choosing Stories

Maybe it is a wise thing to choose a challenging story, this helps you dive into the deep end quicker. The trick is to not drown however.

Ok, I’m being dramatic again however, I have begun a story in the productivity page, and this connects to many other parts of the code. Eventually I would be in the situation but I placed myself here quickly.

There are many atoms that are being called, that is tough to figure out what they contain, and how they relate to each other. One atom will contain a small bit of information, but that information can be used to place into a map of another atom to recall lots of information.

It is one thing working on your small project which you know so intimately, it is another to jump into a large project that has multiple places that stores information which make sit challenging to learn what is going on.

I assume this is a right of passage most people go through once they begin Internal development, or just begin working for their company in general.

With a little help here and there hopefully I will accomplish the stories I said I would.

Best,

Merl

read more

Inspecting Elements

I have finally moved on to Internal Develeopment, working on actual production code instead of my own Tic Tac Toe.

It is an exciting but nervous feeling, because with great power comes great responsibility. I don’t want to make an error that will send the system crashing down.

The great thing, is the use of TDD. I can just run the cljs tests and the specs, and make sure everything passes. This provides the comfort of safety.

The new trick that I learned today was to help find what I am working on in the website. If I know specifically what I am working on then,

I could go to the website and find what I am changing Right click it, and “Inspect Element” Then I can find out the information that is behind the scenes As I am scrolling through the code it will highlight the parts that are being affected by the code Keep scrolling, expanding, and eventually you can find exactly what you want. Then you can find the class that is associated with what you want Go to the source code, command+shift+f to find that class everywhere in the code

Viola, you have now found where you can work to help fix the bug or change whatever you need to.

Best,

Merl

read more

Grid Timeout

Today I have been focusing more on Internal Dev stuff. I am unsure what I can say and not say here. But I did have a little but of time to work on fixing my Tic Tac Toe game.

So here are the small changes I was able to make.

Another small bug that I had, was the board had buttons that responded to a click. They responded to a click whether the player was AI or human. If it was human it would check if it could make a move there and update accordingly, for AI clicking just allowed the AI to make a move where it wanted.

Now if you read the previous post, you will know that I had problems with the AI button because one could press it multiple times to make the game do multiple moves at once.

I fixed that problem for the AI button, but my board buttons still had the same flaw.

So with the little time that I had a made a fix.

read more

AI is thinking

I am proud of the progress I have made, but there is always more to be done. And ways to get better.

Currently, I have been finding was to make my TTT better. My AI move button was decently designed. It does show up only when it is an AI player’s turn. It also goes away when the game is over.

However, there are some buggy features.

First

The random numbers are instantaneous moves, while the hard/minimax moves take some time to calculate. This is not the most fun user experience.

I have heard ATMs, and other machines/calculators add a delay and noises to their processes so the consumer has more trust in the machine. Because if it provides a sense of calculation. Even if the program’s worked quickly, people trust the noise and slight delay more.

So I added a js/setTimeout for 500 ms. This allows the random guesses by the Easy AI to take longer, so when the Hard AI makes a move it doesn’t seem as long.

Second

When the AI button was clicked it stayed on until it was “done” making it’s move.

So if the Hard AI was taking a long time, then the client had the opportunity to keep pressing the AI button and produce multiple moves at the same time.

This was a trickier solve.

I decided to add another key to my game map :ai-thinking false

This was because I wanted to remove the AI button while it was “thinking”. This key allowed me to change to check the state and respond accordingly.

;part of larger function AI-button
(if ai-thinking
  [ai-thinking-message]
  [:div.flex-center
   [:button
    {:class    "ai-move-btn"
     :on-click handle-ai-move-click}
    "AI Move"]])

(defn handle-ai-move-click []
      (swap! game-state assoc :ai-thinking true)
      (js/setTimeout
        (fn []
            (update-grid -1)
            (swap! game-state assoc :ai-thinking false))
        500))

(defn ai-thinking-message []
      [:div.flex-center
       [:p "The AI is thinking..."]])

So I changed the logic in my AI button to check the game-state and see if AI was thinking. If it was it sent a message out, if it was not then it produced the button.

read more

Hello Tic Tac Toe

Milestones are important. They are like view points on a hike.

Viewpoint

They help you gage where you have come from and that you still have further to go.

I began coding about 10 months ago. It took me 2 months to go from hello world to my first spaghetti filled unbeatable Tic Tac Toe, which of course had hundreds of lines of if statements.

Now I have written Tic Tac Toe in multiple languages and styles as well. Even through this progress I haven’t been able to show my friends and family. This was due to the game being located on my terminal.

Now the milestone is me saying “Hello World” with my online Tic Tac Toe game:

read more

Meaningful Buttons

When I was working on my Tic Tac Toe game using ClojureScript, I realized that having buttons that do nothing more than look pretty just wouldn’t cut it. I needed these buttons to actually do something meaningful. That’s where the radio-option function came into play. Let me show you how this little function transformed my game.

The radio-option Function

First off, here’s the radio-option function:

(defn radio-option [id option-name value label on-change-fn]
      [:div
       [:input
        {:type      "radio"
         :id        id
         :name      option-name
         :value     value
         :on-change on-change-fn}]
       [:label {:for id} label]])

This function is a handy way to create reusable radio buttons with:

id: A unique identifier for each radio button.

option-name: Groups radio buttons together.

value: The value that the button represents.

label: The text that appears next to the button.

on-change-fn: What happens when the button’s value changes.

Making My Buttons Interactive

The radio-option function allowed me to make the buttons interactive and meaningful. Here’s how I used it in my form:

[:form {:on-submit #(handle-submit %)}
 [:p "Please choose which board you want to play with"]
 [radio-option "3x3" "size" :3x3 "3x3" #(swap! game-state assoc :size :3x3)]
 [radio-option "4x4" "size" :4x4 "4x4" #(swap! game-state assoc :size :4x4)]]

This form lets users pick the board size for their game. Each radio-option updates the game state with the chosen size.

Managing Game State I manage my game’s state using an atom:

(def default-game-state
  {:game-id  1
   :player-1 {:kind :human :token "X"}
   :player-2 {:kind :human :token "O"}
   :size     :3x3
   :moves    []
   :new-game true})

(defonce game-state (r/atom default-game-state))

This state keeps track of everything: the players, board size, moves, and whether we’re setting up a new game.

Connecting It All

When someone picks a board size, the corresponding radio button’s on-change function gets triggered. This function updates the game-state atom:

[radio-option "3x3" "size" :3x3 "3x3" #(swap! game-state assoc :size :3x3)]
[radio-option "4x4" "size" :4x4 "4x4" #(swap! game-state assoc :size :4x4)]

These buttons dynamically change the :size in my game-state, making the user’s choice actually matter.

Submitting the Form

To top it off, the form’s on-submit handler, handle-submit, stops the page from reloading and updates the game state to show that setup is done:

(defn handle-submit [e]
      (.preventDefault e)
      (swap! game-state assoc :new-game false))

The radio-option function might look simple, but it really helped me clean things up and connect everything smoothly. It made my buttons super interactive and meaningful. Every time a player picks an option, it updates the game’s state.

These radio buttons let players set up their game just the way they want. It’s a small addition, but it makes a big difference in making the game more user-friendly and engaging.

Best,

Merl

read more

Changing Screens

In our ClojureScript Tic Tac Toe game, we have a simple yet crucial function called handle-submit. This function is pivotal in managing our game’s state, particularly when transitioning from the game setup phase to the actual gameplay. Let’s dive into what this function does and why it’s important.

read more

Small Steps to Complete

That title might be a bit drastic, but it is in reference to my progress. There is no “complete” in software, there is always more. However, there are complete projects. And although I have while to go, I have made some important steps in adding TTT to my blog.

Initial process

First, connected my new UI to my old project TTT. Next I made sure I converted the necessary files from clj to cljc, because my new project is cljs and cljc can connect to both clj and cljs with some caveats.

For now I wanted to add some logic into my cljs file, and clj will not connect.

I kept getting many errors, but eventually I was able to convert the correct files to cljc and add old logic to my new cljs files.

Old logic

Luckily life repeats itself, so I went to my previous Web Server TTT project and found the old logic I used there and took note of how I could do the same for the CLJS project. The first is board/game-over? This makes sense since it is a huge component of any game really.

```clojurescript (defn game-over-display [grid] (if (board/game-over? grid {:token “X”} {:token “O”}) [:div.game-result [:p (ui/endgame-result grid “X” “O”)]] nil))

read more

Combining Projects

I wanted to learn how to go from ClojureScript to a static webpage . I was able to do this to a small extent with the sample project I mentioned before, however what I needed to do was to change my previous TTT game to this and have it all maintain the same functionality.

This proved to be more challenging. Initially I thought If I changed the deps.edn and added the files that aren’t the same it would work. Ok maybe I knew it wouldn’t be so simple but I figured that would be close enough.

Dependencies

In hindsight it was a decent idea but there are always bumps. Part of it was I did not change my dependencies perfectly initially, and it took time to figure that out. The aliases and dependencies were correct, but I forgot to scroll up and change the :paths in my deps.edn.

read more

New Syntax in ClojureScript

I have been learning more and more about ClojureScript, Reagent, and Hiccup. I might go over Hiccup later but I wanted to focus on the new syntax I have been using.

What is great is, I have a baseline of code to work with and I have been trying to translate my HTML to Hiccup and Reagent components.

```clojurescript (defn group-buttons [grid side index] [:<> [button (get grid index) #(update-grid index)] (new-line side index)])

read more

ClojureScript

I have had the wonderful task of using ClojureScript to connect to the web eventually.

Currently I just want to connect it to a local host. I was able to follow in the footsteps of the giants before me and I found a great sample project to begin.

https://github.com/mdwhatcott/cljs-sample-project

There were a few nuances. Instead of using Leiningen I converted everything to deps.edn. Along with this I made sure all the dependencies were up to date.

Next I had to go in and change the output location and name in the clj.edn file.

:development {  :cache-analysis true
                :optimizations  :none
                :output-dir     "resources/public/cljs"
                :output-to      "resources/public/cljs/ttt_merlness_dev.js"
                :pretty-print   true
                :source-map     true
                ;:sources       ["spec" "src"]
                :sources        ["spec" "src/cljs"]
                :specs          true                                   ;; Run speclj specs after compile
                :verbose        false
                :watch-fn       c3kit.scaffold.cljs/on-dev-compiled    ;; Callback to run speclj specs after each compile when in auto mode
                }

I had to make sure I called the right rile everywhere it was called.

Now my main changed to this:

(defn ^:export main []
    (println "Hello, from main!")
    (let [app (js/document.getElementById "ttt_merlness_dev")]
        (js-invoke js/console "log" app)
        (rdom/render [components/hello-world] app)))

Of course now this looks easy once you know where to gom and change what you need to. But when you are going through this process it takes up a lot of research, time, and trial and error.

Now I could finally go into my index.html file and add the changes to make this project sing.

read more

Stubs but different

I have been hearing recently from my mentor that I need to limit Stubs in my testsing as much as possible.

The powerful thing about stubs is that they can allow us to test different portions of the test without running parts of the code you don’t want to run. This is of course useful at the higher functionality of a program where you don’t want to run the whole program you just want to know certain functions do what they are supposed to.

Stubs allow us to do this but at a cost of actually running. This means if there is an error on the number of parameters, or an error in general, Stubs might overlook this and produce a passing test. And now that this test is passing, your program might break, and now you don’t know where to begin.

I wanted to test a function that draws a white square using the quil library.

    (it "makes a white  square"
        (let [fill-args (atom [])
                rect-args (atom [])]
            (with-redefs [q/fill (fn [& args] (swap! fill-args conj args))
                  q/rect (fn [& args] (swap! rect-args conj args))]
            (sut/draw-square 3 "M" 1 2)
            (should= '(255 255 255) (flatten @fill-args))
            (should= [[(* 1 (/ 300 3)) (* 2 (/ (- 400 50) 3)) (/ 300 3) (/ (- 400 50) 3)]] @rect-args))))

In this test, I used with-redefs to redefine the q/fill and q/rect functions to capture their arguments. I thought this approach would eliminate the need for stubs. However, I realized that I was still essentially stubbing these functions by manually capturing their arguments. Here’s a similar test using stubs directly:

(it "makes a white square - stubs"
  (with-redefs [q/fill (stub :fill)
                q/rect (stub :rect)]
    (sut/draw-square 3 "M" 1 2)
    (should-have-invoked :fill {:with [[255 255 255]]})
    #_(should= [[(* 1 (/ 300 3)) (* 2 (/ (- 400 50) 3)) (/ 300 3) (/ (- 400 50) 3)]] @rect-args)))
read more

Mediator Design Pattern

Mediator Pattern

Initially I chose this pattern because I perceived it to be similar to a Regulator, like one of my favorite old school songs. This is far from this, however this is more like a counselor rather than a big boss dog.

However this still solves problems!

Analogy

Say you are a pilot and you have the airstrip all to yourself. You can come in when you want to, fly and land when you want. Life is grand!

Now, suddenly the airstrip gets a new pilot and plane. Now there is a little restriction of your freedom, but you can manage because you can communicate with the new pilot and you can take off and land mostly when you want.

Over time the airstrip is becoming more and more popular. Now there is a third pilot and you and the second pilot must communicate with each other and the new flier. This continues and continues, sometimes even with helicopters and drones now too.

Your main goal was to fly but it seems like most of your time and energy is spent trying to coordinate rather than fly.

What if there was a …

Solution

The mediator pattern! It is a way to manage how different parts of a program talk to each other. Instead of having these parts (or objects) communicate directly, they go through a middleman called the mediator. This setup keeps things from getting tangled and complicated because each part only needs to know about the mediator, not every other part. By centralizing the communication in one place, the Mediator pattern makes the whole system easier to update and maintain.

In this situation the mediator would be like an air traffic controller. You would still need to communicate with the mediator, but that’s only one person and you don’t need to worry about any other flying object, identified or not. Now all you have to focus on is your love of flying.

To further understand the pattern, let’s break down its components: Mediator Interface: Declares methods for communication between components. Concrete Mediator: Implements the mediator interface and coordinates communication. Colleague Interface: Declares methods for communication with the mediator. Concrete Colleagues: Implement the colleague interface and communicate with the mediator instead of directly with each other. In this example: The AirTrafficControl interface acts as the mediator. TowerControl is the concrete mediator that manages communication between the airplanes. Airplane is the abstract colleague, and Boeing737 and AirbusA320 are concrete colleagues that interact through the mediator. There are advantages and disadvantages however:

Advantages:

Disadvantages:

read more

TTT Online

I have this new story I need to complete and I wanted to provide a brief overview of what I needed to do. As I go through this I am sure it will change and I will miss pivotal details but this is mainly to help me map out what I want to do.

I feel like in the back of my mind I knew I had to place my tic tac toe game online.

Now I begin this process.

Conversion

The first step is to make our Clojure code compatible with ClojureScript by converting .clj files to .cljc files. This allows the same file to be used by both Clojure and ClojureScript, working with the code that is shared between the backend and the frontend.

One thing I have noticed is that my first step is usually my most challenging. I faced this problem changing from Leiningen to deps.edn. The other part was connecting Clojure to Java. As well as learning how to connect my tic tac toe to a GUI. I think you are starting to get the picture. The start has almost always been my biggest challenge.

From what I have seen it seems like certain cases might be as simple as changing the literal nale file from example.clj to example.cljs. However I have seen that there might be cases where I might need to rewrite my code to work in Clojure and in ClojureScript. This makes me unsure how much I need to refactor.

Why?

Why would I need to convert to ClojureScript? It is because ClojureScript compiles to JavaScript, and “JavaScript helps the users to build modern web applications to interact directly without reloading the page every time.”

read more

Abstract Factory

Imagine you’re building a furniture shop simulator, and your client is your girlfriend. She loves to change styles like Modern, Victorian, and Art Deco, and she wants the flexibility to add or remove styles whenever she feels like it. You need a way to ensure her selections always match without rewriting your code every time she changes her mind.

read more

Using Macros in testing

Testing higher-level implementations can be challenging without worrying about the lower-level code. Recently, I explored using macros in Clojure to help my testing process. Here’s how it worked out.

Macros in Clojure offer powerful capabilities, allowing you to write code that writes code. This is particularly useful for creating reusable test templates. The symbols # and ~ play crucial roles in macros:

# is used to generate unique symbols, avoiding naming conflicts.
~ is used to unquote expressions, allowing you to evaluate them within the macro.

Why I am choosing this right now instead of just using a function, is if my tests fail with a macro, then the error will appear exactly where the error happened. If I create a function in the same way without the macros, then the error will appear on the function itself and where where your test failed.

(defmacro should-be-tictactoe-form [response]
  `(let [response# ~response
         body# (.getBody response#)]
     (should-contain "<title>Tic Tac Toe</title>" body#)
     (should-contain (str "<body>" gh/generate-tictactoe-form "</body>") body#)
     (should= 200 (.getStatusCode response#))))

This macro checks that the response contains the correct title, body content, and status code.

The macro also allowed me to write concise and clear tests for my handler:

(with handler (sut/->TheHandler))

(it "creates an empty tic tac toe form on an empty request"
    (let [request (Request. "GET" "/tictactoe")
          response (.handle @handler request)]
      (should-be-tictactoe-form response)))

(it "creates an empty tic tac toe when newGame is specified"
    (let [request (doto (Request. "GET" "/tictactoe")
                    (.setBody "newGame=true"))
          response (.handle @handler request)]
      (should-be-tictactoe-form response)))
(with handler (sut/->TheHandler)): Initializes the handler.
(should-be-tictactoe-form response): Uses the macro to verify the response.

By using macros, I focused on higher-level behavior without getting bogged down by lower-level details. This approach made my tests more readable and maintainable.

Using macros to test higher-level implementations made my tests more efficient and easier to maintain. And it allowed me to not repeat myself in my tests, while being able to identify exactly where my tests might fail. If you’re new to testing, maybe macros could help.

Best,

Merl

read more

Testing With Dummy Servers

Testing my code is always a crucial part of my development process. Today, I wanted to share how using protocols and dummy servers helped me test my server setup more effectively. I’ll break down the process and the insights I gained along the way.

read more

Testing in 2 Languages

I will try my best to split up the ideas I learned today for today and tomorrow’s blog. Tomorrow I will go over the more complicated test today I wanted to show the integration and how to create a small abstraction to help test 2 languages at the same time.

read more

Connecting AI Move

I was close to what I wanted to complete but there were a few obstacles.

These obstacles were all made by me of course and I had to fix them.

First was how I made player 1 and player 2 in my map.

{:game-id  game-id
             :player-1 {:kind player-1 :token "X"}
             :player-2 {:kind player-2 :token "O"}
             :size     size :moves []}

This only worked because :kind :human worked, however for my computer I need kind to be AI and also to have a difficulty rating. So I had to change this first part to be able to connect to anything useful.

initial-game {:game-id  game-id
             :player-1 (assoc player-1-info :token "X")
             :player-2 (assoc player-2-info :token "O")
             :size     size :moves []}

I also had to change how I sent information through the Request, but that is similar and related to this change.

What I want to focus on is how i get move.

```clojure ;Before move (get params-map “move” “-1”);

read more

Making A Better Map

One interesting thing I have noticed working on Java for the past maybe 2 months, is that coming back to Clojure has been interesting.

It was a little rough getting my handle on working quickly.

That was the mildly interesting part , what I wanted to focus on was updating my map.

```clojure

       :player-2 {:kind :human :token "O"}
       :size     :3x3 :moves [1 2 3 4 5 6 7]}
read more

Connecting AI

One of the great things about trying to make Tic Tac Toe again is that I have done this many times, and if I am stuck with a problem I can look to what I did before to gain inspiration.

In this case I will look at what I did for my GUI.

read more

Abstract Server

Let’s create a simple situation. Say you want to write a program to control a light, and a switch.

What would you do?

I say if the situation is that simple then just create a light object, place turn off and turn on inside. Then you should have a Swtich to do just that. Nice and simple!

One

As we all know, life is never that simple. And as a developer you should know this as well.

Let us add in a fan to go with it.

Well, then let’s just add another object Fan, again it can turn on and off. Then we need a Fan Switch which can control the fan as well. Fan Switch could inherit from Switch. However, Switch is dependent on light, so that means we have to take light everywhere we take Switch. So Fan Switch would be dependent on the object light.

Two

If only there was a Design Pattern to help us solve this ….

But there is: ABSTRACT SERVER

Before we were violating the Open/Closed principle, as well as the Dependency Inversion Principle. The way to fix that is by using the Abstract Server which begins with Dependency Inversion.

Here we can create an Interface Switchable and have the Light and Fan object implement Switchable, and then have Switch control them!

This gets rid of our previous violations because now we are dependant on abstraction and not concrete details, as well as if we want to add more lights, fans, or anything that has a switch we can do so easily without disrupting the rest of the code.

Three

Hopefully this helps describe the Abstract Server.

Best,

Merl

read more

Design Patterns

Let me set the scene for you.

It is Christmas time and you need to make cookies for your family. It just so happens that your family loves Gingerbread man cookies. So you need to make a huge batch with many different flavors and styles.

What do you do?

Well, sadly you are ignorant of any solutions so you must make them all by hand. You know that you must make many different flavors. But because you make each one by hand they all are shaped differently, some look great, others terrible and towards the end they stop looking like a person at all?

gingerman

What if you knew about cookie cutters? What if you were able to use a cookie cutter to help you and this gave you more time to focus on what you wanted, which was to decorate the cookies in the style that you wanted. Or go and nap!

gingerbreadcutter

gingermen

If you want to make many stars or hearts you can use the same strategy.

I bring up the analogy to bring out the benefits to the Design Patterns. These are tried and true solutions to common problems that arise in software.

If you are ignorant of them, you could be like my initial premise and have a hard time forming whatever design you want.

However, if you are away from the design patterns then you can use the correct one to help you solve the problem that you need.

Unlike an algorithm or Stack Overflow, you can’t just copy and paste the code. But you can make your code fit the blueprint provided. Not only that, you have the flexibility to arrange your software in your own style to help fix your problem. Like decorating the cookie in the manner that you want.

Lesson to be learned is that knowing your Design patterns will help you be a better developer because then you can solve your problems faster, and in a SOLID manner as well.

Best,

Merl

read more

Tests are Great

That is it really, tests are great. In the past, especially when learning TDD I have yelled out an cursed the proccess, however I am maturing and turning a new leaf.

Why you may ask?

Well one thing I do really appreciate about this apprenticeship is nothing is really wasted. Meaning the stories I complete are beneficial, and specifically relate to the conceptual things I have learned before.

Let’s take the analogy of basketball. I may have the knowledge that there is dribbling and shooting in basketball. However, just because I know that does not make me a great player.

In order to be a great player I need to practice and put myself in a position to play and learn from my mistakes. Watching the NBA alone will not make me better.

How does this apply?

Well, I have had the understanding that testing is good. However, when I have good tests this gives me freedom. This provides freedom where I know, I can change my code and as long as my tests pass, I can rest easy.

This week, I have been in the process of refactoring my old Tic Tac Toe code, as well as my Server code. My server code was not tested well. So when it came to having to refactor my code, I had to change many tests as well. This was quite tedious as one can imagine.

Now I moved to my tic tac toe code. I followed TDD pretty well, and when it came to make changes my tests still passed which allowed me to make many changes easily.

Here is an example I am referencing.

(it "tests print a tie in a 3x3 "
  (should= "Womp, its a tie\n"
           (with-out-str
             (sut/print-end {:player-1 "X" :player-2 "O" :size :3x3 :moves [1 2 3 5 4 7 8 9 6]}))))

(it "tests print the end of x winning 4x4"
  (should= "O is the winner!\n"
           (with-out-str
             (sut/print-end {:player-1 "O" :player-2 "X" :size :4x4 :moves [1 3 5 4 9 6 13]}))))

These test are focused on printing the end. I have a suspicion I may have to change a few parts in my UI to I decided to change my original funciton into a multimethod so my Web Tic Tac Toe game might possibly use this function/multimethod without printing to the command line.

(def ui-type (atom :cui))

(defmulti print-end (fn [_game] @ui-type))
(defmethod print-end :cui [game]
  (let [player-1 (board/player-token (:player-1 game))
        player-2 (board/player-token (:player-2 game))
        size (:size game)
        moves (:moves game)
        board (game/convert-moves-to-board player-1 player-2 size moves)]
    (println (endgame-result board player-1 player-2))))

I very easily changed my previous funciton to this. Once I ran the tests, I say they still passed and I moved forward. Now I have the ability to create my own multimethod in my Web Tic Tac Toe, and implement it in my own specific need without the original Tic Tac Toe library knowing about it.

Again, this was something I knew however I found it interesting that I am now benefitting from the practice of TDD.

Best,

Merl

read more

Updates Are Important

It can be the small things that make the biggest difference.

I am in the process of connecting my Tic tac toe game with my server. However this has been quite a challenge. Initially I thought it would not be. I knew I needed to make a JAR file from my server. I had done this before so no problem.

But I needed to connect my old Clojure code.

For Clojure initially I have just been using Leiningen. It has served me well, but to convert that project into a library it is best to convert this to deps.edn.

This is a more straightforward path to accomplish this task. What should have been a simple process was made difficult. I was making sure my dependencies were using their latest version. I had to make sure I matched the exact syntax. I also had to make sure I incorporated speclj in correctly.

All of these took some time but this still did not work.

```clojure { :paths [“src” “resources”] :deps { org.clojure/clojure {:mvn/version “1.11.1”} org.clojure/data.json {:mvn/version “2.5.0”} org.postgresql/postgresql {:mvn/version “42.7.2”} com.github.seancorfield/next.jdbc {:mvn/version “1.3.909”} quil/quil {:mvn/version “4.3.1563”}

read more

Polymorphism

I remember first hearing this phrase while watching the Clean Code series with Uncle Bob. It sounded like a spell from Harry Potter and I had no idea what in the world it meant.

I mean, the root words mean “many forms” but I did not know how that related to code.

Now, after months in my apprenticeship I have learned what it actually means and how to implement it.

Below I will provide my old code:

```java public Response handle(Request request) { String requestPath = request.getPath();

read more

The Actual Size

I want to correct what I displayed yesterday. I am unsure if I was thinking too simply or over complicating it.

In reality I was not specific enough to be simple.

The answer was right in front of me the whole time. One of the headers had the content type, but what I glossed over was it also contained the exact boundary that was being used.

Content-Type: multipart/form-data; boundary=——WebKitFormBoundaryXYZ

That is an example of the boundary but it would look very similar. My problem was whenever I made tests and also uploaded files into any web browser, the boundary would have the same exact structure so, the code I posted below would be consistent.

Again the code was too reliant on the consistency of the data provided. This is bad code in general but also, for several reasons and one of the major reasons is when I would pass through the clojure tests for finding the size of the uploaded files, it would give me a completely different answer.

Maybe you see where this is going. I never made a print statement, so I don’t know what the boundary looked like for the clojure tests but I can tell you, one way or another it had a different structure. This means my previous code which was general and dependent on consistency did not account for a different boundary.

I hard coded in what I thought the boundary would be rather than use the boundary that the header provided.

Very silly indeed. Below is my correction to the problem. And since this correction I have been correct to the byte when it comes to finding the size of any upload.

```java

//”——WebKitFormBoundaryXYZ\n” + // “Content-Disposition: form-data; name="file"; //filename="testfile.jpeg"\n” + // “Content-Type: text/plain\r\n” + // “\r\n” + // “This is the content of the file.” + // “\r\n——WebKitFormBoundaryXYZ–”;

read more

The Right Size

When building a web application that handles image uploads, you might think knowing the size of an uploaded image would be straightforward—just read the Content-Length header, right? Well, it turns out it’s not always that simple, especially when dealing with web forms.

Imagine you’re sending a package to someone you love but need to include a form in the box. Or even packaging so your items arrive safely. These can add extra weight and size to the package, but the label on the box only tells you the total weight, not how much the contents or the form weigh individually. Similarly, when images are uploaded through a form, the Content-Length header tells us the total size of the entire package, not just the image.

This extra information can include things like the file’s name and type and additional boundaries or markers used to separate different parts of the form.

The challenge comes in determining exactly where the image data starts and ends. Just as you might scan through a packed box to find the item you want, we have to carefully parse the content of the web form upload to find where the image data begins and where it ends.

For example, suppose an image is embedded in a form. The form might start with some text fields before the image data begins, and might even contain more data after the image.

read more

Testing Exceptions

No, this is not an exception to testing. It is testing exceptions!

read more

AAA

I have been learning more about TDD and how to implement it. This has been helpful because in general, learning is challenging but specifically creating tests for abstract concepts such as Servers is tough especially when you are new to it.

Luckily I have access to a great resource in the the Clean coders videos. Now I just want to focus on the simple concept of Arrange, Act and Assert.

Arrange

Here you Arrange everything you need for the test. Only arrange elements directly relevant to the test to avoid unnecessary complexity!

This might mean using builders or factory patterns to handle the more complex setups without making a mess. Keeping it manageable and scalable is the name of the game here.

Keep it Light: Stick to the essentials for setup. Make it Reusable: Lean on helper methods or fixtures for common setups to stay efficient and avoid repetition. Focus on Clarity: Ensure the setup is straightforward, no need for unnecessary complexity .

Act

This is where the action happens, pun intended. This runs the actual code that you’re testing. It should be a simple and directly call method or function.

Test one behavior or aspect at a time. This not only keeps tests clean but also ensures that each test remains focused on a single responsibility.

Assert

read more

Flags

When you are learning to get better at something, once you learn a new move it seems like that becomes your hammer. And once you have your new hammer, everything looks like a nail.

For me this new hammer has been flags. Flags to make things happen but also flags to help test.

As of this moment I am unsure if this is good practice or I need to refactor more, but I I do have to refactor more this was a nice bandaid to keep me going.

Recently I wanted to add functionality to my argos into my main.

read more

Trying to Catch

The try catch block has been quite helpful in helping me keep my server running. While I was creating my server, every now and then it would just randomly stop working.

There were many reasons for this. Sometimes it was a bug, sometimes it was unhandled situations, but all in all it was because my code just wasn’t very good.

Insert the try catch and this was quite the savior. It helped allow my server to keep working even though there may have been problems with my code.

I think the problem now is that I have been using it too much.

I refactored it now but it was possible when I began using the try catch blocks I may have had 3 of those blocks in one method. That just feels wrong.

One way to avoid this has been by refactoring the code and trying to remove the logic that caused me to bring out the block, the other has been to make even smaller methods, Single Responsibility principle to again take the try/catch block away from the larger method.

The other situation that I faced is since it was a different kind of code I did not think to test it.

Now that I have done both of these steps to limit my throws and to test them I can do a little something like this.

public static String readTextFromFile(File file) {
   try {
       return new String(Files.readAllBytes(file.toPath()), StandardCharsets.UTF_8);
   } catch (IOException e) {
       throw new RuntimeException(e);
   }
}

Above is a method that I made smaller to remove the try/catch block from a larger method. And I made it public static to test more easily.

Here is the test.

@Test
public void readBytesFromFileIOExceptionTest() {
   File nonExistentFile = new File("does_not_exist.tmp");
   Exception exception = assertThrows(RuntimeException.class, () -> FileHandler.readTextFromFile(nonExistentFile));
   assertTrue(exception.getCause() instanceof IOException);
}

Now that wasn’t so bad was it?

Now I can move through the rest of my code to limit these cases and to test more thoroughly.

Best,

Merl

read more

Thoughts on Dependency Injection

I am beginning to see the light.

One of the reasons why Dependency Injection is so powerful is because of its ability to be tested. This may be common knowledge to the reader, but it is different when you are building it for the first time.

It’s like thinking about Karate. It can be described as a martial art, with disciplines, and there are kicks and punches involved. However, it is one situation knowing you have to kick and punch, and an entirely different situation to actually kicking and punching. Not to mention the practice behind it.

Same situation here, I know I need tests. I know abstraction is helpful for flexibility, preventing code rot, and for testing as well. When it comes to implementing the ideas together, well it is challenging.

Creating the interface is simple, creating the real class that implements that interface again straightforward. Now, when it comes to creating the mock class and its tests. That is challenging.

Probably the biggest hurdle is that I am writing the abstraction last as opposed to writing it first along with the tests. This helps with design and bugs later, though without the experience of building something it is tough to know what to test for and how to test to begin.

It is possible I am just being lost in all of the abstraction for the moment.

Like many situations in software. After practicing and practicing the situation becomes clearer, slowly but surely.

Best,

Merl

read more

Multithreading

Welcome back to my blog, where today I’m excited to share how something so small, improving the responsiveness of a ping program, led me to embrace multithreading in my server. A Ping One of the items to add to my server was a ping ability. This basically means I would sleep the program for lets say 10 seconds, and it would return the current time. The point of this is to implement multithreading. Because if my server were to receive multiple requests then ideally one request should not be queued up one after the other.

They should be produced at their respective time.

read more

Dependency Injection

In the process of adding tests for my code I came across a class that was tough to test.

It had the name GuessingGameHandler.

It was the abstraction between my Request Handler and my guessing game.

This allowed the guessing game to worry only about the game, and this lets call it GGH would worry about sending back a response to the Request Handler.

Again this was created initially by checking the server over and over again and printing many statements.

I had to recreate this class by beginning with tests.

Now how can one test an abstraction about a random number game?

It is tough to test a random number generator, unless you can control what the random number is.

Now I did have a way of doing this in my game, but not so much in the GGH. So how can I control the game and test the result and the response?

The answer is making more abstractions! Dependency Injection (DI) allowed me to introduce a layer of control over the randomness inherent in the guessing game. By abstracting the creation of game instances into a factory interface, I could inject different implementations of the game during testing versus production.

I made and interface:

public interface GuessingGameFactory {
   GuessingGame create();
}

Here is the implementation of that interface for the actual random game:

read more

Tests

One of the challenges I have been facing in my server project has been testing.

When it comes to using TDD to test for small problems like euler problems or even Tic Tac Toe, TDD seems easier. I believe this is so because most of the problems I have faced are small, modular, and they can be easily identifiable.

In the case of a server and its games, it has been a challenge to make an easy test for what I want to build.

Because of this I have had a hard time changing it.

Whenever I wanted to build something instead of going straight to my tests to make sure everything works, I would run my server and test it out there with print statements.

Now given, this is a way to build my project but clearly, it was not the best. Because when it came to making changes or trying to build upon what I had, the process was always slow and tedious.

Not just that, I was reluctant to try and make changes, because of the current functionality.

I have been stuck holding on to my spaghetti code that was in the process of rotting.

I have been and will continue to test each line of code so I can be comfortable making changes in the future.

Best,

Merl

read more

Try Again

Tinkering with your project causes interesting side effects.

read more

Making JARs

Making JARs is useful because they can store things. Yes that was a very general statement made on purpose.

A Java Archive (JAR) file is useful for multiple reasons.

One is it allows developers to bundle many classes, and data into one single file to send out to others.

Two it allows for a compressed version of your code which can make it easier/faster to transfer to someone else.

There are more reasons but those 2 are the most important to me at this moment.

Now to the steps of making a JAR file.

Step 1: Compile

To compile Java code, I used the javac command.

javac -cp src -d out src/MerlsServer/Main.java

javac is the command that calls the Java compiler.

-cp src sets the classpath to the src directory. This tells the compiler where to find any classes that are used as dependencies during compilation.

-d out specifies the directory where the compiled .class files should be output. If this directory does not exist, javac will create it.

src/MerlsServer/Main.java is the path to the Java file we want to compile. This path is relative to the classpath.

Step 2 Making the JAR File

jar cfm MyHTTPServer.jar src/META-INF/MANIFEST.MF -C out/ .

jar is the command that invokes the JAR utility cfm are options passed to the jar command: c is for “creating” a new JAR f is for the output to a “file” m says that a manifest file will be included. The manifest file (src/META-INF/MANIFEST.MF)

MyHTTPServer.jar is the name of the JAR file we are creating

-C out/ . tells the jar tool to change to the out/ directory and include all files and directories from .

Running the JAR File

java -jar MyHTTPServer.jar -p 8080 -r .

java is the command to run Java

-jar MyHTTPServer.jar tells Java that we are running an application packaged as a JAR file

-p 8080 and -r . are arguments

For example, -p 8080 tells the server it should listen on port 8080, and -r . begins the root directory to begin at that location.

Now you can compile, create, and run a JAR file too!

Best,

Merl

read more

Different Forms

Again I have been working on the guessing game for some time.

This button has been moderately challenging.

I say this because on the surface it is very convenient. The fact that in HTML one can just say make a button and it does immediately is nice.

The next part is making it work the way you want.

Let me show you

private String generateGameResponse(String message, String randomNumber, String gameId) {
    return "<h1>Guessing Game</h1><p>" +
          //fluff
           "<form action=\"/guess\" method=\"post\">" +
           //fluff
           "<input type=\"number\" name=\"guess\" min=\"1\" max=\"99\" placeholder=\"37\">" +
           "<input type=\"hidden\" name=\"gameId\" value=\"" + gameId + "\" />"
// the interesting part is right below this
+ "<button type=\"submit\" name=\"newGame\" value=\"Submit\">New Game</button>"
+"</form></br></p>";
}

Now, creating the button was straightforward. There are many places that tell you how to do this.

The problem that I was having is it would always produce the same result.

In my request body I would Submit every time.

guess=20&gameId=25&newGame=Submit

read more

Static Saves Lives

Again with the dramatic titles. I just want to highlight how important one word can be.

As you know I have been having trouble with the guessing game.

Little by little I have been making progress. One thing I have found super useful was to write down overall what I needed to accomplish in a general sense, then slowly add in the details to help accomplish this. This idea may not be completely revolutionary but it has been incredibly useful. I probably should have made a post about this by itself but we are here now.

This post is about the abstraction between my guessing game and the request handler. This is about the guessing game handler.

Guessing Game Handler

I have been progressing, little by little.

Initially I created an input that would take a number between 1 and 100.

read more

Abstraction FTW

There is a difference between knowing something and implementing it.

I have been well versed in the SOLID principles, on top of that I have given short presentations on them. However, sometimes it may be difficult to implement those ideas into your code.

I faced such an issue today.

I had been having my RequestHandlerdo many duties. Before I refactored it was 162 lines of code. Originally it was meant to guide the send the requests to their desired handling. Then I decided to handle the requests there as well.

This violates the Single Responsibility principle, the Open-Closed principle, and the Dependency Inversion principle.

SRP because clearly the class was doing multiple things.

OCP because I could not have added new features without going in and doing extensive code surgery.

And finally DIP specifically because I am trying to implement the Guessing game as one of the pathways.

I have a guessing game, and I wanted to connect it directly to this RequestHandler class. However, I was creating a method in the RequestHandler class and it was getting very large. This meant that the RequestHandler was dependent on the details of the Guessing game.

Why does the RequestHandler care about the details of the Guessing Game? It shouldn’t, it should care that it can send the request to the correct location and that is it!

So now I have cleaned up the Class and it is now only 64 lines long, and I created 3 more classes to handle their desired locations!

Now my main method in RequestHandler looks like this:

```java private Response handleDirectories(Request request) {

read more

Different Routes

One of the ways to learn when creating something is to create something you will not use.

I have been having this problem where I want to compile and run my program from the command line rather than from the IDE.

With this ability, I want to also be able to go into any directory and make it my root directory while the program is running.

I was able to make this happen, but not in the way that I wanted.

See originally my root directory is . which is also MyHTTPServer/.

Now I want to be able to go into other files from the terminal and explore.

This means run my program from ./src/ to be able to begin there.

read more

Get bodies

I have to say one of the randomly surprisingly challenging tasks has been to get the information from the body of a request.

read more

Images

One of the proudest moments so far has been the ability to present images/gifs/txt in my web server.

Part of the reason why I was struggling to display it at the end was because of how I was able to display information initially.

See my initially way that I was able to send information to the client was through this line of code right here

Response response = handler.handle(Request.fromString(requestString));
writer.println(response);

The important line is the last one where I used the print line to pass my information.

Looking back it is silly to not see that this could be a problem when I would want to display a file.

The phase I had to get through first was if I was looking at the right file and how would i transfer that information through.

if (contentType.startsWith("image") || contentType.startsWith("application")) {
   byte[] byteBody;
   try {
       byteBody = Files.readAllBytes(file.toPath());
   } catch (IOException e) {
       throw new RuntimeException(e);
   }
   return new Response(200, byteBody, contentType);
}

The other part I had to do is have different constructors for Response, so I could place either an image like this or a txt body. I only provided the code for the image byte copying.

After passing it through to the correct places, I had to finally send it back to the client.

This next code does have the HTTP message already included in oStream. This code is to decide whether the response has an image or is a text file.

And Finally I found what I needed to write to send out the image to the client. Flush!

if (response.byteBody != null) {
   oStream.write(response.byteBody);
} else if (response.body != null) {
   oStream.write(response.body.getBytes(StandardCharsets.UTF_8));
}
oStream.flush();

Little by little.

Best,

Merl

read more

Continue

It is interesting the small things we can do to make things work very well. I have been working on my server and have had it close every now and then. This means it will work, then randomly it will break.

Initially it was because I was getting a /favicon.ico request. I found a work around, where I had a placeholder at my previous page, and if that request came through I called my previous page. This may not be the best idea but it is one that has worked so far.

The other problem is that randomly I will be getting null values from my buffered reader.

BufferedReader bufferedReader = new BufferedReader(input); This is what kept breaking my server. And of course this would take time to restart the server, every time it broke.

I needed to fix this bug ASAP.

I was able to find the simplest solution that is quite useful.

if (request == null) {
   continue;
}

This now allows me to keep my server running even if the request is null.

I have had no problems since!

Best,

Merl

read more

Inconsistent Bug

Let me tell you about an inconsistent bug I had. Which I have now learned is more disruptive than a consistent but because, a consistent bug is slightly easier to understand.

Next, let me provide the code that was giving me problems before.

```java public void start() { System.out.println(“Server is running”);

read more

Connection Handler

onnection Handler

I wanted to show one of my proudest pieces of code.

Not necessarily because it was the most complex. On the contrary its only a switch case situation. But this method shows the connecting between my input and my output. This is where that magic connection happens. There is still a lot of work to do to make it better, but the fact I created this location, and it works just fine for right now is pretty awesome.

```java

read more

Building With Maps

I am progressing in understanding how to make a server text and I wanted to make a class that allowed me to help produce information with the least amount of information possible.

Here wer begin with the few status codes that I am using at the moment

static final Map<Integer, String> statusCodes = Map.ofEntries(
       entry(200, "OK"),
       entry(404, "Not Found"),
       entry(405, "Method Not Allowed")
);

Now I have a map that contains the codes along with their message.

Next I have one of my constructors, the other ones have less options if you want to make a simpler message but here is the overal idea

public Message(Integer statusCode, String header, String body) {
   this.statusCode = statusCode;
   this.header = new HashMap<>();
   this.body = body;
}

I already have my status code that I provided but you see a new hashmap arises.

It maybe that I have maps on the brain or it might be that a Map is necessary for the header. More on this later.

I created this new method to add headers if you need to

public void addHeader(String key, String value) {
   this.header.put(key, value);
}

Now back to why it is necessary to have a map here. Initially I just had my header as a string, then I would just add to it. This works in theory if you make no mistakes. This is, something I need to always keep in mind while I progress.

It can work if you perfectly put the correct headers in there. As you know you can place as many headers as possible in there, but what happens when you placed the incorrect one? Or You changed your mind later and wanted a different header?

If I just kept adding to the string then there would be some unexpected errors. Now with my map, if I add my new Header with the same key, it will just replace what I had previously. This allows for more flexibility and less breaking of the system.

Now we have the final toString method that allows us to bring the information back to life, or into a text that is readable by the socket.

```java @Override public String toString() { StringBuilder headerString = new StringBuilder(); for (Map.Entry<String, String> entry :header.entrySet()){ headerString.append(entry.getKey()); headerString.append(“: “); headerString.append(entry.getValue()); }

read more

First Server

I am in the process of creating my first server in Java.

The problem is, it is quite challenging. The concept is simple, it is a server listens on a port for a request in a particular protocol and returns a response.

Now to write this into code is something different especially with new tools, in the language I am slowly progressing it.

Now first I need to make a “socket” in order to communicate. For me the socket is properly named because it is what connects the client and server. It is what “listens” for the connection on the port.

Next I need to accept the connection to the server. In this case I just want to make something super simple that I can see in my local host. In this case it is “hello”.

In order to write hello I noticed I needed to use PrintWriter in order to send data to the client. But I am getting ahead of myself. The socket has an input and an output. So in order to send information to the client I need to create an output stream in order to communicate.

read more

Testing Time

I had the wonderful opportunity to write a few programs but bring them into a server. Currently I am still learning a lot about servers so I am making the simple programs that I need to implement in the server.

First one is a guessing game to see if you can guess the number, the game will respond back with higher, lower, or if you guessed correctly.

Next, is this one I am talking about for today. Telling time. It is nothing revolutionary but I had to provide the time, when asked. I also had to respond 1 second after I asked for the time.

Since I use TDD I decided to test this. I began by testing if I could return the current time.

```java Time timer = new Time();

read more

Doing Threads

One of the problems that I had when I was completing my GUI was changing certain details in my state.

```clojure

               :player-2 {:kind ::ai :difficulty :easy :token "O"}
               :moves    [1 2 3 4 5 6 7]}}
read more

Helpful Atoms

I’m sure we are thankful for the atoms that make up our body but of course I am referring to the atoms in Clojure.

read more

Connecting the AI

For my last post I provided a hypothesis.

That hypothesis was wrong.

I found the best way to incorporate my GUI and logic was to use what I had already created, and place it in the GUI.

Let’s take a look again at my two functions that I combined.

```clojure

read more

Connecting the GUI

I have been making the GUI for Tic Tac Toe but I have been having a challenge connecting it to my previous game logic.

I think this is because of several reasons.

First, I created it in the wrong order. I created a GUI by just making boxes, then making Xs and Os, then I made it clickable.

Now I think I should have made a connection to my game logic first, then build it from there.

This is my setup, and my mouse-clicked for my :play multimethod:

```clojure

read more

compareTo

I wrote sorting algorithms some time ago. They were written specifically to sort for Integers. I wanted to change this up and to sort through any generic types.

I had to change up my code. Before I could just use their values in an inequality in the if statement, and swap the values if I needed to.

public static void sort(List<T> list) {
   boolean continueSorting = list.size() > 1;
   while (continueSorting) {
       continueSorting = false;
       for (int i = 0; i < list.size() - 1; i++) {
           if (list.get(i) > list.get(i + 1)) {//Operator '>' cannot be applied to 'T', 'T'
               swap(list, i, i + 1);
               continueSorting = true;
           }
       }
   }
}

As you can see, an inequality does not work for a generic.

So, I need to move on to compareTo, which led me to this:

read more

Two Removes

In order to allow MyHashmaps to run on my own versions of Hashmaps I had to create my own Iterators and remove methods in MyArrayList and MyLinkedList.

Let us focus on MyArrayList for now.

I prefer MyArrayList because most of it seems straight forward. I had already created an Iterator for this class so I had to create a remove method, but i wanted to incorporate new methods with it.

@Override
public T remove(int index) {
   if (index < 0 || index >= count) {
       throw new IndexOutOfBoundsException(index);
   }
   T element = array[index];
   for (int j = index; j < count - 1; j++) {
       array[j] = array[j + 1];
   }
   count--;
   return element;
}

This is the first remove. Nothing fancy, just removing an item based on its index. This was very straightforward. What I had to do was to remove and item from my array based not off its index but off the element itself.

I began the process of doing so, however I noticed I had another method that might be helpful.

@Override
public int indexOf(Object o) {
   for (int currentIndex = 0; currentIndex < count; currentIndex++) {
       if (o == null) {
           if (array[currentIndex] == null) {
               return currentIndex;
           }
       } else if (o.equals(array[currentIndex])) {
           return currentIndex;
       }
   }
   return -1;
}

Index of! If I could get this method to work it should not be that bad. For indexOf I had to find the index of any object that is in the list.

I tried a while loop, but this is one of those cases where a for loop is preferred. Mainly because there is an index out of bounds exception that can be called if the object you are searching for may not exist in the array.

The other interesting thing that I learned is that in those instances where the object doesn’t exist in your array, the method needs to return something. I tried null but indexOf returns an int every time. So it must return -1 to fit that criteria but also signify that something is wrong.

Finally I could get to my remove the object method.

```clojure @Override public boolean remove(Object o) { int currentIndex = indexOf(o); System.out.println(currentIndex);

read more

Implementing Iterator

I have learned a few things writing code for Java.

THe simple part is it is possible to place “if” statements in the return value.

The second possibly more powerful ability is to create an anonymous class. This is done also by placing much information in the return section of a method. I will provide my code at the bottom.

I wanted to create an anonymous class that implemented the Iterator interface. It is simple and is used to iterate over a linked list.

This was done because I wanted to implement my own linked list into my own hashmap.

The error messages kept pointing me to my uncompleted iterator method.

I had to come up with a solution:

Below you can see the code and the methods explained.

The hasNext() method checks if there’s a next node in the list. The next() method returns the value of the current node and moves the pointer to the next node. The remove() method is not supported in this implementation, so it throws an UnsupportedOperationException.

I see that this anonymous class is a concise way to provide custom behavior without having to define a separate named class.

```java @Override public Iterator iterator() { return new Iterator<>() { private LinkedListNode current = head;

read more

Extending Generics

I have been in the process of changing my Sorting Algorithms to take in Generic types instead of only taking Integers.

To accomplish this I initially began changing <Integer> to <T> however that was not enough.

read more

Changing Pages

Today I will talk about changing pages in a GUI.

Now, before I get in to how to change the page, I need to get into this function.

read more

Making Buttons

In the world of Quil is is important to make boxes/rectangles/buttons.

Before I was able to make those boxes, however I made them one after the other. This meant I was able to use a doseq to make one after another. Also the size of the box was the dimensions of the GUI divided by 3 or 4.

Now I have to make boxes that are in the middle of my GUI with text inside of it.

This is not the toughest of tasks but there was a small wrinkle when trying to implement this. When you choose the coordinates of (q/rect x y h w) this chooses the top left corner of where to place the box.

If you want the box in the center of your GUI using ‘(q/rect (/ x 2) (/ y 2) w h)’ this would not do this. This would place the top left corner of the box in the center and the rest would be hangin down in the 4th quadrant of this Cartesian plane.

How can you make the box with the coordinates at the center of the box along with the text in the middle also?

Here it is.

(defn draw-button [text x y w h]
  (q/fill 237)
  (q/rect (- x (/ w 2)) y w h)
  (q/fill 0)
  (q/text-align :center :center)
  (q/text text x (+ y (/ h 2))))

(defn draw-state [state]
  (let [w (q/width)
       h (q/height)]
   (q/background 255)
   (q/text-size 38)
   (q/text-align :center :center)
   (q/text (str "Welcome to Merl's Tic Tac Toe game!\n Please choose your board size:") (/ w 2) (/ h 5))
   (draw-button "3x3" (/ w 2) (* h 0.33) (/ w 10) (/ h 10))
   (draw-button "4x4" (/ w 2) (* h 0.5) (/ w 10) (/ h 10))))

Ok in this situation I was able to fix the X coordinate so it will be at the halfway point in the GUI, the y is the default value for quil.

This was my solution to display the rectangle in the center of the GUI according to X ` (q/rect (- x (/ w 2)) y w h) The only part that changed was the X. I took half the width of the box and subtracted the starting X coordinate x- (w/2)’, so I can focus on my center point when calling draw-button.

When it comes to my solution to have the text be in the middle of the box. I used: (q/text-align :center :center) (q/text text x (+ y (/ h 2))) As was mentioned before, the y was unchanged so it would be at the top of the box is unchanged. So I had to add half the height of the box so the text will go to the center of the box. Since X was also located at the center of the box. Now I can call the alighment to the coordinates in the center and voila.

Everything is in it’s rightful place.

Now I can choose exactly where I want my boxes, and also what I want them to say with these 2 simple functions.

This will be very helpful when I make my other pages so a player can choose, their size of the game, and which types of players they want.

Things are slowly coming together.

Best,

Merl

read more

Hidden Mouse

I want to talk about a hidden mouse I found!

Of course this is in the best way possible.

I wanted to mention somehting that could help others in the future. Specifically those of you who are working in Clojure and using Quil for your GUI purposes.

With out further adieu. Here is the usual defsketch that is presented while using quil.

(q/defsketch Merl's Blog
             :title "Example"
             :size [1000 1000]
             :setup setup
             :update update-state
             :mouse-pressed mouse-pressed ;not used by default, but important later
             :draw draw-state
             :features [:keep-on-top]
             :middleware [m/fun-mode])

Have you been in the situation where you are creating a GUI in Quil and you wish to use mouse clicking for an input.

Initially I was using

(defn update-state [state]
 (if (and (q/mouse-pressed?) (q/mouse-x 100) (q/mouse-y 100))
  :do_this
  :else_this))

There was more code of course but I was using this set up to update my state based on the location of the mouse and if it was pressed. This is not the worst implementation, however it is dependent on the refresh rate that is set up rather than just the clicking.

If for some reason you refreshed your system every second, it would take a long time to sense the clicks and perform an action.

However I found something to both limit the complicated code presented and to not depend on the refresh rate.

I was able to find a much easier solution to this dilemna.

 (defn mouse-pressed [state hidden_mouse]
  (let [x (:x hidden_mouse)
        y (:y hidden_mouse)]
   (if (and (= 100 x y))
    :do_this
    :else_this)))

;hidden_mouse => {:x 0 :y 0 :button :left}

This is great because mouse pressed is already built into the function. On top of that it contains the location of where the button was pressed as well as which button was pressed.

Instead of making my own implementation, I can use the built in secret features from quil.

Best,

Merl

read more

GUI Boards

Learning something new is always challenging, GUIs are no exception.

Going through the Quill library I was able to find functions that helped me change my GUI when I clicked on something. mouse-pressed if you are interested, without the question mark.

What is interesting is I was able to create rectangles and have them change color by clicking on them. But I wanted to move on to bringing in my game-map which contained all of the important information needed for my Tic Tac Toe game. Now I needed to bring in such a map and have the GUI transform that into a visual experience.

I am proud that I have done such a thing.

(defn draw-state [state]                                   
 (q/background 245)
 (let [size (size (:game state))
       w (/ (q/width) size)
       h (/ (q/height) size)
       game (:game state)
       board (convert-moves-to-board game)]
   (doseq [y (range size)
           x (range size)]
     (let [index (+ x (* y size))
           token (get board index)]
       (q/fill (case token
                 "X" (X x y w h)
                 "O" (O x y w h)
                 [255 255 255]))
       (q/rect (* x w) (* y h) w h)
       (q/fill 0)))))

It is important to be resourceful because I had written a previous function that can get the size of the board, the moves present and transform that into a 1-D vector which contains the Xs and Os present, and the available moves. That function is called convert-moves-to-board.

I also created a function X and O which draw their respective letters. What is great is based on the height, width and index, I can create the letter in its place. Which looks lovely.

The trouble is now, I am not changing boxes to colors, i am making boards. This ruined my clicking function. Of which I have been banging my head against the wall in order to find a solution.

As of right now that has not helped, but I hope soon to write another blog in which I solved this dilemma.

Until then…

Best,

Merl

read more

Java Maps 2

I am in the process of remaking/refactoring my previous HashMap in Java.

I decided to use my old previous tests and begin the process of Test Driven Design anew. It was interesting because I did have some curve balls in my tests that I had to figure out. One of them was having null as a key and still using that as a way to store a value.

What was interesting was my solution to those tests I had written before. Instead of having to create a literal hashmap with an array with linked lists in the buckets, I was able to make every test pass using 2 arrays.

``java Key key; Value value;

List list1 = new MyArrayList<>(); List list2 = new MyArrayList<>();

read more

Functionality

Learning is definitely not linear, however it is important to learn in a particular way especially when there are deadlines in place.

I am trying to find a way to connect my Tic Tac Toe game to a GUI that can display the game while having the logic in the background.

I was so excited that I went into the display of my Os and my Xs. I went into great detail on how they should look like. I was able to make lines that could split the board into 3x3 or 4x4. Then depending on whether the letter was X or O I was able to fill every section with a red X and a blue O.

The O was blue and a lovely ellipse that took about ⅔ of the available space. The X was quite fancy in that it was red and instead of just being lines it had a style where the center point where the lines met was just a point, but the corners of the X had an area that had a cool effect.

I spent most of my day on this. I came to find out that although I did learn a lot and was able to manipulate the program to display what I wanted, it was not the best time spent.

See that is just the image on top of the cake. Sure it can make things look nice. But if the cake is not baked correctly, or tastes terrible then it doesn’t matter how it looks on top it’s a bad cake.

What I’m trying to say is, I spent so much time making my O and X look super rad that I needed to make sure the game functioned.

Right now I am struggling with having the computer sense my click!

This feels like the most basic part. If I can’t sense a click, how is my UI supposed to work?

Good news, I like playing around with the GUI. Things to work on, focus on the necessary bits then make the frosting pretty.

Best,

Merl

read more

End Game

End game, this usually refers to chess or a lesser Avengers movie. They undid what made Infinity War interesting. You can’t bring everyone back that you killed off. That defeats the purpose!

Sorry for spoilers and going off topic.

In my Tic Tac Toe game I wanted any player to have the opportunity to play again after they completed a game without having to run the program again. So if they were having the time of their lives playing Tic Tac Toe over and over again, they could do so without having to start the program over again.

I was under the impression that it would be challenging because there was a game loop that was in the way.

(defn game-loop [game-id db-type]
 (let [[game id] (continue-game? game-id)]
   (ui/print-id-and-board id game)
   (loop [game game]
     (let [game (gm/play-round db-type game)
           new-board (game/convert-moves-to-board game)]
       (if (board/game-over? new-board game)
         (ui/print-end game)
         (recur game))))))

I was nervous because there is this loop that has quite a lot going on. Especially that continue-game? function. There is much going on under the hood.

This is one of those moments where I am so happy I was wrong. Given it did take me some time, and I laugh now because everything seems so simple now. But I do have the ability to continue this loop no problem. And everything runs quite smoothly.

```clojure (defn end-game [game db-type] (let [game-id (data/get-next-game-id)] (ui/print-end game) (if (ui/play-again-message) (game-loop game-id db-type))))

read more

Java Maps

I have been spoiled by Clojure and Python. The dynamically typed languages so far are my favorite. They help make life easier for me, which I am all about!

I do however have to learn for the rest of my life, so it would be wise to learn and get better at Java.

I was trying to create a hash map in Java. But I have not been making the map as succinct as it should be.

read more

Coding Mad Libs

Today felt like a coding MadLibs.

I was working on connecting to the PostgreSQL to my code. That was challenging however once this was done I was able to play around with the database.

I was able to create my table


(def db {:dbtype "postgres" :dbname "tic_tac_toe"})
(def ds (j/get-datasource db))

(j/execute! ds ["
CREATE TABLE games
(game_id int, board_size VARCHAR(9), moves VARCHAR(100),
player_1 VARCHAR(50), player_2 VARCHAR(50))"])

Success!

Now I wanted to find a way to add into this table a specific game I had.

{:game-id  1, :player-1 {:kind :human, :token "X"},
             :player-2 {:kind :ai, :difficulty :hard, :token "O"}, :size :4x4, :moves [10 7]}

(j/execute! ds ["
INSERT INTO games (game_id, board_size, moves, player_1, player_2)
VALUES (1, ':4x4', '[10 7]',
'{:kind :human, :token \"X\"}',
'{:kind :ai, :token \"O\", :difficulty :hard}'
)"])

This allows us to have a database that looks something like this game_id | board_size | moves | player_1 | player_2
———+————+——————————-+———————————————-+—————————- 1 | :4x4 | [10 7] | {:kind :human, :token “X”} | {:kind :ai, :token “O”, :difficulty :hard}

Now I have to create the Mad Libs function I was talking about to save any game into the PostgreSQL database.

(defmethod save :psql [game _db-type]
 (let [game-id (:game-id game)
       board-size (str (:size game))
       moves (str (:moves game))
       player-1 (str (:player-1 game))
       player-2 (str (:player-2 game))
       query (str "INSERT INTO game_map (game_id, board_size, moves, player_1, player_2) VALUES ("
                  game-id ", '"
                  board-size "', '"
                  moves "', '"
                  player-1 "', '"
                  player-2 "')")]
   (j/execute! ds [query])))

Since I am here I will show my fetch-the-games Mad Libs as well.

```clojure (defn psql-to-map [data] (let [game (into {} data)] {:game-id (:games/game_id game) :player-1 (read-string (:games/player_1 game)) :player-2 (read-string (:games/player_2 game)) :size (read-string (:games/board_size game)) :moves (read-string (:games/moves game))}))

read more

Log Jam

Refactoring is challenging but necessary. I feel like a broken record however, it is an important lesson that is being hammered into my mind. I would say it takes me about the same time to refactor as it does to create functioning code.

It is tough uncoupling the tightly wound code. But once the code is uncoupled it is amazing. Now I can add to the existing abstract code and I will not need to change too much.

Now we are here at my coupled code. I am currently using the EDN database, along with the JSON database, and I will soon be using the PostgreSQL database as well. I need to get into the habit of writing my code so that it has the option to simply add on databases or anything similar without adding too many unnecessary functions or coupled code.

I hid my fetch-the-games multimethod to focus on my different logs.

read more

PostgreSQL

I am beginning on a new database. The trouble is I cannot see it directly. Downloading the program I can create a new table and add to it, sadly I can’t see it unless I say in the terminal I want to see it.

That’s ok. I can go through this slowly. Let me show you the simple moves I have made to move forward.

Creating the table is straight forward. I have to use CREATE TABLE then mention the name of the table and parenthesis. Then I have to place the name of the variable, the type and a comma. So on and so forth until your title section of your table is complete.

read more

Commits are Important

I know this is obvious but this has happened a few times and I wanted to stress the importance of committing. I’m sure many significant others would agree with that, it is also important for our code.

See I had made a functionality before where I could print out all of my previous moves and it was no problem.

Since I have been refactoring my code as well as my database I had to get creative with how I was going to do what I did previously.

I had deleted my previous function because it was no longer necessary. However I needed to do something similar and I no longer had it. I knew there were useful bits of information that would help me accomplish this task.

Then I went to my previous commits and found exactly what I needed.

(defn print-previous-moves [input-id]
(let [game-data (data/game-history-by-id input-id)]
(run! (fn [game]
(println "Player" (if (board/player1? (:moves game)) "2" "1") "made a move:")
(print-board (:board game)))
game-data)))

Here I can use run! For the purpose of side effects. So I wanted to use it again in my new function that would behave similarly. This time I would have to use a vector of vectors in order to print out my previous moves.

(defn print-previous-moves [game-data]
 (run! (fn [game]
         (println "Player"
                  (if
                    (even? (count (filter string? game)))
                    "2" "1") "made a move:")
         (print-board game))
       game-data))
read more

Recreating The Past

As you saw I have been finding ways to use my database and limit the information inside. The downside to limiting the information inside is being able to extract all of the data you need.

Before I saved every move of every game by saving the board after every move. You saw hits before, every move would have the same map saved with this inside :board [1 “X” 3 4 5 6 7 8 9] and then a new move would be made and a new map with the same information would be saved along with this :board [1 “X” 3 4 5 6 7 8 “O”] clearly inefficient.

Now I only save one map per game instead of 5 to maximum 27 maps per game. It was done so by saving the size of the game and the moves played so the above situation would be saved as :size :3x3 :moves [2 9] This is way cleaner.

The problem is how can I provide the move by move replay if I don’t have the previous boards and print them out like I did before.

I believe I can print it well, I just need to create a collection of vectors representing my boards.

```clojure (defn place-moves-into-board [player-1-token player-2-token board-size moves] (let [players (cycle [player-1-token player-2-token]) _coll (map vector players moves)] (vec (reduce place-token board-size _coll))))

read more

json

I have been in the process of learning a new database. Boy are these interesting.

I have been able to save data using a multimethod!

(defmulti save (fn [game db-type] db-type))

(defmethod save :edn [game db-type]
  (->> game
       (swap! log-edn assoc (:game-id game))
       pr-str
       (spit "log.edn")))

(defmethod save :json [game db-type]
  (->> game
       (swap! log-edn assoc (:game-id game))
       json/write-str
       (spit "log.json")))

This is quite useful and pretty amazing.

Now the interesting part has been retrieving the data. From what I have collected it is not so easy to retrieve the exact data that was placed in JSON. This makes things complicated.

Initially I assumed it would be data in is the data out.

(defmulti fetch-the-games (fn [db-type] db-type))

(defmethod fetch-the-games :edn [_db-type]
  (let [log-edn (slurp "log.edn")]
    (if (empty? log-edn) {} (edn/read-string log-edn))))

(defmethod fetch-the-games :json [_db-type]
  (let [log-json (slurp "log.json")]
    (if (empty? log-json) {} (json/read-str log-json :key-fn keyword))))

So I created this multimethod to retrieve the data. Let me show you what this brings back.

(json/write-str {:a 1 :b 2})
;;=> "{\"a\":1,\"b\":2}"

(json/read-str "{\"a\":1,\"b\":2}")
;;=> {"a" 1, "b" 2}

(json/read-str "{\"a\":1,\"b\":2}"
               :key-fn keyword)
;;=> {:a 1, :b 2}

Upon seeing this I believed I found the way to get my precious data completely. However if you save something like {:a :example :b :example2} and use the :key-fn keyword, you will receive back `{:a “example” :b “example2”}.

Alas I am still at this point. Hopefully soon I will be able to overcome this obstacle and continue playing Tic Tac Toe.

Best,

Merl

read more

Saving Better

If I haven’t said it before, refactoring is tough! But It is well worth it.

Let me show you from where i started to where i am now!

```clojure ; initially here

read more

Game of Life Kata

I have been practicing my Game of Life Kata. In that process I have been given some incredible advice on how to proceed.

When I first wrote Game of Life, very recently, I began at the low level details and worked my way up. I know this is not the best course of action, but implementing such a thing is not easy. It is simple but not easy.

I began to redo my whole method of doing the Game of Life. I began at the end with evolve, and worked my way up to getting the neighbors and the state of the current cell.

This process helped limit a few of my previous functions and made my tests more robust. I now have fewer tests but they are more meaningful.

You can see my work in action, here:

read more

Game of Life 3

As you might remember I have been working on creating Conway’s Game of Life.

I was able to predict the next state and get the neighboring states of a particular cell I am looking at, I changed next-generation to survived.

Here it is ```clojure

read more

Game of Life 2

They say the sequels are better than the originals right?

I wanted to talk about the middle of the Game of Life!

Initially I wrote the 4 laws and their functions. Now I will write about the other half of the coin and how I can find information regarding the laws. There are two important pieces of information that are necessary to create this game.

  1. The state of the individual cell, whether it is alive or dead
  2. The number of neighbors that cell has.

The State

This will not be a rant on taxes, this will be how I got the state of the cell. In this code snippet I did something different and provided the grid and tests with their respective function below it.

read more

Game of Life

Since I do updates every day this will only go over the concept of Conway’s Game of Life as well as the first bit of code I wrote for it.

Game of Life

To those of us who do not know, I wouldn’t call this a game. I would call this a simulation based on an initial state. It reminds me of a chaotic system like a double pendulum, where changing a small condition initially can have drastic effects later on. What most people call the butterfly effect.

Here are the 4 rules this game is based on:

  1. Any live cell with fewer than two live neighbors dies, as if by underpopulation
  2. Any live cell with two or three live neighbors lives on to the next generation.
  3. Any live cell with more than three live neighbors dies, as if by overpopulation.
  4. Any dead cell with exactly three live neighbors becomes a live cell, as if by reproduction.

Coding

Here are my first tests to check my concepts on these rules:

```clojure

(it “checks rule 1” ;whether the cell lives or dies ;| number of neighbors ;| | 1 for live cell, 0 for dead cell ;V V V
(should= 0 (sut/next-state 0 1)) (should= 0 (sut/next-state 1 1)))

read more

Drawing blocks

Currently my new task is to create the Game of Life. Of course I am referring to the coding game of life.

This is still interesting because I am working on a brand new GUI that I have never worked with before.

I kept playing around with the Gui and I was able to come up with a great solution to cover my GUI with a grid!

(let [step 15]
  (doseq [x (range 0 (q/width) step)
          y (range 0 (q/height) step)]
    (q/line x 0 x (q/height))
    (q/line 0 y (q/width) y)))

I was able to create all of of the lines I needed.

Of course I had to look at the 5 thousand line library to find line I’m not too inefficient I searched for line and eventually found the one I was looking for.

This is great because it provides the visual structure that I want!

However, of course the game of life is dependent on cells that are alive and cells that are dead. Their visual representations as well. I was playing around with fill to see if it could do that to my grid. But alas it was not meant to be.

I did more searching and found a few tools to help me complete my task. The logic of the Game of Life will be another blog post.

Like I said I found the tools and I am in the process of coming up with a solution.

I will list the tools to help me. q/rect this draws rectangles. I can use this and doseq to draw my rectangles all over the GUI.

I see that rectangles can have background colors and fill colors. This will allow me to choose which colors are alive and which ones are dead.

I will now focus on implementing this, along with the logic behind . . . The GAME of LIFE!

Best,

Merl

read more

Sieve of Eratosthenes

I hope I do this justice, but also keep it succint.

I was trying to do an Euler problem and needed a quick way to find primes up to a certain number.

Let me present to you my first response which gave me the correct solution but was took too long.

(defn euler-problem [n]
  (loop [num 3
         primes [2]]
    (cond
      (prime? num primes) (recur (inc num) (conj primes num))
      :else (recur (inc num) primes))))

I erased a condition that told the solution and only focused on the primes section.

As you can see, it is a simple function that provides what I need. You might also be able to see is I have to iterate over ever number until n to reach my solution. Which means the larger n gets the longer this time increases dramatically.

Then I was able to move to this idea which was the Sieve of Eratosthenes.


(defn sieve-of-Eratosthenes [n]
  (loop [primes (vec (range 2 n))
         num 2
         limit (Math/sqrt n)]
    (if (<= num limit)
      (let [non-primes (set (range (* 2 num) n num))]
        (recur  (vec (remove non-primes primes)) (inc num) limit))
      (reduce + primes))))

This was much better I think I decreased the time to a third or even less.

This limited the search up to the square root of n, and removed all of the multiples of our incrementing number from our possible primes list.

read more

Fun with Hash maps

Hash maps, what is all the rave? Well let me tell you.

First of they are very fast, they are constant time. Also you are able to clearly store what you need with the key value pairs.

Let me know provide fun examples to demonstrate.

Have you ever noticed how it can be challenging to remember all of your passwords? There can be so many that need to be stored, what if you stored your passwords secretly in a hash map. Please don’t look at my git hub.

Example one, listen I’m not sure how many of you were young and had simple passwords, I will admit this may have been my password for a possible website or two.

(def password-map {:easy "password"})

Don’t judge, we all start somewhere.

Next we were more refined and added extra layers for protection

read more

Refactor Save

I am incredibly happy because I have accomplished what I wanted to do for many weeks, that is save the game!

I can save the a game mid game, cancel, and resume normally by putting in the id or by the computer asking me. I can resume any previous game that is incomplete as well, Human vs human, human vs AI, AI vs AI it doesn’t matter.

That is the wonderful thing. The interesting thing is I need to refactor how I save. It takes too much space and can be done better.

```clojure [{:game-id 94, :player-1? false, :board (“X” 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27), :player-1 {:kind :human, :token “X”}, :player-2 {:kind :ai, :token “O”, :difficulty :hard}}

read more

Algorithms performances

I have been in the process of helping recreate algorithms in my own style. Along with creating an interface for linked lists and array lists.

The time has come to compare algorithmic performances on the different types of data structures, My Array List and My Linked List. The algorithms that were tested were quick sort, merge sort, and bubble sort.

read more

Save Everything

Finishing this was incredibly satisfying.

Have you ever heard of a false summit? In case you haven’t let me paint a picture. You are on a journey in nature. You want to reach the top of this mountain to get a great view. You see the top, you think when I get there I will sit under a tree and enjoy the view. Then you get to that spot and you realize that is not the top. There is a path that goes higher to the real top of the mountain. Rinse and repeat.

I believe I am past my false summits and have finally been able to save all of my games, as well as retrieve any uncompleted games in history if the command line argument matches those games. I kept thinking I was close to finishing this story but just like Al Pacino said, “just when I thought I was out, they pulled me back in”.

read more

Hidden in Plain Sight

Have you ever been in the situation where you are looking for your keys/glasses/phone for some time. Only to find it in your hand?

I will admit, this is me sometimes. Now this is the first time I have felt this way in terms of coding.

I had previously had this form for printing the previous moves:

(defn print-previous-moves [] ;test
 (let [data (data/fetch-all-games)
       max-game-id (data/max-game-id data)
       game-data (filter #(= (:game-id %) max-game-id) data)]
   (run! (fn [game]
           (println "Player" (if (:player-1? game) "2" "1") "made a move:")
           (print-board (:board game)))
         game-data)))

Think of this as the glasses in my hand.

The problem I was facing is I had provided ways to be able to save and continue games but only for the last game. I had to find a way to be able to continue any previous game that had not finished given the correct key was placed in the argument.

So Now I had to find a way to get any game from its id and to check if the last board was completed.

I was able to find it after I began refactoring. Which goes to show how important it is to refactor after one has completed something because you never know what you may find.

I refactored the previous function to this:

(defn print-previous-moves [input-id]
 (let [game-data (data/game-history-by-id input-id)]
   (run! (fn [game]
           (println "Player" (if (:player-1? game) "2" "1") "made a move:")
           (print-board (:board game)))
         game-data)))

(defn game-history-by-id [game-id]
   (filter #(= (:game-id %) game-id) (all-games)))

Now I have the ability to find all of the boards for the game-id provided.

I need to find a way to see if the last game ended in a tie, or a win for either player.

(defn game-by-id [id]
 (->> id
      data/game-history-by-id
      last))

(defn possible-to-continue? [game] (and game (not (board/game-over? game))))

The game-by-id returns the last board and then is passed into possible-to-continue?. possible-to-continue?’ checks whether the game exists and if the game was not over. Then it returns the boolean true` if both criteria are met.

This is not the end but it is a great path forward.

The lesson is to refactor! Often when I do I can delete unnecessary things. In this case, I found something incredibly valuable.

Best,

Merl

read more

Arguments

Growing up as a Latino with older sisters I am quite accustomed to arguments. The ones I will talk about are new to me however.

As you know I have been working on saving and retrieving my previous Tic Tac Toe games.

Today I have been working on resuming the play from before. Now previously I have provided a message asking if the user wanted to resume the previous play, but I wanted to provide an arguments into main that would allow you to just resume the previous game without the terminal prompting you.

This was new, I have never done this in Clojure before. Thankfully it was not too tough.

(defn -main [& args]
 (let [game-id (first args)
       last-game (data/get-last-game)
       [game id] (continue-last-game? last-game game-id)]
   (ui/print-id-and-empty-board id (:board game))
   (loop [game game]
     (let [game (gm/play-round game)]
       (if (board/game-over? game)
         (gm/complete-game game)
         (recur game))))))

Apparently I can just add & argos and it works! I did have to change my continue-last-game function in order to return both the game id and the game map containing all of the data.

Here is what I turned that into

```clojure (defn continue-last-game [last-game] (ui/print-previous-moves) (ui/print-resume-game last-game) last-game)

read more

Reliving the Past

I have never been to war but I have faced battles. Battles between myself and the computer. These battles consist of none other than Tic Tac Toe.

Dramatic but I wouldn’t have it any other way.

I have been working on many things, primarily I have been working on saving my game. Today I have been working on printing the previous moves made by the players.

So if you were in the middle of a Tic Tac Toe game, and something urgent came up, there was an opportunity to resume your previous game. And if you don’t remember what the logic you were thinking at the time was, I wanted to be able to provide the player that made the move as well as what moves were made and in what order.

This is a daunting task. I have all of that information saved but how to retrieve it?

Here is how:

(defn print-previous-moves [] ;test
 (let [data (data/fetch-all-games)
       max-game-id (data/max-game-id data)
       game-data (filter #(= (:game-id %) max-game-id) data)]
   (run! (fn [game]
           (println "Player" (if (:player-1? game) "2" "1") "made a move:")
           (print-board (:board game)))
         game-data)))

The toughest part was being able to do print which player made a move and what the state of the board was per move. Initially I used map but the sequence did not work as I intended.

read more

Sorting Bubbles

I’m excited to share with you something I’ve been exploring recently - sorting algorithms, specifically the Bubble Sort algorithm.

Sorting algorithms are fundamental to computer science and programming. They help us organize and order data, which is crucial for tasks like searching and merging datasets.

As a fan of bubbles and simple things I have enjoyed this algorithm the best.

Initially when I wrote the bubble sort I used 2 for loops to be able to implement it. It worked well, but I have since learned that while loops are better, and simpler.

After using TDD and building slowly I have come to this conclusion.

public class BubbleSort {

    public static void sort(IList list) {
        boolean continueSorting = list.size() > 1;
        while (continueSorting) {
            continueSorting = false;
            for (int i = 0; i < list.size() - 1; i++) {
                if (list.get(i) > list.get(i + 1)) {
                    swap(list, i, i + 1);
                    continueSorting = true;
                }
            }
        }
    }

    private static void swap(IList arr, int left, int right) {
        int temp = arr.get(left);
        arr.remove(left);
        arr.add(temp, right);
    }
}

Let’s begin with swap. It does exactly what you think it does. Nice, simple, and private.

Now sort is where the real magic happens. It takes a list as an argument. It continues to sort the list until no more swaps are needed.

read more

Hashmaps in Clojure 2

Today I have learned something very powerful that I wanted to share with you!

Did you know you could pass a map into a function and get the key values?

This is brand new information! for me, let me give you this example:

(defn print-person [person]
  (println (:name person) "is" (:age person) "years old."))

In this function, person is a hashmap that contains information about a person. The function print-person takes this hashmap as an argument and uses the keys :name and :age to retrieve the relevant information.

read more

Saving Games

I want to share with you something I’ve been working on recently. I’ve been learning about how to save the state of a game for my Tic Tac Toe game in Clojure, and I’ve found it to be quite interesting.

Let’s start with the basics. I just learned that we can define a hashmap to hold our current game state. Here’s an example:

(def save-data {:game-id nil :player-1? nil :player-1 nil :player-2 nil :board nil})

In this hashmap, we have keys for the game ID, whether it’s player 1’s turn, the names of player 1 and player 2, and the current state of the game board.

Now, let’s say we want to save using that hashmap. I can do this:

(defn save-round [game-id player-1? player-1 player-2 grid]
  (let [log-edn (slurp "log.edn")
        log (if (empty? log-edn) [] (edn/read-string log-edn))
        game-state (assoc save-data :game-id game-id :player-1? player-1?  :player-1 player-1 :player-2 player-2 :board grid)
        new-log (conj log game-state)
        new-log-edn (pr-str new-log)
        ]
    (spit "log.edn" new-log-edn)))

This function takes in the game ID, whether it’s player 1’s turn, the names of player 1 and player 2, and the current state of the game board. It then reads the current log from a file, adds the new game state to the log, and writes the updated log back to the file.

This is a simple but powerful way to keep track of the state of a game. It allows us to save the state of a game at any point, and then load it back up later if we need to.

I just need to get to the point where I can recall the saved game.

That might be a post for the future. Until then, hope you’re doing alright.

Best,

Merl

read more

Crutch or Solution?

As you read last time I have been going through my old code and finding bugs.

As of right now, fingers crossed, I have found my last major one.

The Bug

The bug? When Minimax, my unbeatable AI, is in a lose lose situation it just “gives up” and chooses 6.

Example: ```clojure (it “selects blocking move” (should= 7 (sut/next-move [ “X” “O” “X” “O” “X” 6 7 8 9

read more

Cleaning Out My Code

As you may have noticed I have been in the process of replacing my previous code.

read more

Refactoring Bad Code

I know this is the never ending story but let me add this chapter.

I will begin by providing my previous code that was the same exact idea for 3 different game types. Human vs human, human vs computer, and finally computer vs computer.

(defn two-humans [board]
 (let [x-o (ui/get-user-x-o)
       display board/display]
   (loop [grid board
          X? x-o]
     (ui/print-board grid display)
     (let [new-grid (ui/update-board grid X?)]
       (if (ui/endgame-result new-grid)
         (ui/print-end new-grid display)
         (recur new-grid (not X?)))))))

(defn comp-vs-comp [board difficulty-1 difficulty-2]
 (loop [grid board
        x-turn? true]
   (let [move (if x-turn?
                (difficulty-1 grid)
                (difficulty-2 grid))
        new-grid (comp-move-statement x-turn? grid move)]
     (ui/print-board new-grid board/display)
     (if (not (ui/endgame-result new-grid))
       (recur new-grid (not x-turn?))
       (ui/print-end-computer new-grid)))))

(defn human-vs-comp [board difficulty]
 (let [user-token (ui/get-user-vs-ai-x-o)
       difficulty (hard-ai-x-o difficulty user-token)]
   (loop [grid board
          comp-turn? (ui/start-first? board)]
     (let [move (difficulty grid)
  new-grid (grid-after-comp comp-turn? grid move user-token)]
       (ui/print-board new-grid board/display)
       (if (not (ui/endgame-result new-grid))
         (recur new-grid (not comp-turn?))
         (ui/print-end-computer new-grid))))))

As you can see they have basically identical structures. However I built them at different times, and so I built added to my code instead of refactoring.

Classic newbie mistake. Hopefully, I give myself more time in the future to refactor the code nicely and quickly instead of trying to do it once I’ve already created a mess.

I wanted to create new loop that could handle every combination you can imagine, player 1 as Ai or human, and same for player 2. But I would only need the 1 loop to function. This could get rid of a lot of previous code that was needed to support these 3 frankensteins.

After much deliberation, this is the solution I have as of today. It needs more work especially with the player maps. But as of right now it works, and it is glorious. But again it needs to be refactored more.

(defn player-vs-player []
 (let [board (board-size)
       player-1 (create-player 1 nil)
       player-2 (create-player 2 (:token player-1))
       diff-1 (when (= :ai (:kind player-1)) (ui/get-difficulty))
       diff-2 (when (= :ai (:kind player-2)) (ui/get-difficulty))
       token-1 (name (:token player-1))
       token-2 (name (:token player-2))]
   (loop [grid board
          player-1? true]
     (let [move (if player-1?
                  (get-move player-1 grid token-2 diff-1)
                  (get-move player-2 grid token-1 diff-2))
           new-grid (grid-after-move player-1? grid move token-1 token-2)]
       (ui/print-board new-grid board/display)
       (if (board/game-over? new-grid token-1 token-2)
         (ui/print-end-2 new-grid token-1 token-2)
         (recur new-grid (not player-1?)))))))

Refactoring is like the dishes and laundry, you will never be done!

Best,

Merl

read more

Multi-Methods-2

Multi-methods-2

It has been an interesting one. I am in the process of refactoring my previous code and I wanted to provide another short example of multimethods that could provide this ability.

(defmulti ai-move (fn [_board _ai-token _opponent-token difficulty] difficulty))

(defmethod ai-move :easy [board _ai-token _opponent _difficulty] (ec/place-easy-move board))

(defmethod ai-move :medium [board ai-token opponent-token _difficulty]
 (let [move-count (count (remove number? board))
       hard-ai? (or (< move-count 5) (zero? (rand-int 2)))]
   (if hard-ai?
     (mm/next-move-real board ai-token opponent-token)
     (ec/place-easy-move board))))

(defmethod ai-move :hard [board ai-token opponent-token _difficulty]
 (mm/next-move-real board ai-token opponent-token))

Previously, I did have multiple ai-move functions but this was nice to simplify the code. This process also allows me to decouple my code from the previous hard coded letters X and O. As well as my minimax function was dependent on what letter the computer was.

If the AI was X I would have to call maximize, and if the AI was O I would have to call minimize. This is not a good software foundation. I had to fix that.

Now you see I pass through the ai token and the opponent token, and I only have to call next-move-real. I know the name is funny but while I am rebuilding my program i am creating new but similar names to keep up to continuity.

Here is part of my previous code below:

(defn next-hard-move [token]
 (if (= token "X") mm/next-move-2 mm/next-move))

(defn hard-ai-x-o [difficulty user-token]
 (if (and (= mm/next-move difficulty)
          (= "X" user-token))
   mm/next-move-2
   difficulty))

(defn medium-difficulty [next-move grid]
 (let [move-count (count (remove number? grid))
       hard-ai? (or (< move-count 5) (zero? (rand-int 2)))]
   (if hard-ai?
     (next-move grid)
     (ec/place-easy-move grid))))

Best,

Merl

read more

Multi-Methods

For several weeks now I have heard the magic of multi-methods.

I have been focusing so much on completing my work that I have not allowed myself time to learn more and refactor. I have built my code on spaghetti!

Today I will take the small step to learn multi-methods to begin to untangle my code.

```clojure (defn board-type [board] (if (two-dimensional? board) :2d :3d))

read more

Beatable AI

Bold statement incoming.

I don’t think you can make an unbeatable AI for a 3x3x3 game. Whoever goes first, must win if the player is playing semi optimally. There are too many winning conditions.

(
; 1 | 2 | 3     10 | 11 | 12    19 | 20 | 21
; 4 | 5 | 6     13 | 14 | 15    22 | 23 | 24
; 7 | 8 | 9     16 | 17 | 18    25 | 26 | 27)

Let’s say player 1 goes to spot 14, after playing 3D Tic Tac Toe in my head I think this is the optimal starting position. You can win in every direction from here.

(
; 1 | 2 | 3     10 | 11 | 12    19 | 20 | 21
; 4 | 5 | 6     13 | X | 15    22 | 23 | 24
; 7 | 8 | 9     16 | 17 | 18    25 | 26 | 27)

Now player 2 has options, what would you choose? I think a corner would be best, of course you could choose a side square but a corner makes the most sense. So O chooses 1.

(
; O | 2 | 3     10 | 11 | 12    19 | 20 | 21
; 4 | 5 | 6     13 | X | 15    22 | 23 | 24
; 7 | 8 | 9     16 | 17 | 18    25 | 26 | 27)

If I am X I want to try and win now, but not allow O to have a winning possibility right now. So I make O go away from where it is located now. I choose 11.

(
; O | 2 | 3     10 | X | 12    19 | 20 | 21
; 4 | 5 | 6     13 | X | 15    22 | 23 | 24
; 7 | 8 | 9     16 | 17 | 18    25 | 26 | 27)

Of course O has to choose 17.

(
; O | 2 | 3     10 | X | 12    19 | 20 | 21
; 4 | 5 | 6     13 | X | 15    22 | 23 | 24
; 7 | 8 | 9     16 | O | 18    25 | 26 | 27)

Now X can choose 2. Now X has 2 winning conditions20 or 26, O can block one but it cannot block both.

read more

Limiting_moves

Limiting my moves

I have to make my program faster.

I’m sure that’s something you have said before as well. The way that I am going to accomplish it today is to limit the number of moves minimax is able to go into the future.

See initially, minimax searched through every possible move. This was not a problem when the board was 3x3. When the board went to 4x4 however, things changed. It took about 8 seconds for minimax to find the first move for a 3x3 board, I let the program run for the whole weekend to find the first move for a 4x4 board. It told me there was insufficient data for a meaningful answer. Ok it didn’t say that but, there was no answer.

Increasing the board slightly exponentially changed the timing of minimax! Now that I have a 3d board, the same issue arises. How can I fix this?

Before I had depth begin at 1 and increase by the number of moves after every move.

(defn value [game-board depth]
 (cond
   (board/x-wins game-board) (/ 12 depth)
   (board/o-wins game-board) (/ -12 depth)
   (board/tie game-board) 0))

I chose 12 because this quotient will most likely be a whole number, that doesn’t really matter I just like that idea. As you can see the more moves( larger depth) the closer to 0 we get. Of course we want values away from 0.

What I wanted to do now, is instead of going through every possible move to limit the number of moves my game could make. So instead of starting at 1 and moving up, we can start at an arbitrary number like 4 and go to 0. This way minimax can provide the best move within 4 moves.

This is like a monkey paw situation. Yes, this will make the program faster, but the tradeoff could be that a good move was placed rather than the ideal move.

For performance I’m sure many of us will make that trade.
I won’t go over all of the functions I changed but I will show these:

```clojure

(def default-depth 4)

read more

Flexible Conditionals

One of my favorite abilities of Clojure is its flexibility to place conditionals wherever you want, as well as let.

I have created the logic for the 3 dimensional Tic Tac Toe but today I was in the process of integrating the logic to the UI and the board.

Initially there were a few aspects that were incompatible with my previous functions so I began to write new functions that behave similarly. It was until after I wrote multiple functions that I noticed integration was not that complicated.

It begins with this function:

(defn two-dimensional? [board]
 (> 17 (count board)))

I wrote this to tell if it would be my 2D 3x3/ 4x4, or 3D 3x3x3. It is slightly hard coded and could change if I need to add new modes but at least the hard code is limited to this function.

The next part was adding arguments to previous functions that relied on the board being 2D, this wasn’t too bad it was mostly tough tracking all of them down.

The important part that I wanted to highlight is this:

```clojure (let [x-o (ui/get-user-x-o) display (if (board/two-dimensional? board) board/display board/display-3-3)]

read more

Winning Conditions

First, let me begin that I am proud to have hopefully estimated my story well and have given myself enough time to not just hard code a problem but to put a more elegant solution as well as learn more about clojure.

Winning conditions

On to the real blog post, winning conditions for a 3D Tic Tac Toe grid. As I stated there are 49 winning conditions, I had come up with pseudo code let’s say and not the real thing yet.

Until now. It has been a roller coaster ride because I learned more about mapping and list comprehensions in Clojure.

Initially my mind was mapping the problem out. I had used ` map` to solve this previous problem.

(defn front-diagonal [grid]
 (let [size (size grid)
       indices (map inc (range size))]
   (vec (map
          #(nth grid (* % (- size 1)))
          indices))))

In the normal 3x3 TTT this would produce [3 5 7]. Size is 3 ,indices would then be [1 2 3], multiply that by 2 and you get the trio above. This was done because it works for a 4x4 as well.

Map Monster

I wanted to use map again for my new scenarios.

```clojure #_( 1 | 2 | 3
4 | 5 | 6 7 | 8 | 9

read more

Winning is hard

True statement, but I am also referring to winning conditions. Not just any winning conditions but 3D Tic Tac Toe winning conditions.

There needs to be 49 winning conditions.

Let’s take a look at the board.

``` clojure #_( 1 | 2 | 3
4 | 5 | 6 7 | 8 | 9

read more

3D Tic Tac Toe

I have been working on creating a 3 dimensional tic tac toe.

First I wanted to be able to print/present the board. As of right now I don’t have the skills to be able to create a 3-d animation, so this will still be printed 2-d in the terminal. That means I need to print 3 separate boards.

Initially I wanted to print the boards separate horizontally like so:

#_( 1 | 2 | 3     10 | 11 | 12    19 | 20 | 21
   4 | 5 | 6     13 | 14 | 15    22 | 23 | 24
   7 | 8 | 9     16 | 17 | 18    25 | 26 | 27)

But after trying and thinking, I decided to make it easier on myself and do it vertically like so.

``` clojure #_( 1 | 2 | 3
4 | 5 | 6 7 | 8 | 9

read more

Arrays vs Linked List part deux

I know I just covered this topic however, there is something interesting I wanted to cover.

It is this chart right here:

```java for (int i = 0; i < 10000; i++) { back.add(i); front.add(i, 0); middle.add(i, middle.size() / 2); }

// Linked List // total ~309 ms // back ~ 123 ms // front ~4 ms // middle ~67ms

read more

Arrays vs Linked List

Arrays vs Linked List

I recently had the wonderful opportunity to learn how to create linked lists and array lists in Java.

This was quite the challenge for me, as I am still in my crawling phase with Java. Remembering to specify the types, and even just starting the whole process, took a while for me to learn.

Once a few tests were written and the patterns began to emerge, I started to walk like a one-year-old baby before hitting my head on my next challenge: Linked Lists!

Now, I will not go over the difficulty of creating linked lists, and how straightforward creating arrays was. Relatively speaking, of course!

I will say I was fortunate that I created Lists and Arrays that only take Integers. This made my life much easier.

I had to create these simple methods as an interface that implements intoArrayList and LinkedList:

void add(int i)
void add(int i, int index)
int size()
void remove(int index)
int get(int index)

After creating these methods that allow easy implementation for both linked lists and arrays, why use linked lists then?

Bold question with little information, I know. However, if both have the same methods like the ones created above, why linked lists? I would assume there is more functionality to linked lists, the same with creating doubly linked lists that could be useful for web searches and such. Ok, I take it back.

I can see why you can make a case for linked lists, but I wanted to share the times it takes to add data to both lists and arrays.

read more

Adding Logic

If you have been reading along you know that I have been working on Tic Tac Toe.

Recently I tried upscaling my previous game to a 4x4 grid, winning by getting 4 in a row. You saw me update my winning conditions. That worked well for player vs player, and it worked well for anything regarding an easy computer, which is all random.

The problem is when it comes to minimax. Which is my logic for the unbeatable AI. I tried running the unbeatable AI to make its first move. I let it run for over a day. It was not able to produce what the best move would be.

I ran tests to see if minimax worked. Then I slowly started taking away moves to see how long it would take.

read more

Refactoring for NxN sized board

I know the title is a little wordy but so is this post so buckle up!

read more

Estimating Stories

Since this is an amalgamation of thoughts throughout this process I figured I would talk about stories.

Not the wonderful ones we heard about as kids but the wonderful ones in software. The tasks that must be completed depending on your team environment.

Have weekly stories which are great for me. I get weekly feedback on my work, and am able to pivot on certain things quickly. As someone who is learning, this is a gift.

The part where things can be challenging is estimating how long each story will take. I have the control to say it will take this long with all tasks, even ones I am unfamiliar with. This is another process which is quite useful for both parties. This emulates what businesses and companies do when they negotiate. It is up to the estimator to be correct for both parties’ sake.

Catch-22

It is a catch–22. Obviously you do not want to underestimate the story because if the story takes more time than you thought then, it creates long nights or disappointed clients. You do not want to overestimate the story because then the client could potentially be taken advantage of or they could feel that way. It is natural when you have multiple stories to estimate incorrectly in either direction for at least one story.

With all of this being said, I need to estimate better. One part I did not take into consideration was not just basic refactoring my code into smaller more comprehensible parts, but to refactor into a whole nother logic for my code.

My estimations have been on the completion of the code, which could be better as well, but not on make the code change and be better. I have been focusing on comlpetion not improvement.

Hammer

For example let me present you with my hammer:

(defn ai [difficulty]
 (loop [grid [1 2 3 4 5 6 7 8 9]
        x-turn? (ui/start-first?)]
   (let [move (difficulty grid)
         new-grid (grid-after-comp x-turn? grid move)]
     (ui/print-board new-grid)
     (if (not (ui/endgame-result new-grid))
       (recur new-grid (not x-turn?))
       (ui/print-end-computer new-grid)))))

The most important idea to take away from that function is, I like recursion in clojure. Working in python for so long, I like my many loops and this is the equivalent of them.

Since I have been underestimating the stories I have not been able to use a different tool to create the software differently. Don’t get me wrong, the software works well. However it could be cleaner and more efficient.

I just need to give myself more time to change the code to look something more like this:

;(let [game {:board [1 2 3 4 5 6 7 8 9]
;            :mode :pvp ; :pvc :cvc
;            :x    :human
;            :o    :hard
;            :turn :x ; :o
;            }])

I don’t know how to do this yet but it would be great to spend some time to be able to make my code in Clojure look in a similar form to what is above.

All in all it is great to have such quick feedback, however since I am in control of estimating the stories I need to provide myself a better cushion so I can change the code and not just complete it.

Best,

Merl

read more

Medium Computer

I am quite proud of this one. When I first contemplated how to create a medium-level computer, I was unsure of how to approach the problem.

As I had previously managed to create both an Easy-AI and a Hard-AI, my initial thought was to combine them. Fortunately, Clojure has a built-in random function, which sparked an idea. What if, for the Medium-AI, I have the Hard-AI execute the first few moves, then the function ‘flips a coin’ and either transitions into easy mode or remains as the Hard-AI?

This way, the Medium-AI doesn’t lose early and can win or draw due to the Hard-AI or ‘luck’ from the Easy-AI. Alternatively, the Medium-AI can lose to you if the coin flips to easy mode.

(defn medium-difficulty [next-move grid]
 (let [move-count (count (remove number? grid))
       hard-ai? (or (< move-count 5) (zero? (rand-int 2)))]
   (if hard-ai?
     (next-move grid)
     (ec/place-easy-move grid))))

Here, grid represents the board, next-move represents the specific Hard-AI to use, and place-easy-move does exactly what it sounds like. The grid might look something like [“X” “O” “X” 4 5 6 7 8 9].

I was able to count the moves based on how many numbers were available in the grid. If there had been 5 moves, then the proverbial coin is flipped. This random generator provides either a 1 or a 0. If it’s a zero, then it is the Hard-AI; if not, it is the Easy-AI. Then, I incorporated it into my function that runs the logic for all of the modes.

read more

Easy Computer

If I were to go back a year and tell myself that I would be focusing heavily on the ins and outs of Tic Tac Toe, I would have said “What a specific thing to do,and for how long? Also did I lose those 10 pounds I was hoping for?”

Sorry previous Merl, fitness is not a linear journey, neither is Tic Tac Toe.

Linear in the sense where previously I have learned the Minimax Algorithm to create an unbeatable TTT computer. Now I must make a very beatable( “easy”) TTT.

Thankfully I was asked this question months ago and my answer is still the same. Use a random number generator to place the moves for the available positions.

Here was my idea for the computer:

—Get the open available spaces

—Pick a random space

—Place the random move

That turned into this:

```clojure

(defn find-actions [board] (filter number? board))

read more

Coin Changer Kata

One of my favorite learning opportunities has been making these videos. Adding my own flair, while solving a problem.

I am still trying to find a nice balance with how to do these videos. Is typing it enough? Should I do a voice over the whole time saying my thoughts aloud for others to hear. Should I do it half the time, or is the code good enough for others to learn from.

I remember I have watched some previous katas before and been slightly lost in what they were doing. I knew their end goal, however since I am new to these languages the syntax can be confusing, as well as the functionality.

As I am writing this I have come to this realization. I think for the next video I will voice over exactly what i am doing so if anyone is new like me won’t be confused when they see it.

Until then, I hope you like the song in this video.

Merl

read more

For vs While

I have to say I am a big fan of loops. For many of the problems I have wanted to solve they have been right there beside me cheering me on. The tough thing is deciding when to do which?

I did this Coin Changer Kata in Java, and was given some wonderful advice.

In case you don’t know, the Coin hanger kata is the performance of the coin changer problem. Meaning in the old days when people used cash, you would get your change back. Either a human or a machine would give you the change regardless a computer would have to say which and how many coins you get back. So if you were to get back 25 cents, you would be given one quarter instead of 25 pennies.

Back to the Kata, I had used a while loop in my initial function. Then I took it out into a separate function and kept it the same shape but was given a new pointer. Replace the while loop with a for loop and it becomes cleaner:

 public static int addCoins(int amount, int coin, List<Integer> change) {
       while(amount >= coin){
           change.add(coin);
 		amount -= coin;
}
       return amount;

 public static int addCoins(int amount, int coin, List<Integer> change) {
       for(; amount >= coin; amount -= coin)
           change.add(coin);
       return amount;

Three things I learned in this change.

First, we removed an unnecessary line of code and placed the logic in the for loop. This makes the code more efficient, and gives us a for loop which you know my feelings for.

Second, I had no idea I could pass nothing for the initialization. Since I had always seen some version of int i = 0 I assumed it always had to be present. Alas, amount is already initialized previously so no need. Magical!

Lastly, recently Java allowed 1 line for loops to not need {}. This is a style preference, for my video I think I will still use the brackets because it feels right but it is nice to know there are options.

Java’s strongly typed language has been interesting to get used to. These few tips have been quite helpful in understanding it better.

Best,

Merl

read more

Wonderful Condition(al)s

Today I worked on finishing up Tic Tac Toe in Clojure. This included writing the main, computer, but most importantly the minimax file. They are all tied together, and the biggest piece like I mentioned was minimax.

Instead of getting into all of the details I wanted to highlight today’s favorite functionality of Clojure!

Drum roll please ……. That is the power of the let [] statement. Primarily the ability to have conditionals in the statement.

Let me demonstrate:

(let [[compare evaluate token] (if maximizing?
                                [> minimize "X"]
                                [< maximize "O"])
     new-game-board (ui/place-xo game-board action token)]

This snippet is part of a larger function, let me focus on my favorite parts.

First, the ability to place a conditional in this statement allows for many possibilities. Primarily it localizes the logic for all to see. I used this new skill while creating my main and computer files. I was stuck on a few problems and was able to fix them with this new tool. It also provides different pathways to represent what is happening with that boolean maximizing.

Secondly, is the vector that can be used depending on the boolean. Previously my code had multiple variations depending on whether we were maximizing or minimizing. The variables compare, evaluate, and token are assigned values in a single statement, improving clarity and readability This allows the code to be readable, avoids duplication, and is just concise.

Slowly I am learning and becoming more comfortable with Clojure.

Best,

Merl

read more

Static

Learning Java is interesting. There are a few things that seem natural and a few others that do not.

Natural to so far has been the for loop, while loop, and return for methods have been straightforward. I solved very elementary problems in C, I missed the i++ so it is nice to see it return. The while loops and the return are pretty standard, I believe it is just foreign in Clojure.

The strange thing so far has been compiling, and the fact that you need to announce every part of what you are making next. Take this line for example:

public static int addCoins(int amount, int coin, List<Integer> change){
  //stuff
}

I declare a method named addCoins, normal, with the following characteristics. Writing public allows it to be accessible from anywhere in the code. int returns an integer value. static can be called without creating an object of the class, this is the wildest one. For the parameters, the exact type needs to be specified immediately.

Static

All of that is new but the part that sticks out to me is the static, the ability to call the method without creating an instance is what I hoped I had when I wrote tic tac toe in the style of OOP.

As silly as it is, my biggest mistake writing in OOP was forgetting that I had to write an instance in order for my functions to work. Now with static one can call the method whenever you want. Public alone is like your typical method in python or other languages.

Public methods are like individual houses which are accessible from the street, offering unique functionalities specific to each inhabitant. Public static methods are like public libraries which are central hubs everyone can visit directly, offering shared utilities and resources independent of any particular residence.

Both are quite useful depending on their needs. Of course the houses can be quite necessary when your object needs object specific customization, and the libraries can be great when you need efficiency and shared functionality.

If either one is used incorrectly however coupling can happen in different ways. For the public methods objects can potentially become more dependent on each other’s methods, leading to less modular code. Static methods can still create tight coupling if relied upon heavily by other classes.

It is great to add another tool to the tool shed.

I have begun using it in my Coin Changer Kata.

Best,

Merl

read more

FIZZBUZZ Kata

It is a rewarding experience to create something and bring it out into the world. An additional thread to the world wide web.

In this project, I decided to revisit a previous idea, but with a twist. I wanted to infuse it with a bit of my own style, particularly in terms of sound. Growing up, hip hop was my sanctuary, my source of comfort. So, my goal was to incorporate some groovy, rhythmic beats that echo this personal connection.

As you watch this video, I hope it resonates with you in the same way it does with me. I hope it makes you feel the rhythm, the passion, and the joy that I felt while creating it.

read more

Hashmaps in Clojure

I have chosen the Coin Changer kata to perform in Java. It is fairly straightforward, however before I completed it in Java I decided to do it in Clojure. Maybe a wise decision, maybe not.

I wanted to complete it in Clojure to have a good idea as to how to solve it, but also to get better at Clojure.

I have found there is much to learn. Understatement of the year folks. I did work on something I have rarely done before. I think maybe for Advent of Code problems I have used Hashmaps, besides that no.

It was time to begin, I completed the problem initially using loops and returning a vector that meant nothing to others, just me. Don’t get me wrong, it made perfect sense after 1 sentence however I realize the code must read well regardless. There were also repetitions which of course should be avoided.

Hence we are back at hashmaps.

```clojure (def coins { `:quarter 25 :dime 10 :nickel 5 :penny 1})

read more

Music

I would say an underrated and not often discussed part of making videos is the music.

It is a garnish, but it can make or break your video. Like Maya Angelou said, “Music was my refuge.”

I have been looking at other people’s Kata’s and have seen what they have done. It seems like the standard is to just have music in the background. Very few have had verbal tutorials.

Maybe I’m thinking of this too much, but if I make it I want it to be good so I’ve been hyper fixated on the music.

Similar to Johnny Cash’s travels, I’ve been searching everywhere man to find the perfect song, also not to intrude on copyrights.

read more

For Loop?

One of my favorite tools in Python and C was the for loop. It was so simple, and straight forward. I was concerned about going into Clojure.

Luckily Clojure has something similar but more powerful.

read more

New Tricks in Clojure

I am getting more comfortable with Clojure. For some reason I prefer functions, so writing in a functional language is nice.

I am learning new tricks that clojure can do which is quite impressive. Following the practices of TDD, it is necessary to test everything. Before in Python when I wanted to test an input from the user, or even what a printing would produce I would give up because I couldn’t find a nice and easy way to do this.

Now in Clojure you can test anything. Even inputs and printed information.

Here I have a test for the function update-board that takes the board initially with a boolean, and returns a new board with an X or O in its place. Now the point of update board is that you get a user input to replace a number and place your X or O into the board. How do you test user input?

In Clojure read-line is the built-in function that asks for the input. with-redefs is the function that can allow us to test whether the input works or not. with-redefs lets you temporarily change the definitions of functions within a specific block of code, then automatically switches them back to their original forms when you’re done.

read more

Psuedo Code

Maybe I should title this pseudo-psuedo-code, it’s my blog though and I do what I want.

I’m surprised I haven’t written about this yet but I just wanted to mention how helpful pseudo code has been for me.

Previously I was working on a few euler problems. They can definitely be challenging especially if you are learning a new language. Since the syntax was new, and even the problems took some logic to do I decided to do something drastic.

I bought a 3 foot by 2 foot white board. I guess I wanted to be that guy that had the cool equations or what have you on the board behind me. And now I am!

I was initially unsure about my purchase, but then I sat down. I wrote a few concepts that were breaking down the problem, and then I wrote pseudo code to write an algorithm.

It wasn’t perfect but it was a start. The refactoring came later but the fact there was a path to a solution was great.

Point is I did something similar to write Tic Tac Toe in Clojure and let me present you with this example. It actually helped guide me in the necessary functions I needed to create in order to finish this project.

```clojure ;(defn game-loop ;loop [grid [1-9] ; X? true] ; ;ask for player to go ;update board ;print board ;see if game over ;change xo ;recur new grid

read more

Input?

Going from Python to Clojure has been difficult. I am certainly seeing benefits, I think my code is getting smaller. I mentioned threading, and functions/variables that exist for a tiny fraction of time.

read more

FIZZBUZZ

I just wanted to demonstrate a little of what I’ve learned. I’m sure you have done the problem fizzbuzz before.

In case you haven’t it is just counting however if the number is divisible by 3 you say “fizz” if the number is divisible by 5 you say “buzz” and if it is divisible by 3 and 5 you say “fizzbuzz “. Apparently, this is a kids game which I’m not sure would be very fun for children in general. I digress

This is a popular coding problem which should result in something like this. 1 2 "fizz" 4 "buzz" "fizz" 7 8 "fizz" "buzz" 11 "fizz" 13 14 "fizzbuzz". It sounds like being trapped in a tent with a few mosquitoes.

read more

Learning Languages

This will be short, I had a funny thought today. ‘Programming language’ is a perfect analogy for how to communicate with computers or other programmers.

If you have learned a new spoken language I am sure you can relate to learning a new programming language.

A few years ago I had the privilege to spend some months in Brazil. I was trying very hard to learn Portuguese, in about 3 weeks I was mixing Portuguese with Spanish and able to communicate slowly but effectively.

It got to the point where I could have everyday conversations very easily. Asking about where people were from, ordering food, making silly jokes. Things were going well, that is until you are in a group of native speakers.

When you are speaking one on one, the native speaker is able to match your simple words and communicate well. When native speakers are together they speak faster, use colloquialisms, speak cultural references so it is easy to be lost in their conversation. I was in my late 20s and I felt like a child again confused as to what the adults were talking about.

In a way this is true learning programming languages. Solving a problem you use simple but possibly more words or operations to get the same point across. I wrote some code that worked but when I received a little bit of help we were able to clean up the code into a much nicer, readable, and cleaner format.

The functionality was the same but the code was much better. Like learning spoken languages it may take a learner 8 simple words to get a point across, where those with more fluency it might take 3 words.

The only way to resolve this issue is to practice more and more, make more grammar errors till fluency naturally becomes the norm.

Best,

Merl

read more

All About the Primes

I know I have written about primes before but I have 2 new updates.

Initially when I was trying to solve for primes themselves I wrote an inefficient way to do this.

I had the number itself being divided by a range starting from 2 to itself. I don’t even want to write it up here, it was so slow. Thankfully it worked, however it got my answer in about 40 seconds.

Next I got a little bit of help and instead of dividing my possible prime number by every number between 2 and one less of the possible prime number I just divided it by the primes I had collected up to that point.

This was brilliant, of course this makes sense! That’s why prime factorization works because no matter what you will always get primes at the bottom. So you just need to check if it is divisible by primes only! This cut my solution by x10 and it was about 4 seconds!

(defn prime? [num primes]
 (not-any? #(divisible? num %) primes)
 )

I thought this was the end of it, thanks to Billy Mays there’s more! It is still built off of the primes logic, but we do not need to divide by every prime in the list.

We only have to divide by up to the square root of the possible prime itself. Why? Our possible prime is divisible by 2, then 2 is a prime that is smaller than the square root of our possible prime! Therefore the largest prime that is a quotient of our possible prime is the square root of our possible prime! Using this logic we cut down our runtime to 0.8 seconds!

```clojure (defn prime? [num primes] (let [primes<sqrt (filter #(<= % (Math/sqrt num)) primes)] (not-any? #(divisible? num %) primes<sqrt)))

read more

Bowling Game Kata

It is now my turn to join the greats in creating my own Bowling Game Kata video.

Originally, I was thinking of having a cool vibe and having an RnB track in the back playing while some lovely coding was happening.

Then I pondered on the wise words of old Bill Shakespeare “To thine own self be true” To be fair when people think of me I am sure hip hop is a quality that comes up.

I tried to create a hybrid version of what I had seen before, a mixture of explanation and vibes. A Vib-nation if you will.

All silliness aside, it is always a pleasure to be able to express yourself especially in forms you never would have thought you would have.

Without further adieu, here is the Kata.

read more

Let Me Live

Dramatic, I know. This is praise to those that allowed let to exist.

Since I know Python better, I still favor it but the small things like let in Clojure are turning me around.

In case you don’t know what let is in Clojure it is a temporary binding.It allows you to introduce temporary variables that are only valid within the body of let. This allows you to manage values or computation without affecting the surrounding code

For example:

(let [x 1]
  x)
;1

Here we say let x equal to 1, then we call x and out comes 1. If we were to call x outside of the let body, it would not work correctly.

Why do I enjoy this so much?

Because it is another useful tool for our projects. More tools allow the flexibility to get the job done well.

Here is an example I did today. It took me longer than I would like to admit to find this missing key to solve my problem. I wanted to find the sum of some numbers, and square them after I found the sum, here is my answer:

(defn sum-to-square [n]
  (let [sum (apply + (range (inc n)))]
    (square sum)))

As you can see sum was the addition of all of the numbers including n. Then we just squared it to find the solution we needed. I tried other ways to organize the operations, eventually this turned out to be the best.

Not identical but similar in having temporary bindings that exist in its body are loops. I won’t go into the weeds for loops just yet. However, having the ability to loop using temporary bindings is incredible.

I have used loops or lets for every Euler Project problem I have done. Both excellent tools that I am happy I learned how to use.

Best,

Merl

read more

Primes, but not Primes

Primes

I was working on a project Euler problem. It was finding the Largest Prime Factor of a very large number.

It was what I was working on before. I found 2 lessons from that one problem. See, I was trying to find all of the primes up to the number presented, and then select the largest one that was a factor.

As you can see, this was the cause to my problem in the previous blog where I was doing too much and killed the efficiency of the code.

The second lesson I received was, `The answer isn’t always the problem’. See I was trying to solve for primes. I was checking to see if numbers were prime, then I would add them to the list, and retrieve the largest one.

With a bit of help I was able to solve this without going out of my way to solve for primes, they would just pop out.

That blew my mind, I am trying to find the largest prime so therefore I should use primes right?

Not in this answer.

Let me break it down.


(loop [n n
      divisor 2]
 (cond
   (= n divisor) divisor
   (= 0 (mod n divisor)) (recur (/ n divisor) divisor)
   :else (recur n (inc divisor))))

Let’s begin with the 2nd conditional. It states that if the remainder of n and divisor is 0, then to use recursion. You recurse back into itself the quotient (n / divisor) and check to see if the quotient is divisible again by the divisor. It is brilliant! 90 /3 = 3 then 30/3 = 10

The third line means if none of the conditionals are met. Start over again but with the divisor increasing by 1.

The first line is great too because, if n and the divisor are equal then it is your largest prime factor.

It is much cleaner, and simpler than my previous solution. It made the efficiency very high too, solving it in less than a hundredth of a second. I don’t know how long my previous solution would have taken.

Until next time,

Merl

read more

Algorithms

Algorithms

I think I am learning a valuable lesson today. I was working on problem 3 of the project euler problems. Essentially I have to find the largest prime factors

Here is the situation, I was able to create a program to find the largest Prime-factors.

read more

Clojure Exposure

Clojure exposure

Welcome, I have been in the process of learning Clojure and man is it something.

I would say Python does have its quicks, but it felt easier to learn than Clojure. Maybe my current knowledge is biasing my opinion here, that’s just a feeling. To learn this new language I have been going through the Clojure Koans.

read more

OOP in Action

Benefits to classes refactoring Tic Tac Toe.

I will provide a file with many functions/methods and show you why it can be beneficial to use Object Oriented Programming.

Primarily it eliminates repetitive arguments, making it more readable and maintainable, as well as flexible and modular.

I will post a previous collection of functions that I used before refactoring. The whole code does not need to be analyzed, however you can look at the arguments that each function takes.

read more

Misunderstanding Classes

A misunderstanding can be quite the dilemma, although it is great for sitcoms.

The confusion came from not knowing how to use classes very well. I have written about them before, absolutely. Writing about something and doing something are very different things.

If you remember I wrote about the usefulness of classes in containing certain data that are similar. I believe the example that I used are the cars I have owned over the years. They both have a name, age, make and model. This way I can keep track of both of their characteristics.

Simple!

The difficulty comes from implementing classes where you need them. As in I wanted to rewrite Tic Tac Toe, but using classes instead of the functions I had written before. My mistake was not necessarily changing the functions to classes. That was simple.

```python

function

def calculate_rectangle_area(length, width): return length * width

class

class Rectangle: def init(self, length, width): self.length = length self.width = width

def calculate_area(self):
    return self.length * self.width
read more

Becoming more Productive

Let’s change it a little today focusing on focusing!

Sitting and working, not on my feet is a new experience for me. I have been teaching or TAing for the last 10 years so spending everyday sitting at a computer is new for me. Except in the summer when I would game non stop.

Needless to say it has been slightly challenging to stay completely on task.

Here are some tips I will follow to be even more productive.

Put my phone away.

I know this is an obvious one, but I mean put it further away and on silent. Having it anywhere near is a recipe for distraction.

Protecting my eyes.

I have noticed that my eyes have been a bit more tired. In fact, today in the mail, I just received my blue light glasses which help filter the blue light going towards my eyes. This will ease the strain on them and hopefully make my eyes less tired.

After eyes, let’s go to ears.

If not in a quiet space, or there is lots of noise nearby, find some good headphones to drown out the noise, hopefully noise canceling headphones.

read more

Inheritance and Polymorphism

Recently I was tasked with completing Advent of code problems with Object oriented programming. Since I am learning Python and Python is an OOP language this makes sense. I need to be well rounded so let’s do it. If we have any 90s RnB fans I would like to say I am down with OOP!

Why

I have been leaning functional programming which is incredibly useful but it is time to add a new toolset. Here are some general statements about when to use either functional or object oriented programming

# Object oriented programs are good when you have a FIXED SET OF OPERATIONS on things.
#
# Functional languages are good when you have a FIXED SET OF THINGS, and as your code evolves you primarily add new operations on those existing things.

Benefits to OOP

  1. Modularity for easier troubleshooting
  2. Reuse of code through inheritance
  3. Flexibility through polymorphism
  4. Effective problem solving( similar to TDD, breaking it down into solvable chunks)

For steps 1 and 4 they remind me a lot of Test Driven Development. I may be wrong in providing the comparison however, they both aim to make troubleshooting easier and providing smaller chunks. This is what TDD is all about. Modularity is a staple of TDD.

Now onto what was completely new to me was inheritance and polymorphism.

Inheritance

Of course with OOP we work with classes. These classes that are connected are very well named. We have parent classes and child classes. Child classes are classes that refer to the parent class.

Today I won’t be going into the gritty details however here is a representation:

Class Parent:
    {Body}
Class Child(Parent):
    {Body}

The child class inherits the methods and attributes from the parent class. This allows the code to be reusable, require less maintenance and provides strong model structure. Like families the child will carry some of the previous traits from the parents, but it can have it’s own unique traits as well.

Polymorphism

The first time I heard of this it brought me again to the 90s. There were these books called Animorphs, on the cover these books would have a kid transform into some kind of animal. I have 90s on the mind.

But really what is the world, the name makes it seem complicated, which it can be. There will be a brief description, don;t you worry.

Polymorphism means many forms.

Since we are talking about classes, I will provide 2 situations.

One is if you have multiple classes, don’t have inheritance, like Cars, Planes, and Boats. You can have classes to describe each one of those mechanical objects, and you can have a method called self.move in all of them. However they all move differently. Cars drive, planes fly, and boats sail.

Second example is with inheritance. Let’s say you have 2 classes: Cats and Lions. Well the parent class is Cats, and the child class is Lions. If you have a method in Cats called soundtheymake it would be “Meow”, the Lion class would inherit this. Obviously Lions don’t meow, therefore you could override this method and replace it with “I can’t wait to be King!”

Polymorphism means different things in different situations, of course.

Until next time,

Merl

read more

Tic Tac Toe 2

Let’s Talk about the finished product. An unbeatable tic tac toe game! I finished!

It’s definitely not perfect, however it is an incredibly more improved game than the first time I created it. First of all it is much cleaner. My first time, I must say the functions were decently named. However, the white space was not consistent and also my equations were not spaced properly x+= 2 compared to x += 2. I had fewer and larger functions, most of my functions did multiple things which made it tough to test, run, and debug.

Now my functions are smaller, properly named, and have a consistent clean look to them. Initially when I wanted to share my code, I would literally copy and paste, now I can send a link to Github, showing my progress.

Nice changes after rigorously learning about Clean Code and TDD for a month.

Here is some of my previous code when it came to running the AI, compared to my new code.

```python #first time while True: if letterXO == “o”: move() if game_over(): sys.exit()

read more

Minimax

Let’s talk about Minimax.

Before I get into what it is, I want to mention its usefulness in case anyone doesn’t know. Ok, I’m sure you know but it’s still my process.

Why!

During my first iteration of an Unbeatable Tic Tac Toe, I used many if statements for the logic behind the decision making of the computer. I did create a few helper functions to finish the game, and to block the opposition player if that was necessary. Outside of those, I still wrote hundreds of lines of code filled with if statements which are not ideal.

Luckily Tic Tac Toe doesn’t take much time to run, so I constantly tested it to make sure that it functioned the way I wanted it to. I had run it through every game iteration I could conceive, until it worked perfectly. As far as I know there are no holes in the logic, but there could be.

read more

Don't Cut Corners

Reasons for clean code from personal experience. Today was all about minimax. I can write about that later but I wanted to mention a misstep I took today.

I have been training on Clean Code principles and TDD.

Here are a few bullet points regarding Clean code:

# Readable and Understandable:
#
# Consistent Formatting:
#
# Descriptive Naming:
#
# Modular and Small Functions:
#
# Avoid Code Duplication:
#
# Refactor as Needed:
#
# Keep It Simple:

I missed the last bullet point. In my infinite wisdom I knew an outcome of the function would be a string. There were 3 possible strings the function would return and a None as well. These strings were long.

The strings were similar but had small differences. As I was making it a thought occurred which was to make another function in order to make things simpler. I continued.

When it came to test the function,I copied the 3 long whole strings as the answer. When it came to combining all of the functions into an Unbeatable AI there were 2 errors.

Errors

The first which was not mentioned was a python specific problem. I copied a list of lists(matrix) using copy() however that is only a shallow copy, this caused problems while using minimax. I had to use deepcopy() in order to make minmax work. This was a learning opportunity and not really a mistake. Here is a brief description below.

read more

Decision between the old and the new

It seems like creating the framework was incredibly useful.

It took me some time in the beginning to create the board as well as the input. The main reason I was playing with the colors and background on the board. It took a while to just decide on a simple pattern.

The next difficulty I faced was learning how to create simple tests and implement them to the functions I wanted to write in Tic Tac Toe. Especially the input functions where I was trying to get input from the user. It was challenging to find a way to pass the tests for such a thing.

Those were my first 2 days, and once I created the framework yesterday, today was a breeze when it came to coding. When it came to the winning and tie conditions, it was a simple process. To both test and code for.

The next step was one I was on the fence about. Do I refactor my old logic for the computer, with a million if statements. Here is an example:

```python def computer(): list[0] = “x”

read more

Creating the Path

Continuing Tic Tac Toe with TDD.

I am like the tortoise, slow and steady.

I have been making small steps but with those steps I have decided to plan ahead. Focusing on something new may make things clearer, is my hope.

Below I wrote the plan to create the project of Tic Tac Toe,


Make a board
Take user input
User input connects to board
User input for 2 players
Find the winning conditions
Create draw
The make X (first) computer
Then make O (second) computer

This is the plan to move forward but it does not push the code itself. It does help me thnk of the steps needed to complete this project. Make a board, take in user input, but afterwards create a 2 player game. After that 2 player game, create a computer that goes first then one that can go either first or second.

Now that I have this plan in place let us make a pseudo code that will match each of the 3 games mentioned above.

```python 2 player

While true Get user X input Change board check if game over change to O get user 2 input check if game over change to X repeat

read more

Tic Tac Toe TDD

I’ll keep this short since It is the beginning. The current project is to do Tic Tac Toe with TDD.

This seems very helpful because the first time I did TTT it was messy. Don’t get me wrong, I tried my best to make it and clean it up at that time. However, after even just a month of learning what I have written before I cringe at the thought of the previous TTT.

If you don’t cringe you don’t learn. It is nice to have the opportunity to create a new TTT with this new knowledge.

My problems so far are: how to chunk it, writing tests that store the information that the source code will use,and how to write multiple files that call each other.

These are hills that will turn into stepping stones.

Until next time,

Merl

read more

TDD Part 3

Back at it again. They say learning is not linear. While climbing up a mountain, sometimes you must go down a bit to get to the next peak.

To make it clear I do see the incredible value in TDD. Writing tests before writing the actual code can help ensure that your code works as intended, is maintainable, and free of bugs. All of this is useful in general, but especially so in large projects. However, when you’re new to TDD, you might face certain difficulties, such as writing small tests for specific problems.

The Problem: Finding Correct Box IDs

Let’s consider a problem where you need to find two box IDs that differ by exactly one character at the same position in both strings. Given a list of box IDs, you’re tasked with finding the correct box IDs with this unique property.

# Here's a sample list of box IDs:

# abcde
# fghij
# klmno
# pqrst
# fguij
# axcye
# wvxyz

In this example, the IDs “fghij” and “fguij” differ by exactly one character in the third position. To find the common letters between the two correct box IDs, we need to remove the differing character, which results in “fgij.”

Of course in the actual challenge it was a long list of long strings. I will not provide this in the blog.

Challenges

Before, I was practicing TDD on problems I had encountered and solved before. I would erase them and write the tests and the code after. Following TDD principles to the T(DD). In this situation I was attempting to, then I reverted to my old ways.

Identifying the first and second test cases is not too bad. Then using the sample list provided above is straightforward as well. It is the middle that is challenging. The middle is complex which makes it challenging to keep the tests simple and focused. Fortunately I was still able to solve the problem, but like Uncle Bob said, “You are not done when it works, you are done when it’s right.”

read more

Zen Buddhism and Agile

Now, I know what you’re thinking. How can 2 very different concepts like Buddhism and software be related? That’s really up to you to decide if there is a connection or not, but I can tell you what first came to mind when I was learning about agile.

I first thought of an ancient Zen parable known as

The Koan of the Two Monks and a Woman.

read more

Test Driven Development Part 2

I told you there would be more!

Today I focused on ERASING my previous Advent of Code solutions and using TDD to write the new code.

Test –> Code –> Refactor

That is what I was focusing on every step of the way. I started from the beginning, so this is the easiest and first ever Advent of Code problem.

read more

Test Driven Development Part 1

I’m starting with Part One, but I anticipate it’s the first of many, if not a few.

read more

Learning about Linked Lists

Learning about linked lists and arrays. I would have mentioned arrays above, but the title is almost an alliteration which makes me happy. This is another blog going over the fundamentals of coding.

While doing the Advent of code problems, lists have probably been my favorite tool to use so far. In fact I have used lists when I should not have been using them, that’s how much I like them. It is important to know how lists work as well as arrays. Without further adieu.

Arrays

What arrays and linked lists have in common is they both are data structures for storing a collection of items.

I like to think of arrays like a specially made spice rack that is labeled and fits all of the spices you have. Because it is so special you have it organized how you want and you know where every spice is located. When you are cooking and you need some cumin you just turn to it and grab what you need, super fast and easily. What if for your birthday someone gifts you a fancy new spice, like saffron. Your previous spice rack is no good now! You are going to have to get a new spice rack to fit your new collection. This demonstrates the good and bad of using arrays.

Arrays are a chunk of memory in which items are stored. Like the spice rack, the items should be all the same type. Ketchup has no business with the spices. Since everything is in the same place and labeled well it takes a very short time to be able to find what you are looking for. However, since it is a fixed space, adding or changing anything will be a cumbersome experience.

Arrays summed up: Stored in contiguous location Fixed in size Uses less space compared to linked lists Faster, elements can be accessed easily Changing the elements takes time

read more

Dictionaries (HashMaps), what are they?

Ok, no seriously what are they? Today I am not as confident on the whole concept but I will provide what I know now, and my questions at the end. Other languages call dictionaries Hashmaps, however since I am using python I will say dictionaries.

Yesterday I explained classes, and now I will show how dictionaries can be used. Maybe someday I’ll describe their similarities, pros and cons. But until then …

read more

Classes Explained

Since I first laid my eyes upon a Class I have felt intimidated. In the few occurrences that I did come across a Class in Python it has always looked complex and convoluted.

Here is a clear example of what is usually presented:

read more

Cleaning the Code

Today is the implementation of what I learned yesterday. Which was learning how to clean the code.

A quick recap on the problem the code solves below, there was a list of words and you have to identify whether the words are nice! To be nice the words need to fit 3 rules. Then you need to find how many nice words there are in the long list.

With that being said this I will provide my initial code below then the optimized one after. I will comment on what needs to be changed. All the logic is still the same, the new code is optimized.

The concept to solve the problem was to create 3 different booleans(one for each rule), create a loop(rule) for each boolean, and then count how many words fit all 3 booleans.

read more

Clean Code

I have since been watching the Fundamentals of Clean Code. I don’t think I am allowed to mention too much about them but I will mention something that hit me, which is available on the free youtube version: https://www.youtube.com/watch?v=Wibk0IfjfaI.

read more

New Method (For Me)

The “For Me” in the title carries a lot of weight. So far in my problem solving portion of my challenges I have been typing in the code editor Shout out to VS code!. What I mean is I have been mainly storing the ideas in my head then just typing out the code I think could work. The past 2 days I have been on problems where my mental storage has reached capacity. Today’s problem has been Advent of Code year 2017 Day 3 part 1.

The problem I faced:

Screenshot 2023-10-20 at 3 42 21 PM

```python

Here we have an infinite spinning numerical structure.

If given an integer, what are the minimum steps needed to read 1. The steps can only be up, down, left, or right.

#

For example:

#

Data from square 1 is carried 0 steps, since it’s the center.

Data from square 12 is carried 3 steps, such as: down, left, left.

Data from square 23 is carried only 2 steps: up twice.

Data from square 1024 must be carried 31 steps.

read more

New Tools

This is a tale regarding the effectiveness of new tools, along with it’s growing pains, and also a battle between my humility and ambition.

In yesterday’s blog I was talking about how tools like numpy can make life easier. I have completed days 1-5 in the year 2015 of the Advent of Code calendar. I have completed a few other day 1s and 2s from other years, but I’m trying to progress as much as possible in 2015. If you are unaware, I believe that as the days progress so does the difficulty.

I thought to myself, why not try to learn a new tool like numpy while doing a harder day.#genius As you might expect it was harder than you might expect.

Growing Pains

```python

For the last few days I have been consistently using a variation of this functions

def fetch_test_data(path): file = open(path, “r”) text = file.read() file.close() return text.split(“\n”)

text = list(fetch_test_data(‘../2015/day_6.txt’))

read more

Lessons From Yesterday

So far on my short journey I have come across three steps I need to take in order to pass an Advent of Code challenge. Of course over time I am sure I will have a more nuanced view and understanding. Until then, let’s keep things simple.

Step 1: Problem solving

In life if one is presented with a problem, one must solve it. There are many methods to do this, so just choose one! This was the lesson from yesterday. Of course, you can boil everything down to this. I am referring to specifically the image you create in your mind to create a path in which you could move forward in the problem.

read more

More is better?

When it comes to lines of code the idea is less is best. For this blog post I will follow that principle #meta.

Less is best, however sometimes more is better.

I am referring to the specific example that happened to me today. I have been focusing on limiting the lines of code in order to make the code simpler. Too much so. See I was playing around with RegEx I pronounce it like "rejects" in order to solve an Advent of Code problem.

I can do what I assume to be the very simple aspects of RegEx, however I was attempting something more complex. The easy examples are: re.search() re.match() re.split() re.findall(), I tried adding multiple conditions to re.findall() and thought I came across a solution. I knew I could have easily used more if statements to perfectly complete the task, however I was obsessed with limiting the lines of code.

My mistake was instead of choosing 8 lines of code that I knew would work, I chose 2 lines of code that I thought and hoped would work. Big no no! I assumed my program work and was dismayed and disheartened when Advent of Code let me know I was wrong. I spent too much time trying to figure out what was wrong, until I finally did.

I proceeded to write the 8 lines of code that worked, then I cleaned it up by turning those 8 lines into 3 lines. Mission Accomplished


#Lessons learned today:

#1. Write the code that works, then clean it up!

#2. Regex is a powerful tool that is incredibly complicated. Proceed with Caution
read more

Advent of Code: Day 2

If you are unaware of Advent of Code it is a set of programming challenges based around the theme of Christmas; these challenges have been released every December since 2015.

We are going straight to the beginning, 2015! Now you may say to yourself “Merl, if we are we starting at the beginnging where is Day 1?”. Great question, Day 1 was EZPZ as true gamers call it. There is no need to mention it here. Therefore we are starting at Day 2 of Advent of Code.

The premise is that presents need to be wrapped and ribboned by elves. They need to find the exact amount of both wrapping paper and ribbon to order. We solve this by using the dimensions of presents ex: 3x11x24, 13x5x19, 1x9x27, and these equations to come to a precise answer:

wrapping paper: 2*l*w + 2*w*h + 2*h*l
ribbon: the smallest perimeter of any one face and the cubic feet of volume of the present

example:
# A present with dimensions 2x3x4 requires 2*6 + 2*12 + 2*8 = 52 square feet of wrapping paper plus 6 square
#feet of slack, for a total of 58 square feet.

# A present with dimensions 2x3x4 requires 2+2+3+3 = 10 feet of ribbon to wrap the present
#plus 2*3*4 = 24 feet of ribbon for the bow, for a total of 34 feet.

To me the most difficult part of this challenge was importing and formatting the data that is given. I will go over my process here.

read more

Proxy Class

Today, we’re delving into the world of Python, specifically the Python Koans, where we come across a captivating challenge: creating a proxy class. The mission is clear; we want to build a versatile proxy object that can forward attribute calls to a target object and, interestingly, keep track of these attribute calls. Thank you google!

read more

Greed

Complex is better than complicated.

I learned a valuable lesson today.

Going through the Python Koans today I came across this problem to do. It was to create the dice game called “Greed” on Python. Here are the rules I was given:

# Greed is a dice game where you roll up to five dice to accumulate
# points.  The following "score" function will be used to calculate the
# score of a single roll of the dice.
#
# A greed roll is scored as follows:
#
# * A set of three ones is 1000 points
#
# * A set of three numbers (other than ones) is worth 100 times the
#   number. (e.g. three fives is 500 points).
#
# * A one (that is not part of a set of three) is worth 100 points.
#
# * A five (that is not part of a set of three) is worth 50 points.
#
# * Everything else is worth 0 points.
#
#
# Examples:
#
# score([1,1,1,5,1]) => 1150 points
# score([2,3,4,6,2]) => 0 points
# score([3,4,5,3,3]) => 350 points
# score([1,5,1,2,4]) => 250 points
#
# More scoring examples are given in the tests below:
#
# Your goal is to write the score method.

I sat back and began contemplating the process I would go about solving this problem. My philosophy is typically to get started as soon as possible; look for other paths to accomplish your goals as you’re working, and if a better solution arrises follow that route. This is a good principle if followed. As you will soon see, I sometimes become stubborn with accomplishing the goal rather than looking for more elegant solutions.

Besides the stubborness my downfall was thinking in very specific terms instead of general ones. I thought to provide an answer for every scenario, rather than read and analyze what is provided.

Specifically, I used *args to solve for the variability of the lists that could enter my function called score. So I tried to account for every combination possible for rolling 1, 3, 4, or 5 dice. No bueno!

def score(score_list):
      # Behold my monstar(yes it's a star)
    if score_list==[]:
        return 0

    a, *args = score_list
    value=0
    list = [a, *args]
    counter1 =0
    counter5 =0

    if len(list)==3:
        if a==args[0]==args[1]:
            if a ==1:
                value += 1000
                counter1 = -3
            else:
                value += a*100
                if a ==5:
                    counter5 = -3
    if len(list)==4:
        if a==args[0]==args[1] or a==args[0]==args[2] or a==args[1]==args[2]:
            if a ==1:
                value += 1000
                counter1 = -3
            else:
                value += a*100
                if a ==5:
                    counter5 = -3
        elif args[2]==args[0]==args[1]:
            if args[0] ==1:
                value += 1000
                counter1 = -3
            else:
                value += args[0]*100
                if args[0] ==5:
                    counter5 = -3
    if len(list) ==5:
        if a==args[2]==args[3] or a==args[2]==args[0] or a==args[2]==args[1] or a==args[3]==args[0] or a==args[3]==args[1] or a==args[0]==args[1]:
            if a ==1:
                value += 1000
                counter1 = -3

            else:
                value += a*100
                if a ==5:
                    counter5 = -3

        elif args[2]==args[3]==args[0] or args[2]==args[3]==args[1] or args[3]==args[0]==args[1] :
            if args[3] ==1:
                value = 1000
                counter1 = -3
            else:
                value = args[3]*100
                if args[3] ==5:
                    counter5 = -3
        elif args[2]==args[0]==args[1] :
            if args[2] ==1:
                value = 1000
                counter1 = -3
            else:
                value = args[2]*100
                if args[2] ==5:
                    counter5 = -3
    for i in list:
        if i==1:
            counter1 += 1
        if i==5:
            counter5 += 1
    if counter1>0:
        value += counter1*100
    if counter5>0:
        value += counter5*50
    return value

A quarter of the way through I was thinking that there was definitely a simpler and easier way to complete this. However I was in the “zone” and I saw a glimpse of the distant finish line. So I continued down the same path.

Just yesterday when I was writing my blog I wanted to mention some of my favorite tools I was learning in Python. List Comprehensions in particular are what really stood out to me in their usefulness. The ability for Python to ‘intelligently’ look through lists was quite impressive. I bookmarked it in my mind that I should come back to these when I had a future problem. FALSE!

After and unspecified amount of time I completed my creation above. My curiousity got the better of me, so I decided to look up a solution. This is what I found….

def score(dice):
    score = 0
    counts = [0] * 7  # Initialize counts for each dice face (1-6)

    for die in dice:
        counts[die] += 1

    # Calculate the score based on the counts of each dice face
    for face in range(1, 7):
        if counts[face] >= 3:
            if face == 1:
                score += 1000  # A set of three ones is 1000 points
            else:
                score += face * 100  # A set of three numbers (other than ones) is worth 100 times the number

        # Handle individual ones and fives
        if face == 1:
            score += (counts[face] % 3) * 100  # Each one (not part of a set of three) is worth 100 points
        elif face == 5:
            score += (counts[face] % 3) * 50  # Each five (not part of a set of three) is worth 50 points

    return score

Clearly this is much better. My code worked for the solutions it asked for, but no more. This code is more flexible, cleaner, and readable. As the Koan states, complex is better than complicated.

In the future when I hear that voice in my head about there being an easier way. I’m going to listen to it (I hope).

Best, Merl

read more

Python Koans

Python Koans

In order to master Python, I am doing the Python Koans!

The first portion so far has been relatively straight forward. Since it is my first language it is taking sometime to learn the ins and outs utilized by the language. I realize by completing this I will not know everything, nor have everything memorized, but I will learn a lot. Along with learning it will provide a great resource in the future if I have problems or questions regarding Python.

Exceptions and Errors

The section of koans that was giving me the most trouble today has been Exceptions and Errors cue the spooky music. You know how to get better at understanding something? Blog about it!

I’m used to seeing SyntaxErrors like so:

for i in range(5)
    print(i)
*Error message that comes out*
#for i in range(5)
                  ^
#SyntaxError: expected ':'

#Now we fix it and get what we want

for i in range(5):
    print(i)

0
1
2
3
4

In Python, Exceptions are typically raised in response to errors that prevent Python from executing the code, either due to impossibility or when you intentionally include exceptions to guide the program’s behavior according to your preferences.

```python #not possible try: result = 10 / 0 except ZeroDivisionError: print(“If you can divide by 0 there is a fields medal in your future. How you like them apples?”)

read more

Day 0

Oregon Coast

read more