I have a list like this, named x (which I have already split):
['16','bob','2440', '34']
I want to write a code that checks to see if any of the numbers are negative. The code I tried does not work. This is what I have tried:
for num in x:
if num < 0:
print ("Negative number")
Your list contains only strings. So you should cast them to floats (or integers, whatever you need) first:
a = ['"16','bob','2440', '-2', '34"']
for x in a:
try:
if float (x) < 0: print ('negative')
except: continue
EDIT: I changes int to float as OP is asking for numbers and not exclusively integers.
You need to turn your numbers into integers first; use a predicate function to try to do this:
def negative(string):
try:
return int(string.strip('"')) < 0
except ValueError:
return False
The predicate function here also removes quotes; your input list looks like it was not cleaned up properly and you may want to do so first before testing for negative values.
Then use that to test for negative values:
negative_values = [v for v in a if negative(v)]
or test if there are any negative values:
if any(negative(v) for v in a):
print "No negative values please!"
How about checking for - sign in the beginning of an item and for the rest of an item to consist of digits? One-liner:
>>> a = ["-1", "aa", "3"]
>>> any(s.startswith('-') and s[1:].isdigit() for s in a)
True
Using any, because you've said that you want to write a code that checks to see if any of the numbers are negative.
Note: if there can be negative floats, then just replace s[1:] with s[1:].replace(".", "").
Hope that helps.
First, you need to understand that neither '"16' nor '2440' are numbers - they are strings.
Secondly, you need to figure out what you want to do with '"16' - it doesn't represent a number, but I assume you want it to. You could alter these strings, but you should probably just use an appropriate method of splitting in the first place.
That said, you can do this:
x = ['"16','bob','2440', '34"']
def int_is_negative(s)
try:
return int(s) < 0
except ValueError:
return False
is_negative_num = [int_is_negative(s) for s in x]
Related
I've tried to write a simple function, which input is binary number in string format and converts binary to decimal. But in the output I always get the wrong thing: the 'res' value in line 3, no matter what the input is ('1010', '10010111010', etc.). Also, I've tried to debug the code and the function doesn't even start the loop, as if it wasn't there... So, I just don't see my mistake
def bin_to_dec(bin):
bin = bin[::-1]
res = 0
for i in range(len(bin)):
if bin[i] == 0:
res += 2**i
return res
You are comparing the string "0" to the number 0 and they are, trivially, unequal.
So, contrary to what you say, the loop is actually looping; but the if statement will never be true.
Of course, also, you should probably add when the number is 1, not when it's 0.
def bin_to_dec(bin):
bin = bin[::-1]
res = 0
for i in range(len(bin)):
if int(bin[i]) == 1:
res += 2**i
return res
Notice the addition of int().
if bin[i] == '1'
This will correct the problem. bin[i] is a character and you are comparing it to a number which always results in false.
You can just use the built in int function:
def binaryToDecimal(n):
return int(n,2)
My teacher solved this question "Write a function which takes a n digits number as an input and return True if the biggest digit in this number is divisible by 3" like this:
def is_divisable(n):
a = str(n)
b = 0
for i in a:
if int(i)>b:
b = int(i)
if b % 3 == 0:
return "True"
print is_divisable(67479)
I have thought of it in another way but my code is not working and
I am getting an error says:
"TypeError: 'int' object is not iterable"
def is_dvo(n):
if max(n) % 3 == 0:
return True
print is_dvo(67479)
You don't quite say what your question is, but if you want another way to solve the problem,
def is_divisable(n):
return int(max(str(n))) % 3 == 0
This code converts the number to its decimal string representation, finds the largest digit (as a character), changes that digit to an integer, checks if that is divisible by 3, then returns that answer.
If your question is why you are getting that error, your parameter n is an integer, and you try to apply the max() function to that integer. However, max() is supposed to be used on iterable objects such as strings, lists, tuples, generators, and so on. My code changes the integer to a string before using max() so it does not have that problem, and it iterates over the digits in the string.
You can condense the code to a single line:
def is_divisable(n):
return max(map(int, str(n)))%3 == 0
Try:
max(str(n), key=int) in {'3', '6', '9'}
My question is regarding the way Python3 handles certain array elements.
Here is my code:
def isIPv4(inputStr):
inputStr.split('.') #splits input into array elements (no periods)
val = []
for i in inputStr:
if not i.isdigit(): #if the element is not a digit (valid to convert to INT).
return False
if int(i) >=0 and int(i)<=255: #element value between 0 and 255.
val.append(i)
else:
return False
return len(val) == 4 #array has 4 elements ^^
The code should let me know if the input is an IPv4 address, meaning for numbers between 0 and 255, separated by periods. Returns True or False.
inputs that work:
inputStr: "1.1.1.1a"
inputStr: "0..1.0"
For both, my code correctly returns False.
inputs that do not work:
inputStr: "172.16.254.1"
inputStr: "0.254.255.0"
For these, my code also returns False, while it should return True instead.
As you can see, the program handles the splitting of the dot separated values properly, however, even though '1a' is being correctly thrown out as a non-int, '0' and also '172' are being thrown out.
I realize that '0' and '172' are both strings, so is there something I should know about how the Python3 module handles this data?
inputStr.split('.') returns a list. You ignored that list altogether. inputStr itself is an immutable string and does not change.
so inputStr stays the original string, and you are testing if each individual character is a digit. That fails for the . characters.
You need to store the result of the str.split() call and test against that:
def isIPv4(inputStr):
parts = inputStr.split('.')
for part in parts:
if not part.isdigit():
return False
if not (0 <= int(part) <= 255):
return False
return len(parts) == 4
Note that you don't have to build a new vals list either; just test if the split result is the right length.
So I've recently picked up John Guttag's Introduction to Computation and Programming Using Python,the revised and expanded edition, after having worked through most of LPTHW. I am using the book in conjunction with MIT OCW 006. Now, I was trying to complete one of the Finger Exercises listed in the book, specifically the one of page 85, chapter 7, where the author asks you to implement a function using a try-except block:
def sumDigits(s):
"""Assumes s is a string
Returns the sum of the decimal digits in s
For example, if is is'a2b3c' it returns 5"""
This is my code:
def sumDigits(s):
try:
total = 0
list1 = [s]
new_list = [x for x in list1 if x.isdigit()]
for e in new_list:
total += new_list[e]
return total
except TypeError:
print "What you entered is not a string."
When I run this program in the IDLE using a test input, the total is always computed to be zero, indicating that none of the elements of new_list are being passed to the accumulator. Could someone suggest why that is? Thanks.
It seems like the errors have been pointed out already by Rafael but it is still important to note that the more pythonic way to approach this would be:
return sum([int(x) for x in s if x.isdigit()])
There are actually several errors with your code.
Let's break them down in detail
The main problem is located in these lines:
list1 = [s]
new_list = [x for x in list1 if x.isdigit()]
You should loop directly over the string first
new_list = [x for x in s if x.isdigit()] #s is the input string
When you create a new list as you did, the variable x in x for x in list1 will take place as elements of the list. So, in your case, the list will have only one element, which happen to be whole string (because you defined the list as [s]. As the whole string is not a digit, new_list will be an empty list.
That is why you are getting 0 as a return.
However, if you loop through the string directly, x will take place as each letter in the string, and then it will be possible to check whether x is digit or not.
It is also important to highlight that new_list[e] will raise IndexError. You should correct that for e only. The sintax of for e in new_list makes the local variable e assume each value inside the list, so you do not have to get the value via indexes: you can use e directly.
Finally, in order to sum the values in your new_list, the values should be integers (int) and not string (str), so you have to cast the values to int before summing (or, you can cast each element to int during the list comprehension, by using int(x) for x in s if x.isdigit() instead of x for x in s if x.isdigit()). Also, in order to check if the input is a string or not, you better use isinstance(s, basestring) if you're in python2, or isinstance(s, str) if you're using python3.
So the whole code would look like this :
def sumDigits(s):
if isinstance(s, basestring):
total = 0
new_list = [x for x in s if x.isdigit()]
for e in new_list:
total += int(e)
return total
else:
print "What you entered is not a string."
I'm working through the same book and the MITx: 6.00.1x course on edX; here's my solution:
def sumDigits(s):
'''
Assumes s is a string
Returns the sum of the decimal digits in s
For example, if s is 'a2b3c' it returns 5
'''
result = 0
try:
for i in range(len(s)):
if s[i].isdigit():
result += int(s[i])
return result
except:
print('Your input is not a string.')
Since we are to assume that s is a string, the except block should handle those cases where s is not a string. So simple, but it was not obvious to me at first.
You can use reduce method
reduce( (lambda x, y: x + y), [int(x) for x in new if x.isdigit()] )
I'm working through the same book too. I think we should use the try-except block on determining whether characters of string convertible to an integer. So here is my solution.
def sumDigits(s):
"""Assumes s is a string
Returns the sum of the decimal digits in s
For example, if s is 'a2b3c' it returns 5"""
sum = 0
for i in s:
try:
sum += int(i)
except ValueError:
None
return sum
I've just started exploring the wonders of programming. I'm trying to write a code to identify numeric palindromes. Just looking at numbers and not texts. I'm trying to learn to use recursion here. But I'm just not getting anywhere and I can't figure out what's wrong with it.
My idea was to check first string vs the last, then delete these two if they match, and repeat. Eventually there'll be nothing left (implying it is a palindrome) or there will be a couple that doesn't match (implying the reverse).
I know there are better codes to finding palindromes in but I just wanted to try my hand at recursion.
So what's wrong?
def f(n):
global li
li=list(str(n))
if (len(li)==(1 or 0)):
return True
elif li[len(li)-1]==li[0]:
del li[0]
del li[len(li)-1]
if len(li)==0:
return True
if len(li)>0:
global x
x=''.join(li)
str(x)
f(x)
else:
return False
Thanks in advance!
A few comments
Why are x and li globals? In recursion, all variables should be local.
Why are you converting back and forth between str and list? You can subscript both of them
You need to return the result of your recursive call: return f(x)
Try these suggestions, and see how it works out.
Before looking into it too much, if (len(li)==(1 or 0)): doesn't do what you're expecting it to do. (1 or 0) will always evaluate to 1.
You probably want:
if len(li) in (1, 0):
There are a couple of problems with your solution. Let me analyse them line by line.
You don't need global statements if you don't intend to change variables outside of function scope. Thus, I removed two lines with global from your code.
li=list(str(n)): casting a string to a list is unnecessary, as a string in Python has a similar interface to an immutable list. So a simple li = str(n) will suffice.
if (len(li)==(1 or 0)):: although it looks OK, it is in fact an incorrect way to compare a value to a few other values. The or operator returns the first "true" value from its left or right operand, so in this case it always returns 1. Instead, you can use the in operator, which checks whether the left operand is an element of a right operand. If we make the right operand a tuple (1, 0), all will be well. Furthermore, you don't need parentheses around the if statement. You should write: if len(li) in (1, 0):
elif li[len(li)-1]==li[0]: is fine, but we can write this shorter in Python, because it supports negative list indexing: elif li[-1] == li[0]:
Because we don't use lists (mutable sequences) because of point 2., we can't do del li[0] on them. And anyway, removing the first element of a list is very inefficient in Python (the whole list must be copied). From the very same reason, we can't do del li[len(li)-1]. Instead, we can use the "splicing" operator to extract a substring from the string: li = li[1:-1]
if len(li)==0: is unnecessary long. In Python, empty strings and lists resolve to False if tested by an if. So you can write if not li:
if len(li)>0:: You don't have to check again if li is not empty -- you checked it in point 6. So a simple else: would suffice. Or even better, remove this line completely and unindent the rest of the function, because the body of the if in 6. contains a return. So if we didn't enter the if, we are in the else without writing it at all.
x=''.join(li): We don't need to convert our string to a string, because of the decision made in 2. Remove this line.
str(x): This line didn't do anything useful in your code, because str() doesn't modify its argument in place, but returns a new value (so x = str(x) would have more sense). You can also remove it.
f(x): This is a valid way to call a recursive function in Python, but you have to do something with its value. Return it perhaps? We'll change it to: return f(li) (as we don't have an x variable any more).
We end up with the following code:
def f(n):
li = str(n)
if len(li) in (1, 0):
return True
elif li[-1] == li[0]:
li = li[1:-1]
if not li:
return True
return f(li)
else:
return False
It's almost what we need, but still a little refinement can be made. If you look at the lines if not li: return True, you'll see that they are not necessary. If we remove them, then f will be called with an empty string as the argument, len(li) will equal 0 and True will be returned anyway. So we'll go ahead and remove these lines:
def f(n):
li = str(n)
if len(li) in (1, 0):
return True
elif li[-1] == li[0]:
li = li[1:-1]
return f(li)
else:
return False
And that's it! Good luck on your way to becoming a successful programmer!
Split the whole show out into a list, then just:
def fun(yourList):
if yourList.pop(0) == yourList.pop(-1):
if len(yourList) < 2:
return True # We're a palindrome
else:
return fun(yourList)
else:
return False # We're not a palindrome
print "1234321"
print fun(list("1234321")) # True
print "6234321"
print fun(list("6234321")) # False
def palindrome(n):
return n == n[::-1]
It's hard to tell what you intend to do from your code, but I wrote a simpler (also recursive) example that might make it easier for you to understand:
def is_palindrome(num):
s = str(num)
if s[0] != s[-1]:
return False
elif not s[1:-1]:
return True
else:
return is_palindrome(int(s[1:-1]))
number = int(raw_input("Enter a number: "))
rev = 0
neg = number
original = number
if (number < 0):
number = number * -1
else:
number = number
while ( number > 0 ):
k = number % 10
number = number / 10
rev = k + ( rev * 10 )
if (number < 1):
break
if ( neg < 0 ):
rev = ( rev * -1)
else:
rev = (rev)
if ( rev == original):
print "The number you entered is a palindrome number"
else:
print "The number you entered is not a palindrome number"
This code even works for the negative numbers i am new to programming in case of any errors
dont mind.