Nauman Shahid
Nauman Shahid

Reputation: 377

Replacing a certain number of characters only

I was wondering if anyone could help provide some insight on the following problem that I am currently struggling with.

Let's assume that you have a file that contains the following characters:

|**********|

You have another file that contains a pattern, such as:

       -
      /-\
     /---\
    /-----\
   /-------\

How would you go about replacing the characters in the pattern with the characters from the first file BUT at the same time - you can only print the specific number of *'s that are in the first file.

Once you have printed say the 10 stars, in total, you have to STOP printing.

So it would be something like:

    *
   ***
  *****
 *

Any hints or tips or help would be greatly appreciated.

I have been using .replace() to replace all of the characters in the pattern with the '*' but I am unable to print the specific amount only.

for ch in ['-', '/', '\\']:
   if ch in form:
       form = form.replace(ch, '*')

Upvotes: 4

Views: 246

Answers (6)

KBN
KBN

Reputation: 153

import re
inp = open('stars.txt', 'r').read()
count = len(inp.strip('|')) #stripping off the extra characters from either end

pattern = open('pattern.txt', 'r').read() # read the entire pattern
out = re.sub(r'-|/|\\', r'*', pattern, count=count) # for any of the characters in '-' or '|' or '\', replace them with a '*' only **count** number of times.
out = re.sub(r'-|/|\\', r'', out) # to remove the left out characters
print (out)

Added one more re.sub line to remove the left out characters if any.

Upvotes: 0

radzak
radzak

Reputation: 3118

You can use regular expressions and sub() function from re module.

sub() takes an optional count argument that indicates the maximal number of pattern occurrences to be replaced.

import re

with open('asterisks.txt') as asterisks_file, open('ascii_art.txt') as ascii_art_file:
    pattern = re.compile(r'['   # match one from within square brackets:
                         r'\\'  # either backslash
                         r'/'   # or slash
                         r'-'   # or hyphen
                         r']')

    # let n be the number of asterisks from the first file
    n = asterisks_file.read().count('*')

    # replace first n matches of our pattern (one of /\- characters)
    replaced_b = pattern.sub('*', ascii_art_file.read(), n)

    # replace rest of the /\- characters with spaces (based on your example)
    result = pattern.sub(' ', replaced_b)
    print(result)

OUTPUT:

   *
  ***
 *****
*

Upvotes: 1

Addie
Addie

Reputation: 1691

You just need to keep track of the number of * in the input line and then continue to replace the dashes until the counter runs out. Once the counter runs out then replace the remaining dashes with empty strings.

def replace(p, s):
  counter = len(s) - 2
  chars = ['\\', '/', '-']
  i = 0
  for c in p:
    if c in chars:
        p = p.replace(c, '*', 1)
        i += 1
    if i == counter:
        break

  p = p.replace('\\', '')
  p = p.replace('/', '')
  p = p.replace('-', '')

  return p



if __name__ == '__main__':
  stars = '|**********|'
  pyramid = r'''
    -
   /-\
  /---\
 /-----\
/-------\ '''
  print(pyramid)
  print(replace(pyramid, stars))

OUTPUT

   *
  ***
 *****
*

Upvotes: 0

Jay Shankar Gupta
Jay Shankar Gupta

Reputation: 6088

import re
file1 = open("file1.txt", "r") 
s=file1.read()
starcount=s.count('*')
file2 = open("file2.txt", "r") 
line = re.sub(r'[-|\\|/]', r'*', file2.read(), starcount)
line = re.sub(r'[-|\\|/]', r'', line)
print(line)

Syntax of sub

>>> import re
>>> help(re.sub)
Help on function sub in module re:

sub(pattern, repl, string, count=0, flags=0)
    Return the string obtained by replacing the leftmost
    non-overlapping occurrences of the pattern in string by the
    replacement repl.  repl can be either a string or a callable;
    if a string, backslash escapes in it are processed.  If it is
    a callable, it's passed the match object and must return
    a replacement string to be used.

Output

       *
      ***
     *****
    *

Demo

https://repl.it/repls/ObeseNoteworthyDevelopment

Upvotes: 0

Mufeed
Mufeed

Reputation: 3198

Instead of replacing every character at once you can replace items one at a time and use some count on number of replacements.
But str object doesn't support item assignment at specific index, so you have to convert the str object into list first. Then do your operations and convert back to str again. you can write something like this.

characters = ['-', '/', '\\'] 
count = 0  
a = list(form)           # convert your string to list
for i in range(len(a)):
    if a[i] in characters and count < 10:   # iterate through each character
        a[i] = '*'                          # replace with '*'
        count += 1                          #  increment count
 result =  "".join(a)                       # convert list back into str
 print(result)

Upvotes: 0

SalGorithm
SalGorithm

Reputation: 901

Here's my aestric file(aestricks.txt), which contains:

************

And pattern file (pattern.txt), which contains:

    -
   /-\
  /---\
 /-----\
/-------\

And here's the code. I know it can be optimized a little more, but I am posting the basic one:

file1 = open("aestricks.txt","r")

file1 = file1.read()

t_c = len(file1)

form = open("pattern.txt","r")

form = form.read()

form1 = form

count = 0

for ch in form1:
    if ch in ['-','/', '\\']:
        form = form.replace(ch, '*', 1)
        count += 1

    if count == t_c:
        break

for ch in form1:
    if ch in ['-','/', '\\']:
        form = form.replace(ch, '')

print(form)

OUTPUT:

   *
  ***
 *****
***

Upvotes: 3

Related Questions