Wednesday, December 4, 2013

Homework #19 - 10/24 (Makeup)


Tonight I'm going to blog about my project for my databases class. I was really enthusiastic about it and intend to keep working on it after the course is over, just for the experience. It was supposed to be a system for backyard gardeners. Users would be able to create an account with their name, email, and address. They would automatically be assigned a garden object upon their account creation. This was going to be handled by using SQL triggering on the database. The code would look something like this:

DELIMITER \\
CREATE TRIGGER addGarden  AFTER INSERT ON gardeners
BEGIN
  INSERT INTO gardens (owner_id)
  VALUES (OLD.id);
END\\
DELIMITER ;

I did not get this code to actually work, but the idea is that you have to change the delimiter from a semicolon before you write the function so that you can use the semicolon at the end of the insert statement without ending the function early. The trigger runs after an insert occurs in the gardeners table, or in other words, after a gardener has created their account. It then inserts a new garden into the gardens table with the owner_id attribute of the garden set to the OLD.id. Here the OLD means that it is using the id of the statement that caused the trigger, the gardener. I think this may be where I made my mistake, as I am not sure that the OLD.id is doing what I think it is. Then the trigger is ended, and we reset the delimiter back to the semicolon.

There is also a pre-filled database of plants containing attributes such as common name, scientific name, mature height, duration, growth rate, minimum pH, maximum pH, among others. Users will be able to select from plants from this database to add to their personal garden and will get advice on things they should do based on the plants selected, for example, how deep to plant the seed, or how far apart it should be from another seed. The system will also recommend certain plants that the user should try to grow based on the location of their address. It can do this because the database also has table containnig list of states that each plant naturally occur in, so it can do a simple query like the following to produce a suggestion list:

SELECT common_name FROM plants p
INNER JOIN naturally_occuring n
ON p.scientific_name = n.scientific_name
INNER JOIN gardeners g
ON g.state = n.state
WHERE g.state = n.state

This code seems bloated from reading it, but it basically makes a new, temporary table from the three tables, plants, naturally_occurring, and gardeners and matches the tuples accordingly. It then selects only the common name of the plants where the state the gardener lives is the same as the state that the plant naturally occurs in.

For now that is all, I intend to have more features too - perhaps reminders on when to harvest, or weather information to alert users of inclement weather that may endanger their plant.

Sunday, December 1, 2013

Homework #25 - 11/14 (Makeup)

Deliverable 4:

     I'm much more happy with my contribution to the group from this point on. I spent several hours working on this deliverable with material the other group members gave to me. I researched online to see what a professional deliverable report should look like, and borrowed elements of the layout and some formatting designs. I also feel like I have pretty sufficient technical writing skills, so when I compared my report to the ones the group previously produced, I feel as if the writing quality was just a little bit better, or at least more concise and to the point.
     Again, however, the group suffered from our division in both design and communication, and so the product was not written with a complete understanding of the overall system design. For example, in our test cases, the "Requirement" section of the JSON file was usually just a '?'. I had no idea what was even the point of including this in the file if they were all just question marks. When I was reading back through some of the older deliverable instructions, it said that each test case was to be able to be traced back to a single requirement. For me, that is what this section should have stated: which requirement is this specific test case testing for? After asking Ian about it, however, he explained it as it was supposed to be the required circumstances of the input to get the same expected result. Perhaps I still misunderstood what he said, but this is what I took away from it at least.
    I also reworked some of the previous deliverables to fit into this one and rewrote some of the wording, since at each deliverable, it stated that it was supposed to be a chapter in our final deliverable booklet. I was quite pleased with the document after I was finished with it. It really did look like a professional document. Tan whipped up some images we could use as kind of a company logo for our group, and I was able to include those as well, further adding to the convincing professionalism. Getting a good looking deliverable wasn't the only positive thing that came out of the experience, though. All of my team members complimented my work on it, and I felt like I finally did something to really contribute to the group, boosting my confidence as well. Really a great experience overall and I'm glad I was able to work on it and put so much time into it.

Homework #20 - 10/29 (Makeup)

Deliverable 3:

     To be honest, I don't even remember what was going on with my circumstances around the time of deliverable 3. My group basically functioned entirely without me for this one. I feel like I definitely dropped the ball during this part of the semester. I remember Ian showing me the code and walking us through it as a group. I also remember suggesting that we should implement a time stamp attribute to keep track of when the test cases were run. Even though our set of test cases were run basically at the same time, or at least with very little time in between each, it wouldn't matter much for our class project, but in a real world setting, information about who ran the test, and when it was run would also want to be recorded. Other than that, Ian pretty much wrote the entire framework, and Andrew wrote the entire deliverable. I'm not sure what Tan was working on at the time.
     In a sense, I suppose we divided up our group sort of like the surgical team described in the Mythical Man Month, with Ian being the main surgeon. Andrew and I were mainly bookkeepers and Tan ended up filling a dual role of the surgeon's right hand man, and also the public relations person, since he wrote the front end of our application, which would communicate the information to the client. In our case, however, the group suffered from more disorganization than anything else. Normally, the division of tasks among group members is to increase the total efficiency, but in our case it probably hindered us more than doing us any good. It is very much similar to how Brooks describes some systems being developed by large teams: programmers are usually in charge of not only the implementation, but also the design of their components of the system. In this sense, you get several components that are not designed in a unified manner. This was the case in our group as well, I think. We had basically one person writing the framework, so the others might not have fully understood the design. Unfortunately, that includes those of us who wrote the actual deliverables - so some of the information conveyed could have likely been incorrect as it was not fully understood in the first place.

After hearing that we did pretty much a horrible job on this deliverable, I committed myself to putting a lot more effort into the team and our future deliverables.

Homework #18 - 10/22 (Makeup)

Chapter 19 - Service Oriented Architecture

     This chapter brings back memories.... I interned at BMW in Spartanburg at the IT Innovations department. There was a lot of neat things going on there with several different projects being worked on by different interns. I was probably assigned the least interesting project, and also probably the hardest. Let me see if I can recall, in correct details, what I was assigned. I was working on a back end web service which would be used for an in-house app store. The web service was to take in a JSON message which contained metadata about an app and error reporting for that app. It would include the client/developer name and contact information, a time stamp that the error report was sent, the error message, and some other stuff I can't remember. The JSON message was sent via SOAP and RESTful messages to a Glassfish server that was hosting my web service. The service was then to take the JSON, parse it, and store the information in an Oracle database. Whew, I think that's the gist of it.
     The reason this was, at least what I perceived, the hardest task is because I had never had any exposure to all of the technology and standards that come along with web services. For that matter, I don't think any of my colleagues did either. I had to read about SOAP messages, RESTful services, WSDL and XML descriptor files, and other things I don't remember. It's also the first time I had seen SQL or done anything with a database, so the learning curve was huge, as you can imagine. It took me the entirety of my 5 month internship to finish what should have been a relatively simple program.
     If I had another chance to develop the same type of system, I would jump at it. Back then I didn't really have a good grasp of what things such as a WSDL file was. All that I knew is that it was necessary to have for a web service to run. Now that I realize what it actually is and it's purpose, it wouldn't be nearly as confusing if I were have to do it again. Another thing I might employ is an actual life cycle model for my project. I remember not really knowing what I was doing, and just using the code-and-fix or waterfall models. Once something broke, and I couldn't figure out what I did to break it, I would frequently just scrap the whole thing and started over from scratch - it was quite frustrating, really.

Homework #17 - 10/17 (Makeup)

Chapter 18 - Distributed Software Engineering

*After reading my fellow team members' blogs, I realize that mine isn't looking too bad. I'm not saying that their blogs are any better or worse than mine by any means, I just thought I was much farther behind than I really am, which gives me hope. We are optimists, after all, as Brooks says in the Mythical Man Month.

     This chapter is all about distributed systems, which in reality, includes most systems in use today. Even word processors now, are linked to the cloud and remotely load settings in from other sources. The author highlights some of the difficulties included in developing a distributed system:


  • Transparency - Should the system appear as a single unit, or is it sometimes useful to understand that it is, in fact, a distributed system? My intuition here, says that it is better to appear as a single unit. It just seems like a cleaner design and hides the unnecessary details from the end user. 
  • Openness - Should a system be designed using standard protocols that support interoperability or should more specialized protocols be used that restrict the freedom of the designer? Here I think it definitely varies on the system being built. If the system is something that has very specific and unforgiving requirements, then probably specific protocols should be used. If there is a little flexibility in the design of the system, perhaps then, using standard protocols to increase interoperability would be preferred. 
  • Scalability - How can the system be constructed so that it is scaleable? How can the system be designed so that it's capacity can be increased as demand increases? Cloud computing comes to mind as a good solution to this problem. If your service is getting more demand, allocate it more resources from the cloud.
  • Security - How can usable security policies be defined and implemented that apply across a set of independently managed systems?
  • Quality of Service - How should the quality of service that is delivered to system users be specified and how should the system be implemented to deliver an acceptable quality of service to all users? This is a good question - what does quality of service, in the case of your system, mean? Is it having a stellar feature set, or is it more focused on always being available?
  • Failure Management - How can system failures be detected, contained, and repaired? For distributed systems, this is a big concern. You may not have control over some of the components of the system, but when they fail, the service is either interrupted or degraded, so how do you plan for that?
     Reading this chapter has helped me increase my understanding of distributed systems, and what everyone means when they talk about things like, scalability, and quality of service, etc. I've kind of been able to identify certain parts with my databases class. We've had to develop, essentially, a distributed system of our own design over this semester. We use a MySQL database in the back end to store our entities, and their relations, and write a php or java front end to serve the data to clients in the web browser and allow them to perform basic crud operations on the data being stored in the database. I'm very grateful for my undergrad experience here at College of Charleston. I'm not sure how well other schools prepare their students for real world applications, but I feel as if the staff does a good job here by assigning relevant readings and projects.

Homework #16 - 10/10 (Makeup)

WELL - here I was about to read chapter 17 of our book, but when I start flipping through the pages, I realize that I've been reading the wrong textbook for a good portion of this semester, because the book I have been reading doesn't even have a chapter 17. This is pretty depressing....I've been reading the textbook we used for my CSCI 360 class. A lot of the material is similar, but still. I've probably done several incorrect assignments up to now. I don't know when it was that I confused our books, probably after fall break when my health started getting worse and I wasn't sleeping as well and started missing a lot of class. Ah well, what can ya do?

SO, chapter 17 of the right textbook. This chapter is all about software reuse and taking small preexisting components and composing them into a larger target software program. A 'component' can be interpereted in different ways, however. Some define it as a software element that can be independently deployed and is composed according to a composition standard. Others say that it is unit of composition with contractually-specified interfaces and explicit context dependencies. Basically, some think that a software component is only defined a component if it is written by the standards, and others define a component based on its key characteristics.

Some definitions of component characteristics to remember:

  • A component is standardized if it is used in a CBSE process and conforms to a standard component model. This can define interfaces, metadata, documentation, composition, and deployment. 
  • A component is independent if it can be composed and deployed without the use of other components
  • A component is composable if all interactions take place through a publicly defined interface.
  • A component is deployable if it is self contained and able to act as a stand-alone entity. 
  • Components must be documented so that future users can decide whether it will meet their needs or not. All of the syntax and semantics of the interface should be defined.
     The rest of the chapter goes on to define the two different types of component-based software engineering: development for reuse, and development with reuse. The first dealing with making components that will be reused in other applications and the later making applications that use existing components. 
     When writing components for reuse, you need to make sure there are no application-specific methods, names have been generalized, methods provide complete functionality, exception handling is consistent among methods, incorporate a 'configuration' interface to allow the component to be adapted to different situations, and integrate any required components so that the developed component is independent.
     When writing applications that use preexisting components, you first design the application in an outline being as general as possible to maximize the number of potentially usable components. Then, you modify requirements depending on the available components and design the architecture. Further component search and design follows based on whether the previously selected components will fit the need. Finally, after all the components have been selected and the architecture design solidified, the system is composed.


Software reuse is one of the things mentioned in "The Silver Bullet" as a way to dramatically increase software development productivity. Buying off-the-shelf software not only saves you the pain of designing, and writing it, but also the huge task of testing and debugging it. This is certainly an imaginable concept, but it would also require huge effort on the part of the developers to write their components according to a standard so that they may be compatible with other components written in the same fashion.

Homework #13 - 9/26 (Makeup)

     This reading is all about software life cycle models. Not the most interesting thing to read about, but certainly important. Just as we can model systems and their behavior with UML diagrams for a better understanding of the system and an aid in the development of the system, we, too, can model the development cycle of a piece of software. Also, un-intuitively, software life cycles can be modeled as activity-centered diagrams, where a class in the diagram represents an activity in software development (ie Problem Definition Activity, or System Development Activity). The other way life cycles can be modeled uses an entity-centered view, in which each class in the diagram represents the content and structure of the work product (ie a Requirements Specification Document).

     There are several commonly used life cycle models, most of which are activity-centered. The first, and oldest, being the Waterfall model, in which it describes a sequence of activities that occur. The requirements process leads to the design process, which leads to the implementation process, etc. The thing about the waterfall model is that there is no way to back up, to traverse up the waterfall is impossible. Because of this, the waterfall model is not used in large, costly software development. It is mainly only appropriate for small scale personal or school projects, where one can restart with little consequence. The V-model is a variation on the waterfall model in which with each activity before implementation, there is a paired activity afterward that focuses on the validation of the system through testing and client acceptance. There still is no way to go backwards in the life cycle, or re-iterate on activities. For this reason, the spiral model has become popular. This risk-analysis based model starts at an origin and spirals outward. The farther away from the origin, the greater the cost of the development thus far. Each quadrant of the model represents the type of activity that is taking place along that point in the spiral. This way, as you move along the spiral, you will iterate among the four quadrants, first determine objectives, alternatives, and constraints. Then evaluate the alternatives, identify and resolve risks. Then comes developing and verifying the next component in the system, whether it is designing, or coding. Finally, you plan for the next phase, which could be a requirements plan, or integration plan.

     I cannot say I plan on becoming a project manager at any point in my career, but learning about life cycle models is still important to me. It's all related in the end, really. For example, the spiral model can not only be used in modeling software life cycles, but it can also be used to model a design plan for your code. First, design the general layout of your code - come up with classes and methods, etc. Then write some prototypes and evaluate any alternatives, once you've decided the best way to go about it, write the code. After writing that portion of code, test and debug it before moving on to the rest of the program. This way you write in small increments and each part is tested on its own before you integrate all of the components together for the whole program.

Homework #11 - 9/19 (Makeup)

Reading through these old assignments is a little bit depressing. Not in the sense that I don't like reading them, but just realizing how many of them I've actually already read, but never wrote a blog post on.

     Seeing as I have not written very many complicated programs, when I read that about half of the development time of a piece of software is devoted to testing and debugging, I was a little surprised. Can it really be so cumbersome? The author provided many references to back up his statement of this, and it was also mentioned in the Mythical Man Month article, in which the author stated that he devotes one third of the development schedule to designing, one sixth to implementing, then the rest (half) to testing and debugging - wow! I suppose it sounds intimidating, but I'm the inexperienced one here, so I'll take their word for it!
     One of the most interesting parts of this read for me, was the different phases of thinking about testing and debugging. The author has a funny line in the article: "I called the inability to distinguish between testing and debugging 'phase 0' because it denies that testing matters, which is why I denied it the grace of a number". Well said, sir. Well said. Phase 0 thinking assures that your software will have no testing, therefore no quality assurance, and therefore, no quality. Phase 1 thinking is assuming that when your tests succeed, the software works. But in reality, this is not the case. Myers says that it only takes one failed test to prove that software doesn't work, but even an infinite number of tests cannot prove that it does work. Phase 2 thinking is where you assume the software doesn't work. In this case, the tester is always trying to prove that the code is broken, and if perhaps it is not, testing will never end, because there are no bugs to reveal - but they keep trying. Phase 3 is thinking about testing and debugging as gaining confidence in the software. A successful test does not actually improve the quality of the software, but it increases our perception that it is quality software. Therefore, when we have gained an acceptable amount of confidence in the software through testing and debugging, is when we release it. And finally, phase 4 thinking is a state of mind of testing. Developers know there will be bugs, but the main goal is to write your code with testing in mind. The act of thinking about and designing tests while programming will increase your bug prevention, and make your code easier to test when the time comes. Although all of the testing strategies strive towards the same goal of quality software, this is the best. It not only reduces the amount of bugs by using preventative measures, but also makes the labor of testing easier because the code, itself, is more testable.