Repeat string with a specific pattern without slicing - python

I'm working on a pretty annoying Python assignment and I'm lost. These are the requirements:
Ask for input.
For each character in the saved string I need to output said string with a certain modification. For example, if the input is abcd the output looks like this:
abcd
bcda
cdab
dabc
I.e. there are len(input) lines, each line begins with the next input[i] character and repeats to the length of the original input.
I should not use slicing, it's loop practice (T_T). No functions or packages. Loops only.
I made a working script that looks like this:
w = input('Type a word:')
w2 = ''
for i, char in enumerate(w):
w2 = w[i:]+w[:i]
print(w2)
It's neat and short. But it will be marked down for slicing. Can Python loop gurus please help me remake it into loops? Thanks so much in advance!

You can use indexing into the original string using a modulo on itself:
w = "aword"
lw = len(w)
for offset in range(lw):
for character in range(lw):
print(w[(offset+character) % lw], end="")
print()
Output:
aword
worda
ordaw
rdawo
dawor
If your sum of offset and character overshoots the amount of characters the modulo operation wraps it around.

If you can't slice strings, you can append and pop lists. So, convert the string to a list and work with list methods.
>>> test = "abcd"
>>> l = list(test)
>>> for _ in range(len(l)):
... print("".join(l))
... l.append(l.pop(0))
...
abcd
bcda
cdab
dabc

Just for fun another one:
s = 'aword'
ss = s * 2 # 'awordaword'
for i in range(len(s)):
for j in range(len(s)):
print(ss[i+j], end='')
print()
Output:
aword
worda
ordaw
rdawo
dawor

Related

My loop is struggling to move first characters of string to end of string in print for length of string

the output if given a string, "abcdefg" of length 7 as example, should print out 7 lines like:
abcdefg
bcdefga
cdefgab
defgabc
efgabcd
fgabcde
gabcedf
but I seem to be missing the boat after many many hours of various loops and print statements
s = str("abcdefg")
print(s)
print()
for i in range(len(s)):
new_s = s[:i+1] + s[-i:] + s[-i]
print(new_s)
I get this:
abcdefg
aabcdefga
abgg
abcfgf
abcdefge
abcdedefgd
abcdefcdefgc
abcdefgbcdefgb
You're overcomplicating this. The proper expression is just
new_s = s[i:] + s[:i]
slicing is inclusive of the start index, and exclusive of the end index. This above expression guarantees to keep the length of the result the same as the input list, just swapping variable parts of it.
Note that the first new_s value is the original string itself. No need to print it at the start of the program.
The result is:
abcdefg
bcdefga
cdefgab
defgabc
efgabcd
fgabcde
gabcdef
slicing in detail: Understanding slice notation
the loop could be like:
s_len = len(s)
for i in range(s_len):
s = s[1:] + s[0]
print(s)

Is there an easy way to get the number of repeating character in a word?

I'm trying to get how many any character repeats in a word. The repetitions must be sequential.
For example, the method with input "loooooveee" should return 6 (4 times 'o', 2 times 'e').
I'm trying to implement string level functions and I can do it this way but, is there an easy way to do this? Regex, or some other sort of things?
Original question: order of repetition does not matter
You can subtract the number of unique letters by the number of total letters. set applied to a string will return a unique collection of letters.
x = "loooooveee"
res = len(x) - len(set(x)) # 6
Or you can use collections.Counter, subtract 1 from each value, then sum:
from collections import Counter
c = Counter("loooooveee")
res = sum(i-1 for i in c.values()) # 6
New question: repetitions must be sequential
You can use itertools.groupby to group sequential identical characters:
from itertools import groupby
g = groupby("aooooaooaoo")
res = sum(sum(1 for _ in j) - 1 for i, j in g) # 5
To avoid the nested sum calls, you can use itertools.islice:
from itertools import groupby, islice
g = groupby("aooooaooaoo")
res = sum(1 for _, j in g for _ in islice(j, 1, None)) # 5
You could use a regular expression if you want:
import re
rx = re.compile(r'(\w)\1+')
repeating = sum(x[1] - x[0] - 1
for m in rx.finditer("loooooveee")
for x in [m.span()])
print(repeating)
This correctly yields 6 and makes use of the .span() function.
The expression is
(\w)\1+
which captures a word character (one of a-zA-Z0-9_) and tries to repeat it as often as possible.
See a demo on regex101.com for the repeating pattern.
If you want to match any character (that is, not only word characters), change your expression to:
(.)\1+
See another demo on regex101.com.
try this:
word=input('something:')
sum = 0
chars=set(list(word)) #get the set of unique characters
for item in chars: #iterate over the set and output the count for each item
if word.count(char)>1:
sum+=word.count(char)
print('{}|{}'.format(item,str(word.count(char)))
print('Total:'+str(sum))
EDIT:
added total count of repetitions
Since it doesn't matter where the repetition is occurring or which characters are being repeated, you can make use of the set data structure provided in Python. It will discard the duplicate occurrences of any character or an object.
Therefore, the solution would look something like this:
def measure_normalized_emphasis(text):
return len(text) - len(set(text))
This will give you the exact result.
Also, make sure to look out for some edge cases, which you should as it is a good practice.
I think your code is comparing the wrong things
You start by finding the last character:
char = text[-1]
Then you compare this to itself:
for i in range(1, len(text)):
if text[-i] == char: #<-- surely this is test[-1] to begin with?
Why not just run through the characters:
def measure_normalized_emphasis(text):
char = text[0]
emphasis_size = 0
for i in range(1, len(text)):
if text[i] == char:
emphasis_size += 1
else:
char = text[i]
return emphasis_size
This seems to work.

How to loop to generate string in sequence?

I am trying to create a loop where I can generate string using loop. What I am trying to achieve is that I want to create a small collection of strings starting from 1 character to up to 5 characters.
So, starting from sting 1, I want to go to 55555 but this is number so it seems easy if I just add them, but when it comes to alpha numeric, it gets tricky.
Here is explanation,
I have collection of alpha-numeric chars as string s = "123ABC" and what I want to do is that I want to create all possible 1 character string out of it, so I will have 1,2,3,A,B,C and after that I want to add one more digit in length of string so I can get 11, 12, 13 and so on until I get all possible combination out of it up to CA, CB, CC and I want to get it up to CCCCCC. I am confused in loop because I can get it to generate a temp sting but looping inside to rotate characters is tricky,
this is what I have done so far,
i = 0
strr = "123ABC"
while i < len(strr):
t = strr[0] * (i+1)
for q in range(0, len(t)):
# Here I need help to rotate more
pass
i += 1
Can anyone explain me or point me to resource where I can find solution for it?
You may want to use itertools.permutations function:
import itertools
chars = '123ABC'
for i in xrange(1, len(chars)+1):
print list(itertools.permutations(chars, i))
EDIT:
To get a list of strings, try this:
import itertools
chars = '123ABC'
strings = []
for i in xrange(1, len(chars)+1):
strings.extend(''.join(x) for x in itertools.permutations(chars, i))
This is a nested loop. Different depths of recursion produce all possible combinations.
strr = "123ABC"
def prod(items, level):
if level == 0:
yield []
else:
for first in items:
for rest in prod(items, level-1):
yield [first] + rest
for ln in range(1, len(strr)+1):
print("length:", ln)
for s in prod(strr, ln):
print(''.join(s))
It is also called cartesian product and there is a corresponding function in itertools.

How do I repeat words several times in Python?

I'm wanting to create a string that will, If Word 1 was CHEESE and Word 2 = HAM, create a string looking something like this...
CHEESEHAMCHEESEHAMCHEESEHAMCHEESEHAM etc...
I then want the ASCII values of each character to be taken and be used in a Caesar cipher program.
Thanks in advance, I'm not too experienced with Python.
To concatenate two strings s1 and s2, you use the + operator:
s = s1 + s2
To repeat a string s n (integer number) times, you use the * operator:
ss = s * n
To get a list of integers representing each character of a string ss, you can use the built-in ord() method in a list comprehension:
l = [ord(c) for c in ss]
So a full program using two strings and the number of repetitions (here hard-coded as constants), and with the snippets above compressed into one line, would look like this:
s1 = "CHEESE"
s2 = "HAM"
n = 5
l = [ord(c) for c in (s1+s2)*n]
print (l)
you can also try this.
wordOne="cheese"
wordTwo="ham"
i=0
n=5
while i<n:
print("wordOne", end="")
print("wordTwo", end="")
i+=1

Manipulating string to repeat based on the length of another string

I am working on a python project, where I am required to include an input, and another value (which will be manipulated).
For example,
If I enter the string 'StackOverflow', and a value to be manipulated of 'test', the program will make the manipulatable variable equal to the number of characters, by repeating and trimming the string. This means that 'StackOverflow' and 'test' would output 'testtesttestt'.
This is the code I have so far:
originalinput = input("Please enter an input: ")
manipulateinput = input("Please enter an input to be manipulated: ")
while len(manipulateinput) < len(originalinput):
And I was thinking of including a for loop to continue the rest, but am not sure how I would use this to effectively manipulate the string. Any help would be appreciated, Thanks.
An itertools.cycle approach:
from itertools import cycle
s1 = 'Test'
s2 = 'StackOverflow'
result = ''.join(a for a, b in zip(cycle(s1), s2))
Given you mention plaintext - a is your key and b will be the character in the plaintext - so you can use this to also handily manipuate the pairing...
I'm taking a guess you're going to end up with something like:
result = ''.join(chr(ord(a) ^ ord(b)) for a, b in zip(cycle(s1), s2))
# '\x07\x11\x12\x17?*\x05\x11&\x03\x1f\x1b#'
original = ''.join(chr(ord(a) ^ ord(b)) for a,b in zip(cycle(s1), result))
# StackOverflow
There are some good, Pythonic solutions here... but if your goal is to understand while loops rather than the itertools module, they won't help. In that case, perhaps you just need to consider how to grow a string with the + operator and trim it with a slice:
originalinput = input("Please enter an input: ")
manipulateinput = input("Please enter an input to be manipulated: ")
output = ''
while len(output) < len(originalinput):
output += manipulateinput
output = output[:len(originalinput)]
(Note that this sort of string manipulation is generally frowned upon in real Python code, and you should probably use one of the others (for example, Reut Sharabani's answer).
Try something like this:
def trim_to_fit(to_trim, to_fit):
# calculate how many times the string needs
# to be self - concatenated
times_to_concatenate = len(to_fit) // len(to_trim) + 1
# slice the string to fit the target
return (to_trim * times_to_concatenate)[:len(to_fit)]
It uses slicing, and the fact that a multiplication of a X and a string in python concatenates the string X times.
Output:
>>> trim_to_fit('test', 'stackoverflow')
'testtesttestt'
You can also create an endless circular generator over the string:
# improved by Rick Teachey
def circular_gen(txt):
while True:
for c in txt:
yield c
And to use it:
>>> gen = circular_gen('test')
>>> gen_it = [next(gen) for _ in range(len('stackoverflow'))]
>>> ''.join(gen_it)
'testtesttestt'
What you need is a way to get each character out of your manipulateinput string over and over again, and so that you don't run out of characters.
You can do this by multiplying the string so it is repeated as many times as you need:
mystring = 'string'
assert 2 * mystring == 'stringstring'
But how many times to repeat it? Well, you get the length of a string using len:
assert len(mystring) == 6
So to make sure your string is at least as long as the other string, you can do this:
import math.ceil # the ceiling function
timestorepeat = ceil(len(originalinput)/len(manipulateinput))
newmanipulateinput = timestorepeat * manipulateinput
Another way to do it would be using int division, or //:
timestorepeat = len(originalinput)//len(manipulateinput) + 1
newmanipulateinput = timestorepeat * manipulateinput
Now you can use a for loop without running out of characters:
result = '' # start your result with an empty string
for character in newmanipulateinput:
# test to see if you've reached the target length yet
if len(result) == len(originalinput):
break
# update your result with the next character
result += character
# note you can concatenate strings in python with a + operator
print(result)

Categories