Stars and string combination pattern in Python - python-2.7

I want a pattern like:
Input : Python is Interactive (any string separated by space)
Expected Output:
*************
*Python *
*is *
*Interactive*
*************
I tried using python's "re" module ,not able to create the stars in the pattern
inp = "Python is interactive"
import re
split = re.split(' ', inp)
length = []
for item in range(len(split)):
length.append(len(split[item]))
Max = (max(length))
for i in range(len(split)):
print(split[i])

You don't need the re module. Your approach is not that bad, but needs some rework:
input = "Python is interactive"
parts = input.split(" ")
maxlen = max(map(lambda part: len(part), parts))
# or this, if you want to go even more elegant:
maxlen = max(map(len, parts))
print ('*' * (maxlen + 4))
for part in parts:
spaces = maxlen - len(part)
print("* " + part + (" " * spaces) + " *")
print ('*' * (maxlen + 4))
For splitting you can use the string.split method. Then I calculate the maximum length (like you did, but a little bit more elegant).
Then I print as many stars as the most long string is + 4 because at the beginning and end of each string there is "* " and " *", so 4 more characters.
Then I print the string with as many spaces as padding as needed.
Finally the last line of stars.

Related

Rearranging elements in Python

i am new to Python and i cant get this.I have a List and i want to take the input from there and write those in files .
p = ['Eth1/1', 'Eth1/5','Eth2/1', 'Eth2/4','Eth101/1/1', 'Eth101/1/2', 'Eth101/1/3','Eth102/1/1', 'Eth102/1/2', 'Eth102/1/3','Eth103/1/1', 'Eth103/1/2', 'Eth103/1/3','Eth103/1/4','Eth104/1/1', 'Eth104/1/2', 'Eth104/1/3','Eth104/1/4']
What i am trying :
with open("abc1.txt", "w+") as fw1, open("abc2.txt", "w+") as fw2:
for i in p:
if len(i.partition("/")[0]) == 4:
fw1.write('int ' + i + '\n mode\n')
else:
i = 0
while i < len(p):
start = p[i].split('/')
if (start[0] == 'Eth101'):
i += 3
key = start[0]
i += 1
while i < len(p) and p[i].split('/')[0] == key:
i += 1
end = p[i-1].split('/')
fw2.write('confi ' + start[0] + '/' + start[1] + '-' + end[1] + '\n mode\n')
What i am looking for :
abc1.txt should have
int Eth1/1
mode
int Eth1/5
mode
int Eth2/1
mode
int Eth 2/4
mode
abc2.txt should have :
int Eth101/1/1-3
mode
int Eth102/1/1-3
mode
int Eth103/1/1-4
mode
int Eth104/1/1-4
mode
So any Eth having 1 digit before " / " ( e:g Eth1/1 or Eth2/2
)should be in one file that is abc1.txt .
Any Eth having 3 digit before " / " ( e:g Eth101/1/1 or Eth 102/1/1
) should be in another file that is abc2.txt and .As these are in
ranges , need to write it like Eth101/1/1-3, Eth102/1/1-3 etc
Any Idea ?
I don't think you need a regex here, at all. All your items begin with 'Eth' followed by one or more digits. So you can check the length of the items before first / occurs and then write it to a file.
p = ['Eth1/1', 'Eth1/5','Eth2/1', 'Eth2/4','Eth101/1/1', 'Eth101/1/2', 'Eth101/1/3','Eth102/1/1', 'Eth102/1/2', 'Eth102/1/3','Eth103/1/1', 'Eth103/1/2', 'Eth103/1/3','Eth103/1/4','Eth104/1/1', 'Eth104/1/2', 'Eth104/1/3','Eth104/1/4']
with open("abc1.txt", "w+") as fw1, open("abc2.txt", "w+") as fw2:
for i in p:
if len(i.partition("/")[0]) == 4:
fw1.write('int ' + i + '\n mode\n')
else:
fw2.write('int ' + i + '\n mode\n')
I refactored your code a little to bring with-statement into play. This will handle correctly closing the file at the end. Also it is not necessary to iterate twice over the sequence, so it's all done in one iteration.
If the data is not as clean as provided, then you maybe want to use regexes. Independent of the regex itself, by writing if re.match(r'((Eth\d{1}\/\d{1,2})', "p" ) you proof if a match object can be created for given regex on the string "p", not the value of the variable p. This is because you used " around p.
So this should work for your example. If you really need a regex, this will turn your problem in finding a good regex to match your needs without any other issues.
As these are in ranges , need to write it like Eth101/1/1-3, Eth102/1/1-3 etc
This is something you can achieve by first computing the string and then write it in the file. But this is more like a separate question.
UPDATE
It's not that trivial to compute the right network ranges. Here I can present you one approach which doesn't change my code but adds some functionality. The trick here is to get groups of connected networks which aren't interrupted by their numbers. For that I've copied consecutive_groups. You can also do a pip install more-itertools of course to get that functionality. And also I transformed the list to a dict to prepare the magic and then retransformed dict to list again. There are definitely better ways of doing it, but this worked for your input data, at least.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from itertools import groupby
from operator import itemgetter
p = ['Eth1/1', 'Eth1/5', 'Eth2/1', 'Eth2/4', 'Eth101/1/1', 'Eth101/1/2',
'Eth101/1/3', 'Eth102/1/1', 'Eth102/1/2', 'Eth102/1/3', 'Eth103/1/1',
'Eth103/1/2', 'Eth103/1/3', 'Eth103/1/4', 'Eth104/1/1', 'Eth104/1/2',
'Eth104/1/3', 'Eth104/1/4']
def get_network_ranges(networks):
network_ranges = {}
result = []
for network in networks:
parts = network.rpartition("/")
network_ranges.setdefault(parts[0], []).append(int(parts[2]))
for network, ranges in network_ranges.items():
ranges.sort()
for group in consecutive_groups(ranges):
group = list(group)
if len(group) == 1:
result.append(network + "/" + str(group[0]))
else:
result.append(network + "/" + str(group[0]) + "-" +
str(group[-1]))
result.sort() # to get ordered results
return result
def consecutive_groups(iterable, ordering=lambda x: x):
"""taken from more-itertools (latest)"""
for k, g in groupby(
enumerate(iterable), key=lambda x: x[0] - ordering(x[1])
):
yield map(itemgetter(1), g)
# only one line added to do the magic
with open("abc1.txt", "w+") as fw1, open("abc2.txt", "w+") as fw2:
p = get_network_ranges(p)
for i in p:
if len(i.partition("/")[0]) == 4:
fw1.write('int ' + i + '\n mode\n')
else:
fw2.write('int ' + i + '\n mode\n')

print a character horizontally using the for loop

I'm trying to print characters n numbers of times horizontally, and thus far, I have this code:
#print n times *
times=input("¿How many times will it print * ? " )
for i in range(times):
print"* \t"
but the result is this:
¿How many times will it print * ? 5
*
*
*
*
*
How do I make the asterisk print horizontally?
EG:
* * * * * *
First of all you need to cast your input into int.
Second, by adding a comma at the end of your print statement, it will print horizontal.
Also, as you are using python 2.x, you should use raw_input instead of input
times = int(raw_input("How many times will it print * ? " ))
for i in range(times):
print "* \t",
Output:
* * * * *
That's because by default, python's print function adds a newline after it, you'll want to use sys.stdout.write(), as you can see here
EG:
#print n times *
import sys
times=input("¿How many times will it print * ? " )
for i in range(times):
sys.stdout.write("* \t")
#Flush the output to ensure the output has all been written
sys.stdout.flush()
You can start by trying this. As far as I know, print() systematically inserts a \n (line break) after each call, so the solution is to call "print()" only once.
#print n times *
times=input("¿How many times will it print * ? " )
str = ""
for i in range(times):
str += "* \t"
print(str)

clarification of Python regular expression

I am a little confused on how regular expressions and sub works in Python.
I have this example:
nw = " textttt "
nw = re.sub(r'\s+(textttt)\s+', r'\1 ', nw)
The value in nw will be nw = "textttt ".
However if I have:
nw = " textttt "
nw = re.sub(r'\s(textttt)\s', r'\1 ', nw)
The value of nw will be nw = " textttt ".
Can someone please explain how the first and second results are generated and why they are different?
For clarity, let's replace spaces with digits:
import re
nw = "01textttt2345"
xx = re.sub(r'\d+(textttt)\d+', r'\1 ', nw)
print '[%s]' % xx # [textttt ]
xx = re.sub(r'\d(textttt)\d', r'\1 ', nw)
print '[%s]' % xx # [0textttt 345]
The first expression finds 01textttt2345 and replaces this with the value of the group(=textttt) plus a space. The second one finds only 1textttt2 and replaces that with textttt, leaving the rest of the string untouched.
\\s - works for single whitespace character
\\s+ - works for sequence of one or more whitespace characters.

Manipulating strings python 2.7

I am trying to code a program that will insert specific numbers before parts of an input, for example given the input "171819-202122-232425" I would like it to split up the number into pieces and use the dash as a delimiter. I have split up the number using list(str(input)) but have no idea how to insert the appropriate numbers. It has to work for any number Thanks for the help.
Output =
(number)17
(number)18
(number)19
(number+1)20
(number+1)21
(number+1)22
(number+2)23
(number+2)24
(number+2)25
You could use split and regexps to dig out lists of your numbers:
Code
import re
mynum = "171819-202122-232425"
start_number = 5
groups = mynum.split('-') # list of numbers separated by "-"
number_of_groups = xrange(start_number , start_number + len(groups))
for (i, number_group) in zip(number_of_groups, groups):
numbers = re.findall("\d{2}", number_group) # return list of two-digit numbers
for x in numbers:
print "(%s)%s" % (i, x)
Result
(5)17
(5)18
(5)19
(6)20
(6)21
(6)22
(7)23
(7)24
(7)25
Try this:
Code:
mInput = "171819-202122-232425"
number = 9 # Just an example
result = ""
i = 0
for n in mInput:
if n == '-': # To handle dash case
number += 1
continue
i += 1
if i % 2 == 1: # Each two digits
result += "\n(" + str(number) + ")"
result += n # Add current digit
print result
Output:
(9)17
(9)18
(9)19
(10)20
(10)21
(10)22
(11)23
(11)24
(11)25

Convert punctuation to space

I have a bunch of strings with punctuation in them that I'd like to convert to spaces:
"This is a string. In addition, this is a string (with one more)."
would become:
"This is a string In addition this is a string with one more "
I can go thru and do this manually with the stringr package (str_replace_all()) one punctuation symbol at a time (, / . / ! / ( / ) / etc. ), but I'm curious if there's a faster way I'd assume using regex's.
Any suggestions?
x <- "This is a string. In addition, this is a string (with one more)."
gsub("[[:punct:]]", " ", x)
[1] "This is a string In addition this is a string with one more "
See ?gsub for doing quick substitutions like this, and ?regex for details on the [[:punct:]] class, i.e.
‘[:punct:]’ Punctuation characters:
‘! " # $ % & ' ( ) * + , - . / : ; < = > ? # [ \ ] ^ _ ` { |
} ~’.
have a look at ?regex
library(stringr)
str_replace_all(x, '[[:punct:]]',' ')
"This is a string In addition this is a string with one more "