#!/usr/bin/python3
# -*- coding: utf-8 -*-
# pylint: disable=import-outside-toplevel
'''Pychemqt, Chemical Engineering Process simulator
Copyright (C) 2009-2023, Juan José Gómez Romera <jjgomera@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.'''
###############################################################################
# Module with utilities:
# - representacion: Function for string representation of float values
# - colors: Function to generate colors
# - exportTable; Save data to a file
# - formatLine: Return a matplotlib line formatting kw
###############################################################################
import os
import random
from math import exp
from tools.qt import tr
[docs]
def representacion(number, fmt=0, total=0, decimales=4, eng=False, tol=5,
signo=False, thousand=False):
"""Function for string representation of float values
Parameters
----------
number : float
number to transform
fmt : mode
0 - fixed point
1 - Significant figures
2 - Engineering format
total : integer
total number of digits
decimales : integer
decimal number
eng : boolean
Use engineering repr for big or small number
tol : integer
Exponent limit to use engineering repr over float normal repr
signo : boolean
Show sign, use to force positive sign
thousand : boolean
Use thousand separator point
Returns
-------
repr : str
String representation
Examples
--------
>>> import math
>>> representacion(math.pi, signo=True)
'+3.1416'
"""
if isinstance(number, str):
return number
if signo:
start = "{:+"
else:
start = "{: "
if thousand:
coma = ",."
else:
coma = "."
if eng and (-10**tol > number
or (-10**-tol < number < 10**(-tol+1) and number != 0)
or number > 10**tol):
fmt = 2
if number == 0:
decimales = 1
if fmt == 1:
string = start+"{}{:d}g".format(coma, decimales)+"}"
elif fmt == 2:
string = start+"{:d}{}{:d}e".format(total, coma, decimales)+"}"
else:
string = start+"{:d}{}{:d}f".format(total, coma, decimales)+"}"
return string.format(number)
[docs]
def colors(number, mix="", scale=False):
"""Function to generate colors
Parameters
----------
number: integer
Number of required colors
mix : str
Name color for mix
scale : boolean
Define output in a scale red-blue
Returns
-------
rgb : list
List with color hexadecimal code
"""
rgb = []
for i in range(number):
if scale:
red = int(255*(i/number))
green = 0
blue = int(255*((number-i)/number))
else:
red = random.randint(0, 255)
green = random.randint(0, 255)
blue = random.randint(0, 255)
if mix:
red_mix = int(mix[1:3], base=16)
red = (red + red_mix) / 2
green_mix = int(mix[3:5], base=16)
green = (green + green_mix) / 2
blue_mix = int(mix[5:], base=16)
blue = (blue + blue_mix) / 2
rgb.append(('#%02X%02X%02X' % (red, green, blue)))
return rgb
[docs]
def exportTable(matrix, fname, ext, title=None):
"""Save data to a spreadsheet file
Parameters
----------
matrix : list
array with data to save
ext : str
name of format to save, with supported csv | ods | xls | xlsx
title : list, optional
list with column title
"""
sheetTitle = tr("pychemqt", "Table")
if fname.split(".")[-1] != ext:
fname += ".%s" % ext
# Format title
header = []
if title:
for ttl in title:
line = str(ttl).split(os.linesep)
if line[-1] != "[-]":
line[-1] = "["+line[-1]+"]"
header.append(" ".join(line))
if ext == "csv":
import csv
with open(fname, 'w') as csvfile:
writer = csv.DictWriter(csvfile, fieldnames=header)
writer.writeheader()
for row in matrix:
kw = {}
for ttl, value in zip(header, row):
kw[ttl] = value
writer.writerow(kw)
elif ext == "ods":
import ezodf
spreadsheet = ezodf.newdoc("ods", fname)
sheets = spreadsheet.sheets
sheet = ezodf.Table(sheetTitle)
sheets += sheet
sheet.reset(size=(len(matrix)+1, len(matrix[0])))
# Add Data
if title:
for i, ttl in enumerate(header):
sheet["%s%i" % (spreadsheetColumn(i), 1)].set_value(ttl)
for j, row in enumerate(matrix):
for i, data in enumerate(row):
sheet["%s%i" % (spreadsheetColumn(i), j+2)].set_value(data)
spreadsheet.save()
elif ext == "xls":
import xlwt
spreadsheet = xlwt.Workbook()
sheet = spreadsheet.add_sheet(sheetTitle)
font = xlwt.Font()
font.bold = True
style = xlwt.XFStyle()
style.font = font
# Add Data
if title:
for i, ttl in enumerate(header):
sheet.write(0, i, ttl, style)
for j, row in enumerate(matrix):
for i, data in enumerate(row):
sheet.write(j+1, i, data)
spreadsheet.save(fname)
elif ext == "xlsx":
import openpyxl
from openpyxl.styles import Font
spreadsheet = openpyxl.Workbook()
sheet = spreadsheet.active
sheet.title = sheetTitle
font1 = Font()
font1.size = 9
font1.bold = True
font2 = Font()
font2.size = 9
# Add Data
if title:
for i, ttl in enumerate(header):
sheet["%s%i" % (spreadsheetColumn(i), 1)] = ttl
sheet["%s%i" % (spreadsheetColumn(i), 1)].style.font = font1
for j, row in enumerate(matrix):
for i, data in enumerate(row):
sheet["%s%i" % (spreadsheetColumn(i), j+2)] = data
sheet["%s%i" % (spreadsheetColumn(i), j+2)].style.font = font2
spreadsheet.save(filename=fname)
else:
raise ValueError(tr(
"pychemqt", "Unsopported format") + " " + ext)
[docs]
def spreadsheetColumn(index):
"""Procedure to convert index column in AAA spreadsheet column namestyle
Parameters
----------
index : integer
index of column start with 0
Returns
-------
key : str
column letter code, ej: A, C
Examples
--------
>>> spreadsheetColumn(5)
'F'
>>> spreadsheetColumn(75)
'BX'
"""
index += 1
letters = ""
while index:
mod = index % 26
index = index // 26
letters += chr(mod + 64)
return "".join(reversed(letters))
[docs]
def SimpleEq(Tc, T, coef):
r"""Common procedure for calculation of simple properties like the
ancillary equation for vapor pressure, saturated densities of liquid
and vapor
The procedure define several equations:
.. math::
\frac{x}{x_r} = 1 + \sum_i N_i\theta^{t_i}
.. math::
\ln\left(\frac{x}{x_r}\right) = \sum_i N_i\theta^{t_i}
.. math::
\ln\left(\frac{x}{x_r}\right) = \frac{T_c}{T}\sum_i N_i\theta^{t_i}
.. math::
\theta = 1 - \frac{T}{Tc}
The coef must define the parameters:
* eq: Index of equation to use
* n: Polinomial parameter
* t: Exponent of tita
Parameters
----------
Tc : float
Critical Temperature, [K]
T : float
Temperature, [K]
coef: dict
Coefficient for correlation
"""
Tita = 1-T/Tc
pr = 0
for n, t in zip(coef["n"], coef["t"]):
pr += n*Tita**t
if coef["eq"] == 1:
pr += 1
if coef["eq"] == 3:
pr *= Tc/T
if coef["eq"] in [2, 3]:
pr = exp(pr)
return pr
[docs]
def refDoc(doi, refs, tab=4):
"""Function decorator used to automatic addiction of References section
to documentation of procedures
Parameters
----------
doi : dict
Dictionary with library references
refs : list
List of number to report in References section
"""
def decorator(f):
f.__doc__ += os.linesep + os.linesep
f.__doc__ += " "*tab + "References" + os.linesep
f.__doc__ += " "*tab + "----------" + os.linesep
for ref in refs:
rf = doi[ref]
f.__doc__ += " "*tab + "[%i]_ %s; %s. %s" % (
ref, rf["autor"], rf["title"], rf["ref"]) + os.linesep
f.__doc__ += os.linesep
return f
return decorator
if __name__ == "__main__":
import math
print(representacion(math.pi*1000, decimales=6, tol=5))
print(representacion(0, decimales=6, tol=1))
# print repr(Configuracion("Density", "DenGas").text())
# print representacion("3232326262")
# print(spreadsheetColumn(55))
# print(colors(5))