I dont understand the output of diff function from difflib module - python-3.x

Im having a hard time understanding the output of the Difflib module of python.
This output seems fine here:
import difflib
from difflib import SequenceMatcher, Differ
diff = Differ()
test_string_1 = "Ava D Ava: I'll try... :)"
test_string_2 = "AvaDAva:I'lltry...:)"
diffs = list(diff.compare(test_string, test_string_2))
print(diffs)
[
" A",
" v",
" a",
"- ",
"- :",
" D",
"- ",
" A",
" v",
" a",
" :",
"- ",
" I",
" '",
" l",
" l",
"- ",
" t",
" r",
" y",
" .",
" .",
" .",
"- ",
" :",
" )",
]
But when add a colon before the D character the output changes drastically:
test_string_1 = "Ava :D Ava: I'll try... :)"
test_string_2 = "Ava:DAva:I'lltry...:)"
diffs = list(diff.compare(test_string, test_string_2))
['- A',
'- v',
'- a',
'- ',
'- :',
'- D',
'- ',
' A',
' v',
' a',
' :',
'- ',
'+ D',
'+ A',
'+ v',
'+ a',
'+ :',
' I',
" '",
' l',
' l',
'- ',
' t',
' r',
' y',
' .',
' .',
' .',
'- ',
' :',
' )']
The output suggests both strings start differently when they are the same. I really need help, this doesn't make sense to me.

Related

How to store the output of a for loop as a string in python

This is the code below I want the output as: ("java developer" OR
"software developer") AND (angular) AND (core OR j2ee)
so AND has to be added for every output of for loop please help me-
x=input("Enter job title:").split()
y=input("enter primary skills:").split()
t=input("enter secondary skills").split()
for i in range(len(x)):
if len(x)==1:
print("("+ x[0]+")")
elif i==0:
["("+ x[i] +" OR "]
print("("+ x[i] +" OR ", end= " ")
elif i==(len(d)-1):
print(x[i] +")")
else:
print(x[i] + " OR ", end= " ")
for i in range(len(y)):
if len(y)==1:
print("("+ y[0]+")")
elif i==0:
print("("+ y[i] +" OR ", end= " ")
elif i==(len(y)-1):
print(y[i] +")")
else:
print(y[i] + " OR ", end= " ")
for i in range(len(t)):
if len(t)==1:
print("("+ t[0]+")")
elif i==0:
print("("+ t[i] +" OR ", end= " ")
elif i==(len(t)-1):
print(t[i] +")")
else:
print(t[i] + " OR ", end= " ")
i am getting output as
Execution:
Enter job title: javadeveloper software developer
enter primary skills: angular
enter secondary skills: core j2ee
(javadeveloper OR software OR developer)
(angular)
(core OR j2ee)
I want the output as: ("java developer" OR "software developer") AND (angular) AND (core OR j2ee)
check the following code:
from operator import indexOf
x = input("Enter job title:").replace(" developer","developer").split()
y=input("enter primary skills:").split()
t=input("enter secondary skills").split()
for i in range(len(x)):
varx = x[i]
if x[i].endswith("developer"):
varx = varx.replace("developer", " developer")
varx = '"' + varx +'"'
if len(x)==1:
print("("+ varx+")", end =" ")
elif i==0:
["("+ varx +" OR "]
print("("+ varx +" OR ", end= " ")
elif i==(len(x)-1):
print(varx +")", end =" ")
else:
print(varx + " OR ", end= " ")
print(" AND ", end =" ")
for i in range(len(y)):
if len(y)==1:
print("("+ y[0]+")", end =" ")
elif i==0:
print("("+ y[i] +" OR ", end= " ")
elif i==(len(y)-1):
print(y[i] +")", end =" ")
else:
print(y[i] + " OR ", end= " ")
print(" AND ", end =" ")
for i in range(len(t)):
if len(t)==1:
print("("+ t[0]+")", end =" ")
elif i==0:
print("("+ t[i] +" OR ", end= " ")
elif i==(len(t)-1):
print(t[i] +")", end =" ")
else:
print(t[i] + " OR ", end= " ")
What you've written is pretty confusing because of all the string manipulation. A better way to do this would be to first build a model of what you want, and then print it out.
The model could be a list of lists. Each item in the inner list should be 'OR'ed, and each item in the outer list should be 'AND'ed. So for your example, we would represent it as:
model = [
["java developer", "software developer"],
["angular"],
["core", "j2ee"],
]
Step 1: Generate the Model
It seems that terms can have multiple words, so splitting on whitespace is going to be ambiguous here. Instead we could split on something like ,.
We want to make everything as generic as possible, so here's a function that parses a string of comma separated terms into a list of terms. We can use this every time we want to take input from the user.
def parse_input_string(inp: str) -> list[str]:
return [s.strip() for s in inp.split(",")]
# e.g. parse_input_string("foo, bat bar") => ["foo", "bat bar"]
Step 2: Print the model
We can write a function that takes a row, and outputs an 'OR' statement. And then use that to write a function that gets the entire query statement.
def get_or_statement(items: list[str]) -> str:
# if there's a space in a term, wrap the term in quotes.
items = (f'"{item}"' if " " in item else item for item in items)
return f"({' OR '.join(items)})"
def get_query(model: list[list[str]]) -> str:
or_statements = [get_or_statement(items) for items in model]
return " AND ".join(or_statements)
print(get_query(model))
# ("java developer" OR "software developer") AND (angular) AND (core OR j2ee)
Step 3: Wrap it all together
Then our final program becomes quite simple:
model = [
parse_input_string(input("Enter job titles (comma separated): ")),
parse_input_string(input("Enter primary skills (comma separated): ")),
parse_input_string(input("Enter secondary skills (comma separated): ")),
]
print(get_query(model))
Output
Enter job titles (comma separated): java developer, software developer
Enter primary skills (comma separated): angular
Enter secondary skills (comma separated): core, j2ee
("java developer" OR "software developer") AND (angular) AND (core OR j2ee)

Attribute System of Inherited Python class

class Board:
array = [[" ", " ", " "],
[" ", " ", " "],
[" ", " ", " "]]
def reset(self):
self.array = [[" ", " ", " "],
[" ", " ", " "],
[" ", " ", " "]]
class AI(Board):
def __init__(self):
self.array[0][0] = "X"
ai = AI()
board = Board()
print(ai.array) # [['X', ' ', ' '], [' ', ' ', ' '], [' ', ' ', ' ']]
print(board.array) # [['X', ' ', ' '], [' ', ' ', ' '], [' ', ' ', ' ']]
ai.reset()
print(ai.array) # [[' ', ' ', ' '], [' ', ' ', ' '], [' ', ' ', ' ']]
print(board.array) # [['X', ' ', ' '], [' ', ' ', ' '], [' ', ' ', ' ']]
My question is why board.array is changed while ai.array was. If they are connected to each other, why both the attributes are not changed together while the method belongs to AI is run.
This can be understood in the following manner:
When you get self.array to use or modify it, as in the expression self.array[0][0] = "X", then
first the instance is checked to see if it has such an attribute;
if it does not, the type of the instance is checked for the attribute.
(this is a simplification of what happens, but its all you need to know for this case)
When you set an instance, as you do in the expression self.array = [...] you are setting the attribute directly on the instance
So in your example code:
print(ai.array) # ai does not have an array, Board.array is returned
print(board.array) # board does not have an array, Board.array is returned
ai.reset() # this adds an attribute to ai
print(ai.array) # ai **does** have an array, it is returned
print(board.array) # board does not have an array, Board.array is returned

tictactoe python (prints the board infinite times)

theBoard = {'top left': ' ', 'top middle': ' ', 'top right': ' ',
'center left': ' ', 'center middle': ' ', 'center right': ' ',
'bottom left': ' ', 'bottom middle': ' ', 'bottom right': ' '}
def printBoard(board):
print(board['top left'] + '|' + board['top middle'] + '|' + board['top right'])
print('-+-+-')
print(board['center left'] + '|' + board['center middle'] + '|' + board['center left'])
print('-+-+-')
print(board['bottom left'] + '|' + board['bottom middle'] + '|' + board['bottom right'])
turn = 'X'
for i in range (9):
printBoard(theBoard)
print('Turn for ' + turn + '.Move on which space?')
move = input()
theBoard[move] = turn
if turn == 'X':
turn = 'O'
else:
turn = 'X'
printBoard(theBoard)
I think you've just got your indentation wrong:
theBoard = {'top left': ' ', 'top middle': ' ', 'top right': ' ',
'center left': ' ', 'center middle': ' ', 'center right': ' ',
'bottom left': ' ', 'bottom middle': ' ', 'bottom right': ' '}
def printBoard(board):
print(board['top left'] + '|' + board['top middle'] + '|' + board['top right'])
print('-+-+-')
print(board['center left'] + '|' + board['center middle'] + '|' + board['center left'])
print('-+-+-')
print(board['bottom left'] + '|' + board['bottom middle'] + '|' + board['bottom right'])
turn = 'X'
for i in range (9):
printBoard(theBoard)
print('Turn for ' + turn + '.Move on which space?')
move = input()
theBoard[move] = turn
if turn == 'X':
turn = 'O'
else:
turn = 'X'
printBoard(theBoard)

Translating morse code to English without adding an extra dict

I am making an English to Morse code and vise-versa program. I successfully made it translate English to Morse code but am having a trouble translating Morse code to English. Whenever I try to translate Morse code to English, it gives me a TypeError: “text = ''.join(map(trans_back.get, user_input))
TypeError: sequence item 0: expected str instance, NoneType found”.
Here is my code so far. The last section is the part of the code where I am having trouble:
translation = {
"A": ".- ",
"B": "-... ",
"C": "-.-. ",
"D": "-.. ",
"E": ". ",
"F": "..-. ",
"G": "--. ",
"H": ".... ",
"I": ".. ",
"J": ".--- ",
"K": "-.- ",
"L": ".-.. ",
"M": "-- ",
"N": "-. ",
"O": "--- ",
"P": ".--. ",
"Q": "--.- ",
"R": ".-. ",
"S": "... ",
"T": "- ",
"U": "..- ",
"V": "...- ",
"W": ".-- ",
"X": "-..- ",
"Y": "-.-- ",
"Z": "--.. ",
"1": ".---- ",
"2": "..--- ",
"3": "...-- ",
"4": "....- ",
"5": "..... ",
"6": "-.... ",
"7": "--... ",
"8": "---.. ",
"9": "----. ",
"0": "----- ",
".": ".-.-.- ",
",": "--..-- ",
"?": "..--.. ",
"!": "..--. ",
"/": "-..-. ",
"#": ".--.-. ",
" ": " "
}
user_input = input("Input english or morse code message:\n").upper()
if all(c in translation for c in user_input):
morse = ''.join(map(translation.get, user_input))
print(morse)
elif all(c in ".- " for c in user_input):
print("*needs work in order to change morse to text*")
#trans_back = {v: k for k, v in translation.items()}
#text = ''.join(map(trans_back.get, user_input))
#print(text)
The difference between the two blocks is that the first block expects a character-by-character mapping, but the second block requires a block of characters to be mapped to a single key. You need to split user_input along the spaces so map will apply the function to a group of .s and -s representing a single key. Of course then you will also need to remove the spaces from your reversed dictionary lookup. Here's the code that I got to work:
elif all(c in ".- " for c in user_input):
trans_back = {v.rstrip(' '): k for k, v in translation.items()}
text = ''.join(map(trans_back.get, user_input.split(' ')))
print(text)

Yielding a TypeError: input expected at most 1 arguments, got 4. This error was from the user_input variable associated with strong input

def randomLetters():
numbers = [random.randint(0, 25), random.randint(0, 25)]
alphabet = 'abcdefghijklmnopqrstuvwxyz'
letters = [alphabet[numbers[0]], alphabet[numbers[1]]]
return letters
letters = randomLetters()
print(letters)
print(letters[0])
user_input = input('Enter a word that begins with', "'" + letters[0] + "'", 'and ends with', "'" + letters[1] + "': ")
new_user_input = user_input.lower()
while (new_user_input[0] != letters[0]) and (new_user_input[len(new_user_input) - 1] != letters[1]):
print('Invalid input. Try again.')
new_user_input = input('Enter a word that begins with', "'" + letters[0] + "'", 'and ends with', "'" + letters[1] + "': ")
The user_input variable input is producing a TypeError: input expected at most 1 arguments, got 4
input() only take one arg and you are providing it 4, the , separates arguments, perhaps you meant +:
new_user_input = input('Enter a word that begins with' + "'" + letters[0] + "'" +
'and ends with' + "'" + letters[1] + "': ")
format() helps constructing these strings simpler:
new_user_input = input("Enter a word that begins with '{letters[0]}' and ends with '{letters[1]}': ".format(letters=letters))

Resources