how to add options to inflect number-to-word? - python

I have a program which calculates the number of minutes of a person's age. It works correctly. However, I want to ask if I can print the first letter capitalized.
from datetime import datetime, date
import sys
import inflect
inflector = inflect.engine()
def main():
# heute = date.today()
user = input('Date of birth: ')
min_preter(user)
def min_preter(data):
try:
data != datetime.strptime(data, '%Y-%m-%d')
# Get the y-m-d in current time
today = date.today()
# die y-m-d teilen
year, month , day = data.split('-')
# Convert to datetime
data = date(year=int(year), month=int(month), day=int(day))
# And valla
end = (today - data).total_seconds() / 60
# Convert to words
words = inflector.number_to_words(end).replace('point zero','minutes').upper()
return words
except:
sys.exit('Invalid date')
# convert from string format to datetime format
if __name__ == "__main__":
main()
Here is the output when I enter e.g 1999-01-01:
twelve million, four hundred and fifty-seven thousand, four hundred and forty point zero
where I expected
Twelve million, four hundred and fifty-seven thousand, four hundred and forty minutes
first word 'Twelve'(first letter capitalize)
I don't know what this point zero is. I just want the minutes at the end.
Thank you

You can use string.capitalize(). So you can do that:
return words.capitalize()
... and as for the "point zero", try converting the result to int before running your function, like
end = int((today - data).total_seconds() / 60)

Just replace .upper() by capitalize() in your code
An alternative to your replace would be to obtain the total number of minutes as an integer (point zero is because end is a float number) :
end = int((today - data).total_seconds() / 60)
In that case, your words variable would be :
words = inflector.number_to_words(end).capitalize() + " minutes"

You can use .capitalize() to capitalize the first word of the string.
EXAMPLE: words.capitalize()
"twelve million, four hundred and fifty-seven thousand, four hundred and forty point zero".capitalize()
OUTPUT
'Twelve million, four hundred and fifty-seven thousand, four hundred and forty point zero'
Regarding point zero
This particular code end = (today - data).total_seconds() / 60 is giving output as float which is leading to point zero so instead of division use floor division i.e. // instead of / which will return integer and hence point zero will be gone or else convert end to int.
Lastly add minutes string i.e. end + ' minutes' to final result.

Related

How to remove unnecessary "and" in inflect num to words python package

I'm using the python package inflect to convert numbers to words. I would like to know how I can have inflect convert the numbers the right way without unnecessary "and" in the end result.
Here's my code
from datetime import date
import inflect, sys
def main():
print(time_check(input("What's your DOB?: ")))
def time_check(check):
p = inflect.engine()
year, month, day = check.split("-")
year, month, day = int(year), int(month), int(day)
dob = date(year, month, day)
diff = date.today() - dob
# Convert days to minutes & then use inflect to convert the number to words
ans = p.number_to_words(diff.days*24*60)
return f"{ans.capitalize()} minutes"
if __name__ == "__main__":
main()
When I input "2021-10-10" as my Date of Birth(DOB), ans will become
ans = p.number_to_words(525,600)
This will then print "Five hundred and twenty five-thousand, six hundred minutes" but I don't want that as that is partially incorrect.
I want my code to print "Five hundred twenty five-thousand, six hundred minutes" without the "and".
I know I can use the replace method to replace the "and" with an empty string, but I don't want to do that. I want the inflect python package to convert numbers to words using this right way.
I hope you guys can understand the problem here & hope to get your help.
Just set andword in number_to_words() as it is 'and' by default. See the inflect documentation for more details.
p.number_to_words(diff.days*24*60, andword = '')
This will print the following directly (for 2021-10-10):
Five hundred twenty-five thousand, six hundred minutes

remove numbers from string using python

hello I have a question:
How can I remove numbers from string, I know that the fasted and best way is to use translate
'hello467'.translate(None, '0123456789')
will return hello, but what if I want to remove only numbers that are not attached to a sting for example: 'the 1rst of every month I spend 10 dollars' should be 'the 1rst of every month I spend dollars' and not 'the rst of every month I spend dollars'
import re
s = "the 1rst of every month I spend 10 dollars"
result = re.sub(r"\b\d+\b", '', s)
result = re.sub(" ", ' ', result)
should give:
the 1rst of every month I spend dollars
Split the string and check if the element is a digit and if not then join it to the result.
str = ("the 1rst of every month I spend 10 dollars").split(' ')
result = ' '.join([i for i in str if not i.isdigit()])
print(result)

Convert String to Float (Currency) but has more than one decimal points [duplicate]

This question already has answers here:
Why not use Double or Float to represent currency?
(16 answers)
Closed 1 year ago.
so i was webscraping Foot locker Website , now when i get the price i get it in more than one decimal points.
i want to round it off to 2 digits after decimal point, how can i do that ?
My price list:
90.00
170.00
198.00
137.99137.99158.00
When i try the float function/Method i get an error, can someone Please help :)
print(float(Price))
90.0
170.0
198.0
ValueError: could not convert string to float: '137.99137.99158.00'
and i also want to round it off to two decimal points, so 90.0 will become 90.00 :)
After a second look at your prices it seems to me that the problem with the multiple decimal points is due to missing spaces between the prices. Maybe the webscraper needs a fix? If you want to go on with what you have, you can do it with regular expressions. But my fix only works if prices are always given with two decimal digits.
import re
list_prices = [ '90.00', '170.00', '198.00', '137.99137.99158.00' ]
pattern_price = re.compile(r'[0-9]+\.[0-9]{2}')
list_prices_clean = pattern_price.findall('\n'.join(list_prices))
print(list_prices_clean)
# ['90.00', '170.00', '198.00', '137.99', '137.99', '158.00']
You're getting that error because the input 137.99137.99158.00 is not a valid input for the float function. I have written the below function to clean your inputs.
def clean_invalid_number(num):
split_num = num.split('.')
num_len = len(split_num)
if len(split_num) > 1:
temp = split_num[0] + '.'
for i in range(1,num_len):
temp += split_num[i]
return temp
else:
return num
To explain the above, I used the split function which returns a list. If the list length is greater than 1 then there is more than 1 fullstop which means the data needs to be cleaned.The list does not contain the character you split.
As for returning 2 decimal points simply use
Price = round(Price,2)
Returning two 90.00 instead of 90.0 does not make sense if you are casting to float.
Here is the full code as a demo:
prices = ['90.00', '170.00', '198.00', '137.99137.99158.00']
prices = [round(float(clean_invalid_number(p)),2 ) for p in prices]
print(prices)
[90.0, 170.0, 198.0, 137.99]
replace first dot by a temporary delimiter
delete all other dots
replace temporary delimiter with dot
round
print with two decimals
like this:
list_prices = [ '90.00', '170.00', '198.00', '137.99137.99158.00']
def clean_price(price, sep='.'):
price = str(price)
price = price.replace(sep, 'DOT', 1)
price = price.replace(sep, '')
price = price.replace('DOT', '.')
rounded = round(float(price),2)
return f'{rounded:.2f}'
list_prices_clean = [clean_price(price) for price in list_prices]
print(list_prices_clean)
# ['90.09', '170.00', '198.00', '137.99']
EDIT:
In case you mean rounding after the last decimal point:
def clean_price(price, sep='.'):
price = str(price)
num_seps = price.count(sep)
price = price.replace(sep, '', num_seps-1)
rounded = round(float(price),2)
return f'{rounded:.2f}'
list_prices_clean = [clean_price(price) for price in list_prices]
print(list_prices_clean)
# ['90.00', '170.00', '198.00', '1379913799158.00']
No need to write custom methods, use regular expressions (regex) to extract patterns from Strings. Your problem is that the long string (137.99137.99158.00) are 3 prices without spaces in between. The regex expression "[0-9]+.[0-9][0-9]" finds all patterns with one or more numbers before a "." and two numbers after the "."
import re
reg = "[0-9]+\.[0-9]{0,2}";
test = "137.99137.99158.00";
p = re.compile(reg);
result = p.search(test);
result.group(0)
Output:
137.99
Short explanation:
'[0-9]' "numbers"
'+' "one or more"
'.' "String for the dot"
Regex seems to be quite weird at the start, but it is an essential skill. Especially when you want to mine text.
Ok, i have finally sound a solution to my Problem, nad thank you everyone for helping out as well
def Price(s):
try:
P = s.find("div",class_="ProductPrice").text.replace("$","").strip().split("to")[1].split(".")
return round(float(".".join(P[0:2])),2)
except:
P = s.find("div",class_="ProductPrice").text.replace("$","").strip().split("to")[0].split(".")
return float(".".join(P[0:2]))

Write a function swap_halves(s) that takes a string s, and returns a new string in which the two halves of the string have been swapped

Write a function swap_halves(s) that takes a string s, and returns a new string in which the two
halves of the string have been swapped.
For example, swap_halves("good day sunshine") would return 'sunshine good day'.
I tried something like
def swap_halves (s):
'''Returns a new string in which the two halves of the spring have swapped'''
return (s[0:len(s)] + s[len(s):] )
not sure how to do it without using if or other statements.
I don't know what exactly you want but this might work
def swap_halves (s):
'''Returns a new string in which the two halves of the spring have swapped'''
i = int(len(s)/2)
print(s[i:] + s[:i] )
swap_halves("good day sunshine ")
def func(s):
return(s[0:1]*3+s[1:]+s[-1:]*3)
You are going to want to .split() the text unless you don't mind some words getting cut say if your middle index falls in a word as someone pointed out, for string good day bad sunshine you wouldn't want ad sunshinegood day b
def swapper(some_string):
words = some_string.split()
mid = int(len(words)/2)
new = words[mid:] + words[:mid]
return ' '.join(new)
print(swapper('good day bad sunshine'))
(xenial)vash#localhost:~/python/stack_overflow$ python3.7 images.py
bad sunshine good day
As requested :
def tripler(text):
new = text[:1] * 3 + text[1:-1] + text[-1:] * 3
return new
print(tripler('cayenne'))
(xenial)vash#localhost:~/python/stack_overflow$ python3.7 images.py
cccayenneee

Convert certain numbers in a sentence such as date, time, phone number from numbers to words in Python

I am kind of new to Python so I apologize for my lacks. I have a code in python perfected with other users' help (thank you) that converts a date from numbers into words using dictionaries for days,months,years, like 3.6.2015 => march.third.two thousand fifteen using:
date = raw_input("Give date: ")
I want to input a sentence such as: "today is 3.6.2015, it is 10:00 o'clock and it's rainy" and from it I do not know how to search through the sentence for the date, or time, or phone number and to that date and time to apply the conversion.
If someone can please help, thank you.
You could use regular expressions:
import re
s = "today is 3.6.2015, it is 10:00 o'clock and it's rainy"
mat = re.search(r'(\d{1,2}\.\d{1,2}\.\d{4})', s)
date = mat.group(1)
print date # 3.6.2015
Note, if there's nothing matching this regular expression in the input text, an AttributeError will be raised, that you'll either have to prevent (e.g. if mat:) or handle.
EDIT
Assuming you can turn your conversion code into a function, you could use re.sub:
import re
def your_function(num_string):
# Whatever your function does
words_string = "march.third.two thousand fifteen"
return words_string
s = "today is 3.6.2015, it is 10:00 o'clock and it's rainy"
date = re.sub(r'(\d{1,2}\.\d{1,2}\.\d{4})', your_function, s)
print date
# today is march.third.two thousand fifteen, it is 10:00 o'clock and it's rainy
Just modify your_function to change the 3.6.2015 into march.third.two thousand fifteen.

Categories

Resources