python 2.7 line.index if statement for a multiplication table - python-2.7

lines = [[str(i * j) for i in xrange(1, 13)] for j in xrange(1, 13)]
for line in lines:
for num in line:
if line.index(num):
print ' ' * (3 - len(num)) + num,
else:
print ' ' * (2 - len(num)) + num,
print
I am trying to understand why the else statement pertains to the first line
and the line.index(num) pertains to remaining lines.

As your if statement is not comparing the return of line.index(num) against anything, returning any non zero value will satisfy the condition and returning a value of 0 will result in the else statement.
line.index(num) returns 0 if num is the first entry in line and so only acts on the first entry from each line in lines.

Related

Regular expression for equations, variable number of inside parenthesis

I'm trying to write Regex for the case where I have series of equations, for example:
a = 2 / (1 + exp(-2*n)) - 1
a = 2 / (1 + e) - 1
a = 2 / (3*(1 + exp(-2*n))) - 1
In any case I need to capture content of the outer parenthesis, so 1 + exp(-2*n), 1+e and 3*(1 + exp(-2*n)) respectively.
I can write expression that will catch one of them, like:
\(([\w\W]*?\))\) will perfectly catch 1 + exp(-2*n)
\(([\w\W]*?)\) will catch 1+e
\(([\w\W]*?\))\)\) will catch 3*(1 + exp(-2*n))
But it seems silly to pass three lines of code for something such simple. How can I bundle it? Please take a note that I will be processing text (in loop) line-by-line anyway, so you don't have to bother for securing operator to not greedy take next line.
Edit:
Un-nested brackets are also allowed: a = 2 / (1 + exp(-2*n)) - (2-5)
The commented code below does not use regular expressions, but does parse char arrays in MATLAB and output the terms which contain top-level brackets.
So in your 3 question examples with a single set of nested brackets, it returns the outermost bracketed term.
In the example from your comment where there are two or more (possibly nested) terms within brackets at the "top level", it returns both terms.
The logic is as follows, see the comments for more details
Find the left (opening) and right (closing) brackets
Generate the "nest level" according to how many un-closed brackets there are at each point in the equation char
Find the indicies where the nesting level changes. We're interested in opening brackets where the nest level increases to 1 and closing brackets where it decreases from 1.
Extract the terms from these indices
e = { 'a = 2 / (1 + exp(-2*n)) - 1'
'a = 2 / (1 + e) - 1'
'a = 2 / (3*(1 + exp(-2*n))) - 1'
'a = 2 / (1 + exp(-2*n)) - (2-5)' };
str = cell(size(e)); % preallocate output
for ii = 1:numel(e)
str{ii} = parseBrackets_(e{ii});
end
function str = parseBrackets_( equation )
bracketL = ( equation == '(' ); % indicies of opening brackets
bracketR = ( equation == ')' ); % indicies of closing brackets
str = {}; % intialise empty output
if numel(bracketL) ~= numel(bracketR)
% Validate the input
warning( 'Could not match bracket pairs, count mismatch!' )
return
end
nL = cumsum( bracketL ); % cumulative open bracket count
nR = cumsum( bracketR ); % cumulative close bracket count
nestLevel = nL - nR; % nest level is number of open brackets not closed
nestLevelChanged = diff(nestLevel); % Get the change points in nest level
% get the points where the nest level changed to/from 1
level1L = find( nestLevel == 1 & [true,nestLevelChanged==1] ) + 1;
level1R = find( nestLevel == 1 & [nestLevelChanged==-1,true] );
% Compile cell array of terms within nest level 1 brackets
str = arrayfun( #(x) equation(level1L(x):level1R(x)), 1:numel(level1L), 'uni', 0 );
end
Outputs:
str =
{'1 + exp(-2*n)'}
{'1 + e'}
{'3*(1 + exp(-2*n))'}
{'1 + exp(-2*n)'} {'2-5'}

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')

How to insert text in a line that has an empty line above or below?

I have set of coordinates that are randomly separated with an empty line:
19.815857300 39.791813400
19.816105700 39.791921800
19.816220800 39.791984600
19.816271400 39.792010000
19.786375895 39.678097997
19.783813875 39.677022719
19.782758486 39.676590122
and so on...lot of coordinates :)
I want to insert a specific text at the beginning and at the end of the 1st coordinates set,( first line of the "paragraph").
The same for the last line of each paragraph - different text entry
The coordinates between them, also need another text before and after.
so.. the result I would like to achieve, should be something like
BEGIN_SEGMENT 0 50 10 19.815857300 39.791813400 0.00000000
SHAPE_POINT 19.816105700 39.791921800 0
SHAPE_POINT 19.816220800 39.791984600 0
END_SEGMENT 20 19.816271400 39.792010000 0.00000000
BEGIN_SEGMENT 0 50 10 19.786375895 39.678097997 0.00000000
SHAPE_POINT 19.783813875 39.677022719 0
END_SEGMENT 20 19.782758486 39.676590122 0.00000000
etc..etc..
Any ideas on how this could be done with notepad++ and regular expressions?
Thanx in advance!
Solution using python 3.6.
It reads in a file "input.txt" - line by line - until it gets an empty line.
On each start it recreates the file "result.txt".
Each found paragraph is appended to "result.txt" - until done.
Now you just need to get a python environment ;o) and feed it your file.
import re
import datetime
import random
# recreate empty file with timestamp
with open("result.txt","w") as r:
r.write(str(datetime.datetime.now()) + "\n")
with open("input.txt","r") as f:
while True:
paragraph = []
line = f.readline()
if line == "":
break # readline always retunrs \n on empty lines until file end reached
while len(line.strip()) > 0:
# accumulate lines
paragraph.append(line.strip())
line = f.readline()
if not paragraph:
continue # jumps back up to while True:
rv = []
for idx in range(0,len(paragraph)):
if idx == 0:
rv.append("BEGIN_SEGMENT 0 50 " + str(random.randint(1,10000)) + " " + paragraph[idx] + " 0.00000000 " + "\n")
elif idx != (len(paragraph) - 1):
rv.append("SHAPE_POINT " + paragraph[idx] + " 0" + "\n")
else:
rv.append("END_SEGMENT " + str(random.randint(1,10000)) + " " + paragraph[idx] + " 0.00000000" + "\n" + "\n")
# append results of paragraph
with open("result.txt","a") as resFile:
for line in rv:
resFile.write(line)
# edited code for random numbers instead of fixed ones
Not complete - you'll have to adjust the first and last rows by hand.
Step 1 end segment-begin segment
FIND:\r\n(\d.*)\r\n\r\n
REPLACE: \r\nEND_SEGMENT\t$1\r\n\r\nBEGIN_SEGMENT\t
Step 2: shape point
FIND: ^(\d.*)$
REPLACE: SHAPE_POINT\t$1
Assumes that there will be only one blank line between segments.
You can use https://regexper.com/ to display a diagram of the expressions.

Exiting While loop when reaching the end of the string

I am currently learning to use ord() and chr() but the having difficulties with the following code.
b = '1101'
i = 0
while b != ' ' :
i = i*2 + ( ord(b[0]) + ord('0') )
b = b[1:]
Traceback (most recent call last):
File "<pyshell#86>", line 2, in <module>
i = i*2 + ( ord(b[0]) + ord('0') )
IndexError: string index out of range
Why does my string go out of range and throw the error instead of exiting the loop as I expect?
Your while condition never becomes true. ' ' doesn't mean Nothing, it means an empty space. Unless your original string contains a space at the end, it will never be true.
It should work if you make it '' instead of ' '.
Also, since variables evaluate to True when they hold a value and False when are reduced to None type, you can write the same thing as while b: . This will be true as long as b holds a value, but as soon as it's empty, it'll stop looping.

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)