/* * Copyright 2011 Steven Gribble * * This file is the solution to an exercise problem posed during * one of the UW CSE 333 lectures (333exercises). * * 333exercises is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * 333exercises is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with 333exercises. If not, see . */ // Lecture 7 livecoding example. #include #include #include #include #include #include #include "ll.h" #include "readlinefromfile.h" #include "graphops.h" static void usage(void); static void SlurpScientists(FILE *f); static void PrintGraph(FILE *f, char *scientist); static void SlurpScientists(FILE *f) { int count = 1; printf("slurping in and building collaboration graph...\n"); // Slurp in the graph file, a line at a time while (1) { char *s1 = NULL, *s2 = NULL, *s3 = NULL; int res; // read the "A" field res = ReadNextLine(f, &s1); if (res == 0) break; // read the "B" field res = ReadNextLine(f, &s2); assert(res != 0); // read the empty field separating the edges res = ReadNextLine(f, &s3); assert(res != 0); // add in A--B and B--A AddCollaboration(s1, s2); AddCollaboration(s2, s1); free(s1); free(s2); free(s3); // see if we should print status count++; if (count % 1000 == 0) { printf("read in %d of 175,691 edges...\n", count); } } } // Prints out the "friends + friends-of-friends" two // hop graph for the given scientist. static void PrintGraph(FILE *f, char *scientist) { // Graph the collaborator list for the scientist. Node *clist = GetCollaboratorList(scientist); if (clist == NULL) { usage(); } // Since clist is not NULL, this scientist has at // least one collaborator. So, we're ready to start // generating the graph. // print out the graph header fprintf(f, "graph sciencegraph {\n"); fprintf(f, " overlap=scale\n"); // iterate through the collaborators while(clist != NULL) { char *cname = clist->element; // print out the direct collaboration edge fprintf(f, " %s -- %s\n", scientist, cname); // print out the friend-of-friends edges if (1) { Node *cclist = GetCollaboratorList(cname); while (cclist != NULL) { char *c_of_c_name = (char *) cclist->element; // For each collaborator-of-collaborator, we test // to see if that c-of-c is also a c-of-scientist. // If so, we need to be careful to print out // that c-of-c edge only once, so we'll print it out // conditionally ordered by name. if (TestIfCollaborator(scientist, c_of_c_name)) { if (strcmp(cname, c_of_c_name) < 0) { fprintf(f, " %s -- %s\n", cname, c_of_c_name); } } else { fprintf(f, " %s -- %s\n", cname, c_of_c_name); } cclist = cclist->next; } } clist = clist->next; } // print out graph trailer fprintf(f, "}\n"); } static void usage(void) { fprintf(stderr, "Usage: ./gconsole collaboratorlist\n"); exit(-1); } int main(int argc, char **argv) { FILE *f; if (argc != 2) usage(); f = fopen(argv[1], "r"); if (f == NULL) usage(); SlurpScientists(f); fclose(f); while(1) { // Prompt the user and get input text, using Linux's readline() // helper function. char *sname = readline("scientist name: "); if (sname == NULL) exit(0); // Make sure the scientist provided to us is in the graph. if (GetCollaboratorList(sname) == NULL) { fprintf(stderr, "unknown scientist '%s'\n", sname); } else { // Open up output file for neato graph. char outnamebuf[256]; assert(strlen(sname) < 250); snprintf(outnamebuf, 256, "%s.neato", sname); f = fopen(outnamebuf, "w"); if (f == NULL) { fprintf(stderr, "couldn't open output file '%s'\n", outnamebuf); } else { PrintGraph(f, sname); fclose(f); } } free(sname); } return 0; }