Create string from vector - python

I have a numeric vector. I want to enumerate over the vector and create a string as the result. For example, if I have a vector
x = c(1, 3)
I want the resulting string to be:
y = '1x1 + 3x2'
In Python, I would do this:
l = [1, 3]
equation = ' + '.join(['{}x{}'.format(coef, i + 1) for i, coef in enumerate(l)])
str = 'y = {}'.format(equation)
How can the same thing be done in R?

You can do this:
x <- c(1, 3)
paste0(x, substitute(x), seq_along(x), collapse = " + ")
# [1] "1x1 + 3x2"
Explanation:
Get object name: substitute(x) (this returns "x")
Attach object name ("x") to x values and x index seq_alon(x) using paste0() with collapse = " + " argument.

Related

Replace string one by one

I have a string and I need to replace "e" with "x" one at a time. For e.g.
x = "three"
Then the expected output is:
("thrxe", "threx")
and if I have 3 characters to replace, for e.g.
y = "threee"
Then the expected output will be:
("thrxee", "threxe", "threex")
I have tried this:
x.replace("e", "x", 1) # -> 'thrxe'
But not sure how to return the second string "threx".
Try this
x = "threee"
# build a generator expression that yields the position of "e"s
# change "e"s with "x" according to location of "e"s yielded from the genexp
[f"{x[:i]}x{x[i+1:]}" for i in (i for i, e in enumerate(x) if e=='e')]
['thrxee', 'threxe', 'threex']
You could use a generator to replace e with x sequentially through the string. For example:
def replace(string, old, new):
l = len(old)
start = 0
while start != -1:
start = string.find(old, start + l)
if start != -1:
yield string[:start] + new + string[start + l:]
z = replace('threee', 'e', 'x')
for s in z:
print(s)
Output:
thrxee
threxe
threex
Note I've generalised the code to allow for arbitrary length match and replacement strings, if you don't need that just replace l (len(old)) with 1.
def replace(string,old,new):
f = string.index(old)
l = list(string)
i = 0
for a in range(string.count(old)):
l[f] = new
yield ''.join(l)
l[f]=old
try:
f = string.index(old,f+1)
except ValueError:
pass
i+=1
z = replace('threee', 'e', 'x')
for a in z:
print(a)
OUTPUT
thrxee
threxe
threex

Why this Python "loop code" does not work?

Why this code does not work?
ffi5_1 = pd.read_csv('/Users/d/bm_ffi5_1.csv')
ffi5_2 = pd.read_csv('/Users/d/bm_ffi5_2.csv')
ffi5_3 = pd.read_csv('/Users/d/bm_ffi5_3.csv')
ffi5_4 = pd.read_csv('/Users/d/bm_ffi5_4.csv')
ffi5_5 = pd.read_csv('/Users/d/bm_ffi5_5.csv')
s_list = list(range(1,6))
for x in s_list:
ffi5_x.jdate = pd.to_datetime(ffi5_x.jdate)
Here jdate is the column of dataframe.
Your code probably fails with a message that you attempt to refer to
a non-existing variable ffi5_x.
In order to replace x in the DataFrame name with the current value
of x - loop control variable (in 2 places), change your loop to:
for x in s_list:
exec('ffi5_' + str(x) + '.jdate = pd.to_datetime(ffi5_' + str(x) + '.jdate)')

Return mean value without tuple?

Expected output: report_exam_avg(100, 95, 80) == 'Your average score: 91.7'
def report_exam_avg(a, b, c):
assert is_number(a) and is_number(b) and is_number(c)
a = float(a)
b = float(b)
c = float(c)
mean = (a + b + c) / 3.0
mean = round(mean,1)
x = 'Your average score: ', mean
return x
Actual output: ('Your average score: ', 91.7)
Note: cant unpack the tuple such as below because I need the sentence returned not printed
avg, score = report_exam_avg(100, 95, 80)
print(avg, score)
You are returning x as a tuple in this case. So this is why when you simply print x you get a tuple as output. You should either use the print statement in Function or modify function as follows:
def report_exam_avg(a, b, c):
assert is_number(a) and is_number(b) and is_number(c)
a = float(a)
b = float(b)
c = float(c)
mean = (a + b + c) / 3.0
mean = round(mean,1)
x = mean
return x
So your call to function would be:
print ("Your Avg. Score:", report_exam_avg(100, 95, 80))
I would suggest changing the use of the comma to plus. This would change where you set the variable x:
x = 'Your average score: ' + str(mean)
This will properly handle string concatenation, whereas the comma will generate a tuple.
Additionally, if you are using python 3.6, you could make use of fstrings, a very handy string interpolation tool. This would change the line to look like this:
x = f'Your average score: {mean}'
You can then return x in string form.
Python supports return multiple values in a function, just delimit them with ,. In your case, Python thinks you'are doing this, thus returns a tuple.
To return a string, simply concat string with +:
x = 'Your average score: ' + str(mean)
return x
Or, use string format
x = 'Your average score: {}'.format(mean)
return x

Inserting "-" in string after elements of variable lengths

Is there a way to convert the string "12345678aaaa12345678bbbbbbbb" to "12345678-aaaa-1234-5678-bbbbbbbb" in python?
I am not sure on how to do it, since I need to insert "-" after elements of variable lengths say after 8th element then 4th element and so on.
This function inserts a char at a postion for a string:
def insert(char,position,string):
return string[:position] + char + string[position:]
Python strings cannot be mutated. What we can do is create another string with the hyphen inserted in between, as per your wish.
Consider the string s = "12345678aaaa12345678bbbbbbbb"
Giving s[:8] + '-' + s[8:] will give you 12345678-aaaa12345678bbbbbbbb
You can give the hyphen as you wish by adjusting the : values.
For more methods to add the hyphen, refer to this question thread for answer as to how to insert hypForhen.
Add string in a certain position in Python
You can follow this process :
def insert_(str, idx):
strlist = list(str)
strlist.insert(idx, '-')
return ''.join(strlist)
str = '12345678aaaa12345678bbbbbbbb'
indexes = [8, 4, 4, 4]
resStr = ""
idx = 0
for val in indexes:
idx += val
resStr = insert_(str,idx)
str = resStr
idx += 1
print(str)
output :
12345678-aaaa-1234-5678-bbbbbbbb
This doesn't exactly create the string you want but posting it anyway.
It finds all the indexes where digit becomes alpha and vice versa.
Then it inserts "-" at these indexes.
a = "12345678aaaa12345678bbbbbbbb"
lst = list(a)
index = []
for ind,i in enumerate(list(a)[:-1]):
if (i.isdigit() and lst[ind+1].isalpha()) or (i.isalpha() and lst[ind+1].isdigit()):
index.append(ind)
for i in index[::-1]:
lst.insert(i+1,"-")
''.join(lst)
'12345678-aaaa-12345678-bbbbbbbb'
Simplest solution:
str = '12345678aaaa12345678bbbbbbbb'
indexes = [8, 4, 4, 4]
i = -1
for index in indexes:
i = i + index + 1
str = str[:i] + '-' + str[i:]
print str
Prints: 12345678-aaaa-1234-5678-bbbbbbbb
You are free to change indexes array to achieve what you want.
If your want do this in one time , you can like this.
str = "12345678aaaa12345678bbbbbbbb"
def insert(char,positions,string):
result = ""
for post in range(0, len(positions)):
print(positions[post])
if post == 0:
result += string[:positions[post]] + char
elif post == (len(positions) -1 ):
result += string[positions[post-1]:positions[post]] + char + string[positions[post]:]
else:
result += string[positions[post-1]:positions[post]] + char
print(result)
return result
insert("-", [8, 12, 16, 20], str)

Moving object in list

I made a list like this:
mapxy = [[0 for x in range(16)] for x in range(16)]
and I add object from another normal list like this:
for y in range(0, 16):
for x in range(0, 16):
mapxy[x][y] = mapList[o]
Then I want to move one object in the list both down and just change the first index moving it left and right in the list mapxy[x+1][y]
mapxy.pop(f_pos_x)
mapxy.insert(f_pos_x + 1, ["1"])
f_pos_x += 1
(this didn't work quite as I wanted it too, it ended up in-between/created another list inside the first list instead of inserting in the inner list like I wanted it to.)
but also up and down on y: mapxy[x][y+1].
How I want it to look:
Original
mapxy = [[" ", " ", "1"," "][" ", " ", " "," "][" ", " ", " "," "][" ", " ", " "," "]]
When i press right:
mapxy = [[" ", " ", " ","1"][" ", " ", " "," "][" ", " ", " "," "][" ", " ", " "," "]]
And when I press down:
mapxy = [[" ", " ", " "," "][" ", " ", " ","1"][" ", " ", " "," "][" ", " ", " "," "]]
mapxy is a list of lists (with apparently all "cells" initialized to the single item mapList[o], which is slightly strange). So pop and insert into it would remove and respectively add a whole list at a time, not a single item.
You say you want to "move" an item but not what should take its place. If you just want to copy the item, it's clearly just:
map[x+1][y] = map[x][y]
but if the previous map[x][y] must be filled w/something else you'll then have to assign to that, too, of course. Exactly the same for "moving" along y rather than along x.
Use a dictionary with a tuple as key:
map = {}
for x in range(16):
for y in range(16):
map[x, y] = 0
Actually, you could avoid the initialization and check whether an element is set or use a default value. Concerning this default value, consider None, too. With this dict, you can "move" elements easily:
map[1, 2] = 42
v = map.pop((1, 2))
map[3, 4] = v
Here is the full script that I think does what you want. But before I just paste it and run away, there two things worth saying. 1. You need to swap items in-place. 2. You need to cater for the out of range index errors.
To first i envisaged using a deque of deques with maxlen field set. deque is available from the collections library. So to shift left, you pop at the right and insert at the left and to shift to the right you pop at the left and append at the right. But then I had another idea.
You stick with the list of lists, you swap items in-place and avoid out of range errors by the new computed index is within the set of non-negative integers modulo length of the list containing the item.
Enough talking. To swap in-place in python, given:
x = [8, 21, 100, 9, 5]
You do:
x[2], x[3] = x[3], x[2]
Resulting in:
x = [8, 21, 9, 100, 5]
The script below keeps track of two indices, x corresponds to the index of the item, the string, being moved left and right and y corresponds to the index of the inner list item containing the the item to be moved left and right (the inner list itself is moved up and down). By index i mean position. So x points to the string, y points to the list.
To move up and down the containing list, you only need to know the index of the list to move, y. To move left and right the item (the string), you need to know both the containing list index y and the item index x.
#!/usr/bin/python
from collections import deque
def move_dowm(data, y):
old_y = y
y = (y + 1) % len(data)
data[old_y], data[y] = data[y], data[old_y]
return y
def move_up(data, y):
old_y = y
y = (y - 1) % len(data)
data[old_y], data[y] = data[y], data[old_y]
return y
def move_right(data, x, y):
old_x = x
x = (x + 1) % len(data[y])
data[y][old_x], data[y][x] = data[y][x], data[y][old_x]
return x
def move_left(data, x, y):
old_x = x
x = (x - 1) % len(data[y])
data[y][old_x], data[y][x] = data[y][x], data[y][old_x]
return x
if __name__ == '__main__':
dataset = [
[' ', ' ', ' ', ' '],
['1', ' ', ' ', ' '],
[' ', ' ', ' ', ' '],
[' ', ' ', ' ', ' '],
]
x, y = 0, 1
print dataset
print '-' * 90
y = move_up(dataset, y)
print dataset
print '-' * 90
y = move_dowm(dataset, y)
print dataset
print '-' * 90
x = move_left(dataset, x, y)
print dataset
print '-' * 90
x = move_right(dataset, x, y)
print dataset
print

Categories