Can anyone spot the issue? I get a negative for my index everytime so it always prints "Before Grade 1". I tried doing some regex but I still don't know how to implement it really
import re
from cs50 import get_string
words = 1
letters = 0
sentences = 0
st = get_string("Text: ")
t = len(st)
regex = r'\w+'
output = re.findall(regex,st)
for i in range(t):
if st.isalpha():
letters += 1
if st.isspace():
words += 1
if st[i] == '.' or st[i] == '!' or st[i] == '?':
sentences += 1
L = (letters / words * 100)
S = (sentences / words * 100)
index = 0.0588 * L - 0.296 * S - 15.8
roundedIndex = round(index)
if roundedIndex < 1:
print("Before Grade 1")
if roundedIndex >= 16:
print("Grade 16+")
else:
print(roundedIndex)
Inside your loop, you're checking if the whole string is alphabetical or a space, not whether the letter corresponding to the index i is. You probably want st[i].isalpha() and st[i].isspace().
Or, you could loop over the characters directly, rather than over indexes:
for char in st:
if char.isalpha():
...
if char.isspace():
...
Related
import cs50
text = cs50.get_string("Text: ")
letters = 0
words = 0
sentences = 0
for char in text:
if char.isalpha():
letters += 1
if char.isspace():
words += 1
if char in [".", "!", "?"]:
sentences += 1
L = (letters * 100.0) / words
S = (sentences * 100.0) / words
Grade = int(0.0588 * L - 0.296 * S - 15.8)
if (Grade < 1):
print("Before Grade 1")
elif (Grade > 16):
print("Grade 16+")
else:
print(f"Grade {Grade}")
your text
The grade is correct if its 16+ or 1 but anything inbetween is wrong. The solution must be simple but i have no idea, it should be something to do with the L = (letters * 100.0) / words
S = (sentences * 100.0) / words
Grade = int(0.0588 * L - 0.296 * S - 15.8)
but i can't tell what it is. I'm fairly new to programming so i might just be doing it all wrong here.
Count the words. How many words in that sentence? How many spaces? See the problem?
Additionallly, the int function drops everything after the decimal (it does not round).
An Index calculation Issue in my pset6 readability
This is my code and I think it is correct but, the grade for every paragraph is wrong because the index calculation is wrong. Although, the letters, words, and sentence counting is correct. So, where is the problem? someone help me, please?
from cs50 import get_string
import math
# Loop to count the letters
letters = 0
words = 0
sentences = 0
# Prompt user for some text.
text = get_string("Text: ")
# Loop to count the letters(s) of a paragraph
def count_letters():
global letters
for i in range(len(text)):
if text[i].lower() or text[i].upper():
letters += 1
# pass
print(letters)
return letters
count_letters()
# Loop to count the words of the paragraph.
def count_words():
global words
for i in range(len(text)):
if text[i].isspace():
words += 1
# TODO
if text[i].isspace() and text[i + 1].isspace():
words -= 1
print(words + 1)
return words + 1
count_words()
# Loop to count sentences of the paragraph.
def count_sentences():
global sentences
for i in range(len(text)):
if text[i] == "." or text[i] == "!" or text[i] == "?":
sentences += 1
print(sentences)
return sentences
count_sentences()
# Calc the index of the grades
def indexOfGrade():
global letters
global words
global sentences
l = letters / words * 100
s = sentences / words * 100
index = round(0.0588 * l - 0.296 * s - 15.8)
print(letters / words)
print(l)
print(s)
print(index)
# grades
if index >= 16:
print("Grade 16+")
elif index < 1:
print("Before Grade 1")
else:
print(f"Grade {index}")
indexOfGrade()
Yahooo, after a lot of time I figured out your mistake.
def count_words():
global words
for i in range(len(text)):
if text[i].isspace():
words += 1
# TODO
if text[i].isspace() and text[i + 1].isspace():
words -= 1
print(words + 1)
return words + 1 #This part is wrong
The last line, which is return will just return the value but will not change the value of the variable words, therefore, you need to correct it as follows
def count_words():
global words
for i in range(len(text)):
if text[i].isspace():
words += 1
# TODO
if text[i].isspace() and text[i + 1].isspace():
words -= 1
print(words + 1)
words += 1
return words
Also the letters, words and sentences variables may optionally be float and not int and while calculating the index, python will omit the remaining decimal part, therefore the round may not work.
Also, I have performed check50 on my device and all the results were green with (correct)
Also, if text[i].isspace() and text[i + 1].isspace(): was wrong you need to completely delete that part.
Therefore here is the final answer with the required changes.
from cs50 import get_string
import math
# Loop to count the letters
letters = float(0)
words = float(0)
sentences = float(0)
# Prompt user for some text.
text = get_string("Text: ")
# Loop to count the letters(s) of a paragraph
def count_letters():
global letters
for i in range(len(text)):
if (text[i] >= 'a' and text[i] <= 'z') or (text[i] >= 'A' and text[i] <= 'Z'):
letters += 1
# pass
# # print(letters)
return letters
count_letters()
# Loop to count the words of the paragraph.
def count_words():
global words
for i in range(len(text)):
if text[i].isspace():
words += 1
# # TODO
# if text[i].isspace() and text[i + 1].isspace():
# pass
# # print(words + 1)
words += 1
return words + 1
count_words()
# Loop to count sentences of the paragraph.
def count_sentences():
global sentences
for i in range(len(text)):
if text[i] == "." or text[i] == "!" or text[i] == "?":
sentences += 1
# # print(sentences)
return sentences
count_sentences()
# Calc the index of the grades
def indexOfGrade():
global letters
global words
global sentences
# print(letters)
# print(words)
# print(sentences)
l = 100 * letters / words
# print(l)
s = sentences / words * 100
# print(s)
index = round(0.0588 * l - 0.296 * s - 15.8)
# # print(letters / words)
# print(0.0588 * l - 0.296 * s - 15.8)
# print(l)
# print(s)
# print(index)
# grades
if index >= 16:
print("Grade 16+")
elif index < 1:
print("Before Grade 1")
else:
print(f"Grade {index}")
indexOfGrade()
Note: you may optionally remove all the comment statements.
Link to my check50 result
> #!/usr/bin/env python
>
> import inflect
>
> p = inflect.engine()
s1 = ''
>
> word = 'so do 1st or do 2nd or 3rd byte 4 th so do 5th longest word 3765 word 50 but 7th'
> list_word = list(word)
> print (list_word)
>
> for(m= 0; m <list_word.len(); m++):
> if list_word[m].isalpha():
> s1 += i + ''
> elif list_word[m].isnumeric():
> if (list_word[m+1].isnumeric()):
> continue
> elif (list_word[m+1]+list_word[m+2] == 'st'):
> s1 += first + ''
> m += 2
> elif (list_word[m+1]+list_word[m+2] == 'nd'):
> s1 += second + ''
> m += 2
> elif (list_word[m+1]+list_word[m+2] == 'rd'):
> s1 += third + ''
> m += 2
> elif (list_word[m+1]+list_word[m+2] == 'th'):
> if (list_word[m] == '5'):
> s1 += fifth + ''
> m += 2
> else :
> s1 += p.number_to_words(list_word[m]) + ''
> m += 2
> elif (list_word[m+1].isnumeric()):
> continue
> else:
> s1 += p.number_to_words(list_word[m]) + ''
> else:
> s1 += ' '
>
I need to convert digits to word and make a complete string with alphabets only. But the issue is this kind of for loop can not be used in Python and i need to iterate to next to next character at some places. Can I get any suggestions regarding this, please.
Or if someone can suggest any other approach.
Using the num2words package we can do do this to translate the whole string without any for-loops:
import re
import num2words
def transInt(num, mode=None):
# Changes the mode of the translation to
# correctly translate ordinal numbers.
if mode:
mode = "ordinal"
else:
mode = "cardinal"
# translates the number to either float
# or int, so the translation works correctly.
if "." in num:
num = float(num)
else:
num = int(num)
return num2words.num2words(num, to=mode)
def replaceInt(string):
# Matches numbers, followed by optional ordinal-characters after it.
return re.sub(r"(\d+\.*\d*)(st|nd|rd|th)*", lambda x: transInt(*x.groups()), string)
word = 'so do 1st or do 2nd or 3rd byte 4th so do 5th longest word 3765 word 50 but 7th'
print(word)
print(replaceInt(word))
Output:
so do 1st or do 2nd or 3rd byte 4th so do 5th longest word 3765 word 50 but 7th
so do first or do second or third byte fourth so do fifth longest word three thousand, seven hundred and sixty-five word fifty but seventh
The important thing with the translation is that the suffix ("th" in 5th) is connected to the number. In your example you have "4 th" which will not work with my code. Or rather, it will translate 4 as four instead of fourth
The simplest way would be to use a while loop instead and manually iterate the variable. For example:
m = 0
while m < len(list_word):
body
final else
m += 1
In effect this is the same as using the for loop like you are
heres my current RLE code
import re
def decode(string):
if string == '':
return ''
multiplier = 1
count = 0
rle_decoding = []
rle_encoding = []
rle_encoding = re.findall(r'[A-Za-z]|-?\d+\.\d+|\d+|[\w\s]', string)
for item in rle_encoding:
if item.isdigit():
multiplier = int(item)
elif item.isalpha() or item.isspace():
while count < multiplier:
rle_decoding.append('{0}'.format(item))
count += 1
multiplier = 1
count = 0
return(''.join(rle_decoding))
def encode(string):
if string == '':
return ''
i = 0
count = 0
letter = string[i]
rle = []
while i <= len(string) - 1:
while string[i] == letter:
i+= 1
count +=1
#catch the loop on last character so it doesn't got to top and access out of bounds
if i > len(string) - 1:
break
if count == 1:
rle.append('{0}'.format(letter))
else:
rle.append('{0}{1}'.format(count, letter))
if i > len(string) - 1: #ugly that I have to do it twice
break
letter = string[i]
count = 0
final = ''.join(rle)
return final
the code might have gotten fucked up when I removed all my comments, but the current code isn't too important. the problem is, I am running RLE on hexadecimal values, that have all been converted to letters so that 0-9 becomes g-p. the problem is that there are a lot of patterns like 'kjkjkjkjkjkjkjkjlmlmlmlmlmlmlm' which doesn't compress at all, because of their not single characters. how would I, if even possible, be able to run my program so that it encodes patterns as well?
I am trying to build a random word generator that randomly selects a consonant and vowel structure (e.g. 'cvvc' could be 'mean'). It is not working. The problem when I run it in the debugger is at the last two lines at the end of the while loop.
import random
vowelsList = ['a','e','i','o','u']
constonentsList = ['b','c','d','f','g','h','j','k','l','p','q','r','s','t','u','v','w','x','y','z','th','ch','sh','st','ck']
n = random.randint(1,2)
word = ''
struct = ''
length = 0
x = True
len_con = len(constonentsList)
len_vow = len(vowelsList)
length = 0
while x:
if n == 1:
word += constonentsList[random.randint(0,len_con - 1)]
struct += 'c'
length += 1
elif n == 2:
word += vowelsList[random.randint(0,len_vow - 1)]
struct += 'v'
length += 1
n = random.randint(0,2)
if (length >= 3 & n == 0): #If the word is more than 3 letters and n == 0, don't continue
x = False
print(word)
print(struct)
print(length)
Your code is actually working, albeit only just. The length reflects how many consonants and vowels you produced, but the generated word can be longer as you include two-letter consonants like th and sh. However, there are improvements to be made.
The & operator does not do what you think it does. It is a binary bitwise operator; it sets binary flags in integers:
>>> 1 & 1
1
>>> 2 & 1
3
You want to use the and operator instead to do boolean logic AND testing:
if length >= 3 and n == 0:
For booleans, using & happens to work as the boolean type overloads the operator to return booleans still.
You can greatly simplify your program by using the random.choice() function, and move the termination test to the while loop condition. The length variable is redundant; you can just use len(struct) here:
import random
import string
vowels = 'aeiou'
consonants = [c for c in string.ascii_lowercase if c not in vowels]
consonants += ['th','ch','sh','st','ck']
n = random.randint(1, 2)
word = ''
struct = ''
while len(struct) < 3 or n: # minimum length 3
if n == 1:
word += random.choice(consonants)
struct += 'c'
elif n == 2:
word += random.choice(vowels)
struct += 'v'
n = random.randint(0, 2)
print(word)
print(struct)
print(len(struct))