Reputation: 13
Ok so what im trying to do is to alternate the first two values in the string in the rest of the string.
what i have is..... "*+123"
what i want is ..... "1 * 2 + 3"
im sure the answer is simple but I've racked my head on this.....I am a beginner
ive tried separating the first two positions and putting them into separate variables and alternated that way:
THIS IS MY CODE
formula = '*+*123'
first_part = formula[0:3]
second_part = formula[3:len(formula_chosen)]
print first_part
print second_part
expanded = ''
for i in range(len(second_part)-1):
expanded = expanded + second_part[i] + first_part[i]
print expanded
but what i end up with is: "1*2+"
Upvotes: 1
Views: 1205
Reputation: 21002
You are being very, very specific in what you are trying to do. If this is an exercise that you are trying to do, in which the instructions are, "Given a 5 character string, create a new string where the first two characters alternate with the last 3 in a new string" then the code above will work for you in this limited case.
If you are trying to solve a problem, however, it would be helpful to have more details about the problem you are trying to solve and why you want to solve it.
As en_Knight points out, this function does not work on a variety of inputs. And the point in computing, generally, is to create code that makes tasks easier by being general enough to solve the same problems many times with different inputs.
A few style notes: when getting sections of lists, you only need to provide the starting number when it is not 0, or the ending number when it is not through the end of the list. So instead of
second_part = formula[3:len(formula_chosen)]
you can simply write:
second_part = formula[3:]
where the empty part after :
signals "Get all content to the end of the string".
To give you an idea of what I mean by writing code so it is a more general solution, here is a function that does what you describe on strings of any length: dividing them exactly in half and then alternating the characters.
def alternate_half(input):
output = ""
input_a = input[:len(input)/2]
input_b = input[len(input)/2:]
for pos, char in enumerate(input_b):
output += char
if len(input_a) > pos:
output += input_a[pos]
return output
Explained:
input[:len(input)/2]``input[len(input)/2:]
- these are both just slices of the main list. It uses the trick above — that python automatically fills in 0 or the end of the list. It also uses the trick that when dividing by integers in Python, you get an integer in return. So for example in the case of a 5 length string, len(input)/2
is 2, so input_a is the first 2 characters, and input_b is the characters 2 through the end of the string, so "123".enumerate("*+123")
is functionally equivalent to [(0, '*'), (1, '+'), (2, '1'), (3, '2'), (4, '3')]
. So we can use the positional argument in input_a
and append to the corresponding character in input_b
.input_a
will never be more than one character shorter than input_b.Upvotes: 0
Reputation: 4583
Try using itertools which is worth checking out when working with iterables in Python.
import itertools
def alternate_characters(formula):
try:
if type(formula) is str:
operators = formula[:2]
operands = formula[2:]
iterable = itertools.izip_longest(operands, operators)
alt = ''
for tup in iterable:
for k in tup:
if k is not None:
alt += k
return alt
except TypeError:
print "Formula must be a string"
With an input string:
print alternate_characters('*+123')
'1*2+3'
With a non-string input:
print alternate_characters(*+123)
'TypeError: alternate_characters() argument after * must be a sequence, not int'
Upvotes: 0
Reputation: 509
something like this, using itertools.cycle(). This will work for any length string and any length of part1 that you can decide..(just replace that 2 with a variable)
In [35]: from itertools import cycle
In [36]: s='*+123'
In [37]: part1=cycle(s[:2])
In [38]: part2=s[2:]
In [39]: processed_string=''.join([digit+part1.next() for digit in part2])[:-1]
In [40]: processed_string
Out[40]: '1*2+3'
Take apart first part, make a cycle from it. cycle keeps cycling iterable on next().
A list comprehension constructs a list of each digit in part2 concatenated with the next() on the itertools.cycle called part1(This makes it alternate between * and +).
''.join() this list to make a string. Get rid of the trailing extra as it is not needed for the last iteration.
In [50]: part1=cycle(s[:2])
In [51]: part1.next()
Out[51]: '*'
In [52]: part1.next()
Out[52]: '+'
In [53]: part1.next()
Out[53]: '*'
In [54]: part1.next()
Out[54]: '+'
In [55]: #alternates
In [56]: # list comp
In [57]: [digit for digit in part2]
Out[57]: ['1', '2', '3']
In [58]: [digit+part1.next() for digit in part2]
Out[58]: ['1*', '2+', '3*']
In [59]: # this is a list of strings and can be joined using join.
In [60]: ''.join([digit+part1.next() for digit in part2])
Out[60]: '1+2*3+'
In [61]: # this has a trailing extra character. get rid of it using slices
In [62]: ''.join([digit+part1.next() for digit in part2])[:-1]
Out[62]: '1*2+3'
In [63]: #solution
To avoid the dropping of last character at the end, you can construct the list for all chars of part2 except the last(part2[:-1]) and then add the last character of part2(part2[-1]) like this:
In [64]: part1=cycle(s[:2])
In [65]: ''.join([digit+part1.next() for digit in part2[:-1]])
Out[65]: '1*2+'
In [66]: ''.join([digit+part1.next() for digit in part2[:-1]])+part2[-1]
Out[66]: '1*2+3'
You can enclose it in a function like this:
In [67]: # enclose in a function
In [68]: def process_text(text,no_of_symbols):
....: part1=cycle(text[:no_of_symbols])
....: part2=text[no_of_symbols:]
....: return ''.join([digit+part1.next() for digit in part2])[:-1]
....:
In [69]: process_text('+*-123456',3)
Out[69]: '1+2*3-4+5*6'
Upvotes: 1
Reputation: 5381
You're close!
Here's a version of your code that works - keep going by one character, then chop off the ending
formula = '*+*123'
first_part = formula[0:3]
second_part = formula[3:len(formula)]
print first_part
print second_part
expanded = ''
for i in range(len(second_part)):#changed here
expanded = expanded + second_part[i] + first_part[i]
expanded = expanded[:-1] #changed here
print expanded
You probably don't like that extra chop (you shouldn't). The problem with your algorithm is that it doesn't handle well when things aren't even in length, becuase you're dividing the list in half. A better way to handle even/oddness is with the "modulo" operator
Here's a fun way to solve the problem using some Python tricks, if you want to make your way through it it might be educational :)
formula = '*+123'
out = ''
for c1,c2 in zip(formula,formula[::-1]):
out += c2 + c1
out = out[:len(out)/2][::-1]
print(out)
Upvotes: 0