2013-09-13 5 views
2

для свободного онлайн учебник Python Мне нужно:кредитной карты проверка упражнения питон

написать функцию, которая проверяет, является ли данный номер кредитной карты действителен. Функция check(S) должна принимать строку S в качестве входных данных. Во-первых, , если строка не соответствует формату "#### #### #### ####", где каждый # является цифрой, то он должен возвращать False. Затем, если сумма цифры делятся на 10 (метод «контрольной суммы»), то процедура должна вернуть True, иначе она должна вернуть False. Например, если является строкой "9384 3495 3297 0123", то, хотя формат верен, сумма цифр равна 72, поэтому вы должны вернуть False.

Следующие показывает, что я придумал. Я думаю, что моя логика правильная, но не совсем понимаю, почему она дает мне неправильную ценность. Есть ли структурная проблема в моем коде, или я неправильно использую метод?

def check(S): 
    if len(S) != 19 and S[4] != '' and S[9] != '' and S[14] != '': 
     return False    # checking if the format is correct 

    S = S.replace(" ",'')   # Taking away spaces in the string 
    if not S.isdigit(): 
     return False    # checking that the string has only numbers 

    L = []    
    for i in S: 
     i = int(i)    # Making a list out of the string and converting each character to an integer so that it the list can be summed 
     L.append(i) 
    if sum(L)//10 != 0:  # checking to see if the sum of the list is divisible by 10 
     return False 
+1

Ваши отступы непоследовательны; можете ли вы исправить это? Ваш код не может быть запущен в его нынешнем виде. –

ответ

4

Вы не испытывая для пространств, только для пустых строк, которые вы никогда не найти при использовании прямых индексов на шнурке питона.

Кроме того, вы должны вернуть False, если любой из этих 4-х условий, правда, нет, если они все правда в то же время:

if len(S) != 19 or S[4] != ' ' or S[9] != ' ' or S[14] != ' ': 
    return False 

Далее заменить пробелы, но не снова проверьте длину. Что делать, если я дал вам 19 пространств:

S = S.replace(" ", '') 
if len(S) != 16 or not S.isdigit(): 
    return False 

Последние, вы хотите сначала собрать все цифры, и проверьте, есть ли остаток:

L = map(int, S) # makes S into a sequence of integers in one step 
if sum(L) % 10 != 0: # % calculates the remainder, which should be 0 
    return False 

и не забудьте вернуться Правда, если все эти испытания прошли:

return True 

в конце.

Put, что все вместе, и вы получите:

>>> def check(S): 
...  if len(S) != 19 or S[4] != ' ' or S[9] != ' ' or S[14] != ' ': 
...   return False 
...  S = S.replace(" ", '') 
...  if len(S) != 16 or not S.isdigit(): 
...   return False 
...  L = map(int, S) # makes S into a sequence of integers in one step 
...  if sum(L) % 10 != 0: # % calculates the remainder, which should be 0 
...   return False 
...  return True 
... 
>>> check('9384 3495 3297 0123') 
False 
>>> check('9384 3495 3297 0121') 
True 
3

Вот это метод, основанный на регулярных выражениях:

import re 
def cc(pat): 
    # check for the pattern #### #### #### #### with each '#' being a digit 
    m=re.match(r'(\d{4})\s(\d{4})\s(\d{4})\s(\d{4})$', pat.strip()) 
    if not m: 
     return False 
    # join all the digits in the 4 groups matched, 
    # turn into a list of ints, 
    # sum and 
    # return True/False if divisible by 10: 
    return sum(int(c) for c in ''.join(m.groups()))%10==0 

>>> cc('9384 3495 3297 0123') 
False 
>>> cc('9384 3495 3297 0121') 
True 
1

Вот мой подход, это немного больше кода, но я люблю использовать определяющих функции. По какой-то причине код не работает на веб-сайте Computer Science Circles, но он работает в программе PyCharm.

def CardNumber(): 
     global card  # Making variable global for function SumCardNumDigits(); see below 
     card = input() # Credit card number is entered 
     return card 


    def check(S): 
     CardNumber = S 
     SplitCardNum = CardNumber.split()  # Split credit card number into a list, so we get [####, ####, ####, ####] 
     for i in range(0, len(SplitCardNum)): # Checking if each item in list has length of four strings and each item is 
               # an actual a number 

      if len(SplitCardNum[i]) == 4 and SplitCardNum[i].isdigit(): 
      SplitCardNum.insert(i, True) # We add to a list a True value at position i 
       del SplitCardNum[i + 1] # We delete items at position i + 1 
      return SplitCardNum 


    def checkFormat(SplitCardNum): 
     if SplitCardNum == [True] * 4: # Checking if all above conditions are met in function check(S) 
             # So the returned value from previous function is a list [True, True, True, True] 
      return True 
     else: 
      return False 

    def SumCardNumDigits(): 
     Ncard = card     # Using global variable 'card' from function CardNumber() 
     SumN = 0 
     for i in Ncard:   # Summing up all digits in string 'Ncard', if i position in a string is empty space " " 
            # we skip a step. 
      if i == " ": 
       continue 
      else: 
       SumN += int(i) 
      return SumN 


    def DivideByTen(SplitCardNum): 
     if SplitCardNum == True:  # If conditions from function check(S) are met, we divide the sum of digits 
             # of credit card number by 10 
      SumNumber = SumCardNumDigits() % 10 # We do this by using the returned value of function SumCardNumDigits() 
      global SumNumber  # <--- Fixed code 
      return SumNumber 
     else: 
      return False 


    def IsDivideByTen(SumNumber): 
     check = checkFormat(SplitCardNum)  # Finally we check if the sum of digits of credit card number is divisible by 10 
     if SumNumber == 0 and check == True: # <--- Fixed code 
      return True 
     else: 
      return False 


    print(IsDivideByTen(DivideByTen(checkFormat(check(CardNumber()))))) # Output final result 

    # You can test this code at: http://cscircles.cemc.uwaterloo.ca/visualize/#mode=edit and see how it works. 
    # Try for '9384 3495 3297 4523' and '9384 3495 3297 4526' 
Смежные вопросы