From b845dd1ad98692966399fa1562c01593b0b2f3ac Mon Sep 17 00:00:00 2001 From: Andrew Bailey Date: Thu, 3 May 2018 18:10:02 -0700 Subject: [PATCH] Moved python scripts into rosalind directory Edited rosalind5.py to show how to create doc strings and functions created inc and impl folders to hold .c and .h files created Makefile to compile (May need to be edited to work across linux and mac) created a crude test script to make sure things were working --- Makefile | 26 ++ Rosalind 5.py | 11 - Dictionary.c => impl/Dictionary.c | 224 +++++++++++++----- Dictionary.h => inc/Dictionary.h | 13 +- CountingDNA.py => rosalind/CountingDNA.py | 0 .../ReverseComplement.py | 0 .../TranscribingDnaRna.py | 0 hello_world.py => rosalind/hello_world.py | 0 Rosalind 1.py => rosalind/rosalind1.py | 0 Rosalind 2.py => rosalind/rosalind2.py | 0 Rosalind 3.py => rosalind/rosalind3.py | 0 Rosalind 4.py => rosalind/rosalind4.py | 0 rosalind/rosalind5.py | 36 +++ test_dictionary.c | 47 ++++ 14 files changed, 282 insertions(+), 75 deletions(-) create mode 100644 Makefile delete mode 100644 Rosalind 5.py rename Dictionary.c => impl/Dictionary.c (53%) rename Dictionary.h => inc/Dictionary.h (86%) rename CountingDNA.py => rosalind/CountingDNA.py (100%) rename ReverseComplement.py => rosalind/ReverseComplement.py (100%) rename TranscribingDnaRna.py => rosalind/TranscribingDnaRna.py (100%) rename hello_world.py => rosalind/hello_world.py (100%) rename Rosalind 1.py => rosalind/rosalind1.py (100%) rename Rosalind 2.py => rosalind/rosalind2.py (100%) rename Rosalind 3.py => rosalind/rosalind3.py (100%) rename Rosalind 4.py => rosalind/rosalind4.py (100%) create mode 100644 rosalind/rosalind5.py create mode 100644 test_dictionary.c diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..35327f2 --- /dev/null +++ b/Makefile @@ -0,0 +1,26 @@ +cxx = gcc -std=c99 + +cflags = -O3 -g -Wall --pedantic -fopenmp -funroll-loops -DNDEBUG + + +rootPath = ./ +libPath = ${rootPath}impl/ +headers = ${rootPath}inc/ +binPath = ${rootPath}bin/ + +libSources = ${libPath}*.c + + +all: dictionary.a + ${cxx} ${cflags} -I inc -I ${headers} -o ${binPath}test_dictionary ${rootPath}test_dictionary.c ${binPath}dictionary.a + chmod ugo+xwr ${binPath}test_dictionary + +dictionary.a : + mkdir -v -p ${binPath} + ${cxx} ${cflags} -I ${headers} -c ${libSources} + ar rc dictionary.a *.o + ranlib dictionary.a + rm *.o + mv dictionary.a ${binPath} + +.PHONY: all dictionary.a diff --git a/Rosalind 5.py b/Rosalind 5.py deleted file mode 100644 index b0781bd..0000000 --- a/Rosalind 5.py +++ /dev/null @@ -1,11 +0,0 @@ -string = "When I find myself in times of trouble Mother Mary comes to me Speaking words of wisdom let it be And in my hour of darkness she is standing right in front of me Speaking words of wisdom let it be Let it be let it be let it be let it be Whisper words of wisdom let it be And when the broken hearted people living in the world agree There will be an answer let it be For though they may be parted there is still a chance that they will see There will be an answer let it be Let it be let it be let it be let it be There will be an answer let it be Let it be let it be let it be let it be Whisper words of wisdom let it be Let it be let it be let it be let it be Whisper words of wisdom let it be And when the night is cloudy there is still a light that shines on me Shine until tomorrow let it be I wake up to the sound of music Mother Mary comes to me Speaking words of wisdom let it be Let it be let it be let it be yeah let it be There will be an answer let it be Let it be let it be let it be yeah let it be Whisper words of wisdom let it be" - -array = string.split(" ") -dictionary = {} -for word in array: - if word in dictionary: - dictionary[word] += 1 - else: - dictionary[word] = 1 -for word in dictionary: - print(word + " " + str(dictionary[word])) \ No newline at end of file diff --git a/Dictionary.c b/impl/Dictionary.c similarity index 53% rename from Dictionary.c rename to impl/Dictionary.c index 95b1f85..aafde8c 100644 --- a/Dictionary.c +++ b/impl/Dictionary.c @@ -7,13 +7,19 @@ #include #include"Dictionary.h" +//const int TABLESIZE = 180; +// for you need a constant here and based on what I saw 'const' doesnt mean that it is a C 'constant' +// https://stackoverflow.com/questions/2308194/shall-i-prefer-constants-over-defines/2308364#2308364 +// I set the tablesize to 3 so we can test chaining +#define TABLESIZE 3 + +// TODO you should define the structs in the header file so they are easy to use later // NodeObj -const int tablesize = 180; -int items = 0; struct NodeObj{ char* key; char* value; struct NodeObj* next; + struct NodeObj* prev; } NodeObj; // Node @@ -21,33 +27,41 @@ struct NodeObj{ // newNode() // constructor of the Node type struct NodeObj* newNode(char* k, char* v) { - struct NodeObj* N = calloc(1,sizeof(NodeObj)); - N->key = calloc(strlen(k)+1, sizeof(char)); - N->value = calloc(strlen(v)+1, sizeof(char)); + struct NodeObj* N = (struct NodeObj*) calloc(1,sizeof(NodeObj)); +// N->key = calloc(strlen(k)+1, sizeof(char)); +// N->value = calloc(strlen(v)+1, sizeof(char)); +// this memory was already allocated with the calloc call N->key = k; N->value = v; - N->next = NULL; return(N); } // freeNode() // destructor for the Node type -void freeNode(struct NodeObj** pN){ - if( pN!=NULL && *pN!=NULL ){ - free((*pN)->key); - free((*pN)->value); - free(*pN); - *pN = NULL; +int freeNode(struct NodeObj* pN){ + int n_nodes = 0; + if(pN != NULL){ + struct NodeObj* next_node = pN->next; + free(pN); + n_nodes++; + while (next_node != NULL){ + struct NodeObj* next_next = next_node->next; + free(next_node); + n_nodes++; + next_node = next_next; + } } + return n_nodes; } + + // DictionaryObj struct DictionaryObj{ struct NodeObj* root; - struct NodeObj* table[tablesize]; + struct NodeObj* table[TABLESIZE]; int numPairs; } DictionaryObj; -typedef struct DictionaryObj* Dictionary; // public functions ----------------------------------------------------------- @@ -63,15 +77,45 @@ Dictionary newDictionary(void){ // freeDictionary() // destructor for the Dictionary type -void freeDictionary(Dictionary* pD){ - if(pD!=NULL && *pD!=NULL ){ - if( !isEmpty(*pD) ) makeEmpty(*pD); - //free(*pD->table); - free(*pD); - *pD = NULL; +//void freeDictionary(Dictionary pD){ +// if(pD!=NULL){ +// if( !isEmpty(pD) ) makeEmpty(*pD); +// //free(*pD->table); +// free(*pD); +// *pD = NULL; +// } +//} + +void freeDictionary(Dictionary pD){ + if(pD!=NULL){ + if( !isEmpty(pD) ){ + makeEmpty(pD); + } + free(pD); + } +} + +// makeEmpty() +// re-sets D to the empty state. +// pre: none +void makeEmpty(Dictionary D){ + //setting top/bot to NULL and items to zero empties the Dictionary + int counter = 0; + int num_elements = 0; + while(num_elements < D->numPairs){ + if (D->table[counter] != NULL){ + + int nodes_deconstructed = freeNode(D->table[counter]); + D->table[counter] = NULL; + num_elements += nodes_deconstructed; + } + counter++; } + D->numPairs = 0; + } + // rotate_left() // rotate the bits in an unsigned int unsigned int rotate_left(unsigned int value, int shift) { @@ -98,8 +142,9 @@ unsigned int pre_hash(char* input) { // input points to first char in string // hash() // turns a string into an int in the range 0 to tableSize-1 int hash(char* key){ - int a = pre_hash(key); - a = a%(tablesize); +// This also needs to be unsigned because you are converting an unsigned int to int so it could become negative + unsigned int a = pre_hash(key); + a = a%(TABLESIZE); return a; } // isEmpty() @@ -128,15 +173,26 @@ struct NodeObj* find(Dictionary D, char* k){ int hashkey = hash(k); if(D->table[hashkey] == NULL) return NULL; - while(D->table[hashkey]!= NULL) - { - if(D->table[hashkey]->key == k) - return D->table[hashkey]; - if(D->table[hashkey]->next == NULL) - break; - D->table[hashkey] = D->table[hashkey]->next; - } - return NULL; + if(D->table[hashkey]->key == k) + return D->table[hashkey]; + if(D->table[hashkey]->next == NULL) + return NULL; + else { + struct NodeObj* node = D->table[hashkey]->next; + + while(node != NULL) + { + if(node->key == k) + return node; + if(node->next == NULL) + return NULL; + else{ + node = node->next; + } + } + return NULL; + + } } // size() @@ -155,18 +211,19 @@ int size(Dictionary D){ // such value v exists. // pre: none char* lookup(Dictionary D, char* k){ - if(items == 0) - return NULL; //if the Dictionary is NULL throw an error - if( D==NULL ){ + if( D == NULL ){ fprintf(stderr, "Dictionary Error: calling lookup() on NULL Dictionary reference\n"); exit(EXIT_FAILURE); } + if(D->numPairs == 0) + return NULL; + //initialize N the key to be found so the corresponding value can be found struct NodeObj* N = find(D, k); if (N == NULL){ return NULL; - }else{ + } else{ return N->value; } } @@ -182,20 +239,34 @@ void insert(Dictionary D, char* k, char* v){ fprintf(stderr, "Dictionary Error: cannot call insert on a NULL Dictionary"); exit(EXIT_FAILURE); } - if (lookup(D, k) != NULL){ - fprintf(stderr, "Dictionary Error: cannot insert duplicate keys\n"); - exit(EXIT_FAILURE); - } //intialize a new Node object if current node is empty struct NodeObj* N = newNode(k, v); D->numPairs++; - items = D->numPairs; int hashIndex = hash(k); - while(D->table[hashIndex] != NULL) - { - D->table[hashIndex] = D->table[hashIndex]->next; + + struct NodeObj* node = D->table[hashIndex]; + if (node != NULL){ + for (int i =0; i< D->numPairs; i++) + { + if(node->key == k){ + // this should never happen + fprintf(stderr, "Dictionary Error: cannot insert duplicate keys\n"); + exit(EXIT_FAILURE); + } + if(node->next == NULL){ + node->next=N; + N->prev=node; + break; + } + else{ + struct NodeObj* node2 = node->next; + node = node2; + } + } + + } else { + D->table[hashIndex] = N; } - D->table[hashIndex] = N; } // delete() @@ -209,39 +280,66 @@ void delete(Dictionary D, char* k){ } //if the current key in the dictionary does not match the key we are looking //for, move on. - free(&D->table[hash(k)]); +// Find node, delete after reconnecting nodes +// recreate connection between linked list +// this is pretty hacky and there should be functions for all these linked list operations + struct NodeObj* node = find(D, k); + if (node->next != NULL || node->prev != NULL){ + struct NodeObj* prev_node = node->prev; + struct NodeObj* next_node = node->next; + + if (prev_node != NULL){ + if (next_node != NULL) { + prev_node->next = node->next; + node->next->prev = prev_node; + } else { + prev_node->next = NULL; + } + } else { + D->table[hash(k)] = next_node; + } + } else { + D->table[hash(k)] = NULL; + } + free(node); D->numPairs--; - items--; } // makeEmpty() // re-sets D to the empty state. // pre: none -void makeEmpty(Dictionary D){ - //setting top/bot to NULL and items to zero empties the Dictionary - int counter = 0; - while(&(D->table[counter]) != NULL && counter < D->numPairs){ - struct NodeObj* N; - *N = *D->table[counter]; - D->table[counter]=N->next; - freeNode(&N); - N = NULL; - counter++; - } - D->numPairs = 0; - -} +//void makeEmpty(Dictionary D){ +// //setting top/bot to NULL and items to zero empties the Dictionary +// int counter = 0; +// while(&(D->table[counter]) != NULL && counter < D->numPairs){ +// struct NodeObj* N; +// *N = *D->table[counter]; +// freeNode(N); +// N = NULL; +// counter++; +// } +// D->numPairs = 0; +// +//} void printDictionary(FILE* out, Dictionary D){ if(D==NULL){ fprintf(stderr, "Dictionary Error: printDictionary() called on NULL Dictionary reference\n"); exit(EXIT_FAILURE); } - for(int i =0; i< tablesize; i++){ - while(D->table[i] != NULL){ + for(int i =0; i< TABLESIZE; i++){ +// BORA: you were reassigning each value during that while loop so basically you assign values to NULL + if (D->table[i] != NULL){ fprintf(out, "%s %s \n" , D->table[i]->key, D->table[i]->value); - D->table[i] = D->table[i]->next; + struct NodeObj* node = D->table[i]->next; +// check the chained dictionary + while (node != NULL) { + fprintf(out, "%s %s \n" , node->key, node->value); + struct NodeObj* node2 = node->next; + node = node2; + } } } } + diff --git a/Dictionary.h b/inc/Dictionary.h similarity index 86% rename from Dictionary.h rename to inc/Dictionary.h index a8d6bf7..9531404 100644 --- a/Dictionary.h +++ b/inc/Dictionary.h @@ -7,6 +7,7 @@ #define _DICTIONARY_H_INCLUDE_ + // Dictionary // Exported reference type typedef struct DictionaryObj* Dictionary; @@ -17,7 +18,13 @@ Dictionary newDictionary(void); // freeDictionary() // destructor for the Dictionary type -void freeDictionary(Dictionary* pD); +//void freeDictionary(Dictionary* pD); + +void freeDictionary(Dictionary pD); + +// freeNode() +// destructs entire NodeObj linked list +//int freeNode(struct NodeObj* pN); // isEmpty() // returns 1 (true) if S is empty, 0 (false) otherwise @@ -55,4 +62,8 @@ void makeEmpty(Dictionary D); // prints a text representation of D to the file pointed to by out void printDictionary(FILE* out, Dictionary D); + +struct NodeObj* find(Dictionary D, char* k); + + #endif diff --git a/CountingDNA.py b/rosalind/CountingDNA.py similarity index 100% rename from CountingDNA.py rename to rosalind/CountingDNA.py diff --git a/ReverseComplement.py b/rosalind/ReverseComplement.py similarity index 100% rename from ReverseComplement.py rename to rosalind/ReverseComplement.py diff --git a/TranscribingDnaRna.py b/rosalind/TranscribingDnaRna.py similarity index 100% rename from TranscribingDnaRna.py rename to rosalind/TranscribingDnaRna.py diff --git a/hello_world.py b/rosalind/hello_world.py similarity index 100% rename from hello_world.py rename to rosalind/hello_world.py diff --git a/Rosalind 1.py b/rosalind/rosalind1.py similarity index 100% rename from Rosalind 1.py rename to rosalind/rosalind1.py diff --git a/Rosalind 2.py b/rosalind/rosalind2.py similarity index 100% rename from Rosalind 2.py rename to rosalind/rosalind2.py diff --git a/Rosalind 3.py b/rosalind/rosalind3.py similarity index 100% rename from Rosalind 3.py rename to rosalind/rosalind3.py diff --git a/Rosalind 4.py b/rosalind/rosalind4.py similarity index 100% rename from Rosalind 4.py rename to rosalind/rosalind4.py diff --git a/rosalind/rosalind5.py b/rosalind/rosalind5.py new file mode 100644 index 0000000..44cc555 --- /dev/null +++ b/rosalind/rosalind5.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python +"""Count words in a sentence""" +######################################################################## +# File: rosalind5.py +# executable: rosalind5.py +# +# Author: Bora Mutluoglu +# History: 05/3/18 Created +######################################################################## + + +def count_words(input_sentence): + """Count words in a string and return dictionary of counts of words + :param input_sentence: sentence to split on spaces and count words""" + # split on spaces to get all words + words = input_sentence.split(" ") + # I wouldn't name something dictionary because it is not informative + word_counts = {} + for word in words: + if word in word_counts: + word_counts[word] += 1 + else: + word_counts[word] = 1 + return word_counts + + +def main(): + """Always have a main function if you want to execute the file""" + sentence = "When I find myself in times of trouble Mother Mary comes to me Speaking words of wisdom let it be And in my hour of darkness she is standing right in front of me Speaking words of wisdom let it be Let it be let it be let it be let it be Whisper words of wisdom let it be And when the broken hearted people living in the world agree There will be an answer let it be For though they may be parted there is still a chance that they will see There will be an answer let it be Let it be let it be let it be let it be There will be an answer let it be Let it be let it be let it be let it be Whisper words of wisdom let it be Let it be let it be let it be let it be Whisper words of wisdom let it be And when the night is cloudy there is still a light that shines on me Shine until tomorrow let it be I wake up to the sound of music Mother Mary comes to me Speaking words of wisdom let it be Let it be let it be let it be yeah let it be There will be an answer let it be Let it be let it be let it be yeah let it be Whisper words of wisdom let it be" + word_counts = count_words(sentence) + for word in word_counts: + print(word + " " + str(word_counts[word])) + + +if __name__ == '__main__': + main() diff --git a/test_dictionary.c b/test_dictionary.c new file mode 100644 index 0000000..7ec96b8 --- /dev/null +++ b/test_dictionary.c @@ -0,0 +1,47 @@ +//Bora Mutluoglu | bmutluog | 1564633 | cs12b | March 17, 2018 | +//Dictionary.c using a hash table implementation instead of the ADT +//or BST implementation +#include +#include"Dictionary.h" + + + +int main(int argc, char *argv[]) { + Dictionary mydict = newDictionary(); + int empty = isEmpty(mydict); + fprintf(stderr, "size = %d\n", size(mydict)); + if (empty){ + fprintf(stderr, "Dictionary is empty!\n"); + } else { + fprintf(stderr, "Dictionary is NOT empty!\n"); + } + + char *hey = "Hey"; + insert(mydict, hey, "It Works!"); + fprintf(stderr, "size =%d\n", size(mydict)); + int empty2 = isEmpty(mydict); + if (empty2){ + fprintf(stderr, "Dictionary is empty!\n"); + } else { + fprintf(stderr, "Dictionary is NOT empty!\n"); + } + + find(mydict, "as"); + lookup(mydict, "as"); + insert(mydict, "as", "thing"); + printDictionary(stderr, mydict); + + insert(mydict, "a", "thing"); + insert(mydict, "another", "thing"); + + delete(mydict, "a"); + + char *itworks = lookup(mydict, hey); + fprintf(stderr, "%s\n", itworks); + + freeDictionary(mydict); + +// struct NodeObj *mynode = newNode("a", "b"); +// free(mynode); + return 0; +}