I have been trying to make a scrabble score counter but I end up falling in an infinite loop, I attach my code in case anyone can give me a hand, it personally makes sense, but for some reason Python does not like my code :((
def letterScore(let):
"""Argument let: one character string
Return Value: the scrabble value of the letter"""
if let in 'qz':
return 10
elif let in 'aelnorstu':
return 1
elif let in 'd':
return 2
elif let in 'bcmp':
return 3
elif let in 'vwy':
return 4
elif let in 'k':
return 5
elif let in 'x':
return 8
else:
return 0
def scrabbleScore (S):
""""Argument S: String argument S
Return Value: the total Scrabble score :))"""
if "s[0]" == '':
return 0
else:
return letterScore(S[0]) + scrabbleScore (S[1:])
#
# Tests
#
print( "scrabbleScore('quetzal') should be 25 :", scrabbleScore('quetzal') )
As the comments suggested, you should check for the string to be empty with S == ''. The string comparison you had before made no sense, as it was always false.
def scrabbleScore(S):
""""Argument S: String argument S
Return Value: the total Scrabble score :))"""
if S == '':
return 0
else:
return letterScore(S[0]) + scrabbleScore(S[1:])
Let me expalain what the real problem is.
i am having two strings :
str1="QKHE=K"
str2="Qkhek" #this string donot have '=' inthe same index 'k' is here.
i wanted to match the two strings and the desire result should be like
result="Qkhe=k"#case sensitive
i tried my function :
def matchCap(cap1=None,cap2=None):
if cap1==None or cap2==None:
return cap1
else:
cap1=list(cap1)
cap2=list(cap2)
dictionary = (zip(cap1, cap2))
print(list(dictionary))
final_cap=[]
for key, value in dictionary:
if key=='#' or key=='=':
final_cap.append(key)
else:
final_cap.append(value)
final_cap=''.join(final_cap)
return final_cap
But the zip function not workingwell because of different lengths of list.
so basically i am having two string ..amm like two captcha answers . Gave captcha example for the case sensitive .
i want the result captcha answer is Qkhe=k
One thing you can do is, when you encounter # or = in the string, you can append both the key and value, like this...
def matchCap(cap1=None,cap2=None):
if cap1==None or cap2==None:
return cap1
else:
cap1, cap2 = list(cap1), list(cap2)
dictionary = (zip(cap1, cap2))
final_cap = []
for key, value in dictionary:
if key in ('#', '='):
final_cap.append(key)
final_cap.append(value)
else:
final_cap.append(value)
final_cap = ''.join(final_cap)
return final_cap
print(matchCap("QKHE=K","Qkhek"))
Output:-
Qkhe=k
str1="QKHE=K"
str2="Qkhek"
def matchCap(cap1=None,cap2=None):
if cap1==None or cap2==None:
return cap1
else:
cap1=list(cap1)
cap2=list(cap2)
final_cap=[]
cap_2_i = 0
for cap_1 in range(len(cap1)):
key = cap1[cap_1]
value = cap2[cap_2_i]
if key=='#' or key=='=':
final_cap.append(key)
else:
final_cap.append(value)
cap_2_i += 1
final_cap=''.join(final_cap)
return final_cap
matchCap(str1, str2)
Result: 'Qkhe=k'
You don't need to use zip, just for iterates through it.
Define a variable i that represents the index position of the value from cap2, and i is accumulated each time a value is taken from cap2.
def matchCap(cap1=None, cap2=None):
if cap1 is None or cap2 is None:
return cap1
else:
total_len = len(cap2)
i = 0
final_cap = []
for index, value in enumerate(cap1):
if value == '#' or value == '=':
final_cap.append(value)
else:
final_cap.append(cap2[i])
i += 1
if i >= total_len:
break
final_cap = ''.join(final_cap)
return final_cap
print(matchCap("QKHE=K", "Qkhek"))
# Qkhe=k
I am trying to count the 'name' keys in this nested composed dict-list and i am getting 3 in place of 6 ,i think my problem is with the base case in the recursive function count_elem(tree)
def define_tree3():
tree3 ={'name':'GAS','grade':0.8,'children':[{'name':'CSA','grade':0.5,'children':[{'name':'MB','grade':0.1},{'name':'TA','grade':0.6}]},{'name':'IIW','grade':0.9,'children':[None,{'name':'IP','grade':0.99}]}]}
return tree3
#this fuction is to delete the given key from the given dict and retur the new dict
def delkey(dict1,key):
d=dict(dict1)
del d[key]
return d
#this function is to count the numbers of 'name'
def count_elem(tree):
if len(tree)==0:
return 0
else:
for i in tree:
if i == None:
return 0
elif i == 'name':
return 1+ count_elem(delkey(tree,i))
elif i == 'grade':
return count_elem(delkey(tree,i))
elif i == 'children':
for j in tree[i]:
if j == None:
continue
else:
return count_elem(j)
a=define_tree3()
print(count_elem(a))
This is not an answer to your question. I just tried to solve it and used a different approach. Might be useful as a reference.
tree3 = {'name':'GAS','grade':0.8,'children':[{'name':'CSA','grade':0.5,'children':[{'name':'MB','grade':0.1},{'name':'TA','grade':0.6}]},{'name':'IIW','grade':0.9,'children':[None,{'name':'IP','grade':0.99}]}]}
def count_name(entity):
count = 0
name = 'name'
# print('\n')
# print(count, entity)
if type(entity) == dict:
count += sum([key == name for key in entity.keys()])
for value in entity.values():
# print(count, value)
if type(value) == list:
count += sum([count_name(member) for member in value])
return count
count_name(tree3)
How does one implement a DFA or an NFA for that matter in Python code?
What are some good ways to do it in Python? Are they ever used in real world projects?
A straightforward way to represent a DFA is as a dictionary of dictionaries. For each state create a dictionary which is keyed by the letters of the alphabet and then a global dictionary which is keyed by the states. For example, the following DFA from the Wikipedia article on DFAs
can be represented by a dictionary like this:
dfa = {0:{'0':0, '1':1},
1:{'0':2, '1':0},
2:{'0':1, '1':2}}
To "run" a dfa against an input string drawn from the alphabet in question (after specifying the initial state and the set of accepting values) is straightforward:
def accepts(transitions,initial,accepting,s):
state = initial
for c in s:
state = transitions[state][c]
return state in accepting
You start in the initial state, step through the string character by character, and at each step simply look up the next state. When you are done stepping through the string you simply check if the final state is in the set of accepting states.
For example
>>> accepts(dfa,0,{0},'1011101')
True
>>> accepts(dfa,0,{0},'10111011')
False
For NFAs you could store sets of possible states rather than individual states in the transition dictionaries and use the random module to pick the next state from the set of possible states.
Here is my version of a dfa implementation if you're looking for a more object-oriented one. I was however ever so slightly inspired by John Coleman's answer.
class Node:
def __init__(self, val):
self.val = val
self.links = []
def add_link(self, link):
self.links.append(link)
def __str__(self):
node = "(%s):\n" % self.val
for link in self.links:
node += "\t" + link + "\n"
return node
def __add__(self, other):
return str(self) + other
def __radd__(self, other):
return other + str(self)
def equals(self, node):
ok = (self.val == node.val)
if len(self.links) == len(node.links):
for i in range(len(self.links)):
ok = ok and (self.links[i] == node.links[i])
return ok
else:
return False
class Link:
def __init__(self, from_node, etiquette, to_node):
self.from_node = from_node
self.etiquette = etiquette
self.to_node = to_node
def __str__(self):
return "(%s --%s--> %s)" % (self.from_node.val, self.etiquette, self.to_node.val)
def __add__(self, other):
return str(self) + other
def __radd__(self, other):
return other + str(self)
def equals(self, link):
return (self.from_node == link.from_node) and (self.etiquette == link.etiquette) and (self.to_node == link.to_node)
class Automata:
def __init__(self, initial_node, nodes, terminal_node):
self.initial_node = initial_node
self.nodes = nodes
self.terminal_node = terminal_node
def get_next_node(self, current_node, etiquette):
for link in current_node.links:
if link.etiquette == etiquette:
return link.to_node
return None
def accepts(self, string):
node = self.initial_node
for character in string:
node = self.get_next_node(node, character)
return self.terminal_node.equals(node)
def __str__(self):
automata = "Initial node: %s\nTerminal node: %s\n" % (self.initial_node.val, self.terminal_node.val)
for node in self.nodes:
automata += node
return automata
def __add__(self, other):
return str(self) + other
def __radd__(self, other):
return other + str(self)
if __name__ == '__main__':
pass
s0 = Node("s0")
s1 = Node("s1")
s2 = Node("s2")
s0_0_s0 = Link(s0, '0', s0)
s0_1_s1 = Link(s0, '1', s1)
s1_0_s2 = Link(s1, '0', s2)
s1_1_s0 = Link(s1, '1', s0)
s2_0_s1 = Link(s2, '0', s1)
s2_1_s2 = Link(s2, '1', s2)
s0.add_link(s0_0_s0)
s0.add_link(s0_1_s1)
s1.add_link(s1_0_s2)
s1.add_link(s1_1_s0)
s2.add_link(s2_0_s1)
s2.add_link(s2_1_s2)
a = Automata(s0, [s0, s1, s2], s0)
print(a)
print(a.accepts('1011101')) #True
print(a.accepts('10111011')) #False
Here I present a recursive solution for NFA. Consider the following nfa:
The transitions can be represented using list of lists as follows:
transition = [[[0,1],[0]], [[4],[2]], [[4],[3]], [[4],[4]],[[4],[4]]]
Note: State 4 is a hypothetical state. Once you go to that state, you can't move further. It is helpful when you can't read the input from the current state. You directly go to the state 4 and say input is not accepted for current progress(Check other possibilities by going back). e.g, if you are at q1, and the current input symbol is 'a', you go to state 4 and stop computing further.
Here is the Python code:
#nfa simulation for (a|b)*abb
#state 4 is a trap state
import sys
def main():
transition = [[[0,1],[0]], [[4],[2]], [[4],[3]], [[4],[4]]]
input = raw_input("enter the string: ")
input = list(input) #copy the input in list because python strings are immutable and thus can't be changed directly
for index in range(len(input)): #parse the string of a,b in 0,1 for simplicity
if input[index]=='a':
input[index]='0'
else:
input[index]='1'
final = "3" #set of final states = {3}
start = 0
i=0 #counter to remember the number of symbols read
trans(transition, input, final, start, i)
print "rejected"
def trans(transition, input, final, state, i):
for j in range (len(input)):
for each in transition[state][int(input[j])]: #check for each possibility
if each < 4: #move further only if you are at non-hypothetical state
state = each
if j == len(input)-1 and (str(state) in final): #last symbol is read and current state lies in the set of final states
print "accepted"
sys.exit()
trans(transition, input[i+1:], final, state, i) #input string for next transition is input[i+1:]
i = i+1 #increment the counter
main()
Sample Run(strings ending with abb are accepted):
enter the string: abb
accepted
enter the string: aaaabbbb
rejected
You don't need a for loop over range(len(input)) if you're using recursion. You're overcomplicating the code. Here's a simplified version
import sys
def main():
transition = [[[0,1],[0]], [[4],[2]], [[4],[3]], [[4],[4]]]
input = raw_input("enter the string: ")
input = list(input) #copy the input in list because python strings are immutable and thus can't be changed directly
for index in range(len(input)): #parse the string of a,b in 0,1 for simplicity
if input[index]=='a':
input[index]='0'
else:
input[index]='1'
final = "3" #set of final states = {3}
start = 0
trans(transition, input, final, start)
print "rejected"
def trans(transition, input, final, state):
for each in transition[state][int(input[0])]: #check for each possibility
if each < 4: #move further only if you are at non-hypothetical state
state = each
if len(input)==1:
if (str(state) in final): #last symbol is read and current state lies in the set of final states
print "accepted"
sys.exit()
else:
continue
trans(transition, input[1:], final, state) #input string for next transition is input[i+1:]
main()
I have implemented dfa which works for any of the dfa. But this is not in object oriented pattern.
states=list(map(int,input("Enter States : ").split(" ")))
symbols=list(input("Enter Symbols : ").split(" "))
initial_state=int(input("Enter initial state : "))
final_states=list(map(int,input("Enter final states : ").split(" ")))
transitions=[]
inlists=[]
for i in range(len(symbols)):
print("Enter transitions for symbol "+symbols[i]+" from all states :")
for j in range(len(states)):
inlists.append(int(input()))
transitions.append(inlists)
inlists=[]
cur_state=initial_state
while(1):
cur_state=initial_state
string=input("Enter string : ")
if string=='#':
break
for symbol in string:
print("["+str(cur_state)+"]"+"-"+symbol+"->",end="")
cur_state=transitions[symbols.index(symbol)][cur_state]
if cur_state in final_states:
print("["+str(cur_state)+"]")
print("String is accepted.")
else:
print("["+str(cur_state)+"]")
print("String is not accepted.")
Accepting string 101* and 001* modification of #John Coleman
#Dfa for accepting only 101+00101001
dfa101 = {0:{'1':1},
1:{'0':2},
2:{'1':3},
3:{'0':3, '1':3}}
#Dfa for accepting only 001+00101001
dfa001={0:{'0':1},
1:{'0':2},
2:{'1':3},
3:{'0':3, '1':3}}
def accepts(transitions,initial,accepting,s):
state = initial
try:
for c in s:
state = transitions[state][c]
if(state in accepting):
return 'Accepted'
else:
return 'Rejected'
except:
return 'Rejected'
print('Dfa of 101+ ',accepts(dfa101,0,{3},'10101111000')) #Accepted
print('Dfa of 001+ ',accepts(dfa001,0,{3},'00101010101')) #Accepted
To showcase my solution, let's take the following DFA as an example:
Language over 𝛴 = (0, 1) containing strings that are either made up of only 1’s or strings in which every 0 is followed by a 1.
The transition table for this DFA is:
delta
0
1
->*S
A
S
A
D
S
D
D
D
My program, written in Python3, is designed to accept the transition table of any DFA over the alphabet (0, 1) to check whether a string will be accepted by the DFA or not.
To use my program, we have to input the above transition table in the following format into a text file named fa.txt present in the same directory as the program.
fa.txt:
->*s(a,s)
a(d,s)
d(d,d)
For start state, the state name must be preceded by -> and a final state must be preceded by *. In case the start state is a final state, -> must come before *.
The state name must be only one character in length.
The start state must be named s.
The order of the states in the TXT file is irrelevant.
The code:
file = open("fa.txt", "r")
l = file.readlines()
x = 0
def findState(state):
lines = l
for i in range(0, len(lines)):
if lines[i][0] == '-':
lines[i] = lines[i][2::]
if lines[i][0] == '*':
if state == lines[i][1]:
return [lines[i][3], lines[i][5], 1]
if lines[i][0] == state:
return [lines[i][2], lines[i][4], 0] # state to go to on 0, state to go to on 1, is it final?
s = input("Enter a binary string to test it against the DFA in file fa.txt: ")
on0_on1 = findState('s') # start state
print("s", end = "")
for c in range(0, len(s)):
if s[c] != '0' and s[c] != '1':
print("Fail")
exit(0)
if s[c] == '0':
print(' ---0--->', on0_on1[0], end = '')
on0_on1 = findState(on0_on1[0])
else:
print(' ---1--->', on0_on1[1], end = '')
on0_on1 = findState(on0_on1[1])
if on0_on1[2] == 1 and c == len(s) - 1:
print("\nPass")
elif c == len(s) - 1 and on0_on1[2] == 0:
print("\nFail")
i've searched the forum and found similar questions, but no luck in solving my problem.
My code is designed to swap every two letters of each word using recursion and print the result. For words with an even amount of letters, the word "None" is included in the output and i don't know how to fix...
here's the code:
def encryptLine(line, count):
headline = line[count:]
if length(headline) > 0:
if count == length(line) - 1:
new = headline
return new
elif count <= length(line):
new = head(tail(headline)) + head(headline)
new = new + str(encryptLine(line, count+2))
return new
print(encryptLine('abcd', 0))
the output for 'abcd' is badcNone, which is correct except for the word None. the output for 'abcde' is 'badce', which is correct...
thanks in advance for your help!
Add return "" to the function definition, that is
def encryptLine(line, count):
headline = line[count:]
if length(headline) > 0:
if count == length(line) - 1:
new = headline
return new
elif count <= length(line):
new = head(tail(headline)) + head(headline)
new = new + str(encryptLine(line, count+2))
return new
return ""
Otherwise, the function will return None if length(headline) > 0 does not hold.
None is here because your function return nothing.
There is 1 case where you return nothing it is
if length(headline) <= 0:
In Python, if there is no return to a function and you try to access to a return value, the value will be None.