How can I fix the output problem in my code? - python

So I wrote this code to print out true or false depending on whether the value goes below zero or not. Here is my code
L = [10,10,10]
init_hp = 0
def is_dead(L: list[int], init_hp:int):
if init_hp == 0:
return True
elif sum(L) + init_hp > 0:
return False
else:
return True
print(is_dead(L,init_hp))
However, for the L: list I want to make sure that the output prints out True if the value has gone below zero already. For example, if L: list = [2,-3,5], I want to make sure that the output prints out True, because 2+(-3), the first two variables, already return a negative number,"-1", EVEN THOUGH THE END RESULT IS POSITIVE... however using my code, that doesn't work, what code should I use to make sure that it will print true if a scenario like this happens

The shortest way I could think of was to use itertools.accumulate:
from typing import List
from itertools import accumulate
def is_dead(lst: List[int], i_hp: int):
if i_hp == 0:
return True
for total in accumulate(lst):
if total < 0:
return True
return False
print(is_dead([2, -3, 5], 1))
# True
print(is_dead([10, 10, 10], 1))
# False
Or slightly shorter (but also may be slightly less memory efficient):
def is_dead(lst: List[int], i_hp: int):
if i_hp == 0:
return True
if [True for total in accumulate(lst) if total < 0]:
return True
return False
Sources:
itertools.accumulate docs

You can use loop and iterate all numbers in the list.
L = [10, 10, 10]
init_hp = 0
def is_dead(L: list[int], init_hp:int):
if init_hp == 0:
return True
v = 0
for num in L:
if v+num < 0:
return True
v += num
if init_hp+v < 0:
return True
return False
print(is_dead(L,init_hp))

You can use a for loop to iterate through the numbers and check whether the sum is less than zero or not.
def is_dead(L: list[int], init_hp: int):
if init_hp <= 0:
return True
s = 0
for num in L:
s += num
if s < 0:
return True
return False # sum > 0
# Test cases:
print(is_dead([2, -3, 5], 1)) # True
print(is_dead([10, 10, 10], -1)) # True
print(is_dead([10, 10, 10], 1)) # False

Related

How To write a function to Check for a Sequence of integers in an array in python

I'm trying to figure out why the code I wrote to find a sequence of integers in any given array is not catching all the instances. Could you help, please?
Here's the code:
def array123(nums):
if len(nums) < 3:
return False
else:
for i in range(len(nums) - 1):
if nums[i:i + 3] == [1, 2, 3]:
return True
return False
The return False part should be indented as follows.
def array123(nums):
if len(nums) < 3:
return False
else:
for i in range(len(nums) - 1):
if nums[i:i + 3] == [1, 2, 3]:
return True
return False # This should be indented this way.
def array123(nums):
nums_to_string = str(nums)
if len(nums_to_string) < 3:
return False
else:
for i in range(len(nums_to_string) - 1):
if nums_to_string[i:i + 3] == "123":
return True
return False
def array123(nums):
for i in range(len(nums)-2):
if nums[i:i + 3] == [1, 2, 3]:
return True
return False
"""'i' in range and then go for the length of nums because I don't know how long nums are going to be as a list. I will say -2 because I don't want to go all the way to the end. so -2 back because I'm going to be counting in steps of three."""

How to find duplicate number in a list using recursive in python?

I have tried following code, its only returning true or false,I just want to return which element is repeated but using only recursive approach only. Can anyone help me out please?
def check(myList):
if len(myList) <= 1:
return False
if myList[0] == myList[1]:
return True
if check([myList[0]] + myList[2:]):
return True
if check(myList[1:]):
return True
return False
print(check([1,2,2,3,4]))
Sample output: 2
Then you should return the repeated element:
def check(myList):
if len(myList) <= 1:
return None
if myList[0] == myList[1]:
return myList[0]
return check(myList[1:])
Change last calling
def check(myList):
if len(myList) <= 1:
return False
if myList[0] == myList[1]:
return myList[0]
return check(myList[1:])
print(check([1,2,2,3,4]))
# Sample output: 2
This approach unlike the other answers, prints all duplicates and not just the first one found.
def check(myList):
if len(myList) <= 1:
return # No need for False, just return.
if myList[0] == myList[1]:
print(myList[0], end = ' ')
return check(myList[1:])
check([1, 2, 2, 3, 3, 4]) # No need to use check in print()
When run this outputs:
2 3

check if a numbers comes before the same number but am not getting any output from the code

number =[2,3,4,9,9,5,1]
def checkList(List1):
for i in range(len(List1 - 1)):
if List1[i] == 9 and List1[i+1] == 9:
return True
return false
this code does not output any value either true or false, it is suppose to output true if 9 comes after 9 or false if otherwise
[enter image description here][1]
[1]: https://i.stack.imgur.com/kwm0S.png this link contain the code and the output
I've just fixed logical mistakes.
number = [2, 3, 4, 9, 8, 5, 1]
def checkList(List1):
for i in range(len(List1) - 1):
if List1[i] == 9 and List1[i + 1] == 9:
return True
return False
checkList(number)
The indentation is incorrect. If you wrote it like:
def checkList(List1):
for i in range(len(List1 - 1)):
if List1[i] == 9 and List1[i+1] == 9:
return True
return False
Then it means that from the moment the if check fails, it will return False. So that means that if the first two items are not both 9, the if fails, but in your for loop, you then return False, and you never let your program look at the remaining elements.
You furthermore should use len(List1)-1, not len(List1-1), since you can not subtract a number from a list.
You can fix this by moving the return False out of the for loop:
def checkList(List1):
for i in range(len(List1)-1):
if List1[i] == 9 and List1[i+1] == 9:
return True
return False
That being said, you can solve this in a more elegant way by using zip(..) to iterate both on a list that list shifted one position:
from itertools import islice
def checkList(iterable):
return any(x == y == 9 for x, y in zip(iterable, islice(iterable, 1, None)))
For example:
>>> checkList([2,3,4,9,9,5,1])
True

Project Euler #37 issue

I tried to solve Project Euler #37:
The number 3797 has an interesting property. Being prime itself, it is possible to continuously remove digits from left to right, and remain prime at each stage: 3797, 797, 97, and 7. Similarly we can work from right to left: 3797, 379, 37, and 3.
Find the sum of the only eleven primes that are both truncatable from left to right and right to left.
NOTE: 2, 3, 5, and 7 are not considered to be truncatable primes.
I wrote my code in Python but I am facing weird issues.
Here's my code:
def isPrime(n):
if n == 2 or n == 3 or n == 5: return True
if n < 2 or n%2 == 0: return False
if n < 9: return True
if n%3 == 0: return False
if n%5 == 0: return False
r = int(n**0.5)
f = 5
while f <= r:
if n%f == 0: return False
if n%(f+2) == 0: return False
f +=6
return True
def gen(nb):
results = []
nb_str = str(nb)
for k in range(0, len(nb_str) - 1):
results.append(nb_str[k:])
results.append(nb_str[-k:])
return results
def check(nb):
for t in gen(nb):
if not isPrime(int(t)):
return False
return True
c = 0
s = 0
i = 2
while c != 11:
if check(i):
c += 1
s += i
i += 1
print(s)
Where does the error come from? (The expected result is 748317)
I suspect the errors coming from the results list
Yes, the gen() function is not working correctly as your slicing is off, also, you count 2, 3, 5 and 7 as truncatable primes which the question denies.
The second slice should be the other way around:
>>> s = 'abcd'
>>> for i in range(1,len(s)-1):
... print(s[i:])
... print(s[:-i])
...
bcd
abc
cd
ab
which we can see produces the right strings.
Altogether then, the function should be:
def gen(nb):
results = [nb]
nb_str = str(nb)
for k in range(1, len(nb_str)):
results.append(int(nb_str[k:]))
results.append(int(nb_str[:-k]))
return results
note I also added a string to int conversion - not sure how Python didn't make that obvious for you :/
And before get the full solution, Project Euler nearly always gives you an example which you can use to check your code:
>>> check(3797)
True
You must also add a condition in the check function to return False if the number is 2, 3, 5 or 7 as this is stated clearly in the question.
And the result is the expected: 748317.
Joe Iddon has explained the error in your code, but you can speed it up a little by turning gen into an actual generator. That way, you can stop checking the results for a given nb as soon as you detect a composite number (and gen will stop generating them). I've also made a few minor tweaks to your primality tester. Remember, the or operator short-circuits, so if a is True-ish in a or b then it doesn't bother evaluating b.
def isPrime(n):
if n in {2, 3, 5, 7}:
return True
if n < 2 or n%2 == 0:
return False
if n%3 == 0 or n%5 == 0:
return False
r = int(n**0.5)
f = 5
while f <= r:
if n%f == 0 or n%(f+2) == 0:
return False
f += 6
return True
def gen(nb):
yield nb
nb_str = str(nb)
for k in range(1, len(nb_str)):
yield int(nb_str[k:])
yield int(nb_str[:-k])
def check(nb):
for t in gen(nb):
if not isPrime(t):
return False
return True
c = s = 0
# Don't check single digit primes
i = 11
while c < 11:
if check(i):
c += 1
s += i
print(i)
i += 2
print('sum', s)
output
23
37
53
73
313
317
373
797
3137
3797
739397
sum 748317
In fact, you can get rid of the check function, and replace it with all, which also short-circuits, like or does. So you can replace the
if check(i):
with
if all(map(isPrime, gen(i))):

List with multiple conditions

I am creating a boolean function that checks if each element in my list is greater than 1 and less than 6. Also the list is positive integers and not negative, 0, string or anything else.
I feel like I have tried almost everything and cant find my solution. This is what I tentatively have right now.
def checkList(aList):
for i in aList:
if i < 1:
return False
elif i > 6:
return False
else:
return True
Use a generator expression to build an intermediate list of elements, then check them against all to see if they fit in your constraints.
def check_list(li):
return all((type(i) == int and 1 < i < 6 for i in li))
A single generator expression with all using isinstance(i, int) to check is each element is an int and 1 <= i <= 6 to make sure each int is in the range 1-6:
def checkList(aList):
return all(isinstance(i, int) and 1 < i < 6 for i in aList)
all will short circuit and return False for any non int or any value less than 1 or greater the 5 or return True if all the elements are ints and in the range 1-6.
In your own code you are checking for if i < 1 and elif i > 6 when you say you want to check if each element in my list is greater than 1 and less than 6 so it would be if i < 2 and elif i > 5 return False, 1 is not less than 1 and 6 is greater than 5, so to correct your own logic and to check for ints.
def checkList(aList):
for i in aList:
if not isinstance(i, int):
return False
if i < 2:
return False
if i > 5:
return False
return True # outside loop
You need to move the return True outside loop, just because one is an int
between 1 - 6 does not mean they all are.
Which could be rewritten as:
def checkList(aList):
for i in aList:
if not isinstance(i, int):
return False
if 2 > i > 5:
return False
return True
This will work for you
def check_sequence(sequence, low, high):
if all(isinstance(i, int) for i in sequence):
return all(low < i < high for i in sequence)
else:
return False
print(check_sequence([2, 5, 4, 3, 3], 1, 6))
>> True
The important concept here is low < i < high. In Python, you can specify a range of values that the variable should be between.
You could just use filter it would go something like this
filtered = filter(seq, lambda x: 1 < int(x) < 6)
That will return a filtered list containing only items which were between 1 and 6. You can then check if the list has the same length to see if anything was removed.
Going this route, your function would look like this:
def checkList(seq):
filtered = filter(seq, lambda x: 1 < int(x) < 6)
return len(filteted) == len(seq)

Categories