/*
* 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;
}