#!/usr/bin/env python3
# sym.py

from sympy import *

class Vect(Matrix):
	"""
	Vector Matrix dimensions are n×1
	Vect('x, y, z') is Matrix((x.S, y.S, z.S)) 
	__str__ return '(x, y, z)'
	"""
	def __new__(cls, data):
		v = map(sympify, data.split(','))
		return Matrix.__new__(cls, list(v))	

	def __str__(self):
		return '('+', '.join([f'{x}' for x in self])+')'


def matrix(data):
	"""
	Columns Matrix
	`data` is a string, it is interpreted as a matrix with 
	semicolons separating rows, and commas or spaces separating columns.
	return Matrix
	sympify is applied at all terms

	>>> matrix('1 1 0;0 1 1;1/2 0 1')
	Matrix([
	[  1, 1, 0],
	[  0, 1, 1],
	[1/2, 0, 1]])
	>>> matrix("1 0 1")
	Matrix([[1, 0, 1]])

	"""
	# adapted from numpy defmatrix
	rows = data.split(';')
	newdata = []
	ncols = -1
	for row in rows:
		trow = row.split(',')
		newrow = []
		for col in trow:
			tmp = col.split()
			newrow.extend(map(sympify, tmp))
		if ncols == -1:
			ncols = len(newrow)
		elif len(newrow) != ncols:
			raise ValueError("Rows must the same size")
		newdata.append(newrow)
	return Matrix(newdata)

def cmatrix(data):
	"""
	Columns Matrix
	`data` is a string, it is interpreted as a matrix with 
	semicolons separating columns, and commas or spaces separating rows.
	return Matrix with the given vectors as columns
	sympify is applied at all terms

	>>> matrix('1/2, -1, sqrt(3);0 0 1;1,0 1')
	Matrix([
	[    1/2, 0, 1],
	[     -1, 0, 0],
	[sqrt(3), 1, 1]])Rationals are preserved
	>>> matrix('1/2 0')
	Matrix([
	[1/2],
	[  0]])
	"""

	return matrix(data).T
