Problem in output of CS50 week 2 Problem set readability - c

The code is ment to take user input, then compute how many words, letters and sentences are in the input. Then calculate the index.
index = 0.0588 * L - 0.296 * S - 15.8
Where L = average number of letters per hundred words and S is the average number of sentences per 100 words in the text.
if the index is in less than one print "below grade 1" and if it is greater than 16 print "greater than 16". and anything in between should be grade __ (where __ = the index number), For example, if index number = 12. Print grade 12.
In my case the code seems to only be showing the correct output for grades less than 1 and more than 16 and ignoring the other cases.
More details and inputs to the problem here - https://cs50.harvard.edu/x/2022/psets/2/readability/
#include <cs50.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <math.h>
int count_letters(string text);
int count_sentances(string text);
int count_words(string text);
int Grade_level(int i, int j, int k);
int main(void)
{
string text = get_string("Text = ");
int num_letters = count_letters(text);
int num_sentances = count_sentances(text);
int num_words = count_words(text);
int gradeLevel = Grade_level(num_letters, num_sentances, num_words);
if (gradeLevel < 1)
{
printf("Before Grade 1\n");
}
else if (gradeLevel > 16)
{
printf("Grade 16+\n");
}
else
{
printf("Grade level %d\n", gradeLevel);
}
}
int count_letters(string text)
{
int letters = 0;
for (int i = 0; i < strlen(text); i++)
{
if (isalpha(text[i]))
{
letters++;
}
}
return letters;
}
int count_sentances(string text)
{
int sentances = 0;
for (int i = 0; i < strlen(text); i++)
{
if (text[i] == '.'|| text[i] == '!' || text[i] == '?')
{
sentances++;
}
}
return sentances;
}
int count_words(string text)
{
int words = 1;
for (int i = 0; i < strlen(text); i++)
{
if (text[i] == ' ')
{
words++;
}
}
return words;
}
int Grade_level(int num_letters, int num_words, int num_sentances)
{
float index, L, S;
L = (num_letters/num_words) * 100;
S = (num_sentances/num_words) * 100;
index = (0.0588 * L) - (0.296 * S) - 15.8;
index = round(index);
return (int)index;
}

Related

Why does my code repeat the output of the grade level when ran. This is Harvard's CS50 pset2 called readability

I thought the code was fine until I tested using "Red fish, blue fish, one fish, two fish." and it gave me the correct output (Below Grade 1) but it said it a bunch of times. I know the problem is most likely in my loop but I can't find the issue in it.
int main(void)
{
//Text from User
string text = get_string("Text: ");
int letters = 0;
int words = 1;
int sentences = 0;
for (int i = 0; i < strlen(text); i++)
{
if (isalpha(text[i]))
{
letters++;
}
else if (text[i] == ' ')
{
words++;
}
else if (text[i] == '.' || text[i] == '!' || text[i] == '?')
{
sentences++;
}
float L = (float) letters / (float) words * 100;
float S = (float) sentences / (float) words * 100;
int index = round(0.0588 * L - 0.296 * S - 15.8);
if (index < 1)
{
printf("Before Grade 1\n");
}
else if (index > 16)
{
printf("Grade 16+\n");
}
else
{
printf("Grade %i\n", index);
}
You are missing header files, depend on code you didn't share with us (get_string()) and your source is truncated. You need to do the calculations after the loop:
#include <ctype.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef char * string;
#define LEN 1000
string get_string(const char *prompt) {
printf("%s", prompt);
string s = malloc(LEN + 1);
if(!fgets(s, LEN, stdin)) {
free(s);
return NULL;
}
size_t n = strlen(s);
if(n) n--; // strip trailing newline
s[n] = '\0';
return s;
}
int main(void) {
string text = get_string("Text: ");
int letters = 0;
int words = 1;
int sentences = 0;
for (size_t i = 0; i < strlen(text); i++) {
if (isalpha(text[i])) {
letters++;
} else if (text[i] == ' ') {
words++;
} else if (text[i] == '.' || text[i] == '!' || text[i] == '?') {
sentences++;
}
}
float L = (float) letters / (float) words * 100;
float S = (float) sentences / (float) words * 100;
int index = round(0.0588 * L - 0.296 * S - 15.8);
if (index < 1) {
printf("Before Grade 1\n");
} else if (index > 16) {
printf("Grade 16+\n");
} else {
printf("Grade %i\n", index);
}
free(text);
return 0;
}

Readability, why won't Coleman-Liau index formula work when I plugin words, letters, and sentences?

whats wrong with my code? this is the part that doest work
float L = (letters / words) * 100; and float S = (sentences / words) * 100;
when I plug in letters, words, and sentences into the formula it gives the wrong answer.
#include <stdio.h>
#include <string.h>
#include <cs50.h>
#include <ctype.h>
#include <math.h>
int main(void)
{
char ch[500];
int i;
int ii;
int iii;
int LettersWspace = 0;
int letters = 0;
int words = 1;
int sentences = 0;
int index;
string text = get_string("Enter Text: ");
for(i = 0; text[i] != '\0'; i++)
{
LettersWspace++;
}
for( i = 0; i < LettersWspace; i++)
{
if (text[i] == 32)
letters++;
}
letters = LettersWspace - letters;
ii = 0;
{
if (text[ii] == ' ')
{
words++;
}
ii++;
}
while (ii <= text[ii]);
iii = 0;
do
{
if (text[iii] == '?' || text[iii] == '!' || text[iii] == '.')
{
sentences++;
}
iii++;
}
while (iii <= text[iii]);
float L = (letters / words) * 100;
float S = (sentences / words) * 100;
return (index = 0.0588 * L - 0.296 * S - 15.8);
printf("%i\n", (int) sentences);
return 0;
}

Getting unexpected results in CS50 readability problem

In solving this readability problem, I have been getting some weird unexpected results(expected Grade 16+, getting Grade 10 etc etc), I am not being able to figure out where the bug is or how can I solve it, please help me figure out the bug. The codes are as follows:
//includes
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <math.h>
//global variables
int lc; //letter count
int wc; //word count
int sc; //sentence count
bool awc; //already word counted
double L; //average number of letters per 100 words
double S; //average number of sentences per 100 words
float index;
//function declaration
int count_letters(string x);
int count_words(string x);
int count_sentences(string x);
//main
int main(void)
{
string text = get_string("text : ");
count_letters(text);
printf("%i letters\n", lc);
count_words(text);
printf("%i words\n", wc);
count_sentences(text);
printf("%i sentences\n", sc);
L = lc / wc * 100.0f;
S = sc / wc * 100.0f;
index = (0.0588 * L) - (0.296 * S) - 15.8;
if(index < 1)
{
printf("Before Grade 1\n");
}
else if(index >= 16)
{
printf("Grade 16+\n");
}
else
{
printf("Grade %i\n", (int) round(index));
}
}
//functions
int count_letters(string x)
{
lc = 0;
for(int i = 0, n = strlen(x); i < n; i++)
{
if((x[i] >= 'a' && x[i] <= 'z') || (x[i] >= 'A' && x[i] <= 'Z'))
{
lc += 1;
}
}
return lc;
}
int count_words(string x)
{
wc = 0;
awc = false;
for(int i = 0, n = strlen(x); i < n; i++)
{
if((x[i] >= 'a' && x[i] <= 'z') || (x[i] >= 'A' && x[i] <= 'Z'))
{
if(awc == false)
{
wc += 1;
awc = true;
}
}
if(x[i] == ' ')
{
awc = false;
}
}
return wc;
}
int count_sentences(string x)
{
sc = 0;
for(int i = 0, n = strlen(x); i < n; i++)
{
if(x[i] == '.' || x[i] == '!' || x[i] == '?')
{
sc += 1;
}
}
return sc;
}
The number of letters, words and sentences from these functions are correct so far so I think the problem lies in the main section, probably something to do with the variable type of "L" and "S" or the index formulae, please help me figure out where the problem is. Thank you
here are some of the tests: sentences(expected results)
1.One fish. Two fish. Red fish. Blue fish. (Before Grade 1)
2.Harry Potter was a highly unusual boy in many ways. For one thing, he hated the summer holidays more than any other time of year. For another, he really wanted to do his homework, but was forced to do it in secret, in the dead of the night. And he also happened to be a wizard. (Grade 5)
3.A large class of computational problems involve the determination of properties of graphs, digraphs, integers, arrays of integers, finite families of finite sets, boolean formulas and elements of other countable domains. (Grade 16+)
L = lc / wc * 100.0f;
wrong
L = 100.0f * lc / wc;
right.
When both operands of / are integers, the result is integer as well, so 5/3 == 1.
the OPs code contains several problems, as discussed in the comments to the question.
The following proposed code:
corrects those problems exposed in the comments
cleanly compiles
strongly suggest all those 'global' variables be moved to inside the appropriate functions and when needed else where be passed as parameters.
and now, the proposed code:
//includes
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <math.h>
//global variables
int lc; //letter count
int wc; //word count
int sc; //sentence count
bool awc; //already word counted
double L; //average number of letters per 100 words
double S; //average number of sentences per 100 words
double i;
//function declaration
int count_letters(string x);
int count_words(string x);
int count_sentences(string x);
//main
int main(void)
{
string text = get_string("text : ");
count_letters(text);
printf("%i letters\n", lc);
count_words(text);
printf("%i words\n", wc);
count_sentences(text);
printf("%i sentences\n", sc);
L = lc / wc * 100.0;
S = sc / wc * 100.0;
i = (0.0588 * L) - (0.296 * S) - 15.8;
if(i < 1.0)
{
printf("Before Grade 1\n");
}
else if(i >= 16.0)
{
printf("Grade 16+\n");
}
else
{
printf("Grade %i\n", (int) round(i));
}
}
//functions
int count_letters(string x)
{
lc = 0;
for( size_t i = 0, n = strlen(x); i < n; i++)
{
if((x[i] >= 'a' && x[i] <= 'z') || (x[i] >= 'A' && x[i] <= 'Z'))
{
lc += 1;
}
}
return lc;
}
int count_words(string x)
{
wc = 0;
awc = false;
for( size_t i = 0, n = strlen(x); i < n; i++)
{
if((x[i] >= 'a' && x[i] <= 'z') || (x[i] >= 'A' && x[i] <= 'Z'))
{
if(awc == false)
{
wc += 1;
awc = true;
}
}
if(x[i] == ' ')
{
awc = false;
}
}
return wc;
}
int count_sentences(string x)
{
sc = 0;
for( size_t i = 0, n = strlen(x); i < n; i++ )
{
if(x[i] == '.' || x[i] == '!' || x[i] == '?')
{
sc += 1;
}
}
return sc;
}

Simple float calculation in C resulting in -nan coming back as a value

I'm writing a simple program for calculating the readability of a text, and when calculating the average, I am getting an odd result back: "-nan". It's what comes back for both float calculation functions at the bottom of my code, and when I calculate the index in the main function, I get a negative number back. This should be impossible since none of the numbers being divided are negative. Anyone know what -nan means or how I can remedy this?
Thanks!
#include <stdio.h>
#include <string.h>
int count_letters (string text);
int count_words (string text);
int count_sentences (string text);
float avg_letters (int lettercount, int wordcount);
float avg_sents (int wordcount, int sentcount);
int main (void)
{
string text = get_string("Text: ");
int lettercount = 0;
int wordcount = 0;
int sentcount = 0;
float S = 0;
float L = 0;
count_letters (text);
count_words (text);
count_sentences (text);
avg_letters (lettercount, wordcount);
avg_sents (wordcount, sentcount);
float index = 0.0588 * L - 0.296 * S - 15.8;
printf("%f\n", index);
}
//Counts letters in entire text
int count_letters (string text)
{
int lettercount = 0;
for (int i=0, n = strlen(text); i<n; i++)
{
if ((text[i] > 64 && text[i] < 91) || (text[i] > 96 && text[i] < 123))
{
lettercount ++;
}
}
printf ("%i\n", lettercount);
return lettercount;
}
//Counts words in text
int count_words (string text)
{
int wordcount = 0;
for (int i=0, n = strlen(text); i<n; i++)
{
if (text[i] == 32)
{
wordcount ++;
}
}
wordcount += 1;
printf ("%i\n", wordcount);
return wordcount;
}
//Counts sentences in text
int count_sentences (string text)
{
int sentcount = 0;
for (int i=0, n = strlen(text); i<n; i++)
{
if ((text[i] == 33) || (text[i] == 63) || (text[i] == 46))
{
sentcount ++;
}
}
printf ("%i\n", sentcount);
return sentcount;
}
//Averages letters per 100 words
float avg_letters (int lettercount, int wordcount)
{
float L = ((float) lettercount / wordcount) * 100;
printf("%f\n", L);
return L;
}
//Averages sentences per 100 words
float avg_sents (int wordcount, int sentcount)
{
float S = ((float) sentcount / wordcount) * 100;
printf("%f\n", S);
return S;
}
You forgot to assign the variables.
lettercount = count_letters (text);
wordcount = count_words (text);
sentcount = count_sentences (text);
L = avg_letters (lettercount, wordcount);
S = avg_sents (wordcount, sentcount);
Since you never assigned them, they all still have the 0 values that you initialize them with, so you divided 0 by 0 in avg_letters and avg_sents. This produces nan, which stands for not a number.

How to divide a string to substring and assign another substring?

I want to divide *eString to substrings. Substrings should be like that:
y_{1} = y_{1}y_{m+1}y_{2m+1}...
y_{2} = y_{2}y_{m+2}y_{2m+2}...
y_{m} = y_{m}y_{2m}y_{3m}...
where y is the element of *eString, and y is the substring of these elements.
For instance, if an user expects the key length which is 5, there should be (string size / 5) substrings. y_{1} has to contain the fist element of each divided substring. So, how can I implement this?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ALPHA 26
char *ReadFile(char *);
int main(int argc, char *argv[])
{
double frequency[ALPHA] = {0};
int c = 0;
int keylen = 0;
int counter = 0;
double indexofCoincidence = 0,total = 0;
const char *eString = ReadFile("cipher.txt");
int len = 0;
if (eString) {
puts("The encrypted text is:");
puts(eString);
puts("");
len = strlen(eString);
printf("The length of text is %d\n",len);
}
puts("");
while(eString[c]!= '\0'){
if(eString[c]>= 'a' && eString[c]<='z')
frequency[eString[c]-'a']++;
c++;
}
puts("The letters frequencies are :\n");
for(c=0; c<ALPHA;c++){
if(frequency[c]!= 0)
printf("%c : %.3f\t",c+'a',(frequency[c]/len));
total += (frequency[c]*(frequency[c]-1));
}
indexofCoincidence = (total/((len)*(len-1)));
printf("\n\nIndex of Coincidence : %.3f\n",indexofCoincidence);
if(indexofCoincidence < 0.060){
printf("\nIt looks like randomly.\n");
}
printf("Enter the your expected key length : ");
scanf("%d",keylen);
printf("\n");
char *y;
while(counter != keylen)
{
for(int i = 0; i<(len/keylen);i++){
y[counter] = *eString();
}
counter++
}
return EXIT_SUCCESS;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void){
char *eString = "The quick brown fox jumps over the lazy dog";
int keylen = 5;
int len = strlen(eString);
int y_len = (len + keylen) / keylen + 1;
int i,j;
char **y = malloc(keylen * sizeof(*y));
for(i=0; i < keylen; ++i){
y[i] = malloc(y_len * sizeof(**y));
}
char *p = eString;
i = j = 0;
while(*p){
y[i % keylen][j] = *p++;
y[i % keylen][j+1] = 0;
if(++i % keylen == 0)
++j;
}
//check print & deallocate
for(i = 0; i < keylen; ++i){
printf("y_{%d} : %s\n", i+1, y[i]);
free(y[i]);
}
free(y);
return 0;
}

Resources