Python 3.4 help - using slicing to replace characters in a string - python-3.4

Say I have a string.
"poop"
I want to change "poop" to "peep".
In fact, I also want all of the o's in poop to change to e's for any word I put in.
Here's my attempt to do the above.
def getword():
x = (input("Please enter a word."))
return x
def main():
y = getword()
for i in range (len(y)):
if y[i] == "o":
y = y[:i] + "e"
print (y)
main()
As you can see, when you run it, it doesn't amount to what I want. Here is my expected output.
Enter a word.
>>> brother
brether
Something like this. I need to do it using slicing. I just don't know how.
Please keep your answer simple, since I'm somewhat new to Python. Thanks!

This uses slicing (but keep in mind that slicing is not the best way to do it):
def f(s):
for x in range(len(s)):
if s[x] == 'o':
s = s[:x]+'e'+s[x+1:]
return s

Strings in python are non-mutable, which means that you can't just swap out letters in a string, you would need to create a whole new string and concatenate letters on one-by-one
def getword():
x = (input("Please enter a word."))
return x
def main():
y = getword()
output = ''
for i in range(len(y)):
if y[i] == "o":
output = output + 'e'
else:
output = output + y[i]
print(output)
main()
I'll help you this once, but you should know that stack overflow is not a homework help site. You should be figuring these things out on your own to get the full educational experience.
EDIT
Using slicing, I suppose you could do:
def getword():
x = (input("Please enter a word."))
return x
def main():
y = getword()
output = '' # String variable to hold the output string. Starts empty
slice_start = 0 # Keeps track of what we have already added to the output. Starts at 0
for i in range(len(y) - 1): # Scan through all but the last character
if y[i] == "o": # If character is 'o'
output = output + y[slice_start:i] + 'e' # then add all the previous characters to the output string, and an e character to replace the o
slice_start = i + 1 # Increment the index to start the slice at to be the letter immediately after the 'o'
output = output + y[slice_start:-1] # Add the rest of the characters to output string from the last occurrence of an 'o' to the end of the string
if y[-1] == 'o': # We still haven't checked the last character, so check if its an 'o'
output = output + 'e' # If it is, add an 'e' instead to output
else:
output = output + y[-1] # Otherwise just add the character as-is
print(output)
main()
Comments should explain what is going on. I'm not sure if this is the most efficient or best way to do it (which really shouldn't matter, since slicing is a terribly inefficient way to do this anyways), just the first thing I hacked together that uses slicing.
EDIT Yeah... Ourous's solution is much more elegant

Can slicing even be used in this situation??
The only probable solution I think would work, as MirekE stated, is y.replace("o","e").

Related

how would I delete item's in a dictionary within specific parameters?

for my code I want all numbers from a dictionary under 70 to be deleted, I'm unsure of how to specify this and I need it to also delete the associated name with that number as well, either that or only diplay numbers that are 70 or above.
Below is the code that I have in it's entirety:
name = []
number =[]
name_grade = {}
counter = 0
counter_bool= True
num_loop = True
while counter_bool:
stu = int(input("please enter the number of students: "))
if stu < 2:
print("value is too low, try again")
continue
else:
break
while counter != stu:
name_inp = str(input("Enter your name: "))
while num_loop:
number_inp = int(input("Enter your number: "))
if number_inp < 0 or number_inp > 100:
print("The value is too high or too low, please enter a number between 0 and 100.")
continue
else:
break
name_grade[name_inp] = number_inp
name.append(name_inp)
number.append(number_inp)
counter += 1
print(name_grade)
sorted_numbers = sorted(name_grade.items(), key= lambda x:x[1])
print(sorted_numbers)
if number > 70:
resorted_numbers = number < 70
print(resorted numbers)
how would I go about this?
Also if it's also not too much trouble could someone explain in detail about dictionary keys and how the lambda function I've used works? I got help but I would prefer to know the small details on how it's applied and formatted but don't worry if it's a pain to explain.
You can just iterate over the dictionary and filter for values less than 70:
resorted_numbers = {k:v for k,v in name_grade.items() if v<70}
dict.items method returns a list of key-value tuple pairs of a dictionary, so the lambda function is telling the sorted function to sort by the second element in each tuple.

Tokenizing a letter as an operator

I need to make a language that has variables in it, but it also needs the letter 'd' to be an operand that has a number on the right and maybe a number on the left. I thought that making sure the lexer checks for the letter first would give it precedence, but that doesn't happen and i don't know why.
from ply import lex, yacc
tokens=['INT', 'D', 'PLUS', 'MINUS', 'LPAR', 'RPAR', 'BIGGEST', 'SMALLEST', 'EQ', 'NAME']
t_PLUS = r'\+'
t_MINUS = r'\-'
t_LPAR = r'\('
t_RPAR = r'\)'
t_BIGGEST = r'\!'
t_SMALLEST = r'\#'
t_D = r'[dD]'
t_EQ = r'\='
t_NAME = r'[a-zA-Z_][a-zA-Z0-9_]*'
def t_INT(t):
r'[0-9]\d*'
t.value = int(t.value)
return t
def t_newline(t):
r'\n+'
t.lexer.lineno += 1
t_ignore = ' \t'
def t_error(t):
print("Not recognized by the lexer:", t.value)
t.lexer.skip(1)
lexer = lex.lex()
while True:
try: s = input(">> ")
except EOFError: break
lexer.input(s)
while True:
t = lexer.token()
if not t: break
print(t)
If i write:
3d4
it outputs:
LexToken(INT,3,1,0)
LexToken(NAME,'d4',1,1)
and i don't know how to work around it.
Ply does not prioritize token variables by order of appearance; rather, it orders them in decreasing order by length (longest first). So your t_NAME pattern will come before t_D. This is explained in the Ply manual, along with a concrete example of how to handle reserved words (which may not apply in your case).
If I understand correctly, the letter d cannot be an identifier, and neither can d followed by a number. It is not entirely clear to me whether you expect d2e to be a plausible identifier, but for simplicity I'm assuming that the answer is "No", in which case you can easily restrict the t_NAME regular expression by requiring an initial d to be followed by another letter:
t_NAME = '([a-ce-zA-CE-Z_]|[dD][a-zA-Z_])[a-zA-Z0-9_]*'
If you wanted to allow d2e to be a name, then you could go with:
t_NAME = '([a-ce-zA-CE-Z_]|[dD][0-9]*[a-zA-Z_])[a-zA-Z0-9_]*'

Python 3.6 user-defined board size win check with 2 variables

I have somewhat a general question for more experienced programmers. I'm somewhat new to programming, but still enjoy it quite a bit. I've been working with Python, and decided to try to program a tic tac toe game, but with variable board size that can be decided by the user (all the way up to a 26x26 board). Here's what I've got so far:
print("""Welcome to tic tac toe!
You will begin by determining who goes first;
Player 2 will decide on the board size, from 3 to 26.
Depending on the size of the board, you will have to
get a certain amount of your symbol (X/O) in a row to win.
To place symbols on the board, input their coordinates;
letter first, then number (e.g. a2, g10, or f18).
That's it for the rules. Good luck!\n""")
while True:
ready = input("Are you ready? When you are, input 'yes'.")
if ready.lower() == 'yes': break
def printboard(n, board):
print() #print board in ranks of n length; n given later
boardbyrnk = [board[ind:ind+n] for ind in range(0,n**2,n)]
for rank in range(n):
rn = f"{n-rank:02d}" #pads with a 0 if rank number < 10
print(f"{rn}|{'|'.join(boardbyrnk[rank])}|") #with rank#'s
print(" ",end="") #files at bottom of board
for file in range(97,n+97): print(" "+chr(file), end="")
print()
def sqindex(prompt, n, board, syms): #takes input & returns index
#ss is a list/array of all possible square names
ss = [chr(r+97)+str(f+1) for r in range(n) for f in range(n)]
while True: #all bugs will cause input to be taken for same turn
sq = input(prompt)
if not(sq in ss): print("Square doesn't exist!"); continue
#the index is found by multiplying rank and adding file #'s
index = n*(n-int(sq[1:])) + ord(sq[0])-97
if board[index] in syms: #ensure it contains ' '
print("The square must be empty!"); continue
return index
def checkwin(n, w, board, sm): #TODO
#check rows, columns and diagonals in terms of n and w;
#presumably return True if each case is met
return False
ps = ["Player 1", "Player 2"]; syms = ['X', 'O']
#determines number of symbols in a row needed to win later on
c = {3:[3,3],4:[4,6],5:[7,13],6:[14,18],7:[19,24],8:[25,26]}
goagain = True
while goagain:
#decide on board size
while True:
try: n=int(input(f"\n{ps[1]}, how long is the board side? "))
except ValueError: print("Has to be an integer!"); continue
if not(2<n<27): print("Has to be from 3 to 26."); continue
break
board = (n**2)*" " #can be rewritten around a square's index
for num in c:
if c[num][0] <= n <= c[num][1]: w = num; break
print(f"You'll have to get {w} symbols in a row to win.")
for tn in range(n**2): #tn%2 = 0 or 1, determining turn order
printboard(n, board)
pt = ps[tn%2]
sm = syms[tn%2]
prompt = f"{pt}, where do you place your {sm}? "
idx = sqindex(prompt, n, board, syms)
#the index found in the function is used to split the board string
board = board[:idx] + sm + board[idx+1:]
if checkwin(n, w, board, sm):
printboard(n, board); print('\n' + pt + ' wins!!\n\n')
break
if board.count(" ") == 0:
printboard(n, board); print("\nIt's a draw!")
while True: #replay y/n; board size can be redetermined
rstorq = input("Will you play again? Input 'yes' or 'no': ")
if rstorq in ['yes', 'no']:
if rstorq == 'no': goagain = False
break
else: print("Please only input lowercase 'yes' or 'no'.")
print("Thanks for playing!")
So my question to those who know what they're doing is how they would recommend determining whether the current player has won (obviously I have to check in terms of w for all cases, but how to program it well?). It's the only part of the program that doesn't work yet. Thanks!
You can get the size of the board from the board variable (assuming a square board).
def winning_line(line, symbol):
return all(cell == symbol for cell in line)
def diag(board):
return (board[i][i] for i in range(len(board)))
def checkwin(board, symbol):
if any(winning_line(row, symbol) for row in board):
return True
transpose = list(zip(*board))
if any(winning_line(column, symbol) for column in transpose):
return True
return any(winning_line(diag(layout), symbol) for layout in (board, transpose))
zip(*board) is a nice way to get the transpose of your board. If you imagine your original board list as a list of rows, the transpose will be a list of columns.

Check if palindrome while ignoring special characters

I'm failing the last test case, which is the one with the spaces and single quotation mark.
I used s.strip, but the error still persists.
Is there another way to go about this?
Thank you.
from test import testEqual
def removeWhite(s):
s.strip()
s.strip("'")
return s
def isPal(s):
if s == "" or len(s) == 1:
return True
if removeWhite(s[0]) != removeWhite(s[-1]):
return False
return isPal(removeWhite(s[1:-1]))
testEqual(isPal(removeWhite("x")),True)
testEqual(isPal(removeWhite("radar")),True)
testEqual(isPal(removeWhite("hello")),False)
testEqual(isPal(removeWhite("")),True)
testEqual(isPal(removeWhite("hannah")),True)
testEqual(isPal(removeWhite("madam i'm adam")),True)
At first your removeWhite function doesn't return all spaces because strip only removes from the end and the beginning of a string. See:
>>> " a ".strip()
'a'
>>> " a a ".strip()
'a a'
So i suggest this approach:
def removeWhite(s):
return ''.join(filter(lambda x: x not in " '", s))
Please note that I use join because filter returns an iterator which needs to be converted back to a string.
For finding the palindromes i would suggest this function:
def isPal(s):
if len(s) <= 1: # Special case to prevent KeyError later
return True
stripped = removeWhite(s) # Strip off all whitespaces
first = stripped[:len(stripped) // 2] # First half of the string
if len(stripped) % 2: # Length of string is even?
second = stripped[len(stripped) // 2 + 1:] # Drop the middle character
else:
second = stripped[len(stripped) // 2:] # Else keep it
secondrev = ''.join(reversed(second)) # Reverse the second half
return first == secondrev # And return wether they're equal.
This holds for all your examples. But it think your isPal function should work too if you fix your removeWhite function

Longest substring in alphabetical order [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
Write a program that prints the longest substring of s in which the letters occur in alphabetical order. For example, if s = 'azcbobobegghakl', then your program should print
Longest substring in alphabetical order is: beggh
In the case of ties, print the first substring. For example, if s = 'abcbcd', then your program should print
Longest substring in alphabetical order is: abc
Here you go edx student i've been helped to finish the code :
from itertools import count
def long_sub(input_string):
maxsubstr = input_string[0:0] # empty slice (to accept subclasses of str)
for start in range(len(input_string)): # O(n)
for end in count(start + len(maxsubstr) + 1): # O(m)
substr = input_string[start:end] # O(m)
if len(substr) != (end - start): # found duplicates or EOS
break
if sorted(substr) == list(substr):
maxsubstr = substr
return maxsubstr
sub = (long_sub(s))
print "Longest substring in alphabetical order is: %s" %sub
These are all assuming you have a string (s) and are needing to find the longest substring in alphabetical order.
Option A
test = s[0] # seed with first letter in string s
best = '' # empty var for keeping track of longest sequence
for n in range(1, len(s)): # have s[0] so compare to s[1]
if len(test) > len(best):
best = test
if s[n] >= s[n-1]:
test = test + s[n] # add s[1] to s[0] if greater or equal
else: # if not, do one of these options
test = s[n]
print "Longest substring in alphabetical order is:", best
Option B
maxSub, currentSub, previousChar = '', '', ''
for char in s:
if char >= previousChar:
currentSub = currentSub + char
if len(currentSub) > len(maxSub):
maxSub = currentSub
else: currentSub = char
previousChar = char
print maxSub
Option C
matches = []
current = [s[0]]
for index, character in enumerate(s[1:]):
if character >= s[index]: current.append(character)
else:
matches.append(current)
current = [character]
print "".join(max(matches, key=len))
Option D
def longest_ascending(s):
matches = []
current = [s[0]]
for index, character in enumerate(s[1:]):
if character >= s[index]:
current.append(character)
else:
matches.append(current)
current = [character]
matches.append(current)
return "".join(max(matches, key=len))
print(longest_ascending(s))
The following code solves the problem using the reduce method:
solution = ''
def check(substr, char):
global solution
last_char = substr[-1]
substr = (substr + char) if char >= last_char else char
if len(substr) > len(solution):
solution = substr
return substr
def get_largest(s):
global solution
solution = ''
reduce(check, list(s))
return solution

Resources