FREE PROJECT DOCUMENT ON AUTOMATION OF TIME COST TRADE OFF ANALYSIS

AUTOMATION OF TIME COST TRADE OFF ANALYSIS 


BY:


####### ######## #########: CS/##/###

####### ######## #########: CS/##/###

####### ######## #########: CS/##/###



DEPARTMENT OF COMPUTER SCIENCE

FACULTY OF SCIENCE

MADONNA UNIVERSITY, NIGERIA.



AUGUST 2016






CERTIFICATION

This is to certify that this research project on Automation of Time Cost Trade Off Analysis By ####### ######## #########: CS/##/########## ######## #########: CS/##/### and ####### ######## #########: CS/##/###. Met the condition for the award of Bachelor of Science (B.Sc.) degree in Computer Science Madonna University Nigeria. It is hereby approved for its contribution in Knowledge.



MRS ########-### ######                                                       DATE
(Supervisor)





MRS ########-### ######                                                        DATE
(Head of Department)





PROF. ########-### ######                                                        DATE
(External Examiner)








DECLARATION

We hereby declare that this project on “Automation of Time Cost Trade off Analysis” has been carried out by us ####### ######## ######### with the registration number CS/##/########## ######## ######### with the registration number CS/##/### and ####### ######## ######### CS/##/### and is a record of our research work and is a record of our research work References made to published literatures have been duly acknowledged.





####### ######## #########                                                      DATE
(Student)



####### ######## #########                                                       DATE
(Student)




####### ######## #########                                                       DATE
(Student)

The above declaration is hereby confirmed by




Mrs ####### ######## #########                                                DATE
(Supervisor)




DEDICATION

This work is dedicated to the almighty God, for His everlasting protection and provision to us and our families throughout this period.




ACKNOWLEDGEMENT

I would like to thank GOD Almighty, our supreme guide, for bestowing his blessing upon me in my entire endeavor. I express my sincere gratitude to our supervisor and Head of Department in the person of Mrs Eberendu-Ogu Adanma. Most importantly our parents for their provision and support from day one till now.





ABSTRACT

Time Cost Trade Off (TCTO) is a process to identify suitable project activities for speeding up and deciding by how much so as to attain the best possible saving in both time and cost for that project . The objective of TCTO is to reduce the original project duration, determined from the critical path, to meet a specific deadline with the least cost . Performing this computation in the past was prone to error, became complex as well as tedious when the size of data was increased and also of technical knowhow of individuals was a problem. This analysis involves the computation of the TCTO model using the Simple Critical Path Method TCTO Algorithm which in the past was done manually. In this work, time and the resource used resulting to the overall cost of the project are considered and the different cost involved in a project . The aim of this work is to automate TCTO analysis by building a system which will help project managers and individuals alike to perform this computation easier and accurately with little or no knowledge of the model in other to save time using Python Programming Language implemented as a desktop software.


CHAPTER 1
INTRODUCTION
1.1 BACKGROUND OF STUDY
Time/cost trade-off is a process to identify suitable project activities for speeding up and for deciding by how much so as to attain the best possible saving in both time and cost , the objective of the time-cost trade-off is to reduce the original project duration, determined form the critical path, to meet a specific deadline, with the least cost . In addition to that it might be necessary to finish the project in a specific time. Time/cost trade-off is one of the highly important challenges in project  execution and has been taken into consideration by project  manager. A project in construction contains many uncertainties. It requires a number of resources and a large amount of investment. Time and cost are main management goals. Contractors want to get   the highest profit so they must plan to complete the job in early time with a minimum   cost . It is general realized that when project duration is compressed the project will call for an increase in labour and more procurement equipment and require more demanding procurement and their cost will increase. 
The development and use of the time-cost tradeoff for a project network is an essential part of a CPM analysis , since small variations in project duration could heavily affect the project 's cash flow. In a project network, each job has an associated crash completion time and normal completion time and the cost of doing the jobs varies linearly between these extreme times. Given that the entire project must be completed in a prescribed time interval, it is desired to find job times that minimize the total project cost 
The essential ingredient of the technique is the network model that incorporates sequence information, durations and costs for each component of the project . Analysis of the network model enables operating personnel to answer the questions concerning labour needs, budget requirements, the effects of delays etc.
Network analysis has caught the attention and stimulated the interest of mathematicians, academicians, operations research analyst s, practitioners, and government officials. The most common name associated with network analysis is CPM. 
This paper shows different outcomes of previous studies with application of various techniques/algorithms used to solve TCTO problems. In this review use of analytical techniques such as critical path method (CPM), Project Duration, EST, LST, Slack, Least Cost Slope etc.

1.2 PROBLEM STATEMENT
The need for project managers and all those involved in project activity scheduling and life cycle are always found in the problem of balancing between the specified duration the project is to take and the cost of carry out the different activities in that project . Problems sometimes arise from inadequate cost budgeting and project activity scheduling. Therefore Time Cost Trade Off (a  
method for mathematically calculating the relationship between the Time and Cost of a project activity) is used. This method is useful when performing this calculations mathematically.
Problems do arise in the use of this model, due to factors that may come from Human errors; where the person carrying out this calculation may make mistakes and lead to inaccurate results or prediction, Lack of technical knowhow in which the person in charge of the project may not know how to perform this predictions and largeness of data; if the amount of data to be calculated is to large or voluminous, the probability of getting accurate predictions may be small. Performing this calculation manually is simply prone to errors and mistakes. On this basis, creating an automated system that can help the individuals concerned with project management to carry out this simple but sometimes complex calculation. This would truly help in catering from errors due to human mistake and in accuracy, also make it easy when calculating with large amount of data. All this and more can be done with little or no error, stress involved.

1.3 AIM AND OBJECTIVES
The main objective of this research is to give proper understanding of the TCTO analysis in order to automate the computation in order to remove the constraint involved existing in the old system and arrive at optimum solution for the balance between the cost and the time.Objectives include:
Aiding in the construction of the network diagram and computation of the project duration.
Computation of the project normal cost and crash cost .
Calculating the cost slope and the maximum reduction time.
Crash time and crashable activities.

1.4 SIGNIFICANCE OF STUDY
At the end of this study we now fully understand the concept of project analysis and management in the organization and structuring of the various activities involved in carrying out jobs and tasks. Part of this study will help in enlightening major parts of project  analysis  and management like; Activity scheduling, budgeting, time estimation etc. with major Focus on Time Cost Trade Off, to now enable calculate crash time and cost slope for each activity.
After this study we will now be able to:
Draw and construct network diagrams.
With the help of the Critical path method, discover the activities on the critical path, calculate the project durations.
Using the project duration to find the Earliest Starting Time and Latest Starting Time, using the forward Pass and Backward Pass.
Crash Activities and calculate the crash cost .
Find the least cost slope.
This knowledge will help in finding the balance between the costs of a project (each activities within that project ) and the duration it takes to complete this tasks.
Thus we can now implement and automated system to perform this calculations and estimations.

1.5 SCOPE OF STUDY
This study going to be covering the basics or project analysis and management. We will be taking an in-depth at the various tools involved in project analysis and management.
We will start by discussing Network Diagram; how to draw and design the diagram of network activities and project task, discuss briefly the types of networks and examples of them. Simply put how to transform the project schedule into a diagrammatical representation.
Next, with the use of the network diagram and project schedule find the critical path, critical activities and the normal project durations.
Along with calculating the Earliest Starting time, Latest Starting Time, Floats, Backward pass and Forward pass method. 
Moving into our focus of the study which Time Cost Trade Off, under this we will be discussing crashing of network activities, how to calculate Least Cost Slope, Crash Cost, Crash Durations.

1.6 LIMITATIONS
The limitations which where encountered in the course of this research came in different forms, firstly there was not an actual knowledge of the topic given. So time was actually spent on understanding the concept fully. For implementing the system a new language which was used, which we all were not familiar with and had to learn at the same time. So in short, unavailability of time to fully carry out all these. Also cooperation between us was an issue, agreeing and coming together to work.

1.7 GLOSSARY
CRITICAL PATH: This is the longest path through the network. The critical path is the minimum time for expected completion the entire project 
TIME COST TRADE OFF: this is the analysis of the relationship that exist between the cost and time of a project and finding the optimum solution to balance.
CRITICAL PATH METHOD (CPM): The critical path method is the backbone upon which the project execution plan is built, it is a relatively simple concept it provides dynamic analysis  of activities sequencing and progress reporting. 
FORWARD PASSING: This is the process of determining the earliest date for each activity starting with the first activity in the CPM network. 
BACKWARD PASSING: This is the process of determining the latest date for each activity starting from the last activity in the CPM network. 
EARLIEST START TIME (EST): This is the earliest time an activity can start, assuming all preceding activities start as early as possible. 
LATEST START TIME (LST): This is the latest time an activity can start and not delay the project .
COST SLOPE: this is the amount it will cost for each activity per unit increase of resource to the price.
MAXIMUM REDUCTION TIME: this is the difference between the normal duration and the crash duration. This is the crash ability of an activity, the amount of time an activity can be crashed.

1.8 ORGANISATION OF CHAPTERS
This report comprises of 6 chapters namely Introduction, Literature Review, System Analysis, System Design, System Implementation and Conclusion.

Chapter 1- Introduction explains the Background of the project , problem statement, scope, objectives, significance and related are clearly defined to give readers an overview of the project .  

Chapter 2 – Literature review on the other hand contextualized the definition, concept and other relevance information regarding the project topic. Many similar researches, concerned concept and related works were viewed in order to determine the methodologies and approaches carried out in the previous research in order to develop idea and see things in different perspective of view, which include reviewing other works with comparison between. 

Chapter 3 – System analysis which a breakdown of all the necessary parts and component node, the requirement both functional and non-functional, general information of the system.

Chapter 4- system design, which are the part of the work that describe the to be implemented I n the working system.

Chapter 5 - System Implementation has to with designing the system and building the program.

Chapter 6 – Conclusion. 

           
CHAPTER 2
LITERATURE REVIEW

2.0 Time Cost Trade off (TCTO)
Project analysis is a part of software development or project development of any system, to carry out any development activity of the activities that make up the whole work must be analyzed in order maximize all the resources available for the carrying out of that project .
In other to carry this out we make use of some methods for critically, Network Analysis where all the activities concerned with the completion of that project are now analyzed along with their respective cost.
Project Management is a set of principles, methods and techniques for effective planning of objective-oriented work, thereby establishing a sound basis for effective scheduling, controlling and re-planning in the management of programs and project .”
This emerged from the need to carry out complex and sophisticated system development activities and process in delivering of quality goods and services. Management in this context just describes the application of scientific and mathematical theories and methods to contribute to the process.
In project activity management or scheduling the durations of an activity will always vary due to factors like the type of activity and the amount of resources applied to the activity. By assigning more workers and resources to an activity will definitely reduce the duration of the job. But this greater speed will also result to increase in the cost of carrying out that job. Project managers are now to create a balance between the time and the cost of the activity.
Time-cost trade-off decisions are involved in complex and require selection of appropriate construction method for individual project activity. Time-cost trade-off is a very important management tool for overcoming one of the critical path method limitations of being unable to bring the project  schedule to a specified duration.
Before we go into reviewing TCTO properly they are some concept to be first discussed first that are part of the project analysis and management techniques.
These are as follows:
Network diagram
Critical path method
Activity
Duration
Cost
Est
Lst

2.1 TYPES OF COST
We have 5 types of project cost direct cost , indirect cost , fixed cost , variable cost , sunk cost .

DIRECT COST: Are expenses that come out of the project budget directly. For example, If you have outsourced some of your development work, the developers are expected to put in a specific amount of time , which is then billed for. The developer salaries are the costs.

INDIRECT COST: Are those that are shared across multiple project . Indirect costs are sometimes also referred to as oversight costs. For example, in software development project , it is common for a project manager or an architect to be partially allocated across several project . Hence, the cost of the project manager or architect will be shared among the project they are allocated to. 
Example of indirect costs could be the salary of an architect or a project manager who are partially allocated.

2.1.1 REAL LIFE EXAMPLE OF DIRECT & INDIRECT COSTS
When you make a product, the materials you use to build it are Direct Cost. This might include the cloth used to make a dress or the plastic used to make a toy. When you calculate the cost of your materials, include any shipping fees. If you need a warehouse or extra square   product, you would not need the extra space. 

2.1.1.1 FIXED COST: Here is everything that is a one-off charge. And fees are not linked how long your project goes on for. So if u need to pay for one time adverting to secure a specialist software engineer or you are paying for a day of agile consultancy to help you start the project up the best way, those are fixed costs.

2.1.1.2 USAGE EXAMPLES OF FIXED COST
It is good to put a fixed cost on your product and not allow for any negotiations if you know that the demand is high.Utility cost every month for your building would be considered as a fixed cost, which is constantly the same every month. I was analyzing my electricity bill and I noticed I pay some even if I do not use the electricity because it has I fixed cost element to it.  
Related Terms of Fixed cost 
Semi Variable Cost
Fixed Expenses
Customer service charge
Contribution analysis 
Account analysis
Distress price
Applied overhead
Direct costing
Relevant range of activity. 


2.1.1.3 VARIABLE COST:
 Is the opposite of cost, the charges that change with the length of your project . And it is more expensive to pay staff salaries over a 12 months project than a 6 month one. 

2.1.1.4 SUNK COST
Are costs that have already been incurred. It could be made up of any of the types of cost above but the point is that they have happened. The money has gone. These costs are often forgotten in business cases, but they are essential to know about.  

2.1.1.5 SUNK COST USAGE EXAMPLE 
My manager informed me that it was already a sunk cost and we would not be able to recover the funds. At some point you just have to admit that your project has failed and of the money you have put into it is now a sunk. If you know that a product is distained to fail you should just give up instead of putting more money in to the sunk cost.
Related Terms of Sunk Cost
Cost classification
Irrelevant cost
Differential analysis.

2.1.1.6 7 STEPS TO HELP YOU TO CALCULATE YOUR ESTIMATED PROJECT
Enterprise project portfolio management.
Program and project management office consulting.
Resources management.
Program and project  management.
Professional staff augmentation.
Software implementation.
Business process services. 

2.1.2 Project Networks:
This is the graphical and symbolic representation of the various parts of a project work structure in other to better analyze these component part as a complete whole. In literature there are 2 different types of representing the project network. These are:
1. Activity On Node (AON)
2. Activity On Arc(AOA)
These forms are differentiated in terms of their Activity and order of precedence relation. Describing this precedence relation we make use of the Preceding and Succeeding activities. If start of activity i requires,  activity j to be completed we say activity i is the predecessor of activity, and activity I is the successor of activity j. if activity i can start immediately after activity j is the immediate predecessor activity I, and activity I is the immediate successor of activity j. (HAFIZOGLU, 2007).

2.1.2.1 Activity on Node (AoN) Representation:
In AoN representation, the activities are shown by nodes. The Nodes are used to represent immediate precedence relations. Direction of the Arc shows the precedence direction. Take a project with 8 activities as shown I the table below.

FREE PROJECT DOCUMENT ON AUTOMATION OF TIME COST TRADE OFF ANALYSIS
Table 2.1
The project is as follows.

Figure 2.1 Critical path diagram Modified from (HAFIZOGLU, 2007)

Figure 2.1 Critical path diagram Modified from (HAFIZOGLU, 2007)
Note that activities 1 and 2 are predecessors of activity 4, and activities 6 and 
8 are successors of activity 4
Below is an example of a project schedule illustration of an Activity on Node.
In this example the department of computer science has decided to carry out a simple forum to create an avenue for the student of the department to come together to be informed from specialist from different fields of the knowledge base. Both student and lecturers will be speaking in this forum. The course rep has been given the job of putting the preparation activities together. Idara usen as the course rep has identified the activities that must be completed prior to the forum. Also identified the activity and the time needed to perform each activity. With these in mind she created this schedule to clearly define all the processes involved. (Mckenna, 1980)

FREE PROJECT DOCUMENT ON AUTOMATION OF TIME COST TRADE OFF ANALYSIS

Table 2.2 Modified from (Mckenna, 1980)




Figure 2.2 Network diagram, Modified from (Mckenna, 1980)

Examine the network diagram:
For activity A we see that there is no preceding value for it (the dash signifies that there is no preceding value).we see the arrow being drawn from the start activity (the circles are representing the activity) to A activity and also from start to C activity. For B activity we see the arrow being drawn from A as the preceding activity meaning B cannot be started until A has been completed., D activity has more than one preceding activity; this means that D cannot also be started until B and C has been completed. Activities E and F are all moving to one direction Finish activity. Also note that Start and Finish are not real activities but signify the beginning and end of the project . (Mckenna, 1980) .

2.1.2.2 Critical path method:
Critical Path Method (CPM) is a project schedule method to analyze and represent the tasks involved in completing a project . It collaborate the trade-off between the duration of activities and cost and relies on concepts similar to the program evaluation and review technique (PERT).
According to Stelth (2006), CPM is a management methodology which has been in use since mid-50s.the primary purpose of this method was to help in determining the best and most suitable ways to reduce time for carrying out normal and repeated task to support an organization. Fore mostly was noted to conduct routine activities like plant over haul, maintenance and construction (Moder and Phillips, 1964). CPM is also an extension to bar chart, following from the work break down structure where all the activities somewhat dependent on one another’s completion time . Several under laying assumptions have been made in respect to the CPM method. The major ones are that a project can be broken down into a 
Series of identifiable tasks, each of which can now be broken down into smaller subtask. Once this is done the activities are now allocated starting dates, durations (time of completion) and ending date. May sometimes have the resources attached to it, and this data is drawn into a table called the Gantt chart. (Needleman, 1993).

The CPM analysis brings a very helpful means of identifying alternate paths or plans that can be undertaken to avoid of control the interruption and hurdles that may arise in execution of the task. Critical path analysis consists of three phases—Planning, Analysis, and Scheduling and Controlling. All three activities are interdependent. But they require individual attention at all different Stages of the project . (P. Stelth, 2006)

FREE PROJECT DOCUMENT ON AUTOMATION OF TIME COST TRADE OFF ANALYSIS
Figure 2.2Network diagram with critical path, Modified from (Mckenna, 1980)



A set of connected activities is called a Path. The critical path is just the shortest amount of time the activities on the network diagram could be completed in without any activity being delayed or incomplete. Following this path will result in a sequence where the project will completed avoiding all setbacks.
From the above diagram we may have more than one critical path, but we have to note to find the route that will cover all the various route from start to finish. Our critical path here is represented by the Red line across the critical activities, which now result to the project duration. Project duration is the sum total of the duration of the critical path activities. (Mckenna, 1980)
Critical Activity: Critical activity are those in which the slack time is equal to its duration. In other words, any activity is called critical if an increase in its duration directly affects the project  duration. All activities which are not critical are called non-critical activities.
.

Our CP=A,B,D,E; there exist other critical path like C,D,F; A,B,D,F; C,D,E. our CP A,B,D,E= 9 weeks.
C, D, F=6 weeks, A, B, D, F =7 weeks and finally C, D, E=8 weeks.
This is done by adding the time specified for critical activities.

Solution
i. Calculate the time duration for the path ABDE.
Activity A=2,
Activity B=1,
Activity D=3,
Activity E=3.


Total Duration= a (A) + a(B) + a(D) + a(E) 
Total Duration= 2 + 1 + 3 + 3
Total Duration=8 Weeks

ii. Calculate the time duration for the path CDF.
Activity C=2,
Activity D=3,
Activity F=1.


Total Duration= a(C) + a(D) + a(F)  
Total Duration= 2 + 3 + 1 
Total Duration=6 Weeks

iii. Calculate the time  duration for the path ABDF.
Activity A=2,
Activity B=1,
Activity D=3,
Activity F=1.


Total Duration= a(A) + a(B) + a(D) + a(F) 
Total Duration= 2 + 1 + 3 + 1
Total Duration=7 Weeks

iv. Calculate the time duration for the path CDE.
Activity C=2,
Activity D=3,
Activity E=1.


Total Duration= a(C) + a(D) + a(E) 
Total Duration= 2 + 3 + 1
Total Duration=6 Weeks
Solution modified from (Mckenna, 1980).
Therefore we now understand that taking different route or path will result in different project duration. But there can be only one critical path for a single Project network diagram.

Step 1.  Make a forward pass through the network diagram, calculating the earliest time (TE) for each event (node).  In other words, what is the earliest time at which all of the activities entering a node will have finished?  To find TE, look at all of the activities which enter a node. TE is the latest of the arrival times for entering arcs, i.e. TE = max [(TE of node at tail of arc) + (arc duration)] over all of the entering arcs.  By definition, TE of the starting node is zero. 

Step 2.  Make a backward pass through the diagram, calculating the latest time (TL) for each event (node).  In other words, what is the latest time that the outflow activities can begin without causing a late arrival at the next node for one of those activities?  To find TL, look at all of the activities which exit a node.  TL is the earliest of the leaving times for the exiting arcs, i.e. TL = min [(TL of node at head of arc) − (arc duration)] over all of the exiting arcs.  By definition, the TL of the ending node equals its TE. 

Step 3.  Calculate the node slack time (SN) for each node (event).  This is the amount of time by which an event could be adjusted later than its TE without causing problems downstream. SN = TL − TE for each node. 

Step 4.  Calculate the total arc slack time (SA) for each arc (activity).  This is the amount of time by which an activity could be adjusted later than the TE of the node at its tail without causing problems later.  SA = (TL of node at arc head) − (TE of node at arc tail) − (arc duration). 

Step 5. The critical path connects the nodes at which SN = 0 via the arcs at which SA = 0. 
It should be no surprise that the critical path connects the nodes and arcs which have no slack.  If there is slack, then the activity does not need to be done on time , which is exactly the opposite definition of the critical path. 

When we shall discuss Crashing, we will see the change of project critical path due change in the duration of the activities. 

2.1.2.3 Activity on Arc (AoA) representation:
In AoA representation the activities are shown by Arcs. Each activity possess source node and sink node. The source represents the starting activity while sink node represents the events completing the activity. Arcs that represents the immediate successor activities of an activity should start with the sink node of that activity. This results in corresponding node becoming the source node of the immediate successor nodes. Parallel acrs are not allowed in networks, bringing in the need to use dummy activity.

Figure 2.3 AoA network diagram, Gotten from (Baweja, 2006) FREE PROJECT DOCUMENT ON AUTOMATION OF TIME COST TRADE OFF ANALYSIS
Figure 2.3 AoA network diagram, Gotten from (Baweja, 2006)


From the diagram above node 0 is the start event of activity 1, therefore starting the project . Node b represents completing of activity 2 and start for activities 4 and 5. Node f represents the completion of activity 8 and completion of the whole project . The time of completion of the last activity 8 defines the completion time of the project . Completion time of the project is also referred to as the project duration.
In project scheduling, each activity has its own duration and a cost. Most often, there may be alternative time/cost values for any activity. Cases like this, durations of activities are inversely proportional with their cost values. 
“For instance, in a tunnel project , drilling operation can be completed with a single drilling machine in a long time . To decrease the operation duration, additional drilling machines can be assigned to the operation. In such a case, the operation duration decreases; however, money paid to drilling machines increases. As more 7 drilling machines are assigned to the operation, duration continuously decreases and total cost increases. The time/cost pair for each alternative situation is called mode. Mode is simply the word used instead of “alternative” in project scheduling terminology.” (HAFIZOGLU, 2007) 

Examine the Project schedule.

Table 2.3 FREE PROJECT DOCUMENT ON AUTOMATION OF TIME COST TRADE OFF ANALYSIS
Table 2.3
Figure 2.4 Network diagram with 5 activities FREE PROJECT DOCUMENT ON AUTOMATION OF TIME COST TRADE OFF ANALYSIS
Figure 2.4 Network diagram with 5 activities
Node 1 serves as the source node of activity A and Node 2 as its sink node. Node 1 is also the starting of the project , the start event of activity B. we also see activities B and C have node 3 as its sink node. Node 2 is the source node for activity C and D. finally node 4 is the sink node for activities E and D and therefore the completion of the entire project .



Figure 2.5 Network diagram 5 activities showing critical path

Using the CPM we can now find our path and activities which is ACE. And from our critical path we can now find our project  duration, which is the sum of the durations of the activities on the critical path.
Our CP=ACE. Where:
Activity A= 4 weeks
Activity C= 2 weeks
Activity E= 5 weeks
CP= 4 + 2 + 5 (weeks)
CP= 11 weeks is the Total time needed to complete the project .

Figure 2.6 AoN networks ,Gotten from (P. Stelth, 2006) FREE PROJECT DOCUMENT ON AUTOMATION OF TIME COST TRADE OFF ANALYSIS
Figure 2.6 AoN networks ,Gotten from (P. Stelth, 2006)

Figure 2.7 AoA networks,Gotten from (P. Stelth, 2006) FREE PROJECT DOCUMENT ON AUTOMATION OF TIME COST TRADE OFF ANALYSIS
Figure 2.7 AoA networks,Gotten from (P. Stelth, 2006)

Earliest Starting Time, Latest Starting Time and Slack
EST, is the earliest time for an activity can begin after which all the preceding tasks before it have been completed without having to delay the entire project  or other task.
If we assume the starting time of the project be time  zero, where the first activity can be at time zero. The expected finish time can now be found just by adding the duration expected to the start time zero. 
Where the general rule stands that:
EF = ES + activity duration
To find ES and EF by passing through the project  network at the beginning to the end:
Earliest starting time of an activity without predecessors is zero.
Earliest finishing time of individual activity is the sum of its ES and the duration.
Earliest starting time  of an activity is the EF of its immediate predecessors.

The ES for the A activity (ESA) is 0 because there is nothing that has happened previously.



Figure 2.8 network diagram showing EST, Gotten from (Ahuja, Batra, & Gupta, 1984)

A starts. The EF time for activity A (EFA) is:
ESA = 0 EFA =  ESA  +  tA
          =  0 + 2
      =  2

Similarly, ESC = 0 EFC =  ESC  +  tC
          =  0 + 2
      =  2

The ES of any other activity will be equal to the largest of the EF of all its immediate predecessors. ESB equals EFA since the predecessor B's only is A; that is

ESB =  EFA

D also has two immediate predecessors, B and C:
EFB = 3 and EFC = 2
And so ESB = 3

LST, this is the latest time that an activity can be commenced without delaying the entire project . Meanwhile, Latest Finishing time of an activity is the latest that the activity can finish without delaying the whole project . At each node LS can be calculated with general rule
LS = LF – duration

To determine the LS and LF of the activity, we pass the network backwards, from the end to the beginning as follow:
Latest finish time of an activity without a successors equals the finishing time project .
Latest start time of an activity is the finish time  – the completion time .
Latest finish time of an activity is the smallest Latest start time of its successors.

The last activities on the network are E and F. The EF corresponding to those activities are 9 and 7 ; thus the earliest time the project  can be completed is 9 weeks, which now is the finish time for the project .LF of the last activity on any of the path is equivalent to the finishing time of the project  . Thus
LFE = 9 and LFF = 9
The LS for any of the activities is the LF – duration.
LFE = 9 LSE = LFE – tE
       = 9 – 3
       = 6
Similarly, LFF = 9 LSF = LFF – tF
       = 9 – 1
       = 8
Activity D is the predecessor of more than one activity. The LF in this case is the smallest LS values of its successors.
LSE = 6 and LSF = 8
LFD = 6

Figure 2.9 network diagram showing LST, Gotten from (Ahuja, Batra, & Gupta, 1984) FREE PROJECT DOCUMENT ON AUTOMATION OF TIME COST TRADE OFF ANALYSIS
Figure 2.9 network diagram showing LST, Gotten from (Ahuja, Batra, & Gupta, 1984)
2.1.3 SLACK
This is the difference between the Earliest Starting Time (EST) and Latest starting Time (LST).

2.2 PROJECT TIME-COST TRADE-OFF
In the earlier part of this literature we briefly introduced TCTO, and said it to be the relationship between the cost of the project and the time taken to complete the activities concerned in the whole project .
In today’s market driven economy reducing the projectscost and time is very critical. This relationship is now what we call time-cost trade-off

OBJECTIVES
The main and primary aim of TCTO analysis is to create a balance between reducing the original duration of the project afore determined by using the critical path method, in other to meet specific deadline, with the least cost. Also may include other reasons like:
- Complete the project within the predefined deadline date.
- Recovery of earlier delays.
- Prevent liquidated damages.
- Free key resources early for other project .
- Avoid bad weather conditions which may affect product quality.
- Get incentives for early completion.
- Increase project cash flow.
The project duration can be reduced by adjust overlaps between activities or just by reducing the duration of the activities. This increase in the direct cost at the decrease in the duration, for example; a simple cases arises from the introduction of overtime work by adding weekend and evening or late night shift. The completion time  or activity duration as calculated in weeks will be reduced. But bear in mind that extra wage and incentives will be paid for such extra and overtime work, thereby increasing the cost. (Elbeltagi, 2008)

According to (Kuar, 2010) in several situation, length of a project can be reduced by injecting additional resource to the activities. The impetus to shorten project may be in order to not incur late penalties or receive monetary incentives for quick and timely completion, to free up some resources to be used on other project . However shortening length of a project merely may reflect attempts to cut down the indirect cost , incurred with the running of the project . Which may include Facilities and equipment cost , supervision and labour and also personnel cost. Different options are available for the managers to make use of when shortening the project length, or crash certain activities. Most commonly practiced is the addition of extra funds and more efficient equipment. So in theory the project manager will able to reduce the indirect cost , by increasing direct cost expenses to speed the project up. “The goal of evaluating time-cost trade-offs is to identify a plan which will minimize the sum of the indirect and project costs.” (Kuar, 2010)
Activity duration can be reduced through the following actions.
- Applying multiple-shifts work.
- Working extended hours (over time ). 
- Offering incentive payments to increase the productivity.
- Working on weekends and holidays.
- Using additional resources.
- Using materials with faster installation methods.
- Using alternate construction methods or sequence. (Elbeltagi, 2008)

2.2.1 Activity Time-Cost Relationship
There exist a trade-off between the time and direct cost involved in the completion of a project activity the lesser the resource, the larger duration to complete the activity. Shortening the duration to an activity will always increase its direct cost , including; cost  of labour, equipment and materials. Although it should never be assumed that the amount of additional resource deployed and the activity duration are inversely related. So this is to say that; “that the work that can be done by one man in 16 weeks can be done by 16 men in 1 week”
“Considering just this activity in isolation and not taking into reference to the project  completion schedule, managers would take a duration which implies minimum direct cost , called the normal duration. At the other extreme, a manager might choose to complete the activity in the minimum possible time , called crashed duration, but at a maximum cost  .” (Elbeltagi, 2008)

Figure 2.10 Activity time relationship, Gotten from (Elbeltagi, 2008) FREE PROJECT DOCUMENT ON AUTOMATION OF TIME COST TRADE OFF ANALYSIS

Figure 2.10 Activity time relationship, Gotten from (Elbeltagi, 2008)

(Elbeltagi, 2008) Described this linear relation as shown in the image above, in between these two points mean that intermediate duration can be used. The line that’s connects the normal point (Lower Point) and the crash point (upper point) is called cost  of the activity.

Figure 2.11 Linear Time-cost relationship, Gotten from (Elbeltagi, 2008) FREE PROJECT DOCUMENT ON AUTOMATION OF TIME COST TRADE OFF ANALYSIS
Figure 2.11 Linear Time-cost relationship, Gotten from (Elbeltagi, 2008)

According to (Kuar, 2010) we have to understand that the duration of an activity cannot be completely reduced indefinitely. Crash time represents the expedited or the minimum duration time that an activity that can be reduced to, attempting to further crash above the limit will just increase the direct cost  without actually decreasing the time . The cost  of the activity that corresponds to the crash time is the crash cost  ; which is the least minimum direct cost   needed to reach the crash time ,
In contrast to the normal time and the normal cost  of the project  activity.

“The normal cost  is equal to the absolute minimum of the direct cost   required to perform an activity. The corresponding activity duration is known as the normal time 

This slope can be calculated by a mathematical method by getting the coordinates of the normal and crash points on the graph. The slope of crashing an activity is the incremental cost of fastening the activity, per unit period which can be calculated as:
Cost slope = crash cost – normal cost / normal duration – crash duration
1.
Cost slope = 
Where the parameters stand for:
CC = Crash Cost
NC = Normal Cost
NT = Normal Time
CT = Crash Time 
Where NT – CT = Maximum time  reduction for an activity.
(Kuar, 2010) Discussed that making rational decisions on activities to be crashed, and the extent to crash to, the project manager needs some level of information on the normal time and the crash time  as well as the normal cost and the crash cost  estimation for each activity and then a list containing all the activities present on the critical path. Most often the activities on the critical path are principle candidates for crashing, due to the fact crashing of non-critical activities have no real impact on the total project duration, looking from an economic stand point, it is the activities with the lower cost  that will be crashed first.
“Moreover, crashing should continue as long as the cost  to crash is less than the benefits received from crashing.” 
Sometimes these benefits may be gotten as incentive payments for completing the project  early, or they may reflect from savings of the indirect project cost  , or sometimes from both.

Figure 2.12 Direct cost, indirect cost, total cost, Gotten from (Goyal, 1975) FREE PROJECT DOCUMENT ON AUTOMATION OF TIME COST TRADE OFF ANALYSIS
Figure 2.12 Direct cost, indirect cost, total cost, Gotten from (Goyal, 1975)

From the figure above, the basic relationships exiting between indirect, direct and total project illustrated, where the crashing of activities brings about a decrease in the indirect cost  while it increases the direct cost  .
Taking from the words of (Kuar, 2010) described the relationship between indirect cost  and crashing having positive relation, indirect cost  has a positive linear curve that is more prone to the x = axis whereby a reduction in project length  leading to a decrease in indirect cost  whereas direct cost  has a negative relation with crashing the activity time showing a negative slope of the curve meaning there is more increase in cost  and little decrease of the project length.
The project cost  is the sum of all the direct cost  of the activities, therefore the project  direct cost  will increase when decrease its durations. While the indirect when decreased the project  direct cost   is also decreased, therefore it’s a linear function that exist between the indirect cost  and the project cost  .

Figure 2.13 linear function of indirect cost and project cost Gotten from (Mckenna, 1980) FREE PROJECT DOCUMENT ON AUTOMATION OF TIME COST TRADE OFF ANALYSIS
Figure 2.13 linear function of indirect cost  and project cost  Gotten from (Mckenna, 1980)

2.2.2 CRASHING:
Nabil Semaan and Joe Rizk defined Crashing as a specific group of project schedule compression which is executed for the purposes of reducing the total amount of time (which can also be refer to as project schedule duration). (Elmaghraby S, 1977) The reduction of the project duration usually take place after a proper analysis of all the possible project  duration reduction alternatives in which any and all methods to reach the apex schedule duration for the minimum additional cost   The aim of crashing a network is to attain the optimum project schedule. Crashing may also be needed to expedite the execution of a project , not minding the increase in cost  . (Grygo) Each stage of project design consumes some resources and so has cost  associated with it. In most of the project stage cost   will differ to some extent with the amount of time needed by the design of each stage. The total expenses of project , which is the sum total of the activities costs will also rely on the project duration, can be reduce to some extent. The objective is always to strike the equilibrium between the cost and time and to get an optimum project schedule. 

Basic steps to approach the crashing of a network
 1. The activity to crashing will start at the least slope value in activity to be selected in critical path (CPM).
 2. The project duration is crashing are starting in critical path because of the project duration is depend in critical path to be selected or work. 
3. The crashing activity are starting the number of days / time is reduced in selected path (CPM) is directly dependent of unselected path. Hence the unselected path is not away or overhead of the critical path.
4. The unselected path is less than or equal to the selected path at crashing duration
(Elmaghraby S, 1977)
 The basic and most common crashing method is the manual crashing method, where project  activities are crashed on a day by day basis. This crashing method, gives the project manager accurate results, but is consider  to consume a lot of time and requires a constant repetition of work and trials. (Portny, 2001) The main data values needed to perform this crashing method are four, along with the project network diagram. The project manager needs to prepare a comprehensive list of project activities, with the following attributes for each activity:, normal duration, normal cost  , crash cost  , and crash duration., evaluates the normal and crashed duration using the following Equations 1 and 2: 
Normal Duration = Estimated Quantity/ Normal rate of productivity
Crash duration  = Estimated Quantity / Normal duration- crash duration
(G. C. Brunnhoeffer, 2010)
Likewise, the project manager needs to attain the normal cost  and crashed cost  after calculating the material cost  , equipment cost  and manpower cost  . After which, the slope is Calculated, which is the daily increase in project  activity cost  using Equation 3:               
Slope = crash cost  –normal cost  /crash duration-normal duration  
At this level, the project manager calculate the critical paths, and choose from each path the critical activity (i.e. activities on the critical path) that has the lowest slope, attaining in the lowest cost  increase. Those slopes of the chosen activities are then added up, and compared to the slopes of common activities, or an addition of common activities and lowest slope activities. Thus, the activities chosen to be crashed need to have the minimum possible project cost  increase. After deciding the activities to be crashed, the project manager will minimize the duration of each of those selected activities by one unit of time , and maximize the project cost  by the sum of their slopes. In that way, the project maximum duration will be minimize by one unit of time . If the project manager wishes to bring down the project duration more, the same step will have to be applied again, until the desired decrease in the total project duration is achieved. When crashing the project , a new set of critical paths may emerge and the project manager needs to take those new critical paths into consideration. On the other hand, when crashing an existing project , the project manager will follow the same steps discussed above. Example. The following table gives data on normal time and cost  and crash time cost  for a project .
Example 1:
Examine the project schedule, the project Manager (PM) is now required to crash the project duration from its original duration to a specified duration of 110 days.
While assuming a daily indirect cost  of LE 100.

Table 2.4 FREE PROJECT DOCUMENT ON AUTOMATION OF TIME COST TRADE OFF ANALYSIS
Table 2.4 

Solution
With our formula the cost  slope of each activity and also their crashability of them. As displayed in the table below.
Table 2.5 FREE PROJECT DOCUMENT ON AUTOMATION OF TIME COST TRADE OFF ANALYSIS
Table 2.5 
We have our project network diagram to look like this.

Figure 2.14 network schedule with slope gotten from (Elbeltagi, 2008) FREE PROJECT DOCUMENT ON AUTOMATION OF TIME COST TRADE OFF ANALYSIS
Figure 2.14 network schedule with slope gotten from (Elbeltagi, 2008)

Network Parameters:
Critical Path: B-C-D-E
Project Duration: 140 Days
Project total normal cost  = sum of project direct of the activities in the schedule: 48300

Step 1: 
From our critical path we take the activity with the least scope, which is D with cost  slope = 60. Minimum reduction time = 10 days.

Figure 2.15 network schedule with critical path gotten from (Elbeltagi, 2008) FREE PROJECT DOCUMENT ON AUTOMATION OF TIME COST TRADE OFF ANALYSIS
Figure 2.15 network schedule with critical path gotten from (Elbeltagi, 2008)

New critical path is formed, B-F-E.
Duration: 130 Days
Direct cost  = 10 * 60 = LE 600
Project direct cost  = 48300 + 48900

Step 2:
At this stage Activity E will now be crashed, it also lies on two new critical path. So it reduced by 10 days. Resulting in activities turning critical.
New critical paths: B-C-D-E & B-F-E
Duration: 120 Days
Direct cost  = 10 * 120 = LE 1200
Project Direct cost  = 48900 + 1200 = LE 50100

Step 3:
Now at this stage crashing one activity will not be enough, so it can be resolved in by either crashing an activity on all critical paths or several activities on different critical paths. A and B are crashed together.
cost  slope of A and B: (100 + 200), by 5 days each.
Duration: 115 Days
Direct cost  = 5 * (10 + 60) = LE 1500
Project direct cost  = 50100 + 1500 = LE 51600

Step 4:
For the Final step, it is now required to decrease of an activity from each path. The duration of A will be crashed to 110 days, c to 35 days, and F to 55 days. To reduce the duration to 110 days. Resulting to project direct cost  of 5 * (100 + 600 + 300) = LE 5000
project direct = 51600 + 5000 = 56600
So this means it will take 56600 to hasten up the project Completion Time to 110 days.

2.3 Gap in Literature:
For the purpose of this research analysis of the previous system which existed before, this was mainly the manual way of carrying out this calculations.
It was time consuming.
Users can make mistake during calculations
Drawing of the network dependent of the know-how of the user and decisions to be made for the crashing is difficult.

CHAPTER 3
ANALYSIS

3.1 METHOD OF DATA COLLECTION
The materials used for this research where and are from different sources ranging from the type of information that was needed at the time and for what purpose. Data for this study where gotten from materials that came in all sorts of formats: Electronic (soft materials) like Books, Reports, Book section, technical papers, journals, presentations, articles and power point slide presentations and articles, Hardware copies like: Textbooks, Handouts etc. media files were also of help, this involved lectures and tutorials and from mere intuitions.
All these and more are sources of information that was used in this study for proper understanding, clarification and ideas, which were properly cited and referenced.

3.2 SYSTEM REQUIREMENTS
3.2.1 HARDWARE REQUIREMENTS
Hardware this is the physical part or components that have in one way or the other been necessary to the research and implementation of the system to be built. This being mainly a software project did not directly involve any major hardware part or component, these are the few hardware part used by reason of the research.
Personal computer
Which should have at least these specifications:
i. 1.0 Giga hertz processor
ii. 200 Giga byte hard disk
iii. Monitor display 15 Inches: wide screens are very essential for developing and coding, this help test the full functionality of the Graphical User Interface (GUI).
iv. Keyboard set
v. USB Disk port (for sharing data)
vi. USB Flash Drive: this will be used for data sharing between team members and also for back-up purposes.
vii. 4G RAM (random access memory)
Modem (Modulator-demodulator, for accessing the internet )

3.2.2 SOFTWARE REQUIREMENTS
Software are the intangible parts or components used in carrying the research and the development of the system to be built. These components are very necessary in carrying out the project .
Operating system
i. Windows
In this research windows 8 operating system will be used by choice and availability. The system used for the coding and documentation of this work has and will be done on windows 8 OS. All other software required will be installed on the Windows 8 OS.
Word processor
i. Microsoft office:
All the reports and documentation for this work will be typed/created using Microsoft Office Word.
Graphic software (for designing charts, symbols and icons): the various software available for such use. Example: 
Photoshop CS6
Corel Draw x7
Windows Paint
Click Chart 
Web browser (needed for accessing the internet): web browser help to connect or client system to the World Wide Web at different times and for different purposes which may include: Research and data gathering, download of files (various formats) and software tools available online. We made use of;
Firefox Developer edition 
Google Chrome

Python compiler and IDE(Integrated Development Environment ) Version 3.4.3
This will be the programming language used for developing the automated system.
QT Creator IDE and GUI developer: this used for designing application interface for across various Platforms and programming languages. It will be used to design the program user interface and controls.
Pycharm IDE (for coding, code testing, debugging and error resolution )
Atom Text Editor: it used for code generation and program code writing. Very suitable because of it additional functions like: 
Code wrapping
Auto fill
Interactive debugger
PySide QT
PyQt 4


 3.3 FUNCTIONAL REQUIREMENTS
Functional requirements (FRQ) of a system are those necessary parts that are needed by the system and cannot carry out its processes without them. These requirement are sometimes in the form of data inputs, functions or method to process these data and make use of them to perform actions or carry out processes and data/information output to show result, display data or information needed by the user, sometimes needed by other parts of the system.

3.3.1 INPUT REQUIREMENTS
These are Input needed by the system to carry out its functions and processes. These data input required may come from different sources which include:
Inputs given by the user through textboxes or other input controls on a form via a window.
Inputs from a database accessed by the program to retrieve stored data.
Inputs from a saved file or folder accessed by the program.

FRQ1:
The system should allow a new user to the system create a new project schedule. This feature is to allow user to start a new project  analysis with new and different values, so each project schedule data will be treated differently from previous schedule or new schedule.

FRQ2:
There should be textboxes for the user to input the attributes of each activity. These attributes are the additional information that is needed to properly analyze the activity record. Each schedule will contain the following columns:
Activity
Description
Precedence
Duration/Time
Normal duration
Crash duration
Normal cost  
Crash cost  
On the form all these are going to have individual textboxes for each unique row of data.

FRQ3:
The system must draw of network is to be worked from the various types, this system is going to be working on only two project network schedule:
Act on Node
Act on Arcs

FRQ4:
The user should be able to make changes or edit the values that he/she has put in, in case of errors before performing the calculations. This means that after the user has entered all the values the user can now crosscheck the input if they are correct.

3.3.2 PROCESSING REQUIREMENTS
These involve the processes and functions that will carried out by the system, either to fulfill some user action event or to perform computations on the data input provided to it form the various afore mentioned sources of input.

FRQ5:
The system should be able to draw the correct network diagram following the project diagram rules from the input data given by the user schedule.

FRQ6:
With the given input the system should be able to, after creating the network diagram find the Critical path and the correct project duration. This is because the project duration and the Critical path are very closely related.

FRQ7:
The system should be able to calculate the project cost. This is the project Normal cost  under all normal circumstances and all conditions are meet. This will be done by summing all the normal cost  of the critical activities (activities on the critical path).

FRQ8:
The system will now calculate and find the LST and EST of the initial project  schedule values. NOTE: this can only be done when the critical path and project duration have been deduced.

FRQ9:
The system will be able to find and get the Least Cost Slope for each activity and least compression time.

FRQ10:
The system should be able to crash each Critical path on the network; by reducing the activity duration and adding to the initial project cost  the least cost  scope of the activity in cost.   

3.3.3 OUTPUT REQUIREMENTS
This is concerned with result to be sent back to the user by the system after performing some computations with the input data given. This maybe some times come as a response to user action event.

FRQ11:
The system should be able to display the values that have been given by the user, after it has been entered into the system. This is to enable the user cross check all the inputs in-case of errors or mistakes.

FRQ12:
The system should be able to show on a form the network diagram when the user clicks on the draw network diagram button.
Also the system should be able to indicate on the network diagram the critical path and critical activities when it is drawn.

FRQ13:
The result from the computations performed for the LST and EST should be displayed on a form in a new table.

FRQ14:
When crashing the system should be outputting all the result of each crash step and the solutions provided for the step.

FRQ15:
The system should display the computed project  cost  and project durations on a form.

FRQ16:
The system should display the cost  slope of each activity on the schedule in a table created on a form after computation.

3.4 NON-FUNCTIONAL REQUIREMENTS
3.4.1 ACCURACY:
Each process, result carried out by the system must be accurate. Wrong result can lead to wrong estimations and predictions and therefore might affect the project in consideration. This will involve crosschecking data inputs and functions and methods output.
Accuracy of the system and the result will be achieved by;
Understanding the methods of performing this calculations manually.
Generating the pseudocode for solving it properly.
Finally, transferring and implementing this Pseudocode in the Python Programming language.
When checking for Accuracy in the system output we must consider the following:
Allow the user cross check all the input given before performing the calculation.
All activities must have a predecessor except the starting activity.
All activities must have a successor except the ending activity.
Every network diagram must have a Starting Activity and an Ending activity.
Activities on the network diagram must not have arrows crossing each other.
When activities are crashed the must not be crashed below their crash duration.
Cost after crashing should not be above the normal duration.

3.4.2 DEPENDABLE:
The system should always carry out the normal calculations on whatever data is given, without a failure or breaking down during it execution. Every output given by the system must be trust worthy.
This will be achieved by:
When entering input the controls will be validated to avoid wrong data entry
i. The activities must be in alphabets and nothing else.
ii. All durations must be in integer data types.
iii. The costs, normal cost must be below the crash cost.
iv. The durations, normal duration must be greater than the crash durations.
When crashing the critical path must be equal to each other. 


3.4.3 AVAILABLE:
The system should always be reached when and where ever it is needed by the customer. Uploading the software on line to make it available for downloading and installation.

3.4.5 USER-FRIENDLINESS:
The system must be very easy to use and learn. This starts from the Graphical User Interface, making sure:
All controls are fully and correctly labelled.
Tool tips will be offered on some controls that may be ambiguous to the user.
Constant color combinations on the forms and controls to avoid over whelming the user visually.
Fonts and font size are used properly. 

CHAPTER 4
Systems Design

4.1 Program design
In the course of this work, several factors were taken into consideration when designing the proposed system, the user-interface to interact with the user was designed properly in order to make the system easy to use and friendly in terms of object and controls, The algorithms were also developed and implemented to carry out the various calculations involved in the system design.

4.1.0 Flowchart
4.1.1 Program General Flowchart:
This describes all the activities to be carried out by the system, sequentially from the first process to the last. 

figure 4.1 program flow chart FREE PROJECT DOCUMENT ON AUTOMATION OF TIME COST TRADE OFF ANALYSIS
figure 4.1 program flow chart

4.1.2 Critical path method flow chart:
When the inputs are given the system uses the method in finding the path of the network diagram and from that it finds the critical path of the network.

Figure 4.2 critical path flowchart FREE PROJECT DOCUMENT ON AUTOMATION OF TIME COST TRADE OFF ANALYSIS
Figure 4.2 critical path flowchart

 4.1.3 Crashing system work:

Figure 4.3 Crashing method analysis FREE PROJECT DOCUMENT ON AUTOMATION OF TIME COST TRADE OFF ANALYSIS
Figure 4.3 Crashing method analysis 

4.2 INPUT DESIGN
GRAPHICAL USER INTERFACE
4.2.0 FORMS 
4.2.1 Splash screen:
The first form the user will see once he starts the program. This form will show for 3 seconds and the next will load to prompt the user on the next action to do.

Splash screen FREE PROJECT DOCUMENT ON AUTOMATION OF TIME COST TRADE OFF ANALYSIS
Splash screen 

4.2.2 Input Form for activities:
This will show to prompt the user to input the number of activities in the project  schedule and will load the next form which is the Mainform where all the calculation will be carried out.

Input Form for activities FREE PROJECT DOCUMENT ON AUTOMATION OF TIME COST TRADE OFF ANALYSIS
Input Form for activities

4.2.3 Main form : This is the form where the time-cost trade-off is computed, it enable a user enter the activities he/she want to calculate, normal time, crash cost  and the normal cost  of the project to be calculated. 

Main form FREE PROJECT DOCUMENT ON AUTOMATION OF TIME COST TRADE OFF ANALYSIS
Main form

4.2.4 INPUTS:
ID:
The user will input the activity ID for all the activities, note that all activities have different IDs. They must all be distinct and must present, because it is used to identify the activity.
DESCRIPTION:
Helps to tell the actual nature and name of the activity.
NORMAL DURATION:
This is the normal completion of the activity with normal activities. Necessary for the crashing computation.
CRASH DURATION:
This the completion time for the activity under increased resources and cost  . Necessary for the crashing computation.
NORMAL COST:
This is the amount the activity will cost  to be completed under the normal time . Necessary for the crashing computation.
CRASH COST:
This is the amount the activity will cost  to be completed under the crash time . Necessary for the crashing computation.

4.2.5 METHODOLOGIES AND ALGORITHMS INVOLVED:
4.2.5.1 Test project Schedule:
We are going to be considering the following set of activities in order to explain the methods and algorithms involved.

Table 4.1 FREE PROJECT DOCUMENT ON AUTOMATION OF TIME COST TRADE OFF ANALYSIS
Table 4.1

4.2.5.2 CRITICAL PATH:
STEPS INVOVLED:
Input all the activities that are involved in the project (A,B,C,D and E) 
Get all the activities that have no predecessor, in this case are (A and B) i.e. find the starting nodes Take each activity from the non-preceding activities and find all activities that are successors to them, repeat the process until there are no activities that have them as predecessors 
First Iteration: A, C and B 
Second Iteration: A, C, A, D and B 
Third Iteration: A, C, A, D and B, E 
Pick the tail activities and find all the activities that are successors to them and Iterate through them (C, D, E) and loop through them until there are no activities that have them as predecessors 

First Iteration: A, C, E, A, D and B, E 
The result yields the all the possible paths in the project which are: 
FREE PROJECT DOCUMENT ON AUTOMATION OF TIME COST TRADE OFF ANALYSIS
result
The algorithm for finding the critical path of the project schedule. This done by finding all the path on the network and then finding the path with highest duration when their activities are summed.

PSEUDO CODE:
START Program 
Get all activities in the project 
FOR each activity in the project 
Get_starting_nodes 
FOR each starting_node in All_activities: 
IF start_node matches activity: 
Connect successor back to preceding activity: 
RETURN Possible Paths 
ELSE: 
END Program

4.2.5.3 COST SLOPE:
For each activity in the project schedule we are to find the cost slope, this is done by using the formula.
CC-NC/ND-CD
Example: activity 1:
CC=4200, NC=3600, ND=4, CD=3
4200-3600/4-3=600
4.2.5.4 REDUCTION TIME:
All activities must also have a corresponding reduction time or sometimes called the Compression time . Gotten by the formula;
ND-CD
4-3=1

4.2.5.5 CRASHING:
STEPS INVOLVED:
Get the critical path from all path.
FREE PROJECT DOCUMENT ON AUTOMATION OF TIME COST TRADE OFF ANALYSIS
critical path
 • Get the least cost  slope and the activity with the least cost   slope of the activity on the critical path.
C=500
Check if the Project Cost < Total Crash Cost, if YES add the least cost  slope to the project cost  and reduce the activity duration until its crash duration is reached.
If multiple activities, it will be determined by comparing cost  slope of the individual activities with the sum of the group of activities that lie on the critical path.
Adjust the timing for the activities.
Get the cost  slope by multiplying the cost  with the appropriate time unit shortened.
Continue until no further shortening is possible and when the crashed point is reached. 

4.3 Output Design
4.3.1 Expected Reports
For the Critical path method analysis the system is meant to give back to certain outputs to the user after the calculations have been done. These output are the solution to the schedule, this reports are as follows:
With the durations the system will create the network diagram and find the critical activities. These are the activities on the critical path in which the project  completion will rest on.
With the critical activities identified the project duration will be found. This is done by adding the durations of the activities of the critical path.
The project normal cost  will be calculated by the summation of the cost  of the critical activities i.e their normal cost  will be added together to give the project duration.
Available compression time : this will be calculated by the system and outputted to the user on a summary form. ACT = (Normal duration – crash duration).
This specifies the amount and the level in which an activity duration can be reduced to get the crash duration of this activity. This is needed when reducing the critical paths of the project . On the summary form this will be added to the columns as a report. 
Cost slope:
All activities on the project schedule have their own individual cost  slope. This can be calculated by using the formula.
Cost slope = (Crash Cost – Normal Cost) / (Normal Time – Crash Time)
When crashing the activities after choosing the activity to be crashed the duration will be reduced and then the cost slope of the activity will be added to current project  cost of the project .
Critical path:
For crashing of activities
Project Cost:
This the total cost of the project all the activities on the schedule will be added.
Crash summary showing the crashing steps involved during the crashing process, each activity and their cost slope and the amount of times the activity was reduced and how much was incurred from reducing that activity.

4.3.2 Expected Result:


Object Name
Description
Widget Name
networkDiagram

This is a widget used to display the network Diagram

QPixmap

scrollArea

This widget provides a scroll view when the network diagram is larger than the default area specified for it in the form design

QScrollView

CriticalPathLabel

This is a label used to display the critical path

QLabel

ProjectDurationLabel

This is the label used to display the total duration of the project 

QLabel

ProjectCostLabel

This label displays the normal cost of the project 

QLabel

costSlopeTable
This table is used to display the result of the activity slope calculation.

QLabel

compressionTimeTable
This table is used to display the result of the activity reduction time 
.
QLabel

Title
Show the title of the result widget.
QLabel
costTitle
Shows the crash cost from the crash process
QLabel

Table 4.2 Object name
4.3.3 Form control Buttons


Button Name
Object name
Description
Widget name
Calculate

CalculateButton

This Button gets all the input from the table and performs all the necessary calculations

QPushButton
addRow
AddRowButton

This button adds a new row to the end of the table
QPushButton
delRow
DeleteRowButton

This button delete a new row to the end of the table
QPushButton
viewCrash
ViewCrashButton
Peforms the crash calculation and then displays the  result
QPushButton
clear
ClearButton
This button clears all the fields in the input table so the user can start afresh

QPushButton

Table 4.3 Form control

4.4 Test Plan


S/N
Test Case
Test Data
Expected Result
1
Invalid Number of activities

Activity number = -6

Display Error message and ask for correct Value again

2
Empty Activity ID
Activity ID = ” ”

Display Error message and ask for correct Value again
3
Empty Activity Normal Duration
Activity Normal Duration = “ ”
Display Error message and ask for correct Value again
4
Empty Activity Crash Duration
Activity Crash Duration = “ ”
Display Error message and ask for correct Value again
5
Empty Activity Normal cost
Activity Normal cost = “ ”
Display Error message and ask for correct Value again
6
Empty Activity Crash cost
Activity Normal cost = “ ”
Display Error message and ask for correct Value again
7
Invalid Activity Crash duration
Activity Crash duration = if crash duration > Normal duration
Display Error message and ask for correct Value again
8
Invalid Activity Crash cost
Activity Crash duration = if crash cost < Normal cost
Display Error message and ask for correct Value again


Table 4.4 Test plan

CHAPTER 5
SYSTEMS IMPLEMENTATION
This system was developed using Python Programming Language, with the python 3.4.3 interpreter which can found and downloaded from the python website www.python.org .For building the GUI (Graphical user interface), a python frame work called the PyQt4 was used. This offers a beautiful setup for designing full honest to goodness UI’s for the python programming language and other languages. 

5.0 WHY PYTHON 
Python was selected to be used for this project due to the following vital reasons:
Python is a high language which support simple syntax and makes it easier to learn and debug in case of errors.
It is a very widely applied language in all fields and therefore has a very large family of user that can provide assistance and solutions to problems when encountered.
It is an open source language that provides a very wide range of solutions to simple code issues because individual developers are allowed freedom in building of modules and packages, not have to wait for the python team for all solutions.
It is a cross platform language, this means it is supported across most widely use operating systems like: Windows, Mac, Linux.
Using this language was also a new challenge to improve and widen our programming language skill.

5.1 TEST PLAN
All the stated out cases are now to be carried on the system to check if it respond and gives the expected reports back as feedback.

Splash screen
This is the first screen when the program is started first. This screen takes 3 seconds to load.

Figure 5.1 Libra splash Screen FREE PROJECT DOCUMENT ON AUTOMATION OF TIME COST TRADE OFF ANALYSIS
Figure 5.1 Libra splash Screen
Main Form

Figure 5.2 main Default window FREE PROJECT DOCUMENT ON AUTOMATION OF TIME COST TRADE OFF ANALYSIS
Figure 5.2 main Default window
The table produced is as a result of the basic input of the number of activities imputed by the user at the first dialog prompt and it produces the corresponding number of rows and columns.

Main window Details

Figure 5.3  Main window details with the inputted FREE PROJECT DOCUMENT ON AUTOMATION OF TIME COST TRADE OFF ANALYSIS
Figure 5.3  Main window details with the inputted
Crash time Dialog
After the software generates the critical path and network diagram along with other parameters that will be generated, it will now prompt the user with a dialog box to enter the crash down time . When this is given it will now perform the crashing and generate the report.

Figure 5.4 Crash Time Dialog FREE PROJECT DOCUMENT ON AUTOMATION OF TIME COST TRADE OFF ANALYSIS
Figure 5.4 Crash Time Dialog

Crash Summary
When the crash process has been done the system will generate the crash report with the new cost and the crash time.
Figure 2.5 Main Window with Crash Summary FREE PROJECT DOCUMENT ON AUTOMATION OF TIME COST TRADE OFF ANALYSIS
Figure 2.5 Main Window with Crash Summary

5.1.1 INVALID NUMBER OF ACTIVITIES
If the user enter an uneven number of activities into the dialog box, the system is suppose return an error message. E.g if the user enters “0” as the number of activities.
Figure 5.6 Invalid activity number FREE PROJECT DOCUMENT ON AUTOMATION OF TIME COST TRADE OFF ANALYSIS
Figure 5.6 Invalid activity number

5.1.2 Empty Activity ID
If the user enters empty activity ID in the dialog box. The system should show the error message that the ID should not be empty.
Figure 5.7 Error Messages for empty id  FREE PROJECT DOCUMENT ON AUTOMATION OF TIME COST TRADE OFF ANALYSIS
Figure 5.7 Error Messages for empty id
5.1.3 Empty Activity Normal Duration
If the user should enter an empty activity normal duration, the system should show a dialog saying that the user has made an invalid entry. If the user does no put in any value.
Figure 5.8 Error message for empty normal duration FREE PROJECT DOCUMENT ON AUTOMATION OF TIME COST TRADE OFF ANALYSIS
Figure 5.8 Error message for empty normal duration
5.1.4 Empty Activity Crash Duration
If the user should enter an empty activity crash duration, the system should show a dialog saying that the user has made an invalid entry. If the user does no put in any value.

Figure 5.9 Error Message for empty crash duration FREE PROJECT DOCUMENT ON AUTOMATION OF TIME COST TRADE OFF ANALYSIS
Figure 5.9 Error Message for empty crash duration
5.1.5 Empty Activity Normal Cost
If the user should enter an empty activity normal cost, the system should show a dialog saying that the user has made an invalid entry. If the user does no put in any value into the normal cost  .
Figure 5.10 Error Message for empty normal cost FREE PROJECT DOCUMENT ON AUTOMATION OF TIME COST TRADE OFF ANALYSIS
Figure 5.10 Error Message for empty normal cost  
5.1.6 Empty Activity Crash Cost
If the user should enter an empty activity Crash cost, the system should show a dialog saying that the user has made an invalid entry. If the user does no put in any value into the Crash cost.
Figure 5.11Error Message for empty crash cost FREE PROJECT DOCUMENT ON AUTOMATION OF TIME COST TRADE OFF ANALYSIS
Figure 5.11Error Message for empty crash cost
5.1.7 Invalid Crash Duration
If the user should enter an invalid activity Crash duration, in which the crash duration is greater than the normal duration therefore is it valid. The system should show a dialog saying that the user has made an invalid entry to the crash duration cell. 

Figure 5.12 Error Message for invalid crash duration FREE PROJECT DOCUMENT ON AUTOMATION OF TIME COST TRADE OFF ANALYSIS
Figure 5.12 Error Message for invalid crash duration
5.1.8 Invalid Crash Cost
If the user should enter an invalid activity Crash Cost, in which the crash cost is lesser than the normal cost therefore is it invalid. The system should show a dialog saying that the user has made an invalid entry to the crash cost cell. 

Figure 5.13 Error Message for invalid crash cost FREE PROJECT DOCUMENT ON AUTOMATION OF TIME COST TRADE OFF ANALYSIS
Figure 5.13 Error Message for invalid crash cost
5.2 User Testing
The system was given to a random user to make use of and give feedback of the functioning of the system based on his/her observation without any help or assistance.
With the first dialog appearing to the user, asking the number of activities to be imputed.
Figure 5.14 Dialog for activities FREE PROJECT DOCUMENT ON AUTOMATION OF TIME COST TRADE OFF ANALYSIS
Figure 5.14 Dialog for activities
It shows to the user what the input to the dialog is to be used for and also provides a button to accept the input and cancel to exit the program.

Figure 5.16 Error Messages and Details FREE PROJECT DOCUMENT ON AUTOMATION OF TIME COST TRADE OFF ANALYSIS
Figure 5.16 Error Messages and Details
Figure 5.15 Error Messages for invalid number FREE PROJECT DOCUMENT ON AUTOMATION OF TIME COST TRADE OFF ANALYSIS
Figure 5.15 Error Messages for invalid number
If the user enters an invalid activity number is prompts the user to change the input used. 
The system has been put in a way that it does not allow the user to input none integer values.

Figure 5.17 Main Window with button FREE PROJECT DOCUMENT ON AUTOMATION OF TIME COST TRADE OFF ANALYSIS
Figure 5.17 Main Window with button
The program controls are used to perform different actions of the system. This buttons are clearly stated and properly named to help the user understand what they do from the names given.
The buttons have on mouse over actions to let the user to know they are clickable.
Figure 5.18 Error Message for empty normal duration FREE PROJECT DOCUMENT ON AUTOMATION OF TIME COST TRADE OFF ANALYSIS
Figure 5.18 Error Message for empty normal duration    
The system also provides error messages in case the user does not put in the proper details for the inputs. These error messages also contain details to help the user better understand the error made by the user.
Figure 5.19 Error Message with Details FREE PROJECT DOCUMENT ON AUTOMATION OF TIME COST TRADE OFF ANALYSIS
Figure 5.19 Error Message with Details
In the figure above the user made an invalid entry. This entry was invalid because for the crashing method, the crash duration is always less than the normal duration and therefore if it greater it is wrong. The error message tells the user the details of the error.
Figure 5.20 Critical path network diagram FREE PROJECT DOCUMENT ON AUTOMATION OF TIME COST TRADE OFF ANALYSIS
Figure 5.20 Critical path network diagram 
The critical path on the network diagram is indicated using a red line to run across the activities “critical activities”.

5.3 Documentation
Libra is a project management software in which the main aim is to automate and simplify the process of Time Cost Trade Off analysis. Libra also implements the automation Critical Path Method to find the project cost and draw the network diagram.

5.3.1 User manual
After launching Libra the software starts up with the splash screen that shows the user the name and version of the system, and then loads to the first dialog form for the user to input the number of activities. The system then loads into the main form for the user to fill in the details of all the activities to be computed.
Controls
There are several control buttons on the form for the user to carry out some simple events and actions, they include:
Calculate Button: this button when clicked performs the critical path calculation and displays network diagram, project duration, project normal cost, on the table displays the Slope and Available compression time for all the activities and the crash computation.
AddRow Button: when clicked adds a new row to the bottom of the table.
DelRow Button: when clicked deletes one row from the bottom of the table.
ViewCrash Button: Performs the crash calculation for the project .
Clear Button: clears all the details on the table for the user to input new set of input.
About: displays a dialog with the names of the developers.
Help: this show little about the problems.

5.3.2 Installation guide
Since cxfreeze was used to build a windows executable, computer users that are running on windows can simply insert the installation cd and run the “setup.exe” file, this will launch an installation wizard that the user can easily follow to install the software to their computer, the same step goes for users of Mac OSX, they can easily run the “setup.dmg” to install the software to their computer. 
For other users who are either running on Ubuntu (or other Debian based Linux Operating systems) and want to build the program from the source code, several packages have to be installed, they include Qt4, Pyside 1.22, Graphviz (dot-language), pip (python-package-installer) graphviz (python-package)

5.3.3 Troubleshooting
Troubleshooting the system will mainly include following the installation guide properly and performing all the necessary processes correctly. Any other that may occur will just be dealt by following the error messages and dialogs produced by the system. Libra is built with the user in mind to provide good, easy and full user friendliness. 


CHAPTER 6
CONCLUSION

6.1 Summary
This project work through critical design and dedicated supervision has been carried out and presented as a contribution to the use of knowledge and aimed at improving the programming skill of the researcher, automation of time cost trade off analysis has been designed to overcome the problems encountered with the existing system (i.e. manually) such as prone to delay in carrying out a project , wrong planning in executing a project , poor project decision making, . The new system is designed in such a way that project manager will be able to estimate the actual time needed in carrying out a project , get correct estimate of amount and resources needed in carrying out a project , make proper planning in cost and resources, execute a project faster than it normal time.

6.2 Evaluation
This research carried out on the automation  of time cost trade off was successful, very important and was made easier for the users. The software developed will really be of good help and great importance to project managers and all those involved in project control and schedule with or without the knowledge of the analysis.

6.3 Problems Encountered
The problems which where encountered in the course of this research came in different forms; firstly there was a challenge of understanding the topic given. So time was actually invested in understanding the logic behind the topic given. For developing the software a new programming language (python) was used, they was also a challenge of learning this new language, which we all were not familiar with and had to learn at the same time. They was also a challenge of conflicting ideals between group member on what to do, how to do it, and when to do it.

6.4 Lessons Learnt
Several lessons were learnt during the course of this research problem, like getting the chance to learn a new programing language, we were able to understanding the benefit of proper planning in carrying out a project , what to do in case of a delay in a project 
6.5 CONCLUSIONS
The conclusion of this project work is based on the advantage of automation of time cost trade off over a manual system. This project work in success has produced documentation software which can be used by a project manager.
Automation of time cost trade off analysis is an automated system that eliminates the manually time cost trade off system and lightens the burden that comes with manual documentation. This research work also draws the conclusion that automations of time cost trade off analysis saves time and ensure proper allocation of cost  as compared to the manual one. 

6.6 RECOMMENDATION 
More functionality could be added which due to time constraint and advanced skill in python programming language 


References
Ahuja, R. K., Batra, J., & Gupta, S. (1984). A parametic algoritm foe convex cost  network and related problem. European journal of operational research, 222.
Atmamand. (2002). Cost Analysis . Managerial Economics Edition, 161-190.
Battersby, A. (1964). Network analysis for planning and scheduling. New York: St Martins Press.
Baweja, S. S. (2006). CPM-schedules -why and how. AACE international Transactions, 22.1-22.5.
Elbeltagi, E. (2008). Construction Management. Project Management and Risk., 260-291.
Elmaghraby S, E. J. (1977). project planning and control by network model. New york.
Falk, James, E., Horowitz, a., & L., J. (1972). Critical path problems with concave costtime curves. Management science , 446-445.
Freier, & Keith. (2000). CPM scheduling -Getting back to basics. Cost Engineering, 7.
Fuckerson, D. R. (1961). A network Flow computation for project cost  curves. Management science, 167-178.
G. C. Brunnhoeffer. (2010). Crashing the schedule of an algorithmic approach with cavent and comment. New York.
Goyal, S. (1975). A simple CPM Time-cost trade off algorithm. Management science, 6.
Grygo, E. (n.d.). Downscaling for better proect information world. 
HAFIZOGLU, A. B. (2007). Discrete Time/Cost Trade-off Problem In Project Scheduling. India: Middle East Technical University.
Hillier, F. S., Lie, B., & Gerald, T. (2007). Network model optimzation of time-cost Trade off. Operations Research, 414-426.
Kuar, G. (2010). A Single Step CPM Time Cost Trade Off Algorithm. India: Thapar University Press.
Mckenna, C. (1980). Project Management: A Network Mode;. In Quantitative Methods For Public Decision Making. New York: McGraw Hill.
P. Stelth. (2006). Projects' Analysis Through CPM (Critical Path Method). School of Doctoral Studies(European Union) Journal, 10-52.
Portny, S. (2001). Project management for dummies. Brick and Hall Press.



APPENDIX

__init__.py
__author__ = 'icona'
Graph.py
import graphviz as gv

class DrawGraph:

    """

    This class handles the generation of datatypes(lists) to enable graphviz

    draw the graphs of the activities using activities on nodes

   """

    def __init__(self):

        pass

    @staticmethod

    def generate_paths(unordered):

        """

        This method gets all the paths in the project appends Start and Finish to them and then splits them into

        sublists of graph edges e.g [[A, B, C]] becomes [[[Start, A]], [[A, B]], [[B, C]], [[C, Finish]]]

        they're nested this way because label_graph will append a dictionary containing properties that style the

        directed graph when passed to graphviz, in this method we're still working with pure Activity objects, they've

        not been substitued with their id's

        :param unordered: List of all possible paths in the project

        :return: Nested Sublist of graph edges e.g [[A, B, C]] becomes [[[Start, A]], [[A, B]], [[B, C]], [[C, Finish]]]

        """

        paths = [[activity for activity in path] for path in unordered]

        graph_path = list()

        for b in paths:

            b.insert(0, 'Start')

            b.append('Finish')

            for c in zip(b, b[1:]):

                ind_lists = [list(c)]

                graph_path.append(ind_lists)

        print(graph_path)

        return graph_path

    @staticmethod

    def label_graph(graph_path):

        """

        This method styles the graph by adding a dictionary to each edge in graph_path, this attributes of the

        dictionary tell graphviz how to style our graph

        :param graph_path: nested sublists of edges in the graph

        :return: nested sublists where each activity has been substituted with it's id (so graphviz can draw)

        """

        for a in graph_path:

            a.append({})

           #  if the first element  == Start it will fail to get a duration and throw an AttributeError, if so set the

            #  duration as 0

            try:

                normal_dur = a[0][0].normal_dur

            except AttributeError:

                a[1].update({'label': str(0)})

                #  if the first activity after Start is a critical activity update the graph line to red

                if a[0][1].is_critical:

                    a[1].update({'color': 'red'})

                continue

                normal_dur = int(normal_dur) if normal_dur % 1 == 0.0 else normal_dur

            a[1].update({'label': str(normal_dur)})

            # if the first activity is a critical and the second activity is critical also update the graph line to red

            if a[0][0].is_critical and getattr(a[0][1], 'is_critical', False):

                a[1].update({'color': 'red'})

            #  if the first activity is critical we're at the end of the graph( =='Finish') update the graph line to red

            elif a[0][0].is_critical and a[0][1] == 'Finish':

                a[1].update({'color': 'red'})

        graph_path = [[[b.id if hasattr(b, 'id') else b for b in a[0]], a[1]] for a in graph_path]

        return graph_path

    @staticmethod

    def add_edges(graph, edges):

        """

        Method that loops through the list of edges and adds the edges and their properties to the graph

        :param graph: graphviz graph

        :param edges: Nested sublists of graph edges (represented by their id's not pure Activity objects)

        :return:

        """

        for e in edges:

            if isinstance(e[0], list):

                graph.edge(*e[0], **e[1])

            else:

                graph.edge(*e)

        return graph

    def draw(self, all_paths):

        """

        :param all_paths: all the possible paths in the project

        :return: None

       """

        graph = gv.Digraph(format='png')

        graph._head = 'strict digraph %s{' 

        graph.node_attr['shape'] = 'circle'

        graph.graph_attr['rankdir'] = 'LR'

        unlabelled_edges = self.generate_paths(all_paths)

        labelled_edges = self.label_graph(unlabelled_edges)

        print(labelled_edges)

        graphviz_path = self.add_edges(graph, labelled_edges)

        graphviz_path.render('graphs/network_diagram')

if __name__ == '__main__':

    main()
main.py
import os

import sys

import ctypes

import time

from paths import CriticalPath, QtGui

def main():

    app = QtGui.QApplication(sys.argv)

    app.setWindowIcon(QtGui.QIcon('img/libraicona.png'))

    if os.name == 'nt':

        # This is needed to display the app icon on the taskbar on Windows 7,8 and 10

        myappid = 'Libra....version 1.0'

      ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid)

        

    pixmap = QtGui.QPixmap('img/librasplash.png')

    splash = QtGui.QSplashScreen(pixmap)

    splash.show()

    app.processEvents()

    time.sleep(3)

    critical_path = CriticalPath()

    splash.finish(critical_path)

    critical_path.initialize_table()  # application starts from here by asking the user for the number of activities

    critical_path.show()

    sys.exit(app.exec_())



if __name__ == '__main__': main()
paths.py
import sys

from itertools import zip_longest

from ui.ui_paths import Ui_MainWindow, QtGui

from level import Level

from graph import DrawGraph





__author__ = 'icona'

class Activity:

    """basic structure of an activity having an id, predecessor, duration and a resource"""

    def __init__(self, activity_id, predecessor, nd, cd, nc, cc):

        self.id = activity_id

        self.predecessor = predecessor

        self.normal_dur = nd

        self.crash_dur = cd

        self.normal_cost = nc

        self.crash_cost = cc

        self.act_slope = None

        self.compression_time = None

        self.est = None

        self.lst = None

        self.is_critical = False

        self.crashed = False

        self.crash = 0

        self.level = [[], []]  # holds each activity resource when the resource loading exercise is carried out

    def __repr__(self):

        return self.id

class CriticalPath(QtGui.QMainWindow):

    """

    def __init__(self, parent=None):

        super().__init__(parent)

        self.ui = Ui_MainWindow()

        self.ui.setupUi(self)

        self.ui.calculateButton.clicked.connect(self.find_paths)

      self.ui.clearButton.clicked.connect(self.ui.tableWidget.clearContents)

        self.ui.addRowButton.clicked.connect(self.add_row)

        self.ui.delRowButton.clicked.connect(self.del_row)

        self.ui.viewCrashButton.clicked.connect(self.intiateCrash)

        self.actionHelp = QtGui.QAction('Help', self, statusTip="Help and Docs", triggered=self.help)

        self.actionHelp.setObjectName("actionHelp")

        self.ui.menubar.addAction(self.actionHelp)

        self.actionAbout = QtGui.QAction('About', self, statusTip="About Libra", triggered=self.about)

        self.actionAbout.setObjectName("actionAbout")

        self.ui.menubar.addAction(self.actionAbout)

        self.all_activities = None  # created because self.start_resource_levelling can't access all the activities

        self.result = None

        self.success = 'No'

        self.progress = 'Yes'

        self.resource_level = Level()

    def __lt__(self, other):

        return other.id > self.id

    def __gt__(self, other):

        return self.id > other.id      

    def about(self):

        QtGui.QMessageBox.about(self, "About Libra", "Libra Version 1.0\nAuthor: Adebayo Temitope\nEkeocha Marcus\n Botimi Matthew")



    def help(self):

        """ Display Help Information when the help button is clicked

        :return: None

        """

        QtGui.QMessageBox.about(self, "Help and Docs", "Documentation will soon Be available")



    def handle_errors(self, message, details):

        """

        :param message: Basic error message to be displayed

        :param details: Detailed error message to be displayed

        :return: None

        """

        msgbox = QtGui.QMessageBox()

        msgbox.setWindowTitle('Error!')

        msgbox.setText(message)

        msgbox.setDetailedText(details)

        msgbox.setStyleSheet('background-color: #00004c; color: #ff9900;')

        msgbox.exec()

        self.progress = 'No'



    def initialize_table(self):

        while True:

            num_rows, ok = QtGui.QInputDialog.getInteger(self, 'Input activity number', 'How many activities are involved?:')

            if ok:

                    if num_rows < 2 :

                        self.handle_errors('{} is not a valid activity number'.format(num_rows), 'Please enter a valid number')

                        continue

                    else:

                        self.ui.tableWidget.setRowCount(num_rows)

                        break

            else:

                sys.exit()



    def add_row(self):

        row = self.ui.tableWidget.rowCount()

        self.ui.tableWidget.insertRow(row)



    def del_row(self):

        row_count = self.ui.tableWidget.rowCount()

        if row_count > 1:

            self.ui.tableWidget.removeRow(row_count - 1)



    def get_properties(self):

        """

        Gets all the activities in the project and puts them into a list, carries out a lot of data validation

        to filter bad user input and displays the appropriate error message when necessary

        :return: All the activities in the project

        """

        all_activities = []  # reset self.activities when calling the method



        row_count = self.ui.tableWidget.rowCount()

        for row in range(0, row_count):

            activity_id = self.ui.tableWidget.item(row, 0)



            if activity_id is not None:

                activity_id = activity_id.text()

                if activity_id == '':

                    error = 'activity id cannot be empty'

                    details = 'please enter a value for the empty activity at row {}'.format(row+1)

                    self.handle_errors(error, details)

                else:

                    self.progress = 'Yes'

            else:

                error = 'activity id cannot be empty'

                details = 'please enter a value for the empty activity id  at row {}'.format(row+1)

                self.handle_errors(error, details)



            predecessor = self.ui.tableWidget.item(row, 2)

            if predecessor is not None:

                predecessor = predecessor.text()

                if predecessor == '':

                    predecessor = ('0',)

                else:

                    predecessor = tuple(predecessor.replace(',', ''))

            else:

                predecessor = ('0',)



            nd = self.ui.tableWidget.item(row, 3)

            if nd is not None:

                nd = nd.text()

                if nd == '':

                    error = 'normal duration cannot be empty'

                    details = 'please enter a value for the activity normal duration at row {}'.format(row+1)

                    nd = None

                    self.handle_errors(error, details)

            else:

                error = 'normal duration cannot be empty'

                details = 'please enter a value for the activity normal duration at row {}'.format(row +1)

                self.handle_errors(error, details)



            cd = self.ui.tableWidget.item(row, 4)

            if cd is not None:

                cd = cd.text()

                if cd == '':

                    error = 'crash duration cannot be empty'

                    details = 'please enter a value for the activity crash duration at row {}'.format(row + 1)

                    cd = None

                    self.handle_errors(error, details)

                if cd > nd:

                    error = 'crash duration is invalid'

                    details = 'please the crash duration cannot be greater than the Normal duration'

                    self.handle_errors(error, details)

            else:

                error = 'crash duration cannot be empty'

                details = 'please enter a value for the activity crash duration at row {}'.format(row + 1)

                self.handle_errors(error, details)



            nc = self.ui.tableWidget.item(row, 5)

            if nc is not None:

                nc = nc.text()

                if nc == '':

                    error = 'normal cost cannot be empty'

                    details = 'please enter a value for the activity normal cost at row {}'.format(row + 1)

                    nc = None

                    self.handle_errors(error, details)

            else:

                error = 'normal cost cannot be empty'

                details = 'please enter a value for the activity normal cost at row {}'.format(row + 1)

                self.handle_errors(error, details)



            cc = self.ui.tableWidget.item(row, 6)

            if cc is not None:

                cc = cc.text()

                if cc == '':

                    error = 'crash cost cannot be empty'

                    details = 'please enter a value for the activity crash cost at row {}'.format(row + 1)

                    cc = None

                    self.handle_errors(error, details)

                if cc < nc:

                    error = 'crash cost  is invalid'

                    details = 'please the crash cost cannot be less than the Normal cost'

                    self.handle_errors(error, details)

            else:

                error = 'crash cost cannot be empty'

                details = 'please enter a value for the activity crash cost at row {}'.format(row + 1)

                self.handle_errors(error, details)







            if nd is not None:

                try:

                    nd = float(nd)

                except ValueError:

                    message = '{} is not a valid normal duration please input a number\n'.format(nd)

                    details = 'you entered a character which is not a number, The normal duration is supposed to be a number'

                    self.handle_errors(message, details)



            if cd is not None:

                try:

                    cd = float(cd)

                except ValueError:

                    message = '{} is not a valid crash duration please input a number\n'.format(cd)

                    details = 'you entered a character which is not a number, crash duration is supposed to be a number'

                    self.handle_errors(message, details)



            if nc is not None:

                try:

                    nc = float(nc)

                except ValueError:

                    message = '{} is not a valid normal cost please input a number\n'.format(nc)

                    details = 'you entered a character which is not a number, normal cost is supposed to be a number'

                    self.handle_errors(message, details)

            if cc is not None:

                try:

                    cc = float(cc)

                except ValueError:

                    message = '{} is not a valid crash cost please input a number\n'.format(cc)

                    details = 'you entered a character which is not a number, crash cost is supposed to be a number'

                    self.handle_errors(message, details)



            '''set the properties based on what was gotten from the user'''

            activity = Activity(activity_id, predecessor, nd, cd, nc, cc)

            all_activities.append(activity)



        return all_activities



    @staticmethod

    def get_starting_nodes(all_activities):

       starting_nodes = list()

        for i in all_activities:

            for a in i.predecessor:

                if '0' in a:

                    starting_nodes.append(i)



        return starting_nodes



    def build_graph(self, all_activities, starting_nodes, result):

        node_found = False

        for count, st_nodes in enumerate(starting_nodes):

            for node in all_activities:

                if st_nodes.id in node.predecessor: 

                    node_found = True

                    if st_nodes.id != result[count][-1].id:

                        temp_list = result[count][:-1]

                        temp_list.append(node)

                        result.append(temp_list)

                    else:

                        result[count].append(node)



        if node_found:

            starting_nodes = list()

            for i in result:

                starting_nodes.append(i[-1])

            return self.build_graph(all_activities, starting_nodes, result)

        else:

            return result



    def get_est(self, all_activities):



        for activity in all_activities:



            if '0' in activity.predecessor:

                activity.est = # starting activities have an est of 0

            else:

                for pred in activity.predecessor:

                    for next_activity in all_activities:

                        try:

                            if pred == next_activity.id and activity.est is not None:

                                value = next_activity.est + next_activity.normal_dur

                                activity.est = max([activity.est, value])

                                activity.est = round(activity.est, 1)



                            if pred == next_activity.id and activity.est is None:

                                activity.est = next_activity.est + next_activity.normal_dur

                                activity.est = round(activity.est, 1)



                        except TypeError:

                                self.handle_errors('Problem calculating the est', 'there was a problem calculating the est please check your predecessors column for non-existing predecessors also the network diagram might not look correct')



        print('Earliest starting time')

        for act in all_activities:

            print(act.id, act.est)



    @staticmethod

    def get_lst(all_activities, project_duration):

        all_activities.reverse()

        for activity in all_activities:

            for succ in activity.predecessor:

                for prev_activity in all_activities:

                    if activity.lst is not None:

                        if succ == prev_activity.id and prev_activity.lst is not None:

                            value = activity.lst - prev_activity.normal_dur

                            prev_activity.lst = min([prev_activity.lst, value])

                            prev_activity.lst = round(prev_activity.lst, 1)



                        if succ == prev_activity.id and prev_activity.lst is None:

                            prev_activity.lst = activity.lst - prev_activity.normal_dur

                            prev_activity.lst = round(prev_activity.lst, 1)

                    else:

                        activity.lst = project_duration - activity.normal_dur

                        prev_activity.lst = round(prev_activity.lst, 1)



        print('Latest starting time')

        all_activities.reverse()

        for act in all_activities:

            print(act.id, act.lst)



    def format_ests_and_lsts(self, all_activities):



        ests = [act.est for act in all_activities]

        lsts = [act.lst for act in all_activities]





    def display_graph_and_labels(self, visual_path, project_duration, project_cost, project_crashedcost):

        self.ui.scrollArea.setStyleSheet('background-color: #ffffff')

        self.ui.criticalPathLabel.setWordWrap(True)

        self.ui.projectDurationLabel.setWordWrap(True)

        network_pixmap = QtGui.QPixmap('graphs/network_diagram.png')

        self.ui.networkDiagram.setPixmap(network_pixmap)

        self.ui.criticalPathLabel.setText(visual_path)

        self.ui.projectDurationLabel.setText('Normal duration of the project: {}'.format(int(project_duration)))

        self.ui.efficiencyTitle.setText('Normal cost {}'.format(int(project_cost)))





    @staticmethod

    def format_est_and_lst(nested_list):

        for i in nested_list:

            for count, j in enumerate(i):

                try:

                    if j % 1 == 0.0:

                        i[count] = int(j)

                except TypeError:

                    pass

        return nested_list



    def intiateCrash(self, all_activities):

        # calculates the cost slope for all the activities



        ls = all_activities



        for act in ls:

            cc = act.crash_cost

            nc = act.normal_cost

            nd = act.normal_dur

            cd = act.crash_dur

            C = cc - nc

            N = nd - cd

            slope = C / N

            act.act_slope = slope

            print(act.act_slope)



            nd = act.normal_dur

            cd = act.crash_dur

            com_time = nd - cd

            act.compression_time = com_time

        slop = [act.act_slope for act in all_activities]

        comt = [act.compression_time for act in all_activities]



        for count, (slop, comt) in enumerate(zip(slop, comt)):

            est_string = QtGui.QTableWidgetItem(str(slop))

            self.ui.tableWidget.setItem(count, 7, est_string)



            lst_string = QtGui.QTableWidgetItem(str(comt))

            self.ui.tableWidget.setItem(count, 8, lst_string)





    def final(self,c_path,all_paths,all_activities,project_cost,project_crashcost):

        crashtime, ok = QtGui.QInputDialog.getInteger(self, 'Input Crash Down Time', 'How long due you wish to crash to?:')

        while project_cost < project_crashcost:

            print(project_cost)

            c_path = list()

            c_path.append(([path for path in max(all_paths, key=lambda ls: sum(obj.normal_dur for obj in all_activities))]))

            project_duration = ((max([sum([node.normal_dur for node in object]) for object in all_paths])))

            print(project_duration)

            current_path = []

            for a in c_path:

                for b in a:

                    current_path.append(b)

                    print(b.id)

            uncrashed =list()

            yet = list()

            for a in current_path:

                if a.crashed == False:

                    uncrashed.append(a)

                else:

                    print(a.id)

            if len(uncrashed) == 0:

                for a in all_activities:

                    if a.crashed == False:

                        yet.append(a)

                least_cost = min(node.act_slope for node in yet)

            else:

                least_cost = min(node.act_slope for node in uncrashed)

            print(least_cost)

            if project_duration == crashtime:

                break

            for b in all_activities:

                if b.act_slope == least_cost:

                    b.normal_dur = b.normal_dur - 1

                    b.crash = b.crash + 1

                    project_cost = project_cost + least_cost



                if b.normal_dur == b.crash_dur:

                    b.crashed = True

                    print(b.crashed)

                b.normal_dur



                crashed = [act.crashed for act in all_activities]

                crash = [act.crash for act in all_activities]



                for count, (crashed, crash) in enumerate(zip(crashed, crash)):

                    est_string = QtGui.QTableWidgetItem(str(crashed))

                    self.ui.tableWidget.setItem(count, 9, est_string)



                    lst_string = QtGui.QTableWidgetItem(str(crash))

                    self.ui.tableWidget.setItem(count, 10, lst_string)

                self.ui.costTitle.setText('Crashable Cost {}'.format(int(project_cost)))

                self.ui.crashDuration.setText('Crashed Duration {}'.format(int(crashtime)))

                continue

            print("this is the new project cost", project_cost)



    def find_paths(self):



        all_activities = self.get_properties()  # gets all the activities and puts them into self.all_activities

        if self.progress == 'Yes':

            starting_nodes = self.get_starting_nodes(all_activities)



            result = [[node] for node in starting_nodes]

            all_paths = self.build_graph(all_activities, starting_nodes, result)

            if all_paths is not None:

                print('The possible paths in the project are')

                for i in all_paths:

                    print('==>'.join(str(a.id) for a in i))



                critical_path = ([path for path in max(all_paths, key=lambda ls: sum(obj.normal_dur for obj in ls))])

                c_path=list()

                c_path.append(([path for path in max(all_paths, key=lambda ls: sum(obj.normal_dur for obj in all_activities))]))

                visual_path = (','.join([str(a.id) for a in critical_path]))

                self.project_duration = ((max([sum([node.normal_dur for node in object]) for object in all_paths])))

                self.project_cost = (sum([object.normal_cost for object in all_activities]))

                self.project_crashcost = sum(node.crash_cost for node in all_activities)

                self.project_crashedcost = None



                visual_path = 'The critical path is: {}'.format(visual_path)





                self.get_est(all_activities)

                self.intiateCrash(all_activities)



                self.get_lst(all_activities, self.project_duration)





                for activity in all_activities:

                    if activity.est == activity.lst:

                        activity.is_critical = True





                self.format_ests_and_lsts(all_activities)





                # Draw the Network Diagram

                graph = DrawGraph()

                graph.draw(all_paths)



                self.display_graph_and_labels(visual_path, self.project_duration,self.project_cost,self.project_crashedcost)

                self.final(c_path, all_paths, all_activities, self.project_cost, self.project_crashcost )

            else:

                print('There was a problem calculating the critical path')

if __name__ == '__main__':

    main()
ui_paths.py
from PyQt4 import QtCore, QtGui



class Ui_MainWindow(object):

    def setupUi(self, MainWindow):

        MainWindow.setObjectName("MainWindow")

        MainWindow.resize(1100, 750)



        MainWindow.setMinimumSize(QtCore.QSize(995, 695))

        MainWindow.setMaximumSize(QtCore.QSize(1100, 750))

        MainWindow.setStyleSheet("background-color: #00004c; color: #ff9900;")

        self.centralwidget = QtGui.QWidget(MainWindow)

        self.centralwidget.setObjectName("centralwidget")

        self.tableWidget = QtGui.QTableWidget(self.centralwidget)

        self.tableWidget.setGeometry(QtCore.QRect(0, 40, 740, 301))

        self.tableWidget.setMaximumSize(QtCore.QSize(740, 301))

        self.tableWidget.setStyleSheet("background-color: #ffffff; color: #000;")

        self.tableWidget.setAlternatingRowColors(True)

        self.tableWidget.setObjectName("tableWidget")

        self.tableWidget.setColumnCount(11)

        self.tableWidget.setRowCount(0)

        item = QtGui.QTableWidgetItem()

        self.tableWidget.setHorizontalHeaderItem(0, item)

        item = QtGui.QTableWidgetItem()

        self.tableWidget.setHorizontalHeaderItem(1, item)

        item = QtGui.QTableWidgetItem()

        self.tableWidget.setHorizontalHeaderItem(2, item)

        item = QtGui.QTableWidgetItem()

        self.tableWidget.setHorizontalHeaderItem(3, item)

        item = QtGui.QTableWidgetItem()

        self.tableWidget.setHorizontalHeaderItem(4, item)

        item = QtGui.QTableWidgetItem()

        self.tableWidget.setHorizontalHeaderItem(5, item)

        item = QtGui.QTableWidgetItem()

        self.tableWidget.setHorizontalHeaderItem(6, item)

        item = QtGui.QTableWidgetItem()

        self.tableWidget.setHorizontalHeaderItem(7, item)

        item = QtGui.QTableWidgetItem()

        self.tableWidget.setHorizontalHeaderItem(8, item)

        item = QtGui.QTableWidgetItem()

        self.tableWidget.setHorizontalHeaderItem(9, item)

        item = QtGui.QTableWidgetItem()

        self.tableWidget.setHorizontalHeaderItem(10, item)

        self.resultWidget = QtGui.QFrame(self.centralwidget)

        self.resultWidget.setGeometry(QtCore.QRect(745, 2, 245, 338))

        self.resultWidget.setStyleSheet("QFrame{\n"

"border: 1px solid #ffffff;\n"

"}\n"

"\n"

"QLabel{\n"

"border:none;\n"

"}\n"

"\n"

"QMenu{\n"

"background-color: red;\n"

"}")

        self.resultWidget.setFrameShape(QtGui.QFrame.StyledPanel)

        self.resultWidget.setFrameShadow(QtGui.QFrame.Raised)

        self.resultWidget.setObjectName("resultWidget")

        self.efficiencyLabel = QtGui.QLabel(self.resultWidget)

        self.efficiencyLabel.setGeometry(QtCore.QRect(10, 190, 221, 17))

        font = QtGui.QFont()

        font.setFamily("Segoe Print")

        font.setPointSize(10)

        font.setWeight(75)

        font.setBold(True)

        self.efficiencyLabel.setFont(font)

        self.efficiencyLabel.setText("")

        self.efficiencyLabel.setObjectName("efficiencyLabel")

        self.criticalPathLabel = QtGui.QLabel(self.resultWidget)

        self.criticalPathLabel.setGeometry(QtCore.QRect(10, 40, 211, 51))

        font = QtGui.QFont()

        font.setFamily("Segoe Print")

        font.setPointSize(10)

        font.setWeight(75)

        font.setBold(True)

        self.criticalPathLabel.setFont(font)

        self.criticalPathLabel.setStyleSheet("")

        self.criticalPathLabel.setText("")

        self.criticalPathLabel.setObjectName("criticalPathLabel")

        self.projectDurationLabel = QtGui.QLabel(self.resultWidget)

        self.projectDurationLabel.setGeometry(QtCore.QRect(10, 120, 221, 41))

        font = QtGui.QFont()

        font.setFamily("Segoe Print")

        font.setPointSize(10)

        font.setWeight(75)

        font.setBold(True)

        self.projectDurationLabel.setFont(font)

        self.projectDurationLabel.setStyleSheet("")

        self.projectDurationLabel.setText("")

        self.projectDurationLabel.setObjectName("projectDurationLabel")

        self.efficiencyTitle = QtGui.QLabel(self.resultWidget)

        self.efficiencyTitle.setGeometry(QtCore.QRect(10, 170, 221, 30))

        font = QtGui.QFont()

        font.setFamily("Ubuntu")

        font.setPointSize(10)

        font.setWeight(70)

        font.setBold(True)

        self.efficiencyTitle.setFont(font)

        self.efficiencyTitle.setStyleSheet("font-family: \'Ubuntu\';")

        self.efficiencyTitle.setText("")

        self.efficiencyTitle.setObjectName("efficiencyTitle")



        self.costTitle = QtGui.QLabel(self.resultWidget)

        self.costTitle.setGeometry(QtCore.QRect(10, 220, 221, 30))

        font = QtGui.QFont()

        font.setFamily("Ubuntu")

        font.setPointSize(10)

        font.setWeight(70)

        font.setBold(True)

        self.costTitle.setFont(font)

        self.costTitle.setStyleSheet("font-family: \'Ubuntu\';")

        self.costTitle.setText("")

        self.costTitle.setObjectName("costTitle")



        self.crashDuration = QtGui.QLabel(self.resultWidget)

        self.crashDuration.setGeometry(QtCore.QRect(10, 270, 221, 35))

        font = QtGui.QFont()

        font.setFamily("Ubuntu")

        font.setPointSize(10)

        font.setWeight(70)

        font.setBold(True)

        self.crashDuration.setFont(font)

        self.crashDuration.setStyleSheet("font-family: \'Ubuntu\';")

        self.crashDuration.setText("")

        self.crashDuration.setObjectName("craashDuration")



        self.scrollArea = QtGui.QScrollArea(self.centralwidget)

        self.scrollArea.setGeometry(QtCore.QRect(0, 343, 991, 351))

        self.scrollArea.setStyleSheet("border: none;")

        self.scrollArea.setWidgetResizable(True)

        self.scrollArea.setObjectName("scrollArea")

        self.networkDiagram = QtGui.QLabel(self.scrollArea)

        self.networkDiagram.setGeometry(QtCore.QRect(10, 0, 981, 341))

        self.networkDiagram.setText("")

        self.networkDiagram.setObjectName("networkDiagram")

        self.scrollArea.setWidget(self.networkDiagram)

        self.horizontalLayoutWidget = QtGui.QWidget(self.centralwidget)

        self.horizontalLayoutWidget.setGeometry(QtCore.QRect(0, 0, 741, 39))

        self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget")

        self.horizontalLayout = QtGui.QHBoxLayout(self.horizontalLayoutWidget)

        self.horizontalLayout.setContentsMargins(0, 3, 0, 0)

        self.horizontalLayout.setObjectName("horizontalLayout")

        self.calculateButton = QtGui.QPushButton(self.horizontalLayoutWidget)

        font = QtGui.QFont()

        font.setFamily("Segoe Print")

        font.setPointSize(14)

        font.setWeight(50)

        font.setUnderline(False)

        font.setBold(False)

        self.calculateButton.setFont(font)

        self.calculateButton.setFocusPolicy(QtCore.Qt.ClickFocus)

        self.calculateButton.setStyleSheet("QPushButton {\n"

"background-color: #d0d0d0; \n"

"color: #ffffff; \n"

"border: 1px solid #ff9900; \n"

"}\n"

"\n"

"QPushButton:hover {\n"

"color: #333;\n"

"border: 1px solid #00008c;\n"

"}")

        self.calculateButton.setObjectName("calculateButton")

        self.horizontalLayout.addWidget(self.calculateButton)

        self.addRowButton = QtGui.QPushButton(self.horizontalLayoutWidget)

        font = QtGui.QFont()

        font.setFamily("Segoe Print")

        font.setPointSize(14)

        font.setWeight(50)

        font.setBold(False)

        self.addRowButton.setFont(font)

        self.addRowButton.setFocusPolicy(QtCore.Qt.ClickFocus)

        self.addRowButton.setStyleSheet("QPushButton {\n"

"color: #ffffff;\n"

"background-color: #d0d0d0; \n"

"border: 1px solid #ff9900; \n"

"}\n"

"\n"

"QPushButton:hover {\n"

"color: #333;\n"

"border: 1px solid #00004c;\n"

"}\n"

"")

        self.addRowButton.setObjectName("addRowButton")

        self.horizontalLayout.addWidget(self.addRowButton)

        self.delRowButton = QtGui.QPushButton(self.horizontalLayoutWidget)

        font = QtGui.QFont()

        font.setFamily("Segoe Print")

        font.setPointSize(14)

        font.setWeight(50)

        font.setBold(False)

        self.delRowButton.setFont(font)

        self.delRowButton.setFocusPolicy(QtCore.Qt.ClickFocus)

        self.delRowButton.setStyleSheet("QPushButton{\n"

"color: #ffffff; \n"

"background-color:  \n"

"tomato; \n"

"border: 1px solid tomato; \n"

"}\n"

"\n"

"QPushButton:hover {\n"

"color: #333;\n"

"border: 1px solid #ffffff;\n"

"}")

        self.delRowButton.setObjectName("delRowButton")

        self.horizontalLayout.addWidget(self.delRowButton)

        self.viewCrashButton = QtGui.QPushButton(self.horizontalLayoutWidget)

        font = QtGui.QFont()

        font.setFamily("Segoe Print")

        font.setPointSize(14)

        font.setWeight(50)

        font.setBold(False)

        self.viewCrashButton.setFont(font)

        self.viewCrashButton.setStyleSheet("QPushButton {\n"

"background-color: #d0d0d0; \n"

"color: #ffffff; \n"

"border: 1px solid #ff9900; \n"

"}\n"

"\n"

"QPushButton:hover {\n"

"color: #333;\n"

"border: 1px solid #00004c;\n"

"}")

        self.viewCrashButton.setObjectName("viewCrashButton")

        self.horizontalLayout.addWidget(self.viewCrashButton)

        self.clearButton = QtGui.QPushButton(self.horizontalLayoutWidget)

        font = QtGui.QFont()

        font.setFamily("Segoe Print")

        font.setPointSize(14)

        font.setWeight(50)

        font.setBold(False)

        self.clearButton.setFont(font)

        self.clearButton.setFocusPolicy(QtCore.Qt.ClickFocus)

        self.clearButton.setStyleSheet("QPushButton{\n"

"color: #ffffff; \n"

"background-color:  tomato; \n"

"border: 1px solid tomato; \n"

"}\n"

"\n"

"QPushButton:hover {\n"

"color: #333;\n"

"border: 1px solid #00004c;\n"

"}")

        self.clearButton.setObjectName("clearButton")

        self.horizontalLayout.addWidget(self.clearButton)

        MainWindow.setCentralWidget(self.centralwidget)

        self.menubar = QtGui.QMenuBar(MainWindow)

        self.menubar.setGeometry(QtCore.QRect(0, 0, 995, 21))

        self.menubar.setStyleSheet("background: #fff; color: #ff9900;")

        self.menubar.setObjectName("menubar")

        MainWindow.setMenuBar(self.menubar)



        self.retranslateUi(MainWindow)

        QtCore.QMetaObject.connectSlotsByName(MainWindow)



    def retranslateUi(self, MainWindow):

        MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "Libra", None, QtGui.QApplication.UnicodeUTF8))

        self.tableWidget.horizontalHeaderItem(0).setText(QtGui.QApplication.translate("MainWindow", "Id", None, QtGui.QApplication.UnicodeUTF8))

        self.tableWidget.horizontalHeaderItem(1).setText(QtGui.QApplication.translate("MainWindow", "Description", None, QtGui.QApplication.UnicodeUTF8))

        self.tableWidget.horizontalHeaderItem(1).setWhatsThis(QtGui.QApplication.translate("MainWindow", "The Description is optional and not needed for the calculation", None, QtGui.QApplication.UnicodeUTF8))

        self.tableWidget.horizontalHeaderItem(2).setText(QtGui.QApplication.translate("MainWindow", "Predecessor(s)", None, QtGui.QApplication.UnicodeUTF8))

        self.tableWidget.horizontalHeaderItem(3).setText(QtGui.QApplication.translate("MainWindow", "NormalDuration", None, QtGui.QApplication.UnicodeUTF8))

        self.tableWidget.horizontalHeaderItem(4).setText(QtGui.QApplication.translate("MainWindow", "CrashDuration", None, QtGui.QApplication.UnicodeUTF8))

        self.tableWidget.horizontalHeaderItem(5).setText(QtGui.QApplication.translate("MainWindow", "NormalCost", None, QtGui.QApplication.UnicodeUTF8))

        self.tableWidget.horizontalHeaderItem(6).setText(QtGui.QApplication.translate("MainWindow", "CrashCost", None, QtGui.QApplication.UnicodeUTF8))

        self.tableWidget.horizontalHeaderItem(7).setText(QtGui.QApplication.translate("MainWindow", "COST SLOPE", None, QtGui.QApplication.UnicodeUTF8))

        self.tableWidget.horizontalHeaderItem(8).setText(QtGui.QApplication.translate("MainWindow", "COMPRESSION TIME", None, QtGui.QApplication.UnicodeUTF8))

        self.tableWidget.horizontalHeaderItem(9).setText(QtGui.QApplication.translate("MainWindow", "CRASHED", None, QtGui.QApplication.UnicodeUTF8))

        self.tableWidget.horizontalHeaderItem(10).setText(QtGui.QApplication.translate("MainWindow", "CRASH", None, QtGui.QApplication.UnicodeUTF8))

        self.calculateButton.setText(QtGui.QApplication.translate("MainWindow", "Calculate", None, QtGui.QApplication.UnicodeUTF8))

        self.addRowButton.setText(QtGui.QApplication.translate("MainWindow", "Add row", None, QtGui.QApplication.UnicodeUTF8))

        self.delRowButton.setText(QtGui.QApplication.translate("MainWindow", "Delete row", None, QtGui.QApplication.UnicodeUTF8))

        self.viewCrashButton.setText(QtGui.QApplication.translate("MainWindow", "View Crash", None, QtGui.QApplication.UnicodeUTF8))

        self.clearButton.setText(QtGui.QApplication.translate("MainWindow", "Clear", None, QtGui.QApplication.UnicodeUTF8))


Post a Comment

0 Comments