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
Related
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
there was a similar question asked on here but they wanted the remaining letters returned if one word was longer. I'm trying to return the same number of characters for both strings.
Here's my code:
def one_each(st, dum):
total = ""
for i in (st, dm):
total += i
return total
x = one_each("bofa", "BOFAAAA")
print(x)
It doesn't work but I'm trying to get this desired output:
>>>bBoOfFaA
How would I go about solving this? Thank you!
str.join with zip is possible, since zip only iterates pairwise up to the shortest iterable. You can combine with itertools.chain to flatten an iterable of tuples:
from itertools import chain
def one_each(st, dum):
return ''.join(chain.from_iterable(zip(st, dum)))
x = one_each("bofa", "BOFAAAA")
print(x)
bBoOfFaA
I'd probably do something like this
s1 = "abc"
s2 = "123"
ret = "".join(a+b for a,b in zip(s1, s2))
print (ret)
Here's a short way of doing it.
def one_each(short, long):
if len(short) > len(long):
short, long = long, short # Swap if the input is in incorrect order
index = 0
new_string = ""
for character in short:
new_string += character + long[index]
index += 1
return new_string
x = one_each("bofa", "BOFAAAA") # returns bBoOfFaA
print(x)
It might show wrong results when you enter x = one_each("abcdefghij", "ABCD") i.e when the small letters are longer than capital letters, but that can be easily fixed if you alter the case of each letter of the output.
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.
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)
Is there a Python-way to split a string after the nth occurrence of a given delimiter?
Given a string:
'20_231_myString_234'
It should be split into (with the delimiter being '_', after its second occurrence):
['20_231', 'myString_234']
Or is the only way to accomplish this to count, split and join?
>>> n = 2
>>> groups = text.split('_')
>>> '_'.join(groups[:n]), '_'.join(groups[n:])
('20_231', 'myString_234')
Seems like this is the most readable way, the alternative is regex)
Using re to get a regex of the form ^((?:[^_]*_){n-1}[^_]*)_(.*) where n is a variable:
n=2
s='20_231_myString_234'
m=re.match(r'^((?:[^_]*_){%d}[^_]*)_(.*)' % (n-1), s)
if m: print m.groups()
or have a nice function:
import re
def nthofchar(s, c, n):
regex=r'^((?:[^%c]*%c){%d}[^%c]*)%c(.*)' % (c,c,n-1,c,c)
l = ()
m = re.match(regex, s)
if m: l = m.groups()
return l
s='20_231_myString_234'
print nthofchar(s, '_', 2)
Or without regexes, using iterative find:
def nth_split(s, delim, n):
p, c = -1, 0
while c < n:
p = s.index(delim, p + 1)
c += 1
return s[:p], s[p + 1:]
s1, s2 = nth_split('20_231_myString_234', '_', 2)
print s1, ":", s2
I like this solution because it works without any actuall regex and can easiely be adapted to another "nth" or delimiter.
import re
string = "20_231_myString_234"
occur = 2 # on which occourence you want to split
indices = [x.start() for x in re.finditer("_", string)]
part1 = string[0:indices[occur-1]]
part2 = string[indices[occur-1]+1:]
print (part1, ' ', part2)
I thought I would contribute my two cents. The second parameter to split() allows you to limit the split after a certain number of strings:
def split_at(s, delim, n):
r = s.split(delim, n)[n]
return s[:-len(r)-len(delim)], r
On my machine, the two good answers by #perreal, iterative find and regular expressions, actually measure 1.4 and 1.6 times slower (respectively) than this method.
It's worth noting that it can become even quicker if you don't need the initial bit. Then the code becomes:
def remove_head_parts(s, delim, n):
return s.split(delim, n)[n]
Not so sure about the naming, I admit, but it does the job. Somewhat surprisingly, it is 2 times faster than iterative find and 3 times faster than regular expressions.
I put up my testing script online. You are welcome to review and comment.
>>>import re
>>>str= '20_231_myString_234'
>>> occerence = [m.start() for m in re.finditer('_',str)] # this will give you a list of '_' position
>>>occerence
[2, 6, 15]
>>>result = [str[:occerence[1]],str[occerence[1]+1:]] # [str[:6],str[7:]]
>>>result
['20_231', 'myString_234']
It depends what is your pattern for this split. Because if first two elements are always numbers for example, you may build regular expression and use re module. It is able to split your string as well.
I had a larger string to split ever nth character, ended up with the following code:
# Split every 6 spaces
n = 6
sep = ' '
n_split_groups = []
groups = err_str.split(sep)
while len(groups):
n_split_groups.append(sep.join(groups[:n]))
groups = groups[n:]
print n_split_groups
Thanks #perreal!
In function form of #AllBlackt's solution
def split_nth(s, sep, n):
n_split_groups = []
groups = s.split(sep)
while len(groups):
n_split_groups.append(sep.join(groups[:n]))
groups = groups[n:]
return n_split_groups
s = "aaaaa bbbbb ccccc ddddd eeeeeee ffffffff"
print (split_nth(s, " ", 2))
['aaaaa bbbbb', 'ccccc ddddd', 'eeeeeee ffffffff']
As #Yuval has noted in his answer, and #jamylak commented in his answer, the split and rsplit methods accept a second (optional) parameter maxsplit to avoid making splits beyond what is necessary. Thus, I find the better solution (both for readability and performance) is this:
s = '20_231_myString_234'
first_part = text.rsplit('_', 2)[0] # Gives '20_231'
second_part = text.split('_', 2)[2] # Gives 'myString_234'
This is not only simple, but also avoids performance hits of regex solutions and other solutions using join to undo unnecessary splits.