# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python [conda env:.conda-gisenv] *
#     language: python
#     name: conda-env-.conda-gisenv-py
# ---

from collections import defaultdict 
import pandas as pd
import os
import math

#myfolder=r'F:\website\cmis6\Civilworks cost\Work Schedule' #office computer
myfolder=r'E:\Website_26_07_2020\cmis6\Civilworks cost\Work Schedule' #home computer
inputpath=os.path.join(myfolder,'Schdule Input.xlsx')


class GanttBar:
    def __init__(self,start,duration):
        self.start_day=start
        self.duration=duration
        self.finish_day=self.start_day+self.duration
        
    def addTaskUnit(self,unit):
        self.taskUnit=unit
    def addTaskVolume(self,volume):
        self.taskVolume=volume
        self.productionRate=math.ceil(self.taskVolume/self.duration)
        


# +
"""Class to represent graph"""
class Graph:
    def __init__(self,vertices):
        self.graph=defaultdict(list)
        self.V=vertices
        self.indeg0=[True]*(self.V+1)
        self.outdeg0=[True]*(self.V+1)
        self.edges=[]
        self.adj=defaultdict(list)
        self.visited=[False]*(self.V+1)
        self.path=[]
        self.durations=[]
        self.taskchains=[]
        self.tc_durations=[]
        self.minimum_start_date=[0]*self.V
    # function to add an edge to graph 
    def addEdge(self,u,v):
        self.graph[u].append(v)
        edge=(u,v)
        print(edge)
        self.edges.append(edge)
        # set indeg0[v] <- false 
        self.indeg0[v] = False  
        # set outdeg0[u] <- false 
        self.outdeg0[u] = False
        #print(self.graph[u])
    # A recursive function used by topologicalSort 
    def topologicalSortUtil(self,v,visited,stack):
        #mark the current node as visited
        visited[v]=True
        # Recur for all the vertices adjacent to this vertex      

        for i in self.graph[v]:
            if visited[i]==False:
                self.topologicalSortUtil(i,visited,stack)
         # Mark the current node as visited. 
        stack.insert(0,v)
    # The function to do Topological Sort. It uses recursive  
    # topologicalSortUtil() 
    def topologicalSort(self):
        # Mark all the vertices as not visited
        visited=[False]*(self.V+1)
        stack=[]
        # Call the recursive helper function to store Topological 
        # Sort starting from all vertices one by one 
        for i in range(self.V):
            if visited[i]==False:
                self.topologicalSortUtil(i,visited,stack)
        print (stack)
    def displayGraph(self):
        print("number of vertices={}".format(self.V))
        print(self.graph)
        print("indegree={}".format(self.indeg0))
        print("outdegree={}".format(self.outdeg0))
        print("edges of the graph......")
        print(self.edges)
        print("durations of tasks")
        print(self.durations)
    def dfs(self,s):
        k=0       
        #append the node in path
        #and set visited
        self.path.append(s)
        self.visited[s]=True
        # Path started with a node 
        # having in-degree 0 and 
        # current node has out-degree 0, 
        # print current path 
        if self.outdeg0[s] and self.indeg0[self.path[0]]:
            print(*self.path)
            self.taskchains.append(list(self.path))
            #for p in self.path:
                #self.taskchains[k].append(p)               
            #myvalue[k]=self.path
            #
        k=k+1
            #print(myvalue)
        # Recursive call to print all paths
        for node in self.graph[s]:
            if not self.visited[node]:
                self.dfs(node)
        # Remove node from path 
        # and set unvisited
        #return self.path
        #print(self.path)
        #self.taskchains[s]=self.path
        self.path.pop()
        self.visited[s]=False
        #return myvalue
    def print_all_paths(self):
        for i in range(self.V):
            if self.indeg0[i] and self.graph[i]:
                self.path=[]
                self.visited=[False]*(self.V+1)
                self.dfs(i)
                #print("path={}".format(p))
        
    def addDurations(self,duration_list):
        self.durations=duration_list
        
    def findPathdurations(self,path):
        total_duration=0
        for p in path:
            total_duration +=self.durations[p-1]
        return total_duration
    def findPathCumulativeDurations(self,path):
        total_duration=0
        path_cum=[]
        for p in path:
            total_duration +=self.durations[p-1]
            path_cum.append(total_duration) 
        self.tc_durations.append(path_cum)
        #return path_cum
    def findStratDateofTasks(self):
        for T in range(1,self.V+1):
            d=self.findMinimumStartDateOfTask(T)
            print("Task-{} sdate={}".format(T,d))
            self.minimum_start_date[T-1]=d
    def findMinimumStartDateOfTask(self,T):
        d=self.durations[T-1]
        duration_list=[]
        for tc,tcd in zip(self.taskchains,self.tc_durations):
            if T in tc:
                index=tc.index(T)
                sdate=tcd[index]-d+1
                duration_list.append(sdate)
                #print("task found in={}".format(index))
            #print("chain={} duration={}".format(tc,tcd))
        #print("duration of tasks no={} total_time={}".format(T,d))
        max_start_date=max(duration_list)
        return max_start_date
    def calculateStartOfAllTasks(self):
        for chain in self.taskchains:
            #duration=self.findPathdurations(chain)
            self.findPathCumulativeDurations(chain)
           
    def scheduleTask(self):
        self.topologicalSort() 
        #self.displayGraph()
        self.print_all_paths()
        print(self.taskchains)
        for chain in self.taskchains:
            #duration=self.findPathdurations(chain)
            self.findPathCumulativeDurations(chain)
        #self.calculateStartOfAllTasks()
        #print(self.tc_durations) 
        self.findStratDateofTasks() 
        self.findProjectDuration()
    def createGanttSchedule(self):
        mytasks=[]
        for i in range(1,self.V+1):
            
            duration=self.durations[i-1]
            sday=self.minimum_start_date[i-1]
            bar=GanttBar(sday,duration)
            mytasks.append(bar)
        return mytasks
    def findProjectDuration(self):
        project_durations=[]
        for tcd in self.tc_durations:
            dmax=max(tcd)
            #print(dmax)
            project_durations.append(dmax)
        self.finishDay=max(project_durations)
            
            
            
        
   
   
        
        


# +
#Python program to print topological sorting of a DAG 
from collections import defaultdict 

#Class to represent a graph 
class Graph2: 
	def __init__(self,vertices): 
		self.graph = defaultdict(list) #dictionary containing adjacency List 
		self.V = vertices #No. of vertices 

	# function to add an edge to graph 
	def addEdge(self,u,v): 
		self.graph[u].append(v) 

	# A recursive function used by topologicalSort 
	def topologicalSortUtil(self,v,visited,stack): 

		# Mark the current node as visited. 
		visited[v] = True

		# Recur for all the vertices adjacent to this vertex 
		for i in self.graph[v]: 
			if visited[i] == False: 
				self.topologicalSortUtil(i,visited,stack) 

		# Push current vertex to stack which stores result 
		stack.insert(0,v) 

	# The function to do Topological Sort. It uses recursive 
	# topologicalSortUtil() 
	def topologicalSort(self): 
		# Mark all the vertices as not visited 
		visited = [False]*self.V 
		stack =[] 

		# Call the recursive helper function to store Topological 
		# Sort starting from all vertices one by one 
		for i in range(self.V): 
			if visited[i] == False: 
				self.topologicalSortUtil(i,visited,stack) 

		# Print contents of stack 
		print (stack )




# +
g= Graph(6) 
g.addEdge(5, 2); 
g.addEdge(5, 0); 
g.addEdge(4, 0); 
g.addEdge(4, 1); 
g.addEdge(2, 3); 
g.addEdge(3, 1); 
  
print ("Following is a Topological Sort of the given graph")
g.topologicalSort() 


# +
def text2List(input_text):
    split_text=input_text.split(',')
    output_list=[int(x) for x in split_text ]
    return output_list
    
def buildGraph(input_df):
    shape=input_df.shape
    g=Graph(shape[0])
    print(shape)
    for index,row in input_df.iterrows():
        v=row['TaskNo']
        if row['Predecessor']!=-1:
            pred_text=str(row['Predecessor'])
            length=len(pred_text)
            if length >1:
                sources=text2List(pred_text)
                #print(sources)
            else:
                sources=[int(pred_text)]
            #print("sources={}".format(sources))
            for u in sources:
                g.addEdge(u,v)
            #print("predecosseo no={} value={}".format(length,pred_text))
            #print(len(pred_text))
            #print(pred_text)
    duration_list=list(input_df['Duration'])
    g.addDurations(duration_list)

    return g

        
# -

sheetName='WBS'
myframe=pd.read_excel(inputpath,sheet_name=sheetName)
myframe.fillna(0,inplace=True)
myframe

g=buildGraph(myframe)
g. scheduleTask()
print(g.finishDay)
mybars=g.createGanttSchedule()
g.findProjectDuration()

g.findProjectDuration()

# +

g.topologicalSort() 
g.displayGraph()
g.print_all_paths()

# -

mybars








print(g.durations)

for chain in g.taskchains:
    duration=g.findPathdurations(chain)
    cum=g.findPathCumulativeDurations(chain)    
    print("tasks={} total duration={}".format(chain,duration))    
    print("tasks={} cumdistance={}".format(chain, cum))   

print( g.tc_durations[1])

max_date=g.findMinimumStartDateOfTask(9)

g.findStratDateofTasks()

print(g.minimum_start_date)



StarcoderdataJupyterScriptsDedupFiltered