Python3: write string into .txt.bz2 file - python-3.5

I want to write the join result by two list into the txt.bz2 file(the file name is named by code, not exist at the beginning). like the following form in txt file.
1 a,b,c
0 d,f,g
.......
But there is error. My code is following, please give me hints how to deal with it. Thanks!
import bz2
x = ['a b c', 'd f g', 'h i k', 'k j l']
y = [1, 0, 0, 1]
with bz2.BZ2File("data/result_small.txt.bz2", "w") as bz_file:
for i in range(len(y)):
m = ','.join(x[i].split(' '))
n = str(y[i])+'\t'+m
bz_file.write(n)
error:
compressed = self._compressor.compress(data)
TypeError: a bytes-like object is required, not 'str'

Open the file in text mode:
import bz2
x = ['a b c', 'd f g', 'h i k', 'k j l']
y = [1, 0, 0, 1]
with bz2.open("data/result_small.txt.bz2", "wt") as bz_file:
for i in range(len(y)):
m = ','.join(x[i].split(' '))
n = str(y[i]) + '\t' + m
bz_file.write(n + '\n')
More succinctly:
import bz2
x = ['a b c', 'd f g', 'h i k', 'k j l']
y = [1, 0, 0, 1]
with bz2.open("data/result_small.txt.bz2", "wt") as bz_file:
for a, b in zip(x, y):
bz_file.write('{}\t{}\n'.format(b, ','.join(a.split())))

You open a bz2-file by using the file bz2.BZ2File(path).
with bz2.BZ2File("data/result_small.txt.bz2", "rt") as bz_file:
#...

Related

Collect coefficients of non-square matrix in sympy

Given three vectors, a(1,4), b(1, 4), c(4,1). I want to do the following
a = MatrixSymbol('a', 1, 4)
b = MatrixSymbol('a', 1, 4)
c = MatrixSymbol('c', 4, 1)
expr = a*c + b*c
c_coeff = .... # How to get the value of (a+b) here
I tried using coeff and collect but it fails because the C matrix is not square.
If it is linear then
>>> from sympy.solvers.solveset import linear_coeffs
>>> linear_coeffs(expr, c)
[a + b, 0]
note that 0 is the constant term; if you added MatrixSymbol('d', 1, 1) to expr the 2nd element would be d; you named 'b' as 'a' in your example; I named it 'b' to get the output shown above.

python error UnboundLocalError and issue with logic

This is what I've written:
def logic( arr , r , l ):
arr = []
i == 0
if (arr[i]) == (i +1) * i :
print('True')
i = i + 1
else :
print('False')
return(arr )
arr = list(map(int, input().split()))
r = int(input())
l = int(input())
print(logic(arr,r,l))
This is what we need:
You task is to calculate a boolean array b, where b[i] = true if there exists an integer x,
such that a[i] = (i + 1) * x and l ≤ x ≤ r. Otherwise, b[i] should be set to false.
Example
For a = [8, 5, 6, 16, 5], l = 1, and r = 3, the output should be logic(a, l, r) = [false, false, true, false, true].
For a[0] = 8, we need to find a value of x such that 1 * x = 8, but the only value that would work is x = 8 which doesn't satisfy the boundaries 1 ≤ x ≤ 3, so b[0] = false.
For a[1] = 5, we need to find a value of x such that 2 * x = 5, but there is no integer value that would satisfy this equation, so b[1] = false.
For a[2] = 6, we can choose x = 2 because 3 * 2 = 6 and 1 ≤ 2 ≤ 3, so b[2] = true.
Below is the error:
UnboundLocalError: local variable 'i' referenced before assignment
You are using i == 0. This is an equals to. This is not asigning the variable. I think you are looking for i = 0. == sign is used in If statements etc.
Also may I ask why you are using the parameters arr , r & l in your logic function. But assign them inside the function?
EDIT: I have not programmed in python for a while and missed the indent

Conpressing repeated loops

I wrote the following code for a HackerRank problem involving repeated FOR loops with very similar syntax:
x, y = map(int, input().split())
inp = []
for _ in range(x):
inp.append(list(map(int, input().split())))
#I get the rest of the input as a nested list.
while len(inp) < 7:
inp.append([1, 0])
#Adding dummy values in the list
list = []
for a in inp[0][1:inp[0][0]+1]:
for b in inp[1][1:inp[1][0]+1]:
for c in inp[2][1:inp[2][0] + 1]:
for d in inp[3][1:inp[3][0] + 1]:
for e in inp[4][1:inp[4][0] + 1]:
for f in inp[5][1:inp[5][0] + 1]:
for g in inp[6][1:inp[6][0] + 1]:
list.append((a ** 2 + b ** 2 + c ** 2 + d ** 2 + e ** 2 + f ** 2 + g ** 2) % y)
#Given function
print(max(list))
I wonder if there's any way to do this in one go.
PS: I'm an absolute beginner in programming.
Use itertools.product can simplify the loops a little bits:
import itertools as it
K, M = map(int, input().strip().split())
# reading the K lines and appending lists to 'L'
L = []
for i in range(K):
lst = list(map(int, input().strip().split()))
L.append(lst[1:])
# Looping through Cartesian product
MAX = -1
for i in it.product(*L):
MAX = max(sum(map(lambda x: x**2, i))% M, MAX)
print(MAX)

IndexError: too many indices for array in Scipy.Optimize

I'm trying to debbug some code with Scipy.Optimize.
The bug comes from the constante: the optimisation works fine without it. The constante itself seems to works fine outside scipy.optimize (the variable testconst is computed normally). The code is the following:
from scipy.optimize import minimize
import numpy as np
def totaldist(dy):
n = np.shape(dy)[0]
temp = 0
for i in range(n):
temp += dy[i] ** 2
return -0.5 * temp
def create_bond(dy_max):
n = np.shape(dy_max)[0]
bond = np.zeros((n, 2))
for i in range(n):
bond[i, :] = [0, dy_max[i]]
tot = tuple([tuple(row) for row in bond])
return tot
# def create_const(type_x, dx, gamma, P):
def create_const(dy, *args):
arg = np.asarray(args)
n = np.shape(dy)[0]
dx = np.zeros((n, 2))
bnd = np.zeros((n, 2))
# from args to numpy array
type_x = np.zeros(n)
dP = 0
delta1 = np.zeros(n)
delta2 = np.zeros(n)
gamma = np.zeros((n, n))
for i in range(n):
a, b = bndr(arg[0, i])
delta1[i] = arg[0, i + n + 1]
delta2[i] = arg[0, i + 2*n + 1]
dx[i, 0] = (b - a) * dy[i]
gamma = GammaApprox(delta1, delta2, dx[:, 1], dx[:, 0])
d = np.dot(delta2, dx[:, 0])
g = np.dot(dx[:, 0], gamma)
g = np.dot(g, dx[:, 0])
dP = float(arg[0, n])
return d + 0.5 * g - dP
def GammaApprox(delta1, delta2, x1, x2):
n = np.shape(delta1)[0]
gamma = np.zeros((n, n))
for i in range(n):
if x2[i] == x1[i]:
gamma[i, i] = 0
else:
gamma[i, i] = (delta2[i] - delta1[i]) / (x2[i] - x1[i])
return gamma
def GetNewPoint(x1, x2, delta1, delta2, type_x, P):
n = np.shape(delta1)[0]
dmax = np.zeros(n)
dy0 = np.zeros(n)
# create the inequality data and initial points
for i in range(n):
a, b = bndr(type_x[i])
if x2[i] > x1[i]:
dmax[i] = (x2[i] - x1[i])/(b - a)
dy0[i] = 1 / (b - a) * (x2[i] - x1[i]) / 2
else:
dmax[i] = (x1[i] - x2[i])/(b - a)
dy0[i] = 1 / (b - a) * (x1[i] - x2[i]) / 2
bond = create_bond(dmax)
# create the args tuple
arg = ()
# type x
for i in range(n):
arg = arg + (type_x[i],)
# dP
arg = arg + (abs(P[0] - P[1]), )
# delta1
for i in range(n):
arg = arg + (delta1[i], )
# delta1
for i in range(n):
arg = arg + (delta2[i], )
testconst = create_const(dy0, arg)
# create the equality constraint
con1 = {'type': 'eq', 'fun': create_const}
cons = ([con1, ])
solution = minimize(totaldist, dy0, args=arg, method='SLSQP', bounds=bond, constraints=cons, options={'disp': True})
x = solution.x
print(x)
return x
def bndr(type_x):
if type_x == 'normal':
x_0 = -5
x_f = 1.5
if type_x == 'lognorm':
x_0 = 0.0001
x_f = 5
if type_x == 'chisquare':
x_0 = 0.0001
x_f = (0.8 * (10 ** .5))
return x_0, x_f
def test():
x1 = np.array([0.0001, 0.0001, -5])
x2 = np.array([1.6673, 0.84334, -5])
delta1 = np.array([0, 0, 0])
delta2 = np.array([2.44E-7, 2.41E-6, 4.07E-7])
type_x = np.array(['lognorm', 'chisquare', 'normal'])
P = (0, 6.54E-8)
f = GetNewPoint(x1, x2, delta1, delta2, type_x, P)
return f
test()
the error message is the following:
Traceback (most recent call last):
File "D:/Anaconda Project/TestQP - Simplified/QP.py", line 134, in <module>
test()
File "D:/Anaconda Project/TestQP - Simplified/QP.py", line 130, in test
f = GetNewPoint(x1, x2, delta1, delta2, type_x, P)
File "D:/Anaconda Project/TestQP - Simplified/QP.py", line 103, in GetNewPoint
solution = minimize(totaldist, dy0, args=arg, method='SLSQP', bounds=bond, constraints=cons, options={'disp': True})
File "C:\Program Files\Anaconda\lib\site-packages\scipy\optimize\_minimize.py", line 458, in minimize
constraints, callback=callback, **options)
File "C:\Program Files\Anaconda\lib\site-packages\scipy\optimize\slsqp.py", line 311, in _minimize_slsqp
meq = sum(map(len, [atleast_1d(c['fun'](x, *c['args'])) for c in cons['eq']]))
File "C:\Program Files\Anaconda\lib\site-packages\scipy\optimize\slsqp.py", line 311, in <listcomp>
meq = sum(map(len, [atleast_1d(c['fun'](x, *c['args'])) for c in cons['eq']]))
File "D:/Anaconda Project/TestQP - Simplified/QP.py", line 40, in create_const
a, b = bndr(arg[0, i])
IndexError: too many indices for array
I find roughly similar error in the website like: IndexError: index 1 is out of bounds for axis 0 with size 1/ForwardEuler
...but I failed to see it's really the same problem.
args is not passed to constraint-functions (automatically)!
This is indicated in the docs:
args : tuple, optional
Extra arguments passed to the objective function and its derivatives (Jacobian, Hessian).
You can see the problem easily by adding a print:
def create_const(dy, *args):
print('args:')
print(args)
arg = np.asarray(args)
...
which will output something like:
args:
(('lognorm', 'chisquare', 'normal', 6.54e-08, 0, 0, 0, 2.4400000000000001e-07, 2.4099999999999998e-06, 4.0699999999999998e-07),)
args:
()
ERROR...
If you remove your test (which is manually passing args; which works) testconst = create_const(dy0, arg), you will see only the non-working output:
args:
()
ERROR...
Constraints have their own mechanism of passing args as described in the docs:
constraints : dict or sequence of dict, optional
Constraints definition (only for COBYLA and SLSQP). Each constraint is defined in a dictionary with fields:
type : str
Constraint type: ‘eq’ for equality, ‘ineq’ for inequality.
fun : callable
The function defining the constraint.
jac : callable, optional
The Jacobian of fun (only for SLSQP).
args : sequence, optional
Extra arguments to be passed to the function and Jacobian.
Equality constraint means that the constraint function result is to be zero whereas inequality means that it is to be non-negative. Note that COBYLA only supports inequality constraints.
In your case:
con1 = {'type': 'eq', 'fun': create_const} # incomplete!
con1 = {'type': 'eq', 'fun': create_const, 'args': (arg,)} # (,)
# to make it behave as needed
# for your code!
This will make it run until some other problem occurs!

Randomizing two lists and maintaining order in Python 3.4

I'm basically asking the exact same question as was asked here, but for Python 3.4.0.
In 3.4.0, this code:
a = ["Spears", "Adele", "NDubz", "Nicole", "Cristina"]
b = [1, 2, 3, 4, 5]
combined = zip(a, b)
random.shuffle(combined)
a[:], b[:] = zip(*combined)
does not work. What is the correct way to do this in 3.4.0?
In python 3, zip returns a zip object (i.e. it's itertools.izip from python 2).
You need to force it to materialize the list:
combined = list(zip(a, b))
If memory was tight, you can write your own shuffle function to avoid the need to create the zipped list. The one from Python is not very complicated
def shuffle(self, x, random=None, int=int):
"""x, random=random.random -> shuffle list x in place; return None.
Optional arg random is a 0-argument function returning a random
float in [0.0, 1.0); by default, the standard random.random.
Do not supply the 'int' argument.
"""
randbelow = self._randbelow
for i in reversed(range(1, len(args[0]))):
# pick an element in x[:i+1] with which to exchange x[i]
j = randbelow(i+1) if random is None else int(random() * (i+1))
x[i], x[j] = x[j], x[i]
Your function could be this:
def shuffle2(a, b):
for i in reversed(range(1, len(a))):
j = int(random.random() * (i+1))
a[i], a[j] = a[j], a[i]
b[i], b[j] = b[j], b[i]
To shuffle an arbitrary number of lists in unison
def shuffle_many(*args):
for i in reversed(range(1, len(args[0]))):
j = int(random.random() * (i+1))
for x in args:
x[i], x[j] = x[j], x[i]
eg
>>> import random
>>> def shuffle_many(*args):
... for i in reversed(range(1, len(args[0]))):
... j = int(random.random() * (i+1))
... for x in args:
... x[i], x[j] = x[j], x[i]
...
>>> a = ["Spears", "Adele", "NDubz", "Nicole", "Cristina"]
>>> b = [1, 2, 3, 4, 5]
>>> shuffle_many(a, b)
>>> a
['Adele', 'Spears', 'Nicole', 'NDubz', 'Cristina']
>>> b
[2, 1, 4, 3, 5]
Change combined = zip(a,b) to combined = list(zip(a,b)). You need a list, not an iterator, in order to shuffle in place.
In Python 3, zip returns an iterator rather than a list, so cast it to a list before shuffling it:
combined = list(zip(a, b))

Resources