Monday, March 1, 2021

Pandemic, Masks, and Friendliness

 We've been in the pandemic of COVID-19 for a while now.  Looks like it will still be months.  At the start, the U.S. government did not recommend masks and most people resisted, because it "impinged" on their personal freedoms.  The president at the beginning of the epidemic even stated that it was "undemocratic" to wear masks.  Huh?  Now, the government has finally see the light.  But, people still resist.  I liked what I friend told me about secondary reasons of why he wore a mask (paraphrased): "I don't want to be responsible for killing someone's grandparent."  For our health and the health of others, we should wear masks when among strangers.

My family wears masks when outside of our personal property (home, yard, cars and grandma's place.)  There are places where I think that it's okay not to wear a mask, but my young teen is terrified of infection.  Well, perhaps not terrified, but terribly concerned.  She freaks when I don't have a mask one and a stranger is within visual distance.  So, I begrudgingly wear one for her.

Friendliness

From reading stories from various sources, many people take offense at someone wearing a mask around them.  I disagree, since neither party knows what exposure the other has had.  But, in my opinion, there are things that we can do to help alleviate tensions.  For the purposes of this post, there is one primary thing to do and that is to be friendly.

I am an introvert.  I rarely engage strangers in conversation.  I have had social anxiety on many occasions.  I consider myself somewhat socially inept.  I an nervous and shy around strangers.  Painting a wonderful picture of myself, eh?

I make an effort to say 'hello' and 'how are you' to strangers while wearing a mask.  Usually, this is when we're out at a park.  Inside stores, I usually do not, but in the parking lot, I do.  I feel that it is important to reach out to strangers when wearing the mask.  The mask is a barrier between people.  It can cause anxiety in others.  I can smile but no one can see that, so I must speak.

In general, most people respond. Makes me feel good when I get a genuine smile.  As a side effect, I hope that my daughter picks up on this habit.  She is like me in many ways.  And I certainly want her to be better than me.  What normal parent doesn't want that for their child?

Monday, December 28, 2020

Strange Times

Yesterday was not a good day.  Another uncomfortable fight with the spouse.

I went to bed and formulated a plan to better myself.  I smiled as I lay there and was... happy.

I woke up this morning and did start putting some of the plan in action.  And I just plunged into darkness.  Depression and hopelessness sprung upon me.  I was running scenarios through my head of how to kill myself.

I posted a message on an online community to ask for help.  Not the same as therapy, but talking about it does help.  And I hope that someone can respond to help give me reasons to help me see that ending my life is not a good answer.

I still will try to implement my plan.  I will still put one foot in front of the other.  I still feel the weight of this life and I hate it.

Sunday, December 13, 2020

Improving

 Feeling less suicidal.

I've been plagued by suicidal thoughts for a very long time.  Perhaps a negative thought pattern that has become a habit.  These thoughts have been with me since I was, at least, 16.  I have clear memories of driving along the interstate and just thinking to drive myself into a bridge column.

I do need to get rid of that thought pattern.  It's not healthy.  In some ways, I'm not too worried about succumbing to the thoughts.  There are two things that stop me: fear and love.

Fear is the first.  I've held a razor to my wrist.  I was scared.  I put the barrel of a gun in my mouth.  I trembled with fear.  I had always hoped that it was a love of life that kept me from killing myself, and it was a cold revelation to know that it was fear.

Love is the second, more recent and more positive reason.  I have a child.  I love my child so much. To kill myself would be to abandon them.  I can't do that.  I can't hurt them that way.  I could write letters telling them that I love them with all my heart, but my suicide would still hurt them and possibly scare them.  I can't do that.

But I still need to break the habit of these thoughts.  It may be a bigger issue.  I have all kinds of thoughts running through my head.  Bad thoughts.  I have never acted on any of them, and really intend never to.  Why do I think such thoughts?  I'll have to dig into that.

Last thought to get down: a waking dream of slicing my wrist.

I had a day dream a long time ago (pre-marriage, pre-child) that I took a razor and sliced my vein from my wrist up towards my elbow.  The vein split open and there was emptiness.  Blackness.  Nothing.  The idea that it was just an empty void weighs on me.  Why the emptiness?  Is it how I feel about what is inside me?

Monday, November 30, 2020

Catharses or B.S.

 Probably do a little bit of wallowing in my own pity...  Play the small violin for me.

Still fighting depression and hopelessness.  Still praying every night asking the God (or whatever) helps the people around me.  I try to leave myself out, except to ask help in seeing my faults, so that I can have a chance to correct them.  I've felt a small amount of joy in my heart on two recent occasions.  My in-laws are beginning to walk every day (I'm a big believer in the health benefits of walking) and a former colleague from years ago posted a photo of her husband home from the hospital.  Both things I have prayed for and will continue doing so with a modification of improving their health.

I believe/want to believe in the divine, whatever that may be.  At the same time, I feel overwhelmed by nihilistic thoughts.

I have conflicts.  I want to have friends that want and enjoy my friendship, but at the same time, I just want to cease to exist and be forgotten. I read an article about the company, Recompose.  They compost the dead and return them to the soil.  The process completely breaks down teeth and bones, too.  Nothing left but soil.  There's a beauty to that, but also a little frightening.  I want that for myself.  Nothing left.

I am nobody.  I am but a grain of sand in the beach that is humanity.  I've left no mark.  I doubt that anyone would mourn for me.  I do hope that my daughter would.  If I disappeared, I wouldn't even leave a hole in anyone's life.  This is the pointlessness that I have been feeling and it feels smothering.

I feel angry, too.  When I was younger, my brother told all my neighbors that I was a devil worshipper.  I had placed a candle on top of an animal skull.  Wow.  Really dark there.  Years later, I took a new acquaintance to a club in Atlanta for some live music.  She told me that she might look weird on the outside, but that I was weird on the inside.  I don't understand people and have been called odd and strange all my life.  It does hurt.

It's hard to connect to people.  I'm in a marriage, but she barely tolerates me.  I blame both of us for our issues, and I am trying to change myself.  It can be hard, especially when I feel so disrespected.  It's a vicious cycle.  We get mad at each other and it goes around in circles.

Enough for now.  The pity pool has been drained some,

Wednesday, November 25, 2020

Yes Sir/No Sir Lesson

I loved my grandfather very much.  He did have his faults and I won't make excuses other than set context.  He grew up in a rural town in Virginia.  He had to quit grade school when his father died, so that he could support his mother and two siblings.  He was an uneducated, blue collar worked drifting from job to job, just trying to make a living.  He did factory work, carpentry, odd jobs, gas station attendant, etc.  And, sad to say, was racist.

The Lesson

My dad never taught my brother and I to say "yes, sir.", "no, sir", "yes, ma'am" and "no, ma'am."  He wanted us to mean it when we said it.  For myself, I started using it when I worked in retail.  There were people that I wouldn't say it to, because, well, they weren't nice.  Today, I will use that when talking with someone.  I believe in giving respect until the other person proves that they don't deserve it.

The lesson was given to my father by his father, and the effect was opposite of the original intention.  I do not recall all of the details and both men are gone from this life, so I cannot fact check.  I rely on my own faulty memory.  Read into the meaning, not the details, please.

My dad was a young boy, I think in middle school when this lesson took place.  A black gentleman came to their house (I do not recall why.)  My grandfather introduced the man to my dad, and my dad responded with "pleased to meet you, sir."  His dad corrected him:  "Oh, you don't have to 'sir' no n****r."

Learned

Right then, my dad decided that if he didn't have to 'sir' this gentleman, then he didn't have to 'sir' anyone.

That's why my dad didn't teach us to do that. I believe that my dad recognized the unfairness at that young age.  I am happy to think about that.  He realized that his father was wrong, though he wouldn't correct him for fear of harsh punishment.

I wish that I could reach out to that gentleman and apologize for the words of my grandfather.

Monday, November 9, 2020

Prayer and Chaos Magic

 I'm Nobody

First, let me say that I am a nobody in an ocean of billions of people.  I am not an expert on what this post is about.  I am writing from my perspective for myself, sharing my thoughts with whoever might read this in hopes that it is food for thought.  I am not trying to stir up controversy nor tell people what to do.  Please try to understand the ideas that I am trying to convey.

Prayer

Years ago, I read the book, The Healing Power of Prayer by Chester Tolson and Harold Koenig.  The ideas posited by the book were that prayer had a positive effect, especially healing when used in that way.  They did not push a religious agenda.  To them, the religion was less important than the prayer itself. It's a beautiful idea and one that I believe in.

I believe that prayer is important and I have begun to think about how I should be praying.  It's still a gray area for me.  I do not have a clear path, but I have begun formulating one. And I admit that I have only recently (May 2020) committed myself to praying consistently.

Chaos Magic

"Magic when talking about prayer?  What the heck?"

Please bear with me and I hope to make the connection clear.  I was listening to a podcast that covers a variety of topics.  The hosts did a couple of episodes on Chaos Magic.  Two of the hosts did delve into the practice and they had a few opinions.  I may not remember everything correctly, but I believe that I have the general concept down and I may have extrapolated.  The next paragraph is my take away and it is combined with many other thoughts and ideas from a variety of sources.

Most people are probably familiar with the concept of white and black magic.  White magic helps other people.  Help as in helping those in need.  Black magic is selfish and is usually used for personal gain and acquisition of power.  White magic doesn't exact a price from the caster.  Black magic always comes at a cost.  The idea has been with us since the beginning.  "What you sow, so shall you reap."  "What goes round, comes around."  The concept of karma, etc.  Basically, white magic equals selfless, black magic equals selfish.

How Should We Pray?

I really don't know, but here's what I am trying to do.  Keeping in mind white and black magic, I am trying to pray primarily for others in need. I believe that by doing so, I will have a positive effect on others and by focusing on others, I will improve myself. I hope that the practice will help me develop more empathy for my fellow humans in addition to helping them spiritually.

Was I Wrong?

Over a decade ago, I prayed hard for my brother to live.  I begged others to pray.  He died.  More recently, I prayed hard for my dad to recover from a surgery gone wrong.  He never did.  He lingered for five months before passing from this world.

Both times, I prayed because I didn't want to lose them.  I was thinking about myself.  I didn't want to lose my big brother.  I didn't want to lose my dad.  For my brother, it has been so long that I don't remember all the details.  I just remember the building dread as the brain tumor came back and his condition worsened until finally his brain just shut down from the pressure.  For my dad, I prayed every day (except one) that he would recover.  I wasn't ready to lose my dad.  I thought that he should have, at least, a decade more of life.  I didn't pray for what was best for him.  I prayed for what I wanted.

Trying

It's hard.  There are people close to me that I do pray for.  I am trying to phrase my thoughts and prayers to address their needs, not the outcome that I want or desire. I am trying to remove myself from the equation.  I am trying hard to pray for the good of the individual.  Mostly, I pray for those that have some kind of connection to me: co-worker, friend, relative, my child's teacher, etc.  I wrestle with that.  How should I pray for those that I do not have a connection, however tenuous?  Should I have a "blanket" prayer for groups in need?  A general prayer for anyone suffering?

And I do pray for myself, though not every day.  I do ask that I recognize what I am doing wrong and give me the insight on how to self-correct. And I make apologies for my failings whether it is forgetting someone on my mental prayer list or for getting frustrated over a silly domestic situation.

Wednesday, November 4, 2020

Follow Your Curiosity

 A dear friend sent me a link to a Ted Talk.  He had good timing, since I was/am in a depressed mental state.

https://www.ted.com/talks/elizabeth_gilbert_it_s_ok_to_feel_overwhelmed_here_s_what_to_do_next?language=en#t-1573508

Please give the video a watch.  The first story that she told was inspiring.  The other topics that she mentioned that hit home were "passion" and "purpose."  Every few years, I go through a period where I am just unhappy with myself (more than usual.)  I feel that I don't have a purpose and haven't found my passion or what I'm really good at.  I feel useless. I have no idea what I want to be when I grow up. And I'm in that state right now.  A little bit worse this this time due to extenuating circumstances which I will not address - not to the point of this post.

Elizabeth Gilbert wanted to replace "passion" and "purpose" with, in her words, a gentler word: curiosity.

Too Crowded

In my opinion, there are just too many people in this world for us all to have a "purpose."  Imagine a Norman Rockwell town.  There's a mechanic who takes care of everyone's cars.  The Milkman delivers fresh milk to everyone.  Hmm, probably too romantic.  Going back further, the blacksmith, the farmer, the tanner, the weaver, the cooper, etc.  There were times when all professions were important to the community.  A loss of one person would be felt throughout the town or village.

If I were to go missing today, I would only have an effect on my immediate family.  Otherwise, the community wouldn't even know that I was gone. My job is non-essential in regards to the good of humanity.  I don't see that changing in my life.  Just a fact.

Curiosity

That greatly appeals to me and fits with what I have done throughout my life with success.  I have had minor successes in my life from curiosity.  I have learned new things that helped me in my various jobs by just exploring because I was curious.  I've learned skills simply because I wanted to know how to do something.

I shouldn't worry about finding "my passion" any more.  And I should forget about a larger "purpose."  I do have a minor purpose.  I use "minor" in that it doesn't go beyond my family.  My greatest purpose right now is to ensure that my daughter is provided for, taking care of her physical and mental needs.

For my free time, I should explore my curiosity, and let it lead me wherever it goes.

  • Archery - make a range, and practice more.
  • Net Weaving - learn how to weave a net.  I made a needle and need to figure out how to knot it properly.
  • Basket Weaving? - can stiltgrass be used for this?
  • Constellations - relearn some basic constellations.  I am outside in the dark in the morning and night, and have enjoyed looking up at the night sky.  I would like to learn some basic navigation techniques based on stars, too.


Friday, October 30, 2020

Something Different

I started writing about my current existential crises which is probably a bout of depression.  Most of it was typed out and was morose.  I deleted it all.  I'm going a different direction with this post.  I was about to stop everything and play a video game.  That got me thinking.

Pre-Dad Days

A video game series that I loved is the Fallout series.  I played the heck out of Fallout and Fallout 2.  And I loved those games.  On a tangent before continuing, Arcanum: Steampunk and Magic was by the original Fallout team and the end story changed depending on your actions just like Fallout.

My standard MO was to play a good character.  Help people and get rid of the bad guys.  I don't think that I was pretending, but trying to do as if the situations were happening to me and how I think that I should act.  I think that my character had the reputation of "savior of the wasteland" or something like that.  Fact checking, it looks like "Champion" in Fallout 2.  

After completing the story line, I'd go back and play a demon from hell which meant my game character killed anyone and everyone in the game.  Bounty hunters would be after my character (random encounters.)  It was sort of fun, after being so good.

Dad Days

Fast-forward 10 years, I was married and had a one-year old. AND Fallout 3 came out!  Okay, I was much more excited about my baby, than the game, but was excited for the game.  No fear, baby took priority.  Game play was a rare luxury.

Back to my MO.  I played good characters.  I helped everyone.  I finished the game.  Also, on a tangent, as much as I loved the game, the ending was so terribly that it wiped out all my good feelings.  I was so mad.  Alright, back to the topic.

After completing the game, I went back and intended my character to be a total bastard.  My character shot one innocent NPC...

Oh my god...

The feeling was terrible.  This was just a video game.  It's not real.  Why did I feel so bad?  I just couldn't do it.  I turned off the game and tried to understand what happened.

Baby

My baby did it.  She changed me.  It's amazing to think that she could have such a profound effect on me.  Years later, I did read an article that researches discovered physiological changes in fathers.  Previously, the common belief was that changes only happened to mothers.  Biology is an amazing thing.

Wednesday, October 28, 2020

Last Day with My Dad

 The purpose is to write down the details before I forget too much.  It's been two weeks, since his passing.  I still have a lot to do to help my mom.

Day Before

My dad had been sent to the ICU from the rehab center, one day before he would have been released to go home.  My mom saw him there.  The doctor told her that he was dying.  They said that if they took him off life support, he would pass on then.  She wasn't prepared, so she asked to wait until the morning.  She secured permission for me to accompany here and to see him at 9:30 AM.

The thought of watching my father die within minutes was hard.  I would be there for him.  I would hold his hand and tell him how much I loved him.  

Last Day

I got a call at 7 AM.  It was one of the doctors.  He told me that my dad was awake, alert, and responding to questions.  He asked that my mom and I come as soon as we can, and that he would probably live for several days.  I was happy that he was alert, but it was an emotional punch to be told the day before that he'd die almost immediately after removing life support.

I want to say that we got to the hospital around 8 AM.  We signed in and headed up to his room.  He was indeed awake and alert.  I could see it in his eyes. I went to his right side and my mom was on his left.  We both said that we loved him.  My mom told him that he could leave this life and that it was selfish of her to ask him to stay.

He held my hand tight and looked at me with his bright blue eyes.  The doctor came in and said that they were going to remove the breathing tube and suggested that we step out.  My mom left the room.  I opted to stay.  They removed the tube and he seemed fine.  His breathing was good enough.

He had no voice, because his lungs and muscles were too weak to make a strong sound.  He could only mouth words.  He did say that he loved me.

The doctor came in and said that he wanted to talk to my mom and I in the hallway.  My mom goes.  I tell my dad and start to stand up.  He doesn't let go of my hand.  I smile at him and sit back down to be with him.  The doctor pops his head back in the door and I just tell him that my dad won't let go and I'm staying with him.

I don't remember everything that I told him.  I said that I loved him and that I hoped that he was proud of me.  And that I knew that I was a strange person that he had as a son.  It's hard to read lips, but I think that he was reassuring me that he was proud and loved me much.

Decision

My mom came back.  She said that the doctor had told her that his body was shutting down.  There was no chance for recovery.  The doctor came in and said that we could take him home or that he could stay at the hospital.  My mom didn't know what to do.  I said that we should take him home and she agreed.

This was around 9:30 AM.  I told my dad that we were taking him home and that I was leaving to get the house ready for him to come home.  He nodded and let go of my hand.  I said that I loved him and would see him soon.

Setting Up

I got to my parents' home and began getting it ready.  There is a room with sliding glass doors looking out into the woods.  I thought that facing the bed to those doors would be best.  I moved my dad's reclining chair and moved a sofa over to give enough room.  My mom's piano was close by and I hoped to get my daughter to play for her granddad.

I called my niece and said that she could come down at any time.  I let my wife and daughter know what was going on.  And I waited.

A truck arrived bearing the bed and oxygen tanks.  The delivery man and I set everything up and he walked me through the usage of the equipment.  My niece and her mother (my brother's widow) had arrived, and her mom helped make up the bed.  I think that my wife was there, too.  My daughter was still taking her virtual classes at our home.

And we waited.

Homecoming

The ambulance arrived close to 5:30 PM.  I almost regret not staying longer with my dad, but I did need to get everything ready.  The EMTs brought him up into the house and got him settled in the bed.  They told us that he was still bleeding from where an intravenous line had been removed from his right inner thigh.  

I walked the EMTs out.  They remarked on how beautiful our woods were.  I pointed out the hobbit holes that my dad had made down the bank from our house.  I told them to be safe and I went back inside.

My dad was pretty much gone.  Eyes closed.  Mouth open. Little to no response to us.  I still feel that he was still there on a subconscious level.

Goodbyes

His two granddaughters got to see him.  My niece is the oldest and she got right up to her grandpa and told him how much she loved him.  My daughter is young, so she was a little afraid.  Her mother and I didn't push.  Her mom probably understood better than I.  I did get her to play a piece on the piano.

I don't have a strong recollection of what happened.  I was frazzled and tried to do all that I could.  The hospice nurse came to "admit" him to home care.  We had to change the dressing on his thigh, so I helped the nurse.  My niece's mom helped prepare dinner, before she and her daughter went home.

On Our Own

My niece and her mom went home (an hour plus drive.)  My family and my mom ate dinner and then we cleaned up the dishes.  And my wife and daughter went home.  I asked my mom for his Kindle and found "The Hobbit" on it.  I thought that reading some to him was appropriate, since he named our road, Hobbitt Trail.  It was one of his favorite books, and I had read it and the trilogy many times.  I read most of the first chapter to him, until my voice was dry and cracking some.  I asked my mom for a hard cider, and I took a break.  She played a CD of his favorite classical music.  I should have noted the music, but didn't.

My mom checked his thigh and it was a bloody mess.  I cleaned him up and changed the bandage,  Even though he didn't react to any physical discomfort, I still tried to be as gentle as I could.  This was my dad. I tried cleaning his mouth that was still bloody from intubation.  I cleaned gently and he did close his mouth on the sponge.  Some of him was still there.

Go to Bed

I was at my dad's side again, holding his hand.  My mom told me to go to bed.  I told her that I'd stay, until she was ready to lie down.  She was going to sleep on the couch beside my dad.  I would be in the guest bedroom.

She went off and did whatever she needed to.  I have no idea.  I was just there holding my father's hand and talking to him.  I told him how proud that I was of my brother for how good a father he was to his stepson.  I told my dad that was because of him.  I told my father how he did have a good effect on people.  One neighbor said he was the toughest on the road (hard work, not fighter.)  Another neighbor remarked that the street wouldn't be the same without him.  One of his friends confided in me that he couldn't read a book that my dad had given him, because every time he picked it up, he thought of my dad and started crying.  My dad wasn't famous.  He didn't do great works, but he was a good person. His circle of influence might be small, but he left his mark on those people.

Last Breath

My mom came over and she was finally ready for bed.  She told me to go.  I was still holding his hand and she was standing at the top of his bed, stroking his hair.  He took a gulping breath and stop.  She asked if he was gone.  I said no and that he had been doing this.  He took a longer, gulping breath and was gone.

We were both in shock.  "Is he gone?"  I felt for breath.  I felt for heart beat.  I got their blood pressure cuff to check, then had to check on myself to make certain that it worked.  10:40 PM.

I called the hospice number and reported that he had gone.  The same nurse that checked him in came by.  They did the paperwork.  His official time of death was listed as 11:10 PM from renal failure.

The Last Goodbye

The men from the funeral home came to get him.  They wrapped my father in his sheets and transferred him to the stretcher.  I caressed his shrouded head one last time before they put a velvet cover over him.  I walked them outside and said thank you and to be safe.

Memorial Garden

My paternal grandfather, Papa*, had a garden when he first moved to the house that my dad built for him and my grandmother.  He grew flowers and vegetables.  After he passed on, my father took over.  There's a granite slab inscribed with "Paw Paw's Garden*."  We have plaques for my grandmothers and my brother.

There's a Japanese maple that I love there.  My dad built a stone circle around it.  I will place a memorial marker for him there.  This is my garden now.  I've never been a gardener, but now I will have to learn.  It will change some under my care, just like it changed when my dad took over from his.  I will seek to honor everyone that the garden has been dedicated to.

I love and miss you all.

 

* I always thought of the spelling "Papa" whereas my dad spelled it "Paw Paw."

Monday, October 26, 2020

It's Monday, but It's Okay

 One of the managers posted a picture with that saying.  It's another day and we're still here.  The morning was overcast, so I couldn't see any stars.  I pulled weeds in the dark, fed my ducks, and put the rest in the compost pile.  

Speaking of composting, I read an article about a startup, Recompose, in Seattle.  They seek to compost humans.  I have to admit that it appeals to me.  Personally, I'm against embalming and burial in a concrete vault.  Place me in the dirt and let me return to the Earth.  Recompose "sounds" romantic and beautiful.  Place your loved one in a bed of alfalfa and let them return to soil.  Don't dig deeper.  Let's just stay at that point.

Details to Dissuade

Not trying to get morbid, but still on the topic of death - losing my dad is still too fresh.  He had opted for cremation.  I went with my mother to the funeral home to sign all the papers and confirm what was to be done with his body.  In the paperwork, she had to sign a statement that she had read details of what happens during a cremation.  The director told us that it was a law in our state.  It came about when cremation was a new option and the funeral homes lobbied against it.  They got our state to pass a law requiring that the relatives of the deceased had to read the gruesome details of what cremation did to a body.  They did it to get people to choose the embalming route.

Transition

Still going through the grief process and the changes that come with losing a loved one.  I still think that he was robbed of life, but so many people in this world have had their lives cut short.  I need to remember that.  I still worry about my mother.  They had a great marriage and loved each other very much.  Now she is alone.  I can walk to her house, but we're still so far away.  There are hours that she must fill and the pandemic makes time feel longer.  I stopped by her house to check on a few things, and found her lying on the sofa.  I asked her if she were okay.  She said that she was tired.  I asked about gardening or cleaning.  She said 'no' and that she was just tired.  Grief weighs heavily upon her.


Saturday, October 24, 2020

Rambling

 Coffee

Sitting here, drinking my coffee.  Soon, I will go out and do my fowl chores (pun intended.).  Extra duties on Saturdays.  I have to turn my compost pile, in addition to cleaning the duck house and gathering greens for them.  Still, I enjoy the dark morning hours.  Too few minutes dedicated to staring up at the stars.

Angry Beaver

When my niece was younger, she watched a show called Two Angry Beavers Even being, 24 years older than her, I had watched that show some, too.  What's my point?  I have an anger issue.  Not serious enough for anyone to fear for their life, but bad enough to make my marriage difficult.  When I talked to my brother (RIP 2009) about my marital issues, he told me not to be an angry beaver.

Help

I still need help.  I feel that I have legitimate complaints about my relationship, but at the same time, there are things that I should be doing to correct issues in myself.  I am frustrated.  I am angry.  I am upset that I have a bad relationship, especially since it had been good at one time.  I feel that life piling more onto my shoulders.  I have two households to maintain and strife between them (parent and spouse.)

I do need help.  Two options that I am inclined towards are Stoicism and meditation.  As a philosophy, Stoicism appeals to me.  I think that I have begun to live some of its tenets, but my dissatisfaction disrupts.  And meditation... I think that it would be good, but, dang, it is hard.  It's so easy to stop doing it as with many other activities that I have done in the past.

Lost

I am lost.  I am certain that there are millions like me out there.  We're all lost.  I am certainly nothing special.  Not a snowflake or unicorn.  Just an asshole wishing for a better life than he deserves.


Friday, October 23, 2020

Back to Career Talk

 Toxic Environment Partially Detoxed

At my previous company, I was a lead developer.  I believe that I did good there.  I worked on making the environment less toxic.  There was a "me me me" attitude when I first got there.  It was shocking.  I did little things to help.  I was certainly not skilled in this area. A simple example of what I did was to pass out our lunches.  The company bought our lunch and we made our individual orders from the restaurant chosen for the day.  I'd distribute those.  Before that, people would just barge up to the desk, toss aside other's food and grabbed theirs.  In a few months, most people were passing out food to their coworkers.  There were still issues, but it was much more collaborative than when I first started.  It wasn't all me, but I think that I helped move us in a better direction.

Insulted

I had to undertake the daunting task of rewriting the company's public website.  I made suggestions on what I believed to be the best course of action based on technical debt avoidance.  The suggestions were ignored.  The head of IT hired a contracting group to upgrade the CMS instead of doing a rewrite on the latest.  It was not pretty.  I don't know the details, but I feel like the contracting group quit.  We had an upgraded CMS, but with all the technical debt and mess of the old one.

Long story short, head of IT made my life a living hell.  He constantly changed his mind.  He berated our work.  He fired the two people working for me, so the project was left to me alone.  The last straw was when I was walking by the lunch room to hear him tell the president of the company that the web team wasn't doing their job and that's why the project was behind.  I was furious.  I was the only one left on the web team, and my days were filled with changes, reversals, tweaks, and all sorts of madness courtesy of the head of IT.

Quitting

I told my boss that I would be quitting once I found a new job.  I told him why.  He fussed at the head of IT and was probably the only person in the company that could get away with that without being fired (we lost our PM due to her disagreeing with the head of IT.)

It took about three months of searching, before I found the right job. And that's where I'll end this post.

Wednesday, October 21, 2020

Another Day

It would be good for me to post more on this blog.  I really don't expect anyone to read this.  It's out there on the web, but it is mainly for me.

Stars

I have ducks and quails.  Not too many, just eight ducks and six quails.  Every morning, I go out around 6:30 AM to let them out of their houses.  I take my wagon and head down my driveway to the family memorial garden.  Walking down my driveway, I look up at the stars.  I really only recognize the Big Dipper.  May be I will learn more constellations.  Looking up at the stars fills me with awe and makes me fill so insignificant at the same time.  I'm lucky that I live somewhere where I can see the stars and am not too affected by light pollution.

It's a lovely walk, even though there are days that I just don't want to do it anymore.  I get to the garden and start pulling weeds.  I get a wagon-full to feed my ducks some fresh greens.

I walk back over, feed them, and start cleaning their house.

At night, I go out around 7:45 PM to get their feed and water set up, then put them up for the night.  Sometimes, I sit by the quail house and look up at those stars again.  Such beautiful lights in the sky.


Tuesday, October 20, 2020

Long Time

Hopefully, I will get back to posting here.  Basically, a post for myself.  May be a sanity check, cathartic writing or still hoping to fix myself.

My dad is dead.  He had heart surgery May 14th, 2020 to replace a leaky valve.  He was rated in the top 99% for survivability.  Surgery went well, but as they were closing up, things went wrong.  In short, the aorta shredded and they fought to save him (40%).  They did.  Then he had one complication after another:  kidney failure, fungal lung infection, steel sutures rejected, bone infection, bacterial lung infection.  He languished for five months in different hospitals with them all telling us that he was getting better.  He was a strong, healthy man before surgery, and they completely broke him.  We did finally get him home for one day.  My mother caressed his head, and I held his hand as he took his last breath.  His grand daughters and daughter-in-laws got to say their goodbyes.

Worse things have happened to better people.

I do think that my dad was a good person.  Not perfect, but good.  As sad as I am, I do know that there is still suffering out in the world, and bad things do happen.

"I would not do anything to hurt my family.  I am spent.  I have lost my glasses, my voice, Hope."

I found the above in his email drafts (I did correct the typos).  It was to go to me and was dated June 27th.  I wish that he would have sent it.

If anything positive has come from this, is that I pray every night for the people that I know that need it (coworkers, friends, relatives, etc.)  I can't say that I am religious, but the book, The Healing Power of Pray had an impact on me.  It doesn't matter who you pray to (whatever fits your beliefs), but know that the prayers do have an effect.  Yes, my father is still dead, but that is for another discussion.  My brother's dead, too. And many other relatives have gone, some naturally, some tragically.  But I still believe.

Friday, September 4, 2015

Career Path Ups and Downs

I've been a working as web developer since 2000, did professional web design starting in 1998, and messed around with websites circa 1996.  Even though I've been around for quite a while, I haven't exactly been a rock star or code ninja, though I did have my moments.  The bulk of my experience is working for smaller companies where I had to do most everything (server setup, database creation and management, and web - both design and development.)  Currently, I am a lead senior .NET developer in a support role.

Note:  Originally, I intended to write about becoming a lead before I was ready, but it morphed into a brief history of my career in computing.  Perhaps, it will be of interest.

Way Back

In the beginning, there was the Commodore 64 and life was good.  Seriously, I got my first computer when I was 12.  It was fun programming on it, but I was no hacker.  I made a color-based alarm that flashed all colors to wake me up in the mornings.  I made a program to help me create characters for different role-playing games (pen and paper variety).  Otherwise, I remember playing games, and writing papers for school on it.

In middle school, I "believe" that I programmed on an Apple II.  Can't swear to it.  I did some simple graphics programming, and even took a course.  There was an amazing guy that was more the hacker, and I did learn some from him.  Sadly, he didn't survive his teens (reckless driving.)  Back to me, I liked computers a lot, but I didn't LOVE them.

Good Beginnings

I got my first taste of the web sometime around 1995/1996.  I'm not certain of the exact date, but I was working as a library assistant for a university library.  I found the web, and I was excited.  It was a whole new world.  I found so much cool information, and I learned that I could make my own pages!  It was simply astounding that I could use notepad to write HTML and see it in the browser.  I still remember when I saw the colors change on hyperlinks when you moved your mouse over them.  Wow!  I dug in, and copied the JavaScript code, so I could learn and do the same.

A Break and a Bump

In 1998, I actually got a job as a web designer.  My personal web page impressed them.  That was a great moment, then I had to work.  I affectionately refer to my work as fast-food web design.  It was work for an online directory, and I had to crank out three page sites for their customers.  The first tool that I had to use was dreadful.  It was all drag-and-drop, and here I was used to hand-coding everything.  It got better when we switched to Dreamweaver.

I did that for a year, and then was moved into a position to manage four web designers.  That was a drag.  I enjoyed working with my designers, but management was a mini-death.  I didn't have time to make anything and I was bored.

Excited Again

Another opportunity arose.  A company wanted a web designer that they could teach to program.  I jumped at the opportunity.  My training?  It consist of them pointing at a computer and telling me to get to work.  I didn't have the benefit of a mentor or even skilled coworkers.  I had to discover everything on my own.  The first year was a little rough as I learned ASP development using VBscript, but it was exciting!

I learned a lot, experimented a lot, and made major improvements to the code base.  I was becoming more skilled as a developer, and cared about my work.

501 Developer

The downside?  There were plenty.  I was too isolated from the development community, and I fear that this has stuck with me even now.  The sites that I worked on changed from greenfield development to legacy projects.  I was being left behind as technology moved forward.  My company resisted the .NET framework, because classic ASP still worked for them.

Why didn't I leave?  I had several reasons for not leaving.  The biggest reason:  I worked in the same office as my older brother.  Other reasons:  I made good money, and the office was 11 miles from my home.  Talk about a great commute.  But I was becoming a 501 developer, and losing my overall excitement.  I still enjoyed experimenting, but I was no longer passionate.

A Kick When I was Down

Sadly, my brother passed away from a brain tumor.  It was a gut-wrenching experience that threatened to break me.  My young daughter kept me grounded, and gave me more support than she will ever realize.  A little less than two years later, the company laid me off.

I got lucky and landed a contract job within two days of being officially unemployed.  Only it wasn't so fortuitous.  The job was maintaining and extending a horrid code base laden with so much spaghetti code that it made me want to run for the hills screaming.  The contract ended early, since the lead wanted fast development without any eye to maintainability, whereas my approach was slower but more maintainable.  Even though they were unhappy with my speed, they freely admitted that I was skilled and knew what I was doing.

From that contract job, I saw the writing on the wall that I should never develop classic ASP again.  Now, I did like it, but putting it on IIS 6 was an issue.  The technology worked, but the support was diminishing and that would make it much harder to support these sites as technology marched on.

Excited Again and Then...

I managed to land a .NET web developer job, but at a 20% pay decrease.  In the long run, I thought that it was worth it.  And I was right.  It started off as a wonderful place.  I got some excitement back, and was able to do more in the .NET space, and showcase my JavaScript Client-Side skills.  There were still issues.  The environment started to shift from the attitude of doing everything in-house to in-house bad, COTS (Commercial Off The Shelf) software good!  I was beginning to wonder why they were employing me.

A Career

I still feel like I haven't decided what I want to be when I grow up, but I should take a programming career seriously.  Amazing, isn't it?  I've been working over a decade in development, and I just now decide that maybe this is my career.

New Goals and D'Oh!

I started a new job with the purpose of becoming a better developer, and really start taking my career seriously.  I told my manager about my goal of sharpening my skills, so that I would be worthy of the title of lead senior developer.  Well, son of a gun... they hired another developer, waved a magic wand, and made me a lead.

What's the deal with the d'oh?  Isn't this what I wanted?  Honestly, I don't think that I'm skilled enough yet to be a lead.  This will definitely be on-the-job training.  I've been successful with mentoring junior developers in the past, but a lead is different.  Juniors come to the mentor for help and to learn.  A lead must, well, take the lead.  I can no longer be heads-down with my code and oblivious of others.  I need to be more aware of what my team mates are doing, and I need to check on their work when necessary, and guide them as needed.

So Far

It sucks.  I have a lot to learn, but I think that it will be good for me.  I have no desire to move into management, but I will need to develop a subset of managerial skills.  I need to improve my own programming skills, and be confident in my knowledge, but not arrogant.

Saturday, June 6, 2015

Writing Bad Code On Purpose

In my current position, I am a .NET Developer that is part of a support team.  I'm responsible for supporting brownfield applications used by the business.  The applications range from Windows Forms to Web Forms to ASP.NET MVC applications, and I even have a CMS to support for the company's public-facing website.  Soon, I'll have some WPF applications and web services handed off to me from the New Development team.

Now, I love greenfield development (who doesn't?), but this is a good opportunity for me to work on my debugging skills and my software archaeology skills.  I even joked that my title should be changed to Software Archaeologist, since I am having to delve into poorly documented legacy applications and carefully sift through layers of code to understand what the original programmers were trying to accomplish.

I like writing good code.

And I do know that I can always improve.  When I need to work on an application, I do my best to improve the code, and leave it in better shape than when I found it.  Unfortunately, there are times when I can't and that truly pains me.

When should I be "okay" with writing bad code?  

Ideally, never.  However, I came to a realization or simply confronted an ugly reality:  There are applications that I shouldn't clean up the code (except for bug fixes) and I can't take the time to write what I consider to be good code.  Though I must state that what code I write, however bad, should be as bug-free as possible or what's the point?

How did I come to this awful conclusion?  

I needed to update a point-of-sales Windows Form application.  I scrolled through line after line of hard-coded values, and was constantly seeing other instances of bad code smell spread throughout the program.  Some of these hard-coded values were rules for the application (i.e. if store has this rule, then allow this function.)  Changing any of these required a rebuild and deployment of the application.  Why weren't these types of values placed in a config file that could be updated via a text editor and deployed?  How in the world would we know what a rule number meant if we lost the database?  I could spend months on fixing all the issues that I considered to be wrong.

The Application has an expiration date.

That fact changed everything - I still didn't like it.  I can't spend valuable development time correcting and changing code that I believe needs attention.  I can't take the time to write code that is going to be maintainable for years to come.  The application isn't going to live that long.  A newer version is coming down the pipeline.

I still struggle.

I do my best to avoid writing bad code as much as possible.  I keep maintainability in mind when I am writing code.  For those legacy applications that have a short lifespan, I write code that is "good enough" to correct the bug or add the required functionality.  And I definitely aim to do no harm when I have to write that less-than-ideal code.


Wednesday, November 19, 2014

Programmer, Thou Art a Fool

I just got burned.

My fault.  My responsibility.

The Lesson

I'm skipping right to the lesson that I learned from today:  Don't assume that you know what a control does.  Oh, and test thoroughly.

The Background

Let me give you some of the back story.  I was tasked with creating an internal website to help distribute some gift cards.  The site was meant to replace reams of paper that had been used in the past.  The requirements were simple: have an employee digitally "sign" something stating that they did indeed receive their gift card.

I had a nice, complicated solution that gave everyone the "personalized" feel that HR was desiring.  Due to other complications out of my control, I had to scale back to a much simpler site that simply asked for the person's employee number and last four digits of their SSN.  The work I did on the more complicated site was not a loss.  It did show us some issues with our Active Directory data and uncovered an error with a system that HR used.

I tested the site with four or five of my coworkers, and it worked as expected.  I presented it to HR, and they absolutely loved it.  The design was elegant and captured the holiday spirit.

The Launch

The day before the launch, HR gave me a new set of data.  I cleaned it up and got it into my database.  Everything was looking good.  We posted the link on HR's internal website, and they prepared packets for all the directors (60+ directors distributing to 2400+ employees.)

On the day of the launch, I had to attend a meeting.  When I got back to my desk, I had quite a few telephone calls, emails, and help tickets concerning the website. Oh, no, I thought.

The Problem

The error reports were from people whom had leading zeroes in either their employee numbers or the last-four digits of their SSN.  It didn't make any sense to me.  The range control was returning false when checking the value for validity.  It would not allow them to "sign" for their cards.

Why are the values being rejected?

What I Had Done

I had to make the site using ASP.NET Web Forms.  I would have preferred MVC, but I had a constraint that made me feel that web forms was the better way to go.  On the page, I used two validation controls per field.  I used the Required Field Validator and the Range Validator controls.  Both fields, employee number and last-four of SSN, were both numbers, so range validator made sense to me.  Both had the minimum value of 1 and the maximum value were 99999 and 9999 respectively.  Here's a sample tag:

<asp:RangeValidator ID="rvEmployeeNumber" runat="server" ControlToValidate="txtEmployeeNumber" Display="Dynamic" Text="*Must be Numeric" MinimumValue="1" MaximumValue="99999"></asp:RangeValidator>

Investigation

I pulled up the documentation (http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.rangevalidator(v=vs.100).aspx) and reviewed it.  I assumed* that the validation control would default to a number, since it is a range after all.  I located the type property, and saw that there were five types: String, Integer, Double, Date, and Currency.

*Never assume.

I used a test page to add five controls with a range validator of each type.  I didn't think that I needed to test a control with the type of Date, but it's best to check.  The three number types gave no issue.  The Date range validator broke as I expected, since the minimum and maximum values weren't even date values.  The String range validator recreated the error condition on the site.  We have a winner.

So, the default type for the Range Validator control is String.  To confirm, I removed the Type attribute, and output the default value to a label on the page.  The default type was, indeed, String.  D'oh!

What I Should Have Done

Since the employee number and the last four digits of the SSN aren't numbers meant to use with calculations, it does make sense to treat them as strings.  After all, I do store them as strings in the database for that very reason.

A more correct way to use the Range Validation control would have been this way:

 <asp:RangeValidator ID="rvEmployeeNumber" runat="server" ControlToValidate="txtEmployeeNumber" Display="Dynamic" Text="*Must be Numeric" Type="String" MinimumValue="00001" MaximumValue="99999"></asp:RangeValidator>

Do:

  • Set the Type attribute.  Even though the default is String, set it, so that others will know that you meant to use the type of String.
  • Add the leading zeroes.
    • Remember, it's a string, not a number.

I'm not certain what my biggest mistake was.  I thought of the input as a number, and gave no thought to the leading zeroes.  If I had written the client-side validation code, I would have used a regular expression that made certain that it was x characters in length and that each character was a digit (0 - 9).  To be truly thorough, I should have run all the employee numbers through the validation logic.

The Brightside

Even with that snafu, the feedback has been very positive, though I am still sore from my mistake.  It has made the card distribution go smoother, and it will help the Accounting department.  Hopefully, I have reduced paper waste, and cut down the time spent by HR and Accounting.

I don't consider myself arrogant, but I can be rather prideful of my code.  This was a good lesson in humility, and I did not enjoy it...

Friday, October 3, 2014

ASP.NET MVC: How to add a model with a dynamic list of child models?

Background

Okay, I admit that the title needs some work.  Let me slide on that.

I like visiting stackoverflow, and I have found it to be a great resource to help me solve the problems that I have encountered.  I believe strongly in doing research first for all my questions, and I usually find answers to them.  However, I have only posted two questions on the site.  Those earned me a tumbleweeds badge.  I ended up removing them, because I felt that they were too specific to a contract job that has come and gone.

But I digress.  I came across a question that interested me.  I like ASP.NET MVC a lot, but I've still got a lot to learn about it, so I didn't feel that I could answer the question outright.  However, I wanted to figure out how to answer it, and I've got multiple ideas.

Posting: Create record using Model List

In a nutshell, the poster wanted to have a view to create a new invoice and add a dynamic number of line items to the invoice all on one page.  I'm not going to address anything else.

Set Up

I pulled up my Sandbox project, added the two models (with some simplification), and added a controller with views.  I let Visual Studio do most of the work, since I wanted to spend time on the problem.

I'm using Visual Studio Premium 2013, and my web project is targeting .NET Framework 4.5.  I'm using Entity Framework and Code-First.

My Attempt

My very first reaction was to open up the Create,cshtml view and modify it, so that it would have a place to add the line items for the invoice, and add the functionality to dynamically add new line items in the client-side.  I thought that a table would be appropriate for the line items:

HTML:
    <table id="invoiceDetails" data-count="1">
        <thead>
            <tr>
                <th>Item Name</th><th>Quantity</th><th>Rate/Hour</th>
            </tr>
        </thead>
        <tbody id="invoiceDetails-Rows">
            <tr>
                <td><input type="text" name="Name" id="Name" /></td>
                <td><input type="number" name="Quantity" id="Quantity" /></td>
                <td><input type="number" name="Price" id="Price" /></td>
            </tr>
        </tbody>
        <tfoot>
            <tr>
                <td colspan="3">
                    <input type="button" id="add-row" value="Add Another Item Row" />
                </td>
            </tr>
        </tfoot>
    </table>

I contemplated automatically adding a new table row when the user clicks on any of the line item text boxes, but decided that I didn't want empty fields to be posted.

JavaScript:
$(document).ready(function () {
    $("#add-row").click(function () {
        var count = $("#invoiceDetails").attr("data-count");
        $("#invoiceDetails-Rows").append(createTableRow(count));
        $("#invoiceDetails").attr("data-count", count++); // increment the count
    });
});

function createTableRow(num) {
    var oTR = document.createElement("tr");
    var oTD = document.createElement("td");
    //<td><input type="text" name="Name" id="Name" /></td>
    var oTB = document.createElement("input");
    oTB.name = "Name"; oTB.id = "Name" + num;
    oTB.type = "text";
    oTD.appendChild(oTB);
    oTR.appendChild(oTD);
    //<td><input type="number" name="Quantity" id="Quantity" /></td>
    oTD = document.createElement("td");
    oTB = document.createElement("input");
    oTB.name = "Quantity"; oTB.id = "Quantity" + num;
    oTB.type = "number";
    oTD.appendChild(oTB);
    oTR.appendChild(oTD);
    //<td><input type="number" name="Price" id="Price" /></td>
    oTD = document.createElement("td");
    oTB = document.createElement("input");
    oTB.name = "Price"; oTB.id = "Price" + num;
    oTB.type = "number";
    oTD.appendChild(oTB);
    oTR.appendChild(oTD);

    return oTR;
}

The JavaScript could be improved, but it will work for now.  I kept the Name attribute of the new input fields the same as the original row, and only changed the Id attribute to append a number, hence keeping the Id attribute unique.  By keeping the Name attribute the same, the page will post back a comma-delimited string.  Example: Name="Labor,Parts,etc."

I tested the Create page, and the client-side worked as I wanted - after a minor correction.

Next, I moved on to the controller.

Initial Controller:
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create([Bind(Include = "InvoiceId,ClientId,Amount,CreationDate,DueDate,InvoiceNotes")] Invoice invoice)
    {
        if (ModelState.IsValid)
        {
            db.Invoices.Add(invoice);
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        return View(invoice);
    }

It's your standard fare, nothing fancy.  I would like for it to use the power of model binding, since that means less code on my part and I'm leveraging the framework.

First attempt: Would a list of InvoiceDetails work?  I changed the method's signature to:
public ActionResult Create(
    [Bind(Include = "InvoiceId,ClientId,Amount,CreationDate,DueDate,InvoiceNotes")] Invoice invoice,
    [Bind(Include = "Name,Quantity,Price")] List<InvoiceDetail> invoiceDetails)
Result: invoiceDetails is null.  Dang it.

Second attempt: Can I get it to work for one line item?
public ActionResult Create(
    [Bind(Include = "InvoiceId,ClientId,Amount,CreationDate,DueDate,InvoiceNotes")] Invoice invoice,
    [Bind(Include = "Name,Quantity,Price")] invoiceDetail)
Result: This works.

Third attempt:  Hey!  What about params?  I can use that to pass in an unknown array of parameters to a method.  Would it work in this case?  Go for it!
public ActionResult Create(
    [Bind(Include = "InvoiceId,ClientId,Amount,CreationDate,DueDate,InvoiceNotes")] Invoice invoice,
    [Bind(Include = "Name,Quantity,Price")] params InvoiceDetail[] invoiceDetails)
Result: No compile errors which is always good.  Same result as the list. The variable is null.

What to do now?  As I mentioned before, if form fields share the same name, the values will be passed to the server as a comma-delimited string.  Let's see what I can do with that.  I commented out my previous changes to the method signature, so that we're back to the initial controller signature.  I've added the code to add the line items and a method to process the line items passed from the web page.

Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(
    [Bind(Include = "InvoiceId,ClientId,Amount,CreationDate,DueDate,InvoiceNotes")] Invoice invoice
)
{
    if (ModelState.IsValid)
    {
        db.Invoices.Add(invoice);
        List<InvoiceDetail> invoiceDetails = new List<InvoiceDetail>(); 
        if (Request["Name"] != null && Request["Quantity"] != null && Request["Price"] != null)
        {
            invoiceDetails = GetInvoiceDetails(Request["Name"], 
                Request["Quantity"], Request["Price"]);
        }
        if (invoiceDetails.Count > 0)
        {
            foreach (var invoiceDetail in invoiceDetails)
            {
                invoiceDetail.InvoiceId = invoice.InvoiceId;
                db.InvoiceDetails.Add(invoiceDetail);
            }
        }
        db.SaveChanges();
        return RedirectToAction("Index");
    }
    return View(invoice);
}

Helper Method:
private List<InvoiceDetail> GetInvoiceDetails(string names, string quantities, string prices)
        {
            List<InvoiceDetail> details = new List<InvoiceDetail>();
            string[] Names = names.Split(',');
            string[] Quantities = quantities.Split(',');
            string[] Prices = prices.Split(',');
            // Not the best, but let's just go with the length on Names (for simplicity)
            // And we need to add validation - but not for the purpose of this post.
            for (int i = 0; i < Names.Length; i++)
            {
                InvoiceDetail detail = new InvoiceDetail() { Name = Names[i] };
                if (i < Quantities.Length) {
                    decimal qty = 0m;
                    decimal.TryParse(Quantities[i], out qty);
                    detail.Quantity = qty; 
                }
                if (i < Prices.Length) {
                    decimal price = 0m;
                    decimal.TryParse(Prices[i], out price);
                    detail.Price = price; 
                }
                details.Add(detail);
            }
            return details;
        }

Result:  This works.  With one page, I can create a new invoice with an unlimited number of line items (relatively unlimited... reasonably unlimited... subject to memory and other limitations...)

But is this the best method?  As it is written, it is not a good solution.  If there is an error with the invoice, all the line items will be lost.  Let's try to fix that.  We need to pass the line items back to the view, if the Invoice model is not valid, then we need to rebuild the line items in the view.

Changes to the Controller:
public ActionResult Create(
            [Bind(Include = "InvoiceId,ClientId,Amount,CreationDate,DueDate,InvoiceNotes")] Invoice invoice 
        )
        {
            List<InvoiceDetail> invoiceDetails = new List<InvoiceDetail>(); 
            if (Request["Name"] != null 
                && Request["Quantity"] != null && Request["Price"] != null)
            {
                invoiceDetails = GetInvoiceDetails(Request["Name"], 
                    Request["Quantity"], Request["Price"]);
            }
            if (ModelState.IsValid)
            {
                db.Invoices.Add(invoice);
                if (invoiceDetails.Count > 0)
                {
                    foreach (var invoiceDetail in invoiceDetails)
                    {
                        invoiceDetail.InvoiceId = invoice.InvoiceId;
                        db.InvoiceDetails.Add(invoiceDetail);
                    }
                }
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            ViewBag.invoiceDetails = invoiceDetails; // pass this back to the view
            return View(invoice);
        }
I moved the declaration and initialization of the invoiceDetails list outside of the if block, and I added the list to the ViewBag.  If the Invoice model is not valid, then I'll send the list of line items back to the view.

Changes to the View:
@{
    List<Sandbox.Models.InvoiceDetail> invoiceDetails = ViewBag.invoiceDetails;
    var count = invoiceDetails != null ? invoiceDetails.Count : 1;
    //if (count <= 0) { count = 1; } // default value
    var name = "";
    var quantity = 0m;
    var price = 0m;
    if (invoiceDetails != null && invoiceDetails.Count > 0)
    {
        name = invoiceDetails[0].Name;
        quantity = invoiceDetails[0].Quantity;
        price = invoiceDetails[0].Price;
    }
}
<table id="invoiceDetails" data-count="@count">
    <thead>
        <tr>
            <th>Item Name</th><th>Quantity</th><th>Rate/Hour</th>
        </tr>
    </thead>
    <tbody id="invoiceDetails-Rows">
        <tr>
            <td><input type="text" name="Name" id="Name" value="@name" /></td>
            <td><input type="number" name="Quantity" id="Quantity" value="@quantity" /></td>
            <td><input type="number" name="Price" id="Price" value="@price" /></td>
        </tr>
        @if (invoiceDetails != null) { 
            for (int i = 1; i < invoiceDetails.Count; i++)
            {
                var num = i + 1;
                var nameid = "Name" + num.ToString();
                var qtyid = "Quantity" + num.ToString();
                var priceid = "Price" + num.ToString();
                name = invoiceDetails[i].Name;
                quantity = invoiceDetails[i].Quantity;
                price = invoiceDetails[i].Price;
        <tr>
            <td><input type="text" name="Name" id="@nameid" value="@name" /></td>
            <td><input type="number" name="Quantity" id="@qtyid" value="@quantity" /></td>
            <td><input type="number" name="Price" id="@priceid" value="@price" /></td>
        </tr>
            }
        }
    </tbody>
    <tfoot>
        <tr>
            <td colspan="3"><input type="button" id="add-row" value="Add Another Item Row" /></td>
        </tr>
    </tfoot>
</table>
It's ugly, but it works.  There's always room for improvement in this code.  I should probably move it into a partial view.  In the controller, perhaps I should have initialized the list to contain one instance of an InvoiceDetail, so I could avoid having to do null checks.  And the list goes on.

Is There a Better Way?

Oh, I am positive that there is.  Here's a few possibilities:

  • Use AJAX or SPA or flavor of the day.
    • Have the initial form show the Invoice model only with a "save" button.  Make a post request to a web service to save the invoice and return the invoice id.  Dynamically, add the fields for the line items with an "update" button that makes a call to a web service to add the line, and then add another set of fields.
  • Separate into two views.
    • Have one view for creating the Invoice.  Upon creating, the user is sent to a second view that displays the invoice and has a form for adding a line item.  After saving the line item, it is added to the invoice display, and the form is cleared for a new line item.  This continues until the user clicks a "Close" button or something similar that makes sense.


Monday, September 22, 2014

SignalR

SignalR

Okay, so I skipped ahead.  I looked at SignalR.  I felt compelled to do a search on Pluralsight for courses on SignalR and picked this one to watch:  Building a Game of Memory with SignalR.  But on the bright side, the project required the use of a singleton which is one of the design patterns that I need to know.  How's that for rationalization?

Overall, it was enjoyable.  I did my best to follow along with the code.  I've got a lower subscription, so no source code for me, but that's okay.  It's good to type it out and work out the missing parts on my own.  The instructor was creating an MVC 4 website.  I tried that at first, but I couldn't get SignalR to install.  NuGet needed to uninstall a JSON module, but the Web API depended on it.

I didn't want to get bogged down with troubleshooting the environment.  I started up a new project using .NET Framework 4.5.1.  I got SignalR 2.2 installed with no problems.  Once I started using it, there were issues.  This article helped me correct the differences between the older and newer versions of SignalR:  Upgrading SignalR 1.x Projects to version 2.

The Memory game matches people up to play a simple memory match game against each other using a Hub to communicate with one another.  When a player joins, they have to wait until another player joins, then a game can begin.  SignalR handles the communication between the client and the server.  It's pretty thrilling to see a card flip simultaneously on different browsers (I used Chrome and IE to test).

I'm not going to post large sections of the code here, but I will talk about some of the gotchas that I had to deal with.  In my opinion, the code belongs to the course, and subscribers have permission to re-type the code and learn how to use it.  Of course, higher subscriptions give access to the full source code which is useful.  The source code should have all the bugs worked out.  If you're not good at debugging, then you may want to pay for that higher subscription...

Upgrading to SignalR 2.2
This did cause a minor issue that was relatively easy to correct.  The correction was to use OWIN.  This is another thing to go on my learning list.  See the link above about upgrading SignalR.

Make Your Own Cards
I needed to make my own cards.  No big deal.  I whipped up some cards quickly in PhotoShop and added them to the project.

Handlebars
This issue was partly my fault, and partly an error in the code shown in the video.  I started a new page to do the final code.  The template failed.  I debugged it in Visual Studio, and it did seem to be giving me the information that I needed.  I switched to the client, and started outputting data to the console.  My game board was undefined!  What?  After a little bit of work, I found the issue.

Original call:
     $("#board").html(template(game));

This seemed correct, until I started looking at the model.  The template was expecting an array containing the cards.  The Game model did not contain a list of cards.  It did contain a property for the game board, Board.  Ah, we're closer.  The Board model is the one with the list of pieces.

Corrected call:
    $("#board").html(template(game.Board.Pieces));

Now, I was getting the correct data out to the console, however, the template was still not working.  This was probably due to not having a dependency added, or having something else out of order.  Again, I didn't want to spend time debugging this part, since I wanted to understand the whole point of the instruction which was SignalR.  This was easy enough to solve.  The template was small, and it was easy to write a simple function in JavaScript to do the exact same work that the handlebars templating engine was doing.  I'll go back later, and set things straight with handlesbars.  It will be good to know what I did wrong, but not right now.

Game Play
Okay, everything seemed to be working.  Only one player goes at a time, and... the player just keeps turning over cards.  Methods to handle the turns and matches don't seem to be firing.  Crikey.  Back to debugging.  A method on the back end was missing a bit of logic.  I kept the code intact, but added another "return true" where I thought appropriate.  Looking at the code, it had some redundancy.  Once I am certain that I understand the code, I intend to go back and clean it up.

It Works!

Huzzah!  It works during my simple testing using two different browsers on my desktop PC.  I still have a few issues to work out concerning the CSS, but it's doing what it needs to do.  I've got two different instances of the webpage in sync.  It's exciting.

Where to Next?
I'll break down the code, and seek to understand it.  I believe that I do, but I'll really know when I go to create a different web application using SignalR.  It'd be fun to make a version of Silent Death to play with a friend.  Silent Death is a turn-based strategy game using miniatures.  If it turned out well, I'd be more than happy to see if the game company that owns the game might be willing to let me release it to the public.  Based on the free time I have right now, all my time should be used on improving my programming skills first.

Tuesday, September 16, 2014

Software Development Game Plan

Software Development Game Plan

I am working in the Microsoft stack right now.  I've worked mostly with Microsoft technology, but I don't consider it to be the one and only option.  That would be limiting.

Before I started my first professional gig as a web designer, I learned the ins and outs of web pages by viewing their source and using Notepad to create my own web pages.  I still enjoy hammering out my own HTML, CSS, and JavaScript by hand.

In the past, I have developed web applications using PHP.  I've coded some basic console applications using C/C++ and have done a little bit of Java programming.  I've even written some ASM for a microcontroller.

C# is my Preferred Language, But That Could Change

I do like C#, but who knows what I'll be writing in the future.  My current plan does revolve around C# as my primary server-side language.  That seems like the wise decision, since I am most familiar with it in comparison to other languages that I've used.  HTML, CSS, and JavaScript are my go-to's for the client-side.

The plan:

  • Gain a deeper understanding of C# and the .NET Framework.
  • Grok design patterns in C#.
  • Have a solid understanding of SOLID.
  • Know ASP.NET MVC.
  • Get my pet project going, and implement it in multiple forms.
  • Work on learning other cool things:
    • AngularJS
    • SignalR
    • KendoUI
    • Onion Architecture
    • And the list goes on...

Gain a deeper understanding of C# and the .NET Framework.
I feel that I have been able to solve all the problems handed to me in the companies where I've worked.  But I'm starting to realize how much that I don't know.  I can blame working for small companies all I want, but that only goes so far.  The development was limited by me and I was alone.  I should have reached out to the community and saw that I need to learn more.

Grok design patterns in C#
I read/heard somewhere that the design patterns are often good habits that we, programmers, should adopt.  I get that.  Also, I see where it creates a common language to talk about potential solutions.  I've worked through some examples with mixed success.  I'll keep at it, until I grok them.

Have a solid understanding of SOLID
I need to understand SOLID and know how it can positively and negatively affect my code base.  I see the value in a lot of it, and I believe that it will help me improve my OOD skills.

Know ASP.NET MVC.
I am familiar enough with it, but need to complete a few more projects using that framework, so that I can be supremely comfortable with it.  I do like it a lot.  I've struggled with ASP.NET Web Forms over control issues.  With classic ASP, I had complete control over my web pages.  With Web Forms, the web controllers caused me no end of grief.  We've reached détente.  I am drawn to MVC, because it gives me back the control, and it seems to encourage OOD more than does Web Forms.

Get my pet project going, and implement it in multiple forms.
I've started working on a pet project.  I'd like to use the Onion Architecture to structure it.  I thought that it would help me design the project, so that I could spin off different versions of my project.  I intend to produce the following, but not limited to: ASP.NET MVC app, AngularJS app with a Web API back-end, WPF, and possibly a Windows Universal App.

Work on learning other cool thing...
Keep on learning.  Too many cool things to know, and not enough time.  Argh... Raspberry Pi, various microcontroller projects, NUI apps, IoT, robotics...  stop. Let me get a handle on the above stuff, before I keep going off on tangents.

Take care,
C.