0

Trying to make a function which detects the the middle digit of an odd number is 0 and returns True if it is, otherwise False. I really want to get this function to work without converting the integer to a string first.

This is what I have so far:

def test(n): 
  n = str(n)
  if len(n) % 2 == 0:
      return False
  else:
      left_side = n[:len(n)//2]
      right_side = n[(len(n)//2):]

      if right_side[:1] == "0" and ((not "0" in left_side)and (not "0" in right_side[2:])):
          return True
      else:
          return False


print (test(0)) # True
print (test(101)) # True
print (test(123)) # False
print (test(21031)) # True
snk
  • 91
  • 1
  • 8
  • 2
    Honestly, doing the manual math here probably isn't worth it from a performance or readability standpoint. I've timed cases like this in Python and Clojure, and string manipulation is usually almost as fast, and is much simpler. – Carcigenicate Nov 28 '19 at 23:02
  • @Carcigenicate is that so? Also is my method the most "Pythonic" way to make this function? I was given a tester for this function and it doesn't seem to be able to pass it for some reason and I can't figure out why. – snk Nov 28 '19 at 23:05
  • 1
    Use the modulus operator `% 10` repeatedly to create a sequence of remainders. – Peter Wood Nov 28 '19 at 23:06
  • @PeterWood Fairly new to python, do you mind elaborating on what you mean by "Use the modulus operator % 10 "? – snk Nov 28 '19 at 23:08
  • You'd have to time this exact case to know for sure, but I wouldn't worry about it unless you were finding that `test` was becoming a bottleneck. And a review of how Pythonic is is would be beyond here. Once you can get the code to work though in your own testing, it can be posted on [Code Review](https://codereview.stackexchange.com/questions) as a review request. – Carcigenicate Nov 28 '19 at 23:08
  • Those are your search terms. – Peter Wood Nov 28 '19 at 23:08

3 Answers3

1
n = 12345
digits = []
while n:
    digit = n % 10
    digits.append(digit)
    n //= 10

digit_count = len(digits)

if digit_count % 2:
    middle = digit_count // 2
    print(digits[middle])

Output:

3

Alternatively, using math.log10:

from math import log10

n = 12345

digit_count = int(log10(n)) + 1
middle = digit_count // 2

print(n // 10 ** middle % 10)

See these two answers:

Length of an integer in Python

How to take the nth digit of a number in python

Peter Wood
  • 23,859
  • 5
  • 60
  • 99
  • I think that my phrasing of the question confused you a bit. I don't want the middle element of any given odd number, I want the function to detect if the middle digit of an odd number is "0" if it is, I'd like it to return True – snk Nov 28 '19 at 23:18
  • 1
    @snk Peter's not confused, you just need to fill in the last step yourself. If you know how to get the middle digit, you can check whether it's zero. – wjandrea Nov 28 '19 at 23:24
  • You could use divmod to save a line: `n, digit = divmod(n, 10)` – wjandrea Nov 28 '19 at 23:26
  • 1
    @wjandrea if we can use `divmod` I'd use `log10` instead to find how many digits there were and `n // 10**middle % 10` to get the answer. – Peter Wood Nov 28 '19 at 23:37
0

Not that it will make much difference in terms of performance, but you can use the log function to compute the number of zeros in a number and remove the rightmost half by dividing to the correct power of 10. For example:

import math

def test(n):
  if n == 0:
    return True
  digits = math.ceil(math.log(n + 1, 10)) - 1
  return digits % 2 == 0 and not (n // 10**(digits / 2) % 10)
Selcuk
  • 57,004
  • 12
  • 102
  • 110
  • 1
    This usually works but in a misleading way. To correctly calculate digits you would need `digits = ceil(log(n+1, 10))`. Then your logic should be `digits % 2 == 1 ...`. As written this succeeds in several cases thanks to rounding. e.g. failure: `test(1000000) == False` but it should be `True` – Cireo Nov 28 '19 at 23:30
  • @Cireo Right, my bad. The original method you suggested should work fine. Edited my answer to reflect that. – Selcuk Dec 02 '19 at 23:10
0

this should do it. it does convert it to a string, but honestly it's faster, easier, and just more efficient.

num = int(input("number too test: "))


def test(number):
    num_len = len(str(number))
    print(num_len)
    if num_len % 2 == 0:
        return False
    else:
        number = str(number)
        half = int((num_len-1)/2)
        print(number[half])
        if int(number[half]) is 0:
            return True
        else:
            return False


test(num)
Julia Fasick
  • 121
  • 7