For a simpler solution you could instead use rjust on the last 4 characters of the string, and fill it with # up to its original length:
s = 'TestName'
s[-4:].rjust(len(s), '#')
'####Name'
The problem with your function, is that you have to repeat the elements you want to use to replace as many times as replacements there will be. So you should do:
def maskify(cc):
c2 = cc.replace(cc[:-4], '#'*len(cc[:-4]))
return c2
Answer from yatu on Stack OverflowFor a simpler solution you could instead use rjust on the last 4 characters of the string, and fill it with # up to its original length:
s = 'TestName'
s[-4:].rjust(len(s), '#')
'####Name'
The problem with your function, is that you have to repeat the elements you want to use to replace as many times as replacements there will be. So you should do:
def maskify(cc):
c2 = cc.replace(cc[:-4], '#'*len(cc[:-4]))
return c2
yatu's solution using rjust() looks good, but str.replace() is a false friend. It works for a reasonably varied string, but if elements are repeated in the string it can fail (this is yatu's 2nd solution):
def maskify(cc):
c2 = cc.replace(cc[:-4], '#'*len(cc[:-4]))
return c2
print(maskify('12121212'))
gives,
########
I suggest 'building' the new string like this instead,
def maskify(cc):
mask = '#' * (len(cc)-4)
return mask+cc[-4:]
which gives the desired result,
####1212
As strings are immutable in Python, just create a new string which includes the value at the desired index.
Assuming you have a string s, perhaps s = "mystring"
You can quickly (and obviously) replace a portion at a desired index by placing it between "slices" of the original.
s = s[:index] + newstring + s[index + 1:]
You can find the middle by dividing your string length by 2 len(s)/2
If you're getting mystery inputs, you should take care to handle indices outside the expected range
def replacer(s, newstring, index, nofail=False):
# raise an error if index is outside of the string
if not nofail and index not in range(len(s)):
raise ValueError("index outside given string")
# if not erroring, but the index is still not in the correct range..
if index < 0: # add it to the beginning
return newstring + s
if index > len(s): # add it to the end
return s + newstring
# insert the new string between "slices" of the original
return s[:index] + newstring + s[index + 1:]
This will work as
replacer("mystring", "12", 4)
'myst12ing'
You can't replace a letter in a string. Convert the string to a list, replace the letter, and convert it back to a string.
>>> s = list("Hello world")
>>> s
['H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd']
>>> s[int(len(s) / 2)] = '-'
>>> s
['H', 'e', 'l', 'l', 'o', '-', 'W', 'o', 'r', 'l', 'd']
>>> "".join(s)
'Hello-World'
you can do
s="cdabcjkewabcef"
snew="".join((s[:9],"###",s[12:]))
which should be faster than joining like snew=s[:9]+"###"+s[12:] on large strings
You can achieve this by doing:
yourString = "Hello"
yourIndexToReplace = 1 #e letter
newLetter = 'x'
yourStringNew="".join((yourString[:yourIndexToReplace],newLetter,yourString[yourIndexToReplace+1:]))
There are two things you should do with this:
- Create a function that prints the current playing field, given the cells. So, you can print it whenever you want.
- Change the item of the cells list, which corresponds to the entered coordinates.
In the example below I used your code to look up the index of the cell you need to change by adding cellnum = coordinates.index(t_given_coordinates). This line defines a new integer variable that holds the cell number according to your map. You may then use this index to change the content of this cell and redraw the complete thing.
cells = ['-']*9
def print_matrix(cells):
matrix = """
---------
| {0} {1} {2} |
| {3} {4} {5} |
| {6} {7} {8} |
---------
""".format(*cells)
print(matrix)
coordinates = [
("1", "3"), ("2", "3"), ("3", "3"),
("1", "2"), ("2", "2"), ("3", "2"),
("1", "1"), ("2", "1"), ("3", "1")
]
print_matrix(cells)
end = False
while not end:
try:
given_coordinates = input("Enter the coordinates: ").split(", ")
t_given_coordinates = tuple(given_coordinates)
cellnum = coordinates.index(t_given_coordinates)
cells[cellnum] = "X"
print_matrix(cells)
except:
print("That was an invalid input")
end = True
The output will look somewhat like that:
---------
| - - - |
| - - - |
| - - - |
---------
Enter the coordinates: 1, 1
---------
| - - - |
| - - - |
| X - - |
---------
Enter the coordinates: 2, 3
---------
| - X - |
| - - - |
| X - - |
---------
Enter the coordinates: hello world
That was an invalid input
But, if I may suggest a slight change:
- The initial filling of the cells could already be the cell indices. So, the user just has to enter the index of the next cell to fill, which is a single integer. That's much less prone to raise errors. So, when the field is empty, it just reads:
---------
| 0 1 2 |
| 3 4 5 |
| 6 7 8 |
---------
I would represent your choises as simple flat list and calculate the position inside this list from the tuples you get as inputs like so:
def print_list(l):
"""Takes a list of 9 elements and prints them in a 3x3 matrix
replacing None with empty spaces."""
matrix = """
---------
| {0} {1} {2} |
| {3} {4} {5} |
| {6} {7} {8} |
---------
"""
print(matrix.format(*(what or " " for what in l)))
# use a list to store the taken fields
choices = ["X", None, None,
"X", "O", "O",
None, None, None]
print_list(choices)
c = ("3","1") # the tuple your input gave you
# create numbers from it
c = list(map(int,c))
# calculate list position
pos = (c[0]-1)*3+c[1]-1
# fill correct letter in
choices [pos] = "X"
print_list(choices)
to get
---------
| X |
| X O O |
| |
---------
---------
| X |
| X O O |
| X |
---------
Obviously you would need to
- check if the position in the list is still
Noneto avoid overwriting X by O (or reverse) - change the letter to be written to X or O (whoever ones turn it is)
- determine if a winning move was made
- ...
See f.e. Search in duckduckgo.com for python + tic tac to on stackoverflow.com
The problem is that .replace(old, new) returns a copy of the string in which the occurrences of old have been replaced with new.
Instead, you can swap the character at index i using:
new_str = old_str[:i] + "b" + old_str[i+1:]
Check the documentation.
You can use
example_string.replace(example_string[0], "b", 1)
though it would be much more natural to use a slice to replace just the first character, as @nbryans indicated in a comment.
strings are immutable (unchangeable). But you can index and join items.
mystring = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
mystring = 'ABCDE'.join([mystring[:20],mystring[24:]])
'XXXXXXXXXXXXXXXXXXXXABCDEXXXXXXXXXXXXXX'
Do be careful as the string length "ABCDE" and the number of items you omit between mystring[:20], mystring[24:] need to be the same length.
Strings are immutable in python! You'll have to split the string into three pieces and concatenate them together :)
mystring = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
new_str = "ABCDE"
first_piece = mystring[0:20]
third_piece = mystring[24:len(mystring)]
final_string = first_piece + new_str + third_piece