Null returns in a simple Python program - python

I'm currently working on my Programming Fundamentals w/ Python final project which is a collection of small games. I'm trying to make the game "High Card", where 2 random numbers between 1 & 13(the face values of a 52 card deck) are generated, then compared for the higher number and a winner is displayed.
We are required to have seperate files for the Class and Program code. This is what my Class looks like.
import random
class card:
def __init__(self, value):
self.card_value = value
def deal(self):
numb = random.randrange(1, 13)
def set_value(self, value):
self.card_value = value
def get_value(self):
return self.card_value
def find_face_value(self, numb):
#face = 'test'
print(numb)
if numb == 1:
print("numb == 1")
return 'Ace'
elif numb == 2:
return 'two'
## elif numb == 3:
## face = 'three'
## elif numb == 4:
## face = 'four'
## elif numb == 5:
## face = 'five'
## elif numb == 6:
## face = 'six'
## elif numb == 7:
## face = 'seven'
## elif numb == 8:
## face = 'eight'
## elif numb == 9:
## face = 'nine'
## elif numb == 10:
## face = 'ten'
## elif numb == 11:
## face = 'jack'
## elif numb == 12:
## face = 'queen'
## elif numb == 13:
## face = 'king'
#return face
def __str__(self):
return 'Numeric Value: ' + str(self.card_value)
I've commented out those (if numb == ...) statements b/c I am testing to see if I can get one correct return.
And Here is my Program code for the game.
def high_card():
#player1_card = cardClass.card(random.randrange(1, 13))
player1_card = cardClass.card(1)
player2_card = cardClass.card(2)
card1 = player1_card.find_face_value(player1_card)
#player2_card = cardClass.card(random.randrange(1, 13))
card2 = player2_card.find_face_value(player2_card)
print('Player 1 got', card1, player1_card, '\nPlayer 2 got', card2, player2_card)
And this is the output I recieve when I run the high_card() function.
>>> high_card()
Numeric Value: 1
Numeric Value: 2
Player 1 got None Numeric Value: 1
Player 2 got None Numeric Value: 2
My problem is in the last 2 lines of the output. It should say "Player 1 got Ace Numeric Value: 1" and "Player 2 got two Numeric Value: 2". I need the find_face_value function in my class to return a string of the "face" of a card. Instead, Python is printing "None", implying that I did not return anything inside the find_face_value function. I'm stumped on what to do to get this working and would greatly appreciate some help.

card1 = player1_card.find_face_value(player1_card)
In the statement above, numb is neither 1 nor 2. numb is a card class (you assigned numb=player1_card). So those if statements inside find_face_value are both false, thus return values are skipped. Python returns None by default. You have to check self.card_value inside if statements, instead of checking numb.
def find_face_value(self):
if self.card_value == 1:
print("card value is 1")
return 'Ace'
elif self.card_value == 2:
return 'two'
card1 = player1_card.find_face_value()
print(card1)
the statement above should print 'Ace'.

Related

Python bingo project

so my code is designed to basically create a bingo card, then when you press enter draws a number and changes the bingo card value to 0 if the drawn number matches. My issue is that my code isn't properly producing a bingo or not a bingo which you can see towards the end of the code. How should I change this so that my code will return bingo when I have bingo.
import random #Condernsed solo version with call and player together
import numpy as np
def bingo_card(): #Code to generate BINGO card using numpy array
test1=np.array(random.sample(range(1,16),5))
test2=np.array(random.sample(range(16,31),5))
test3=np.array(random.sample(range(31,46),5))
test4=np.array(random.sample(range(46,61),5))
test5=np.array(random.sample(range(61,76),5))
test= np.concatenate((test1,test2,test3,test4,test5))
test= test.reshape(5,5)
test[2,2]=0
bingo_card.test = test
BINGO= print("Your Card")
print("B", test[0]),
print("I", test[1]),
print("N", test[2]),
print("G", test[3]),
print("O", test[4])
card = BINGO
return card
def called_value(): #should be close to the code we use to check if called value is in generated matrix, may need some formatting and fixing
checked_card = bingo_card.test
while True:
called_num = input ("Type called number to mark card or press 's' to quit if you think you have bingo").lower()
if called_num != "s":
number_check = int(called_num)
checked_card = np.where(checked_card==number_check,0,checked_card)
BINGO = print("Your Card")
print("B", checked_card[0]),
print("I", checked_card[1]),
print("N", checked_card[2]),
print("G", checked_card[3]),
print("O", checked_card[4])
elif called_num == "s":
BINGO = print("Your Card")
print("B", checked_card[0]),
print("I", checked_card[1]),
print("N", checked_card[2]),
print("G", checked_card[3]),
print("O", checked_card[4])
row_zeros = np.count_nonzero(checked_card == 0, axis=1)
col_zeros = np.count_nonzero(checked_card == 0, axis=0)
diagonal_zeros = np.count_nonzero(np.diag(checked_card) == 0)
diagonal1_zeros = np.count_nonzero(np.diag(np.fliplr(checked_card)) == 0)
for i in range (5):
if (row_zeros[i] or col_zeros[i]) == 5:
return ("Bingo!")
elif (diagonal_zeros or diagonal1_zeros) == 5:
return ("Bingo!")
else:
return ("Not Bingo")
def solo():
bingo_card()
called_value()
solo()
You've committed one of the classic blunders.
for i in range (5):
if (row_zeros[i] or col_zeros[i]) == 5:
return ("Bingo!")
elif (diagonal_zeros or diagonal1_zeros) == 5:
return ("Bingo!")
else:
return ("Not Bingo")
row_zeros[i] or col_zeros[i] is going to be True or False (usually True), which is never equal to 5. And you don't need to loop to check the diagonals. You need:
if diagonal_zeros == 5 or diagonal1_zeros == 5:
return ("Bingo!")
for i in range (5):
if row_zeros[i] == 5 or col_zeros[i] == 5:
return ("Bingo!")
return ("Not Bingo")

List returns None value instead of class object

In my role-playing party creator program, I am trying to have the user create a class object, adding the attributes, and storing it into a party-list index. However, by the time the player goes back to the main menu (the main() function that displays the party list), the slot still shows a None value. Here is my code:
class Creature:
def __init__(self):
self.name = None
self.feet = None
self.inches = None
self.weight = None
self.gender = None
def getName(self):
return "Name: {}".format(self.name)
def setName(self, name):
self.name = name
def getHeight(self):
return "Height: {} ft. {} in.".format(self.feet, self.inches)
def setFeet(self, feet):
self.feet = feet
def setInches(self, inches):
self.inches = inches
def getWeight(self):
return "Weight: {} lbs.".format(self.weight)
def setWeight(self, weight):
self.weight = weight
def getGender(self):
return "Gender: {}".format(self.gender)
def setGender(self, index):
genders = ['Male', 'Female', 'Others']
if int(index) == 1:
self.gender = genders[0]
elif int(index) == 2:
self.gender = genders[1]
elif int(index) == 3:
self.gender = genders[2]
class Dragon(Creature):
pass
class Mermaid(Creature):
pass
class Fairy(Creature):
pass
class Vampire(Creature):
pass
#allows the user to change attributes of creature
def changeAttributes(creature):
value = input("Pick an attribute to change: 1) name 2) height 3) weight 4) gender 5) save")
if int(value) == 1:
creature.setName(input("Enter a name: "))
return changeAttributes(creature)
elif int(value) == 2:
creature.setFeet(input("Enter a foot value: "))
creature.setInches(input("Enter an inch value: "))
return changeAttributes(creature)
elif int(value) == 3:
creature.setWeight(input("Enter a value in pounds: "))
return changeAttributes(creature)
elif int(value) == 4:
creature.setGender(input("Enter a value to set gender; 1 = male, 2 = female, 3 = others: "))
return changeAttributes(creature)
elif int(value) == 5:
confirm = input("Save? 1) yes 2) no")
if int(confirm) == 1:
print('Saving...')
return menu(creature)
else:
return changeAttributes(creature)
else:
print("Not a valid input, please try again.")
return changeAttributes(creature)
#prints the attributes of the creature
def showAttributes(creature):
print(creature.getName())
print(creature.getHeight())
print(creature.getWeight())
print(creature.getGender())
menu(creature)
def Delete(creature):
a = input("Are you sure? 1) yes 2) no ")
if int(a) == 1:
print("Deleting...")
creature = None
return main()
elif int(a) == 2:
print("Cancelled")
return menu(creature)
#checks to see if slot is empty or has a creature object; if empty, create a creature, otherwise go to creature menu
def menu(creature):
value = input("Select an option 1) Show Attributes 2) Change Attributes 3) Delete 4) Back")
if int(value) == 1:
return showAttributes(creature)
return menu(creature)
elif int(value) == 2:
return changeAttributes(creature)
return menu(creature)
elif int(value) == 3:
return Delete(creature)
elif int(value) == 4:
return main()
#checks if slot is empty, if empty, choose a creature subclass and change attributes, else takes user directly to change attribute menu
def check(slot):
if slot == None:
a = input('Choose a creature: 1) Dragon 2) Fairy 3) Mermaid 4) Vampire')
if int(a) == 1:
slot = Dragon()
elif int(a) == 2:
slot = Fairy()
elif int(a) == 3:
slot = Mermaid()
elif int(a) == 4:
slot = Vampire()
return changeAttributes(slot)
else:
return menu(slot)
#user select a slot; note that since development has not finished, you can only change slot 1
def main():
global party
print(party)
inp = input("Select a slot: ")
inp_1 = int(inp) - 1
if int(inp) > 0 and int(inp) < 6:
print("Slot {} selected!".format(int(inp)))
return check(party[inp_1])
party = [None, None, None, None, None]
main()
This is how the program runs so far:
[None, None, None, None, None]
Select a slot:
#User inputs 1
Slot 1 selected!
Choose a creature: 1) Dragon 2) Fairy 3) Mermaid 4) Vampire
#User inputs 1
Pick an attribute to change: 1) name 2) height 3) weight 4) gender 5) save
#User inputs 1
Enter a name: *Name*
Pick an attribute to change: 1) name 2) height 3) weight 4) gender 5) save
#User inputs 5
Save? 1) yes 2) no
#User inputs 1
Saving...
Select an option 1) Show Attributes 2) Change Attributes 3) Delete 4) Back
#User inputs 4
However, after you go back to main(), the list still displays as such:
[None, None, None, None, None]
Select a slot:
What doesn't make sense is that the parameters in the functions should have followed a chain rule that will eventually lead to the party slot. I want it so that a slot index will have a class object stored in it rather than None. As far as I know, I might need to use global variables, but I haven't found out much after that. Any ways to fix this?
Edit: So I managed to fix the problem. I just put the check() function in the main(). It goes like this:
def main():
print(party)
inp = input("Select a slot: ")
inp_1 = int(inp) - 1
if int(inp) > 0 and int(inp) < 6:
print("Slot {} selected!".format(int(inp)))
if party[inp_1] == None:
a = input('Choose a creature: 1) Dragon 2) Fairy 3) Mermaid 4) Vampire')
if int(a) == 1:
slot = Dragon()
elif int(a) == 2:
slot = Fairy()
elif int(a) == 3:
slot = Mermaid()
elif int(a) == 4:
slot = Vampire()
party[inp_1] = slot
return changeAttributes(party[inp_1])
else:
return menu(party[inp_1])
There is no sens of "return" at the end of main. What you should want to do I think is editing the party list. Therefor instead of
return check(party[inp_1])
you should try
party[inp_1] = check(party[inp_1])
Make sure the check function returns a creature type, I'm not sure of that.
there is some really weird interaction you really should try to make class and methods for all of that. In your 4th elseif in the menu function, you shouldn't have to call main again.

Creating the war(card) game using OOP in Python

I am trying to create the war card game where 2 players draw a card each on the table, and the player whose card has max value gets both the cards, if the card values are equal(called war condition) each player draws 5 cards, and the value of the last card among these 5 cards are compared and works similarly as above. A player wins when either the other player runs out of cards or if in war condition the other player has less than 5 cards.
My questions:
When I am running the game logic sometimes it runs but sometimes it gets stuck in an infinite loop. Why?
I can notice that when the total number of cards for both players at all times should be 52, but here it is decreasing. Why? (I can see that the cards are getting lost every time the game goes into war condition, but I am not able to understand why that is happening, since I am adding all the 10 cards to the player whose card has a greater value.)
I have tried another method where I assume that players are always at war and then approach it, which works. But I want to understand why, if I break it into steps which I am trying to do here, is it not working?
Code:
import random
suits = ['Hearts','Clubs','Spades','Diamonds']
ranks = ['Two','Three','Four','Five','Six','Seven','Eight','Nine','Ten','Jack','Queen','King','Ace']
values = {'Two': 2, 'Three': 3, 'Four': 4, 'Five': 5, 'Six' : 6 , 'Seven' :7, 'Eight': 8,'Nine':9,
'Ten':10,'Jack':11, 'Queen': 12,'King': 13,'Ace':14 }
classes:
class Card():
def __init__(self,suit,rank):
self.suit = suit
self.rank = rank
self.value = values[rank]
#string method
def __str__(self):
return self.rank + ' of ' + self.suit
class Deck():
def __init__(self):
self.all_cards = [] #list of objects
for suit in suits:
for rank in ranks:
#create card object
created_card = Card(suit,rank)
self.all_cards.append(created_card)
def shuffle(self): #method to shuffle the card
random.shuffle(self.all_cards)
def deal_one(self):
return self.all_cards.pop() #we want the last card from deck
class Player():
def __init__(self,name):
self.name = name
self.all_cards = []
def remove_one(self):
return self.all_cards.pop(0) #to remove card from beginning of the list
def add_cards(self,new_cards):
if type(new_cards) == type([]):
self.all_cards.extend(new_cards)
else:
self.all_cards.append(new_cards)
def __str__(self):
return f'Player {self.name} has {len(self.all_cards)} cards.'
And below is the final game logic:
#create 2 new instances of the player class
player1_name = input('Enter the name of Player1: ')
player2_name = input('Enter the name of Player2: ')
player1 = Player(player1_name)
player2 = Player(player2_name)
newdeck = Deck()
newdeck.shuffle()
#splitting the deck among the two players - alternate card from deck goes to each player respectively
for i in range(0,len(newdeck.all_cards)-1,2):
player1.add_cards(newdeck.all_cards[i])
player2.add_cards(newdeck.all_cards[i+1])
#for x in range(26):
# player1.add_cards(newdeck.deal_one())
#player2.add_cards(newdeck.deal_one())
print(player1)
print(player2)
game_status = True
round_num = 0
while game_status == True:
round_num +=1
print(f"Round {round_num}")
if len(player1.all_cards) == 0:
print('Player 1 out of cards'+ player2.name + 'Wins!')
game_status = False
break
if len(player2.all_cards) == 0:
print('Player 2 out of cards' + player1.name + 'Wins!')
game_status = False
break
else:
player_cards = []
player1_card = player1.remove_one()
player2_card = player2.remove_one()
player_cards.append(player1_card)
player_cards.append(player2_card)
print('player1_card_value: ',player1_card.value)
print('')
print('player2_card_value: ',player2_card.value)
print('')
print(player1)
print('')
print(player2)
at_war = True
if player1_card.value == player2_card.value:
while at_war == True:
player1_list = []
player2_list = []
card_list = []
if len(player1.all_cards) < 5:
print('Player 2 won')
game_status = False
at_war = False
break
elif len(player2.all_cards) <5:
print('Player 1 won')
game_status = False
at_war = False
break
if len(player1.all_cards) >= 5 and len(player2.all_cards) >= 5:
for i in range(5):
player1_list.append(player1.remove_one())
player2_list.append(player2.remove_one())
card_list.extend(player1_list)
card_list.extend(player2_list)
print("CARD LIST LEN", len(card_list))
if player1_list[0].value > player2_list[0].value:
player1.add_cards(card_list)
at_war = False
break
elif player1_list[0].value < player2_list[0].value:
player2.add_cards(card_list)
#player2.add_cards(player1_list)
at_war = False
break
else:
at_war = True
elif player1_card.value > player2_card.value:
player1.add_cards(player_cards)
#player1.add_cards(player2_cards)
#print('p1>p2', player1)
elif player2_card.value > player1_card.value:
player2.add_cards(player_cards)
print(player1)
print(player2)
if len(player1.all_cards) == 0:
print('Player 2 won')
elif len(player2.all_cards) == 0:
print('Player 1 won')
Output: When it was stuck in an infinite loop:(You can see the total number of cards is now 34 instead of 52.)

TicTacToe Python with board size selection

Desperately trying to create a code for a python TicTacToe game.
Im quite new to Python so am stuck with a feature that I want to add.
The idea is that the player can select whether he wants to play with 2, 3 players or against the computer.
He then selects whether he would like to be X or O (or Y for 3 players)
He then selects any boardsize up to 9x9.
So far so good, the two player, NbyN and X or O selection works and I have split the code into three seperate files (two classes) for ease.
I am lost with trying to figure out how to create the computer algorithm and to extend the game to 3 players.
Has anyone got any idea how I could do this?
Below is the code:
Player File:
class Player:
def __init__(self, player_name, shape):
self.player_name = player_name
self.shape = shape
def get_player_loc_input(self, rows, columns):
player_input = input('Enter in location for your move: ') # player input is with respect to field index location/values
converted_input = int(player_input)
if 1 <= converted_input <= (rows * columns): # bound checking
converted_input -= 1 # adjust from n+1 to n
transformed_value = (rows-(converted_input//columns)-1, converted_input%columns) # (row,col) tuple obj
return transformed_value
else:
raise ValueError('Input is not an index on the playing field. Try again\n')#
TicTac File:
class TicTac:
def __init__(self, rows, columns):
#self.playing_field = [ [7,8,9], [4,5,6], [1,2,3] ] #init the playing field to their respective nums on the numpad: 3x3
self.winner_found = False
self.is_full = False
self.possible_moves_left = columns * rows
self.rows = rows
def DefineBoard():
field = []
value = (rows * columns)
for row in range(rows):
field.append([])
for col in range(columns):
field[row].insert(0, value)
value = value - 1
return field
self.playing_field = DefineBoard()
#value = (rows * columns)
#def decrement(x): return (x-1)
#self.playing_field = [ [ decrement(value) for i in range(columns) ] for i in range(rows)]
def DrawBoard(self): #prints playing field based on size input
print('-------------')
for list in self.playing_field:
print('| ', end='')
for item in list:
print(str(item) + ' | ', end='')
print('\n-------------')
def Instructions(self):
print('\n-------------------------------------')
print('When entering in the location please enter the number of the index you want to replace with your shape.')
print('\nPrinting Initial Playing Field...')
self.DrawBoard()
print('\nLet the game begin!')
print('-------------------------------------')
def PlayerMove(self, index, shape):
row, col = index[0], index[1]
field_value = self.playing_field[row][col]
#if the value is of type int we can replace it
if isinstance(field_value, int):
self.playing_field[row][col] = shape #overwrite the value
self.possible_moves_left -= 1 #reduce the moves left
#check possible moves after its been updated
if self.possible_moves_left == 0:
self.is_full = True
raise EnvironmentError('All index posistions filled.\nGame Over. Nobody won.')
#else its the Player's shape (string)
else:
raise ValueError('Invalid Index. Position already filled. Try again.\n')
def ConsecutiveSymbols(self):
def check_list(passed_list):
#fast & quick check to tell if the "row" is incomplete
if isinstance(passed_list[0], str):
player_shape = passed_list[0] # set to first val
#compare the values to each other
for val in passed_list:
if isinstance(val, int) or player_shape != val:
return False #we found an inconsistency
return True #everything matched up
def Diagonal(orientation):
DiagonalList = []
counter = 0 if orientation is 'LtR' else self.rows-1
for row in self.playing_field:
DiagonalList.append(row[counter])
counter = counter+1 if orientation is 'LtR' else counter-1
return DiagonalList
# check rows for match
for row_list in self.playing_field:
if check_list(row_list):
return True
#check cols for match
transposed_playing_field = [list(a) for a in zip(*self.playing_field)] #convert our tuples from zip to a list format
for col_list in transposed_playing_field:
if check_list(col_list):
return True
#check diagonals for match
if check_list(Diagonal('LtR')): #LtR \ gets replaced each time we check
return True
if check_list(Diagonal('RtL')): # RtL / gets replaced each time we check
return True
return False #if we got here then no matches were found
Main File:
try:
from .TicTac import TicTac
from .Player import Player
except Exception:
from TicTac import TicTac
from Player import Player
winners=[]
def GameBegins():
Game=input("Would you like to play with 2, 3 players or against the CPU?").upper()
if Game=="2":
selection=input("Player 1: Would you like to play as X or O?").upper()
if selection == "X":
Players = {'Player_1': Player('Player_1', "X"), 'Player_2': Player('Player_2', "O")}
elif selection == "O":
Players = {'Player_1': Player('Player_1', "O"), 'Player_2': Player('Player_2', "X")}
else:
print("Please enter either X or O")
return False
if Game=="3":
selection=input("Player 1: Would you like to play as X, O or Y?").upper()
if selection == "X":
selection2=input("Player 2: Would you like to play as O or Y?").upper()
if selection2=="O":
Players = {'Player_1': Player('Player_1', "X"),"Player_2":Player("Player_2","O"),"Player_3":Player("Player_3","Y")}
elif selection2=="Y":
Players = {'Player_1': Player('Player_1', "X"),"Player_2":Player("Player_2","Y"),"Player_3":Player("Player_3","O")}
else:
print("Please enter either O or Y")
return False
elif selection == "O":
selection2=input("Player 2: Would you like to play as X or Y?").upper()
if selection2=="X":
Players = {'Player_1': Player('Player_1', "O"),"Player_2":Player("Player_2","X"),"Player_3":Player("Player_3","Y")}
elif selection2=="Y":
Players = {'Player_1': Player('Player_1', "O"),"Player_2":Player("Player_2","Y"),"Player_3":Player("Player_3","X")}
else:
print("Please enter either X or Y")
return False
elif selection=="Y":
selection2=input("Player 2: Would you like to play as X or O?").upper()
if selection2=="X":
Players = {'Player_1': Player('Player_1', "Y"),"Player_2":Player("Player_2","X"),"Player_3":Player("Player_3","O")}
elif selection2=="O":
Players = {'Player_1': Player('Player_1', "Y"),"Player_2":Player("Player_2","O"),"Player_3":Player("Player_3","X")}
else:
print("Please enter either X or O")
return False
if Game=="CPU":
CPU()
x=input("enter boardsize: ")
if x >="2":
rows, columns = int(x),int(x) #Players input becomes board size
else:
print("Please enter a boardsize of 3 or more")
GameBegins()
global game
game = TicTac(rows, columns)
game.Instructions()
player_id = 'Player_1' # index to swap between players, Player_1 starts
while (game.winner_found == False and game.is_full == False):
print('\nIt\'s ' + Players[player_id].player_name + ' Turn')
# loop until user inputs correct index value
while True:
try:
index = Players[player_id].get_player_loc_input(rows,columns)
shape = Players[player_id].shape
game.PlayerMove(index, shape)
except ValueError as msg:
print(msg)
continue
except EnvironmentError as msg:
print(msg)
break
game.winner_found = game.ConsecutiveSymbols() # check if a player has won
game.DrawBoard()
if game.winner_found:
print(Players[player_id].player_name + ' has won!') # print player who won
winners.append(str(Players[player_id].player_name))
player_id = 'Player_2' if player_id is 'Player_1' else 'Player_1' # switch between the 2 players
Replay() # Game has ended. Play Again?
def Replay():
PlayerDecision = input('\nDo you want to play again? (Y/N) ')
PlayerDecision = PlayerDecision.upper() #force to uppercase for consistency
if PlayerDecision == 'Y':
GameBegins()
elif PlayerDecision == 'N':
file=open("winners.txt","w")
for w in winners:
file.write(str(winners))
file.close()
exit(0)
else:
print('Incorrect input.')
Replay()
def main():
while True:
GameBegins()
if __name__ == '__main__':
main()
Would really appreciate some suggestions, thanks in advance!

Python Credit Card Validation

I'm a beginner Python learner and I'm currently working on Luhn Algorithm to check credit card validation. I wrote most of the code, but I'm stuck with 2 errors I get 1st one is num is referenced before assignment. 2nd one I'm getting is object of type '_io.TextIOWrapper' has no len(). Further help/ guidance will be greatly appreciated.
These are the steps for Luhn Algorithm (Mod10 Check)
Double every second digit from right to left. If this “doubling” results in a two-digit number, add the two-digit
number to get a single digit.
Now add all single digit numbers from step 1.
Add all digits in the odd places from right to left in the credit card number.
Sum the results from steps 2 & 3.
If the result from step 4 is divisible by 10, the card number is valid; otherwise, it is invalid.
Here's what my output is supposed to be
Card Number Valid / Invalid
--------------------------------------
3710293 Invalid
5190990281925290 Invalid
3716820019271998 Valid
37168200192719989 Invalid
8102966371298364 Invalid
6823119834248189 Valid
And here is the code.
def checkSecondDigits(num):
length = len(num)
sum = 0
for i in range(length-2,-1,-2):
number = eval(num[i])
number = number * 2
if number > 9:
strNumber = str(number)
number = eval(strNumber[0]) + eval(strNumber[1])
sum += number
return sum
def odd_digits(num):
length = len(num)
sumOdd = 0
for i in range(length-1,-1,-2):
num += eval(num[i])
return sumOdd
def c_length(num):
length = len(num)
if num >= 13 and num <= 16:
if num [0] == "4" or num [0] == "5" or num [0] == "6" or (num [0] == "3" and num [1] == "7"):
return True
else:
return False
def main():
filename = input("What is the name of your input file? ")
infile= open(filename,"r")
cc = (infile.readline().strip())
print(format("Card Number", "20s"), ("Valid / Invalid"))
print("------------------------------------")
while cc!= "EXIT":
even = checkSecondDigits(num)
odd = odd_digits(num)
c_len = c_length(num)
tot = even + odd
if c_len == True and tot % 10 == 0:
print(format(cc, "20s"), format("Valid", "20s"))
else:
print(format(cc, "20s"), format("Invalid", "20s"))
num = (infile.readline().strip())
main()
You just forgot to initialize num
def main():
filename = input("What is the name of your input file? ")
infile= open(filename,"r")
# initialize num here
num = cc = (infile.readline().strip())
print(format("Card Number", "20s"), ("Valid / Invalid"))
print("------------------------------------")
while cc!= "EXIT":
even = checkSecondDigits(num)
odd = odd_digits(num)
c_len = c_length(num)
tot = even + odd
if c_len == True and tot % 10 == 0:
print(format(cc, "20s"), format("Valid", "20s"))
else:
print(format(cc, "20s"), format("Invalid", "20s"))
num = cc = (infile.readline().strip())
First, maybe you should remove the extra characters:
def format_card(card_num):
"""
Formats card numbers to remove any spaces, unnecessary characters, etc
Input: Card number, integer or string
Output: Correctly formatted card number, string
"""
import re
card_num = str(card_num)
# Regex to remove any nondigit characters
return re.sub(r"\D", "", card_num)
After check if credit card is valid using the Luhn algorithm:
def validate_card(formated_card_num):
"""
Input: Card number, integer or string
Output: Valid?, boolean
"""
double = 0
total = 0
digits = str(card_num)
for i in range(len(digits) - 1, -1, -1):
for c in str((double + 1) * int(digits[i])):
total += int(c)
double = (double + 1) % 2
return (total % 10) == 0
This is a very simpler version of code it is based on lunh's algorithm
def validator(n):
validatelist=[]
for i in n:
validatelist.append(int(i))
for i in range(0,len(n),2):
validatelist[i] = validatelist[i]*2
if validatelist[i] >= 10:
validatelist[i] = validatelist[i]//10 + validatelist[i]%10
if sum(validatelist)%10 == 0:
print('This a valid credit card')
else:
print('This is not valid credit card')
def cardnumber():
result=''
while True:
try:
result = input('Please enter the 16 digit credit card number : ')
if not (len(result) == 16) or not type(int(result) == int) :
raise Exception
except Exception:
print('That is not a proper credit card number. \nMake sure you are entering digits not characters and all the 16 digits.')
continue
else:
break
return result
def goagain():
return input('Do you want to check again? (Yes/No) : ').lower()[0] == 'y'
def main():
while True:
result = cardnumber()
validator(result)
if not goagain():
break
if __name__ == '__main__':
main()
Old thread but the answer concerns me... and the real issue wasn't identified.
Actually, the error is that you have used the identifier (num) for the parameter when defining checkSecondDigits as the identifier/name of the argument when calling the function in the mainline. The function should be called in main() by
even = checkSecondDigits(cc) so the value in cc (which is the argument) is passed into num (as the parameter) for use within the function.
The same rookie error is made with odd_digits and cc_length.
This question (and the initially suggested answer) demonstrates a fundamental mis-understanding of passing arguments to parameters...
The suggested 'declaring' of num just hides this error/misunderstanding and also obfuscates the local and global scopes of num (which should only be local) and cc (which is global) so whilst the suggestion works in this case, it works for the wrong reason and is poor style and bad programming.
Further,
num should not appear anywhere in main() as it should be local to (only appear inside of) the functions called...
The last line in this code should be the same as the first, but the last line incorrectly assigns the data to num instead of cc
cc = (infile.readline().strip())
print(format("Card Number", "20s"), ("Valid / Invalid"))
print("------------------------------------")
while cc!= "EXIT":
even = checkSecondDigits(num)
odd = odd_digits(num)
c_len = c_length(num)
tot = even + odd
if c_len == True and tot % 10 == 0:
print(format(cc, "20s"), format("Valid", "20s"))
else:
print(format(cc, "20s"), format("Invalid", "20s"))
num = (infile.readline().strip())
you can use my code for card validation it is 100% dynamic because of the card structure is stored in CSV file, so it is easy to update here is the code on GitHub profile, python file link, code explanation file link and CSV for datafile link
python code:
# -*- coding: utf-8 -*-
"""
Created on Tue Sep 10 20:55:30 2019
#author: Preyash2047#gmail.com
"""
import csv
import numpy as np
#csv file imported and storf in reader
reader = csv.DictReader(open("card_data.csv"))
#input card number
card_number = input("Enter the card No: ")
#global variable declaration
min_digits=0
max_digits=0
card_number_list = list(card_number)
card_number_list_reverse=card_number_list[::-1]
card_number_length=len(card_number_list)
first_digit = int(card_number_list[0])
#global variable for final output
card_provider_list_number = 0
result_found = False
card_number_digits = 0
mit_name=""
#list
start=[]
end=[]
name=[]
c_d=[]
number_length=[]
min_max_digits_list=[]
#append the list from csv
for raw in reader:
start.append(raw['start'])
end.append(raw['end'])
name.append(raw['name'])
c_d.append(raw['c_d'])
number_length.append(raw['number_length'])
#initialize the value of min_digits & max_digits
def min_max_digits():
global min_digits
global max_digits
for i in range(len(start)):
available_length=number_length[i].split(',')
for j in range(len(available_length)):
min_max_digits_list.append(available_length[j])
min_max_digits_array = np.array(min_max_digits_list)
np.unique(min_max_digits_array)
min_digits=int(min(min_max_digits_array))
max_digits=int(max(min_max_digits_array))
#list to int
def list_to_int(noofdigits):
str1 = ""
return int(str1.join(noofdigits))
#card validation
def iin_identifier():
first_six_digit = list_to_int(card_number_list[0:6])
for i in range(len(start)):
if(first_six_digit >= int(start[i]) and first_six_digit <= int(end[i])):
available_length=number_length[i].split(',')
for j in range(len(available_length)):
if(card_number_length == int(available_length[j])):
global card_provider_list_number
card_provider_list_number = i
global card_number_digits
card_number_digits = available_length[j]
global result_found
result_found = True
#Major Industry Identifier (MII) identification
def mit_identifier():
global first_digit
global mit_name
switcher = {
1: "Airlines",
2: "Airlines",
3: "Travel and Entertainment",
4: "Banking and Financial Services",
5: "Banking and Financial Services",
6: "Merchandising and Banking",
7: "Petroleum",
8: "Health care, Telecommunications",
9: "National Assignment"
}
mit_name=switcher.get(first_digit, "MIT Identifier Not Found")
#Luhn Algorithm or modulo-10 Algorithm
def luhn_algorithm():
for i in range(card_number_length):
if(i%2!=0 and i!=0):
card_number_list_reverse[i]=int(card_number_list_reverse[i])*2
#print(str(i)+" "+ str(card_number_list_reverse[i]))
if(len(str(card_number_list_reverse[i]))==2):
even_number_2=list(str(card_number_list_reverse[i]))
card_number_list_reverse[i] = int(even_number_2[0])+int(even_number_2[1])
#print("\tsubsum "+str(i)+" "+str(card_number_list_reverse[i]))
else:
card_number_list_reverse[i]=int(card_number_list_reverse[i])
division_int = int(sum(card_number_list_reverse)/10)
division_float=sum(card_number_list_reverse)/10
if(division_int-division_float==0):
return True
#initial level number length validation
def card_number_validation():
min_max_digits()
if(card_number_length>= min_digits and card_number_length <= max_digits and first_digit != 0):
iin_identifier()
mit_identifier()
if(result_found and luhn_algorithm()):
print("\nEntered Details are Correct\n")
print("\nHere are the some details we know about you card")
print("\nNo: "+card_number)
print("\nIssuing Network: "+name[card_provider_list_number])
print("\nType: "+c_d[card_provider_list_number]+" Card")
print("\nCategory of the entity which issued the Card: "+mit_name)
else:
print("\nCard Number is Invalid\nPlease renter the number!\n")
else:
print("\nCard Number is Invalid\n")
#method called to run program
card_number_validation()
n = input("Enter 16-digit Credit Card Number:")
lst = []
for i in range(16):
lst.append(n[i])
# print(lst)
# list1 = n.split()
# print(list1)
def validate_credit_card():
global lst
if len(lst) == 16:
for i in range(0, len(lst)):
lst[i] = int(lst[i])
# print(lst)
last = lst[15]
first = lst[:15]
# print(first)
# print(last)
first = first[::-1]
# print(first)
for i in range(len(first)):
if i % 2 == 0:
first[i] = first[i] * 2
if first[i] > 9:
first[i] -= 9
sum_all = sum(first)
# print(first)
# print(sum_all)
t1 = sum_all % 10
t2 = t1 + last
if t2 % 10 is 0:
print("Valid Credit Card")
else:
print("Invalid Credit Card!")
else:
print("Credit Card number limit Exceeded!!!!")
exit()
if __name__ == "__main__":
validate_credit_card()

Categories