python. finding largest integer in string - string

Write the function largestNumber(text) that takes a string of text and returns the largest int value that occurs within that text, or None if no such value occurs.
For example:
largestNumber("I saw 3 dogs, 17 cats, and 14 cows!")
returns 17 (the int value 17, not the string "17").
and
largestNumber("One person ate two hot dogs!")
returns None (the value None, not the string "None").
I tried using isdigit function to separate out integer but how can I compare string?

You can try using a regex, and then max and map functions:
result = [e for e in re.split("[^0-9]", "I saw 3 dogs, 17 cats, and 14 cows!") if e != '']
# list 'result' elements are strings: ['3', '17', '14'], so we use map(int, list) to get integers
print max(map(int, result))

You could also do
def largestNumber(in_str):
l=[int(x) for x in in_str.split() if x.isdigit()]
return max(l) if l else None
First you split in_str based on space () with split() to get a list.
The 'numbers' in this list are identified using isdigit() and converted to integers using int().
These numbers are stored in l as a list.
The expression
max(l) if l else None
will give maximum value in l if l is not empty and otherwise None.
print(largestNumber("I saw 3 dogs, 17 cats, and 14 cows!"))
gives
17
and
print(largestNumber("One person ate two hot dogs!"))
gives
None

Just Another solution:
def findLargestNumber(text):
ls = list()
for w in text.split():
try:
ls.append(int(w))
except:
pass
try:
return max(ls)
except:
return None
print findLargestNumber('I saw 3 dogs, 17 cats, and 14 cows!')
print findLargestNumber('I saw ')
Output:
17
None

def findLargestNumber(text):
front = -1
li = []
for i in range(len(text)):
if front == -1:
if text[i].isdigit():
front = i
else:
continue
else:
if text[i].isdigit():
continue
else:
li.append(int(text[front:i+1]))
front = -1
return max(li)
print findLargestNumber('I saw 3 dogs, 17 cats, and 14 cows!')

import re
def extractmax(str1):
nums=re.findall("\d+",str1)
return max(nums)
\d+ is used to look for a decimal or number with length greater than one, it is appended into the array nums finally maximum value from nums if generated.

The following worked for me, and it works great!
Increment number in the string and then print out the max number in string
import re
import re
Increase number in string
name = "name 1"
number = re.search(r'\d+', str(name))
if number:
rx = r'(?<!\d){}(?!\d)'.format(number.group())
prefix = re.sub(rx, lambda x: str(int(x.group()) + 1), name)
print(prefix)
Instead of just printing this row directly "re.sub(rx, lambda x: str(int(x.group()) + 1), name)"
Store it in a variable, in my case prefix
That's because you will get the updated value in the string and not the original
Store incremented variable "name" into a list
li = [int(prefix[5:])]
print("Largest name", max(li))
Keep in mind that index 5 is where the number is starting, you may need to adjust it depending on the string length
You can try to make 2 variables to see if the max method is working properly

Related

ValueError: invalid literal for int() after reading input into a tuple

I am writing a code that takes some numbers as tuple and then verify if there are numbers divisible by 3.
I am a beginner in python and just know some basic stuff about tuples. I have my code below:
def Div3and5():
data=tuple(input("Enter 3 numbers:"))
c=[]
a=0
for i in range(0,len(data)):
d=data[i]
c.append(d)
m=[int(x) for x in c]
print(m)
for i in m:
if m[i]%3==0:
print("It is not divisible")
Div3and5()
So, when I run this code I get an error which is:
ValueError: invalid literal for int() with base 10: ','
See, the values are stored as integers and when I give a command of printing c, it clearly shows all elements. Then, I try to convert each element to integers but it says error I don't know why. So, can you tell me the reason for that error. And also is there any straight-way for using this (divisibility) operation directly on tuples without converting them to list first.
Thanks
You are likely entering the numbers with spaces (or commas) in between. Hence, these spaces (or commas) make it into the tuple -- and can't be converted into ints.
Try instead, using str.split() to put the input numbers into a list.
def Div3and5():
c = input("Enter 3 numbers:").split(",")
# Gives you the list e.g. ["3", "4", "5"]
m = [int(x) for x in c]
# Gives you the list e.g. [3, 4, 5]
for i in m:
if i % 3 == 0:
print(f"{i} is divisible by 3")
Div3and5()
Remember that str.split() will accept a delimiter as an argument. In this case, I've put a comma ,, but you can have a space ' ' instead, depending on how your input should be entered by the user.
Note also, you were doing if m[i] % 3 == 0 in the if statement instead of if i % 3 == 0. This is not correct since i in each iteration of the loop is an element of the list m, and not an index.
Also, your condition i % 3 == 0 is such that if i is divisible by 3, then the print should indicate that the number is divisible -- you were printing that it's not divisible (probably a typo).
If you want all the numbers divisible by 3 and 5, you can change the condition like this:
if i % 3 == 0 and i % 5 == 0:
print(f"{i} is divisible by 3 and 5")
Here is the answer of your QUESTION :
def Div3and5():
c = input("Enter 3 numbers:")
list=c.split(",")
c=tuple(list)
m = [int(x) for x in c]
for i in m:
if i % 3 == 0:
print(f'{i} is is divisible by 3')
Div3and5()
#Enter 3 numbers with "," : 123,45,67

Splitting number into 2 lists of numbers of certain range

I want to create 2 lists of numbers, generated randomly with certain range.
So, if user want to generate lists as above from value 1000 (example) it should split 1000 into 2 lists:
1st list - 4 numbers in range from 40 to 80
2nd list - 5 numbers in range from 80 to 160
Sum of all produced list numbers must equal input (or hardcoded number, doesn't matter). Main range of input 560 - 1120.
Python 3.7 actually, and some problems in declaring that
See code below, I've managed to generate random 2 lists of certain range but I don't have idea how to work that out that it can have declared sum and split it into lists rather than generating random lists all together.
import random
def function():
num = 4
start = 40
end = 80
def rand(start, end, num):
res = []
for j in range(num):
res.append(random.randint(start,end))
return res
return rand(start, end, num)
def function2():
num2 = 5
start2 = 80
end2 = 160
def rand2(start2, end2, num2):
res2 = []
for k in range(num2):
res2.append(random.randint(start2,end2))
return res2
return rand2(start2, end2, num2)
a = function()
b = function2()
print (a)
print (sum(a))
print(b)
print(sum(b))
suma = sum(a+b)
print (suma)
If anyone could help me solving that I'd be really glad, I'm making a little project and this is required :)

How to compare character frequency and return the most occurring character?

I am trying to build a function which returns the most occurred character in a given string and it's working pretty nicely, but how do I return None if the characters have same frequency?
Like for input: 'abac'
Expected output is: 'a'
and for input: 'abab'
Expected output is: None
I have tried using a dictionary to store character frequency and then returning the element with largest value.
def most_occuring_char(str1):
count = {}
max = 0
c = ''
for char in str1:
if char in count.keys():
count[char]+=1
else:
count[char] = 1
for char in str1:
if max < count[char]:
max = count[char]
c = char
return c
I don't know how to check whether the count dictionary elements have same frequency.
You can do that counting with the dict using collections.Counter.
You basically only have to add a check to see if the maximum count is unique (if so, return the char with maximum number of occurrences) or not (if so, return None):
from collections import Counter
def most_occurring_char(string):
counter = Counter(string)
max_char_count = max(counter.values())
is_unique = len([char_count for char_count in counter.values() if char_count == max_char_count]) == 1
if is_unique:
char = [char for char, count in counter.items() if count == max_char_count][0]
return char
return None
# Tests
assert most_occurring_char('abac') == 'a'
assert most_occurring_char('abab') is None
Once you have a dictionary containing the counts of every character (after your first for loop), you can inspect this to determine whether certain counts are the same or not.
If you wish to return None only when all the character counts are the same, you could extract the values (i.e. the character counts) from your dictionary, sort them so they are in numerical order, and compare the first and last values. Since they are sorted, if the first and last values are the same, so are all the intervening values. This can be done using the following code:
count_values = sorted(count.values())
if count_values[0] == count_values[-1]: return None
If you wish to return None whenever there is no single most frequent character, you could instead compare the last value of the sorted list to the second last. If these are equal, there are two or more characters that occur most frequently. The code for this is very similar to the code above.
count_values = sorted(count.values())
if count_values[-1] == count_values[-2]: return None
Another possibility:
def most_occuring_char(s):
from collections import Counter
d = Counter(s)
k = sorted(d, key=lambda x:d[x], reverse=True)
if len(k) == 1: return k[0]
return None if len(k) == 0 or d[k[0]] == d[k[1]] else k[0]
#Test
print(most_occuring_char('abac')) #a
print(most_occuring_char('abab')) #None (same frequencies)
print(most_occuring_char('x')) #x
print(most_occuring_char('abcccba')) #c
print(most_occuring_char('')) #None (empty string)

Concatenate list and tuple output not favourable

I want to create an output that concatenates the list and tuple to give a single output
def conca(names,storey):
for name in names:
i = 0
d = "%s has %d"%(name,storey[i])
print(d)
i = i+1
conca(names=("White house","Burj khalifa",
"Shit"),storey = [3,278,45])
But it gives an output like
White house has 3
Burj khalifa has 3
Shit has 3
But i dont want only 3. I want i to increase. Give output like
White house has 3
Burj khalifa has 278
Shit has 45
Why is i not incrementing. What am i doing wrong
Problem:
You define i inside loop, so you reset to 0 in every iteration resulting in adding first storey every time.
Corrected:
def conca(names, storey):
i = 0
for name in names:
d = "%s has %d"%(name,storey[i])
print(d)
i = i+1
conca(names=("White house","Burj khalifa",
"Shit"), storey=[3,278,45])
You can also use zip() to iterate over lists simultaneously:
def conca(names, storey):
for name, st in zip(names, storey):
print(f'{name} has {st}')
conca(names=("White house","Burj khalifa",
"Shit"), storey=[3,278,45])

Python 3.xx - Deleting consecutive numbers/letters from a string

I actually need help evaluating what is going on with the code which I wrote.
It is meant to function like this:
input: remove_duple('WubbaLubbaDubDub')
output: 'WubaLubaDubDub'
another example:
input: remove_duple('aabbccdd')
output: 'abcd'
I am still a beginner and I would like to know both what is wrong with my code and an easier way to do it. (There are some lines in the code which were part of my efforts to visualize what was happening and debug it)
def remove_duple(string):
to_test = list(string)
print (to_test)
icount = 0
dcount = icount + 1
for char in to_test:
if to_test[icount] == to_test[dcount]:
del to_test[dcount]
print ('duplicate deleted')
print (to_test)
icount += 1
elif to_test[icount] != to_test[dcount]:
print ('no duplicated deleted')
print (to_test)
icount += 1
print ("".join(to_test))
Don't modify a list (e.g. del to_test[dcount]) that you are iterating over. Your iterator will get screwed up. The appropriate way to deal with this would be to create a new list with only the values you want.
A fix for your code could look like:
In []:
def remove_duple(s):
new_list = []
for i in range(len(s)-1): # one less than length to avoid IndexError
if s[i] != s[i+1]:
new_list.append(s[i])
if s: # handle passing in an empty string
new_list.append(s[-1]) # need to add the last character
return "".join(new_list) # return it (print it outside the function)
remove_duple('WubbaLubbaDubDub')
Out[]:
WubaLubaDubDub
As you are looking to step through the string, sliding 2 characters at a time, you can do that simply by ziping the string with itself shifted one, and adding the first character if the 2 characters are not equal, e.g.:
In []:
import itertools as it
def remove_duple(s):
return ''.join(x for x, y in it.zip_longest(s, s[1:]) if x != y)
remove_duple('WubbaLubbaDubDub')
Out[]:
'WubaLubaDubDub'
In []:
remove_duple('aabbccdd')
Out[]:
'abcd'
Note: you need itertools.zip_longest() or you will drop the last character. The default fillvalue of None is fine for a string.

Resources