I am trying to get the words to appear most often in differents articles. However, I am confronted with the problem of the plural and singular forms of a word.
Table : articles
Id articles
1 <b>Augmentation du nombre de noyades : des pistes d’explications</b><u><br> </u><br/>Paris, le jeudi 12 juin 2019 - Les enquêtes Noyades menées depuis 2002 par Santé publique France ont pour objectifs de recenser l’ensemble des noyades (accidentelles ou non, suivies de décès ou non) et de décrire les caractéristiques des victimes et des circonstances de survenue de ces incidents à des fins de prévention. <br/>Cette enquête est réalisée par questionnaire auprès des services de secours du 1er juin au 30 septembre en France métropolitaine et en Outre-mer. <br/>La dernière enquête a permis de recenser, en 2018, 1 960 noyades dont 30% (597/1 960) ont été suivies de décès. Parmi l’ensemble de ces noyades, 84% (1 649/1 960) étaient d’origine accidentelle, 8% (149/1 960) intentionnelles (tentatives de suicide, suicide ou agression) et 8% (162/1 960) étaient d’origine inconnue. <br/>Les investigateurs se sont plus particulièrement penchés sur les 1 649 noyades accidentelles (dont 25% à l’origine de décès) ces événements ayant augmenté de 30% par rapport à l’enquête de 2015 (1 266) sans qu’on assiste pour autant à une hausse des décès (entre 400 à 500 en moyenne chaque année). <br/><b>La canicule sur le banc des accusés</b><br/>Un premier facteur d’explication de cette forte augmentation des noyades « <i>est le contexte de fortes chaleurs durant la période de l’enquête</i> » soulignent les auteurs de ces travaux publiés dans le Bulletin épidémiologique hebdomadaire. Une étude canadienne a ainsi déjà montré que, sur la période 1999-2009, les températures excédant 30 °C étaient associées à une augmentation de 69% du risque de noyade en extérieur. Or, l’été 2018 a été classé par Météo-France comme le deuxième été le plus chaud depuis 1900. <br/><b>La noyade sèche : un concept faux qui fausse les chiffres</b><br/>Autre facteur explicatif pour les auteurs, la médiatisation depuis quelques années, et particulièrement depuis 2017, du concept de noyade «<i> sèche </i>» (noyade qui interviendrait plusieurs heures, voire plusieurs jours après une activité de baignade) qui ne repose sur aucune réalité scientifique mais qui a pu entraîner une sollicitation plus élevée des services de secours par des parents inquiets à la suite d’un début de noyade d’un enfant. <br/>Autre hypothèse, chez les moins de 6 ans, près des trois-quarts (73%) des noyades accidentelles ont eu lieu en piscine privée familiale. Or, la multiplication de piscines privées hors sol, dépourvues de système de sécurité pourrait être une explication à l’augmentation constatée. <br/><b>Un biais statistique ? </b><br/>Les auteurs soulignent en outre « <i>nous ne pouvons exclure que l’utilisation des données du réseau Oscour</i>® <i>pour la première fois lors de l’enquête 2018 ait pu entraîner une meilleure exhaustivité du recensement des noyades</i> ». Néanmoins, ils tempèrent « <i>Cependant, ceci ne pourrait expliquer qu’une faible partie de l’augmentation du nombre de noyades car lorsque la noyade n’était rapportée que par l’hôpital identifié par les données du réseau Oscour®, elle n’a pas été prise en compte car nous avons considéré que la victime n’avait pas été prise en charge par un service de secours organisé mais avait vraisemblablement été emmenée par un proche</i> ». <br/><b>Xavier Bataille</b></p>
I use this SQL query:
select DISTINCT val, cnt as result from(
select REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE((substring_index(substring_index(t.articles, ' ', n.n), ' ', -1)),',',''),'.',''),'(',''),')',''),'!',''),'?',''),'%',''), '<b>', ' '), '</p>', ' '), '</b>', ' '), '<br/>', ''), '<br>', ''), ',', ' '), '<i>', ' '), '</i>', ' '), '.', ' '), '<u>', ' '), '</u>', ' '), '’', '\''), '*', ' '), '"', ' ') val,count(*) as cnt
from articles t cross join(
select a.n + b.n * 10 + c.n * 100 + 1 as n
from (select 0 as n union all select 1 union all select 2 union all select 3 union all
select 4 union all select 5 union all select 6 union all
select 7 union all select 8 union all select 9
) a cross join
(select 0 as n union all select 1 union all select 2 union all select 3 union all
select 4 union all select 5 union all select 6 union all
select 7 union all select 8 union all select 9
) b cross join
(select 0 as n union all select 1 union all select 2 union all select 3 union all
select 4 union all select 5 union all select 6 union all
select 7 union all select 8 union all select 9
) c
) n
where n.n <= 1 + (length(t.articles) - length(replace(t.articles, ' ', '')))
AND (substring_index(substring_index(t.articles, ' ', n.n), ' ', -1)) NOT REGEXP '^[0-9]+$'
AND (substring_index(substring_index(t.articles, ' ', n.n), ' ', -1)) NOT REGEXP '>[^<]'
AND (substring_index(substring_index(t.articles, ' ', n.n), ' ', -1)) > ''
AND (substring_index(substring_index(t.articles, ' ', n.n), ' ', -1)) NOT REGEXP '[0-9]'
AND CHAR_LENGTH((substring_index(substring_index(t.articles, ' ', n.n), ' ', -1))) > 2
group by val
order by cnt desc
) as x
ORDER BY `result` DESC
SQL DEMO
What I get :
val result
des 15
noyades 10
...
noyade 6
...
What I want :
val result
noyade 16
des 15
...
So my question is: how can I accumulate the plural and singular forms of a word by ignoring the final 's' ?
I would like to replace the words ending with an "s" only if the same word without the final "s" exists
Let's suppose you instead just for the purposes of clarity, extracted all the words into a separate table (it could be a temporary table) called results with a single column named word. I would recommend having an index on column word. Then the following SQL would work:
select word, count(*) from (
select if (word in (
/* all words such as 'noyades' such that 'noyade' also exists */
select distinct sq.word from (
select word, REGEXP_REPLACE(word, '(.*)s', '$1') as edited_word from results
) sq
join results on sq.edited_word = results.word
where sq.word <> edited_word
), REGEXP_REPLACE(word, '(.*)s', '$1'), word) as word from results
) sq
group by word
order by count(*) desc
;
See the following DB-Fiddle
I am trying to get the words to appear most often in different articles while excluding some words that do not interest me.
However, I have a problem with the case sentive, when I exclude the word "ce", I wish that "ce" and "Ce" is excluded but only "ce" is excluded.
Table : articles
Id article
1 <b>Nuit blanche à Lariboisière : les grévistes en arrêt de maladie pour éviter les réquisitions </b><u><br> </u><br/>Paris, le mardi 4 juin 2019 - Les grèves des professionnels de santé ne font généralement pas de bruit. Tout en se déclarant grévistes, les infirmières, médecins, aides-soignants qui souhaitent exprimer leur mécontentement et leurs revendications concernant leurs conditions de travail se contentent généralement de quelques débrayages ponctuels, de grèves administratives et de porter un brassard sur leurs blouses blanches. Cette absence de conséquence directe sur le fonctionnement des services explique que ces mouvements passent souvent inaperçus. Ainsi, même si les colonnes du JIM s’en sont fait régulièrement l’écho ces dernières semaines, les grèves des personnels soignants d’une cinquantaine de services d’urgence français depuis plus d’un mois n’ont guère été relayées. <br/><b>Après une journée de travail, enchaîner la nuit</b><br/>Mais ce matin, la presse nationale ne peut plus ignorer ce phénomène. Hier soir, à l’heure où l’équipe de nuit devait prendre son service aux urgences de l’hôpital Lariboisière, une grande partie des personnels attendus étaient absents. Une vingtaine de personnes selon les syndicats n’ont pas pris leur service. Les réquisitions se sont rapidement révélées impossible : la plupart étaient en effet en arrêt maladie, ce qui empêche le déclenchement de ce type de mesure. Ce sont donc les équipes de jour qui après une première longue période de travail ont dû prendre le relais, multipliant les heures, mettant (peut-être) en péril la sécurité de la prise en charge des patients. <br/><b>Des autorités aux abonnés absents</b><br/>Ce matin, l’information était révélée avec émotion et mettait en lumière d’autres situations périlleuses dans le reste du pays. Ainsi, un interne des urgences de Lons-le-Saunier a raconté au Quotidien du médecin un week-end de l’ascension cauchemardesque, marqué par l’absence de nombreux personnels, médecins comme infirmiers, dont plusieurs en arrêt maladie, alors qu’un mouvement de grève se poursuit dans l’établissement. Bien plus que ses collègues et confrères, le jeune médecin qui est convaincu que les soins délivrés aux patients ont pâti des effectifs réduits et de la fatigue des équipes présentes sur place, blâme les autorités qui n’ont pas su prendre la mesure de la gravité de la situation. L’administration s’est quasiment contenté de s’assurer que les praticiens avaient pu faire face aux urgences, tandis qu’une manifestation sportive potentiellement dangereuse a été maintenue. <br/><b>Que chacun prenne ses responsabilités</b><br/>Pour les syndicats, telle que l’Association des médecins urgentistes de France, si le recours à l’arrêt maladie pour contourner les réquisitions (méthode que l’on avait vu utilisée dans certaines grèves au sein des forces de l’ordre) peut être jugé discutable (il pose notamment la question de la complicité des praticiens prescripteurs de ces arrêts) il témoigne de la souffrance éprouvée par les personnels. « <i>Ce qu’il faut bien comprendre, c’est que la réponse du personnel est liée à l’inconséquence des gens qui nous gouvernent</i> » a ainsi commenté le porte-parole de l’AMUF, le docteur Christophe Prudhomme. Le ministre de la Santé, Agnès Buzyn, interrogée par France Inter a pour sa part estimé que la méthode était un « <i>dévoiement</i> » de « <i>ce qu’est un arrêt maladie. Je pense que ce n’est pas bien car ça entraîne une surcharge de travail pour les autres</i> » a-t-elle observé. Alors que ce jugement sera sans doute critiqué, le ministre a encore tenu à rappeler que les discussions avec les urgentistes avaient été nombreuses et que des sommes importantes avaient déjà été débloquées. Elle a en outre considéré que la crise des urgences était principalement liée à la difficulté pour les Français de pouvoir consulter un médecin en ville (ce qui sera probablement commenté par les représentants des médecins libéraux). Elle a d’ailleurs enjoint les Français à différer le plus possible leurs visites aux urgences. <br/>Mais si la question de la responsabilité des citoyens ne pourra pas être toujours éludée, celle de la fermeture de lits, de la réorganisation de certaines structures et de la vacance de nombreux postes ne le pourra pas plus. <br/><b>Aurélie Haroche </b></p>
Table containing the words to exclude :
Table : exception
Id keyword
1 ce
I use this SQL query:
select DISTINCT val, cnt as result from(
select REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE((substring_index(substring_index(t.article, ' ', n.n), ' ', -1)),',',''),'.',''),'(',''),')',''),'!',''),'?',''),'%',''), '<b>', ' '), '</p>', ' '), '</b>', ' '), '<br/>', ''), '<br>', ''), ',', ' '), '<i>', ' '), '</i>', ' '), '.', ' '), '<u>', ' '), '</u>', ' ') val,count(*) as cnt
from articles t cross join(
select a.n + b.n * 10 + c.n * 100 + 1 as n
from (select 0 as n union all select 1 union all select 2 union all select 3 union all
select 4 union all select 5 union all select 6 union all
select 7 union all select 8 union all select 9
) a cross join
(select 0 as n union all select 1 union all select 2 union all select 3 union all
select 4 union all select 5 union all select 6 union all
select 7 union all select 8 union all select 9
) b cross join
(select 0 as n union all select 1 union all select 2 union all select 3 union all
select 4 union all select 5 union all select 6 union all
select 7 union all select 8 union all select 9
) c
) n
where n.n <= 1 + (length(t.article) - length(replace(t.article, ' ', '')))
AND (substring_index(substring_index(t.article, ' ', n.n), ' ', -1)) NOT REGEXP '^[0-9]+$'
AND (substring_index(substring_index(t.article, ' ', n.n), ' ', -1)) > ''
AND REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE((substring_index(substring_index(t.article, ' ', n.n), ' ', -1)),',',''),'.',''),'(',''),')',''),'!',''),'?',''),'%',''), '<b>', ' '), '</p>', ' '), '</b>', ' '), '<br/>', ''), '<br>', ''), ',', ' '), '<i>', ' '), '</i>', ' '), '.', ' '), '<u>', ' '), '</u>', ' ') NOT IN (SELECT keyword FROM exception)
group by val
order by cnt desc
) as x
ORDER BY `result` DESC
I get list of all the words with their numbers of appearance . The word "ce" is excluded but "Ce" is not excluded.
What I tried:
LOWER(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE((substring_index(substring_index(t.article, ' ', n.n), ' ', -1)),',',''),'.',''),'(',''),')',''),'!',''),'?',''),'%',''), '<b>', ' '), '</p>', ' '), '</b>', ' '), '<br/>', ''), '<br>', ''), ',', ' '), '<i>', ' '), '</i>', ' '), '.', ' '), '<u>', ' '), '</u>', ' ')) NOT IN (SELECT keyword FROM exception)
But that does not work..
My question is therefore, how to exclude a word with the first letter in upper case by inserting in the table of exclusion the word in lower case ?
EDIT
I think, I have found the problem :
With
select (substring_index(substring_index(t.articles, ' ', n.n), ' ', -1)) val,count(*) as cnt
I get :
val result
<i>Ce 2
How can I delete special characters pasted to words?
How about you first convert everything to lower case and then use the REPLACE() function?
This would convert everything to lower case and then you could do the replace
EDIT
Try regex SELECT * from table WHERE colmn_name REGEXP '>[^<]*mytext';
I have a Reportlab form for a billing system and it works good. But what I want to get are the values in sytem local values, with decimal comma, or separator; something as next instead as shown in the picture:
1,350,000.00
I'd like something like FORMAT in MySQL, but the problem with this one is that it does'nt let me to sum the values to get the total because it returns the values as string.
SELECT FORMAT (columna, 'es_CO') FROM tabla;
How my form looks like
And my Python code:
Just retefuente, ivajuridico, rteiva and i_vlrenta are float in mysql
#!/usr/bin/python
#-*- coding:utf-8 -*-
from Tkinter import*
from tkMessageBox import*
import MySQLdb
from controller import *
import analisis_arrendatarios
import os
import datetime
import time
import locale
locale.setlocale(locale.LC_ALL, "")
#LIBRERÍA PLATYPUS DE REPORTLAB PARA CREAR TABLAS
from reportlab.platypus import (SimpleDocTemplate, PageBreak, Image, Spacer,
Paragraph, Table, TableStyle)
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib.pagesizes import letter
from reportlab.lib import colors
styleSheet = getSampleStyleSheet()
style = styleSheet['BodyText']
class Proceso_Fact_Auto_Arre(Frame):
def __init__(self, parent, controller):
Frame.__init__(self, parent)
global opt
#VARIABLES
opt = IntVar()
#WIDGETS
header = Label(self, text="TENANTS AUTO BILLING PROCESS", font="bold")
header.pack(pady=20, side=TOP)
wrapper = Frame (self)
wrapper.pack()
r1 = Radiobutton(wrapper, text="Generate Analysis", variable=opt, value=0).pack(pady=5, anchor=W)
r2 = Radiobutton(wrapper, text="Generate Billings", variable=opt, value=1).pack(pady=5, anchor=W)
Button(wrapper, text="Iniciar Proceso", bg='navy', foreground='white', activebackground='red3', activeforeground='white', command=operacion).pack(pady=5, anchor=W)
def operacion():
if opt.get()==0:
showinfo('Operation', "Generate Analysis")
try:
connect.commit()
#Consulta de códigos y valores de la tabla 'configuracion'
cursor.execute("SELECT cod_canon, cod_subtotalarrend, cod_ivaarrend,
retefuente, ivajuridico, rteiva, resolucion
FROM configuracion;")
dato1 = cursor.fetchall()
#Consulta de datos generales del propietario y el arrendatario para la factura
cursor.execute("SELECT p_cc, dueño, r_carpeta, relacionip.i_cod, i_dir, i_vlrenta, i_tel, contratos.a_cc, inquilino, a_tpersona, a_contribuyente
FROM contratos
INNER JOIN relacionip ON contratos.r_id = relacionip.r_id
INNER JOIN inmuebles ON relacionip.i_cod = inmuebles.i_cod
INNER JOIN arrendatarios ON contratos.a_cc = arrendatarios.a_cc;")
#cursor.execute("SELECT p_cc, dueño, r_carpeta, relacionip.i_cod, i_dir, FORMAT(SUM(i_vlrenta), 2,'es'), i_tel, contratos.a_cc, inquilino, a_tpersona, a_contribuyente
#FROM contratos
#INNER JOIN relacionip ON contratos.r_id = relacionip.r_id
#INNER JOIN inmuebles ON relacionip.i_cod = inmuebles.i_cod
#INNER JOIN arrendatarios ON contratos.a_cc = arrendatarios.a_cc;")
dato2 = cursor.fetchall()
except:
pass
for c in dato1:
canon = c[0]
subtotal = c[1]
iva = c[2]
retef = c[3]
ivajuridi = c[4]
retei = c[5]
resolucion = c[6]
doc = SimpleDocTemplate("facturas/factura_auto_inquilino.pdf", pagesize = (595.27,400.00), rightMargin=5, leftMargin=5, topMargin=10, bottomMargin=0)
story=[]
for i in dato2:
nit = i[0]
prop = i[1]
folder = i[2]
inm = i[3]
loc = i[4]
renta = i[5]
tel = i[6]
cc = i[7]
arrend = i[8]
tipo = i[9]
contri = i[10]
#SI ARREND ES NATURAL(1)
if tipo == 1:
tipo = 0
#SI ARREND ES JURÍDICO(2)
if tipo == 2:
tipo = renta*ivajuridi/100
total = renta+tipo
tiempo = datetime.date.today()
anio = time.strftime("%Y")
mes = time.strftime("%B")
#-------------------------------------------- CABECERA DEL DOCUMENTO
#VARIABLES
logo = Image("img/logo.gif", width=150, height=45) #LOGO
logo.hAlign ='LEFT' #Posicion de la img en la hoja
info = Paragraph('''<para align=center leading=8><font size=6>CALLE 11A N°42-68 LOC,195 ED. EL DORADO<br/>TELEFONO: 3110513 FAX:2664154<br/>AFILIADO A FENALCO<br/>M.A.V.U N°000078</font></para>''', styleSheet["BodyText"])
tipoDoc = Paragraph ('''<para align=right><b>FACTURA DE VENTA<br/>N°</b></para>''', styleSheet["BodyText"])
#TABLA 1
tabla1 = Table([[logo, info, tipoDoc]], colWidths=[200,150,140], rowHeights=None)
tabla1.setStyle([
('VALIGN', (1,0), (2,0), 'TOP'),
('ALIGN', (2,0), (2,0), 'RIGHT')#ALINEAR A LA DER
])
story.append(tabla1) #Construye la tabla 't' definida anteriormente
story.append(Spacer(0,-10)) #Espacio del salto de línea con el siguiente Ejemplo
#-------------------------------------------- DATOS GENERALES DEL DOCUMENTO
#VARIABLES
inquilino = Paragraph ('''<font size=6><b>Nombre Arrendatario:</b><br/></font>%s'''%arrend, styleSheet["BodyText"])
docID = Paragraph ('''<font size=6><b>CC/Nit: </b></font> %s''' %nit, styleSheet["BodyText"])
locImn = Paragraph ('''<font size=6><b>Dirección Inmueble:</b><br/></font>%s'''%loc, styleSheet["BodyText"])
telefono = Paragraph ('''<font size=6><b>Teléfono:</b><br/></font>%s'''%tel, styleSheet["BodyText"])
IDpropietario = Paragraph ('''<font size=6><b>CC/Nit:</b><br/></font>%s'''%cc, styleSheet["BodyText"])
propietario = Paragraph ('''<font size=6><b>Propietario: </b></font>%s'''%prop, styleSheet["BodyText"])
fechaFormato = Paragraph ('''<para align=center fontSize=6>Día Mes Año</para>''', styleSheet["BodyText"])
hoy = time.strftime("%d/%m/%Y")
fecha = Paragraph ('''<para align=center spaceBefore=0>%s</para>''' %hoy, styleSheet["BodyText"])
codigoImn = Paragraph ('''<font size=6><b>Código Inmueble:</b><br/></font>%s'''%inm, styleSheet["BodyText"])
#TABLA 2
datos = [[inquilino,'','','','',[fechaFormato,fecha]],
[docID,'','',propietario,'',''],
[locImn,'',telefono,IDpropietario,'',codigoImn]]
tabla2 = Table(datos,
style=[('BOX',(0,0),(2,2),0.5,colors.black),
('VALIGN', (0,0),(2,0),'TOP'),
('SPAN',(0,0),(2,0)),#Combinar 3 filas (col0,row0) hasta (col2,row0) Arrendatario #0
('SPAN',(0,1),(2,1)),#Combinar 3 filas CC/Nit #1
('SPAN',(0,2),(1,2)),#Combinar 2 filas Dirección #2
('SPAN',(3,1),(5,1)),#Combinar 3 filas Nombre Propietario #
('SPAN',(3,2),(4,2)),#Combinar 2 filas CC/Nit Propietario #
('GRID',(3,1),(4,2),0.5,colors.black),
('GRID',(5,0),(5,2),0.5,colors.black)
],colWidths=[100,90,90,90,80,70], rowHeights=None)
#Constructor y espaciado
story.append(Spacer(0,15)) #Espacio del salto de línea con el siguiente Ejemplo
story.append(tabla2) #Construye la tabla 't' definida anteriormente
#-------------------------------------------- DETALLES DEL DOCUMENTO
#VARIABLES
desc = Paragraph('''<para align=center><b>DESCRIPCION</b></para>''', styleSheet["BodyText"])
vlr = Paragraph('''<para align=center><b>VALOR</b></para>''', styleSheet["BodyText"])
concepto = Paragraph('''Valor Arrendamiento Mes: %s/%s''' % (mes,anio), styleSheet["BodyText"])
resol = "Resolucion Dian N°110000658514 de Diciembre de 2015 Consectivo Facturacion 33001 al 36000. P"
#TABLA 3
data=[[desc, '', vlr], #0
[concepto, '', renta], #1
['', '', ''], #2
['', '', ''], #3
['', '', ''], #4
['', '', ''], #5
['', '', ''], #6
['Observaciones', 'SUBTOTAL', renta], #7
['', 'IVA', tipo], #8
[resolucion, 'TOTAL', total]] #9
#Formato de la tabla
tabla3 = Table(data,
style=[('GRID',(0,0),(2,0),0.5,colors.black),#Color regilla de DESCRIPCION & VALOR
('BOX',(2,1),(2,9),0.5,colors.black), #Color & grosor de la tabla/marco externo de los VALORES
#('BACKGROUND',(0,0),(2,0), colors.pink), #Color de fondo de DESCRIPCION & VALOR #0
('SPAN',(0,0),(1,0)), #Combinar filas DESCRIPCION #0
('BOX',(0,1),(2,6),0.5,colors.black), #Color & grosor de la tabla o marco externo de los DETALLES
('ALIGN', (2,1), (2,1), 'RIGHT'),#Centrar renta #1
('ALIGN', (2,7), (2,7), 'RIGHT'),#Centrar renta #7
('ALIGN', (2,8), (2,8), 'RIGHT'),#Centrar tipo #8
('ALIGN', (2,9), (2,9), 'RIGHT'),#Centrar total #9
#('ALIGN', (2,9), (2,9), 'CENTER'),#Centrar total #9
('SPAN',(0,1),(1,1)), #Combinar filas de Detalle #1
('SPAN',(0,2),(1,2)), #Combinar filas de Detalle #2
('SPAN',(0,3),(1,3)), #Combinar filas de Detalle #3
('SPAN',(0,4),(1,4)), #Combinar filas de Detalle #4
('SPAN',(0,5),(1,5)), #Combinar filas de Detalle #5
('SPAN',(0,6),(1,6)), #Combinar filas de Detalle #6
('GRID',(1,7),(2,9),0.5,colors.black),#Color regilla de SUBTOTAL, IVA, TOTAL
('BOX',(0,7),(0,9),0.5,colors.black), #Color & grosor de la tabla o marco externo de los OBSERVACIONES Y RESOLUCION
('FONTSIZE', (0,9),(0,9),7), #Tamaño de la Resolucion
#('BACKGROUND',(1,9),(1,9),colors.black),#Color de fondo de TOTAL
('TEXTCOLOR',(1,9),(1,9),colors.black), #Color de letra de TOTAL
#('BACKGROUND',(2,9),(2,9),colors.grey)#Color de fondo de VALOR TOTAL
],colWidths=[340,80,100], rowHeights=None)
story.append(Spacer(0,15)) #Espacio del salto de línea con el siguiente Ejemplo
story.append(tabla3) #Construye la tabla 't' definida anteriormente
#-------------------------------------------- FIN PDF
doc.build(story) #Constructor del documento
if sys.platform == 'linux2':
os.system("xdg-open ~/Project/facturas/factura_auto_inquilino.pdf")#DEBIAN
elif sys.platform == 'linux2':
os.system("/usr/bin/gnome-open facturas/factura_auto_inquilino.pdf")#UBUNTU
else:
os.startfile("Project/facturas/factura_auto_inquilino.pdf")#WINDOWS
else:
#Code to insert data into a billinf table)
SELECT FORMAT(SUM(columna), 2, 'es_CO') FROM tabla;
For example:
mysql> SELECT FORMAT(SUM(population), 3, 'es_CO') FROM canada;
+-------------------------------------+
| FORMAT(SUM(population), 3, 'es_CO') |
+-------------------------------------+
| 23584718,000 |
+-------------------------------------+
1 row in set (0.01 sec)
I suspect you wanted something like
| 23.584.718,000 |
Then I suggest you file a bug with bugs.mysql.com . It seems that the 'grouping separator' is incorrect?
Meanwhile, will 'es' (instead if 'es_CO') work correctly enough?
As some guys suggested, what I had to do was: sum the values, which was already done in my code, add a new variable appling a format with 'locale.format', and then just place that variable in the corresponding place in the reportlab form. For the total value it was not necessary to create a new variable, but just apply locate.
So, I added to my code something like this:
for i in dato2:
#...
renta = i[5]
#New var to show value with thousands separator in the form
renta1 = locale.format("%d", renta, grouping=True)
tipo = i[9]
#SI ARREND ES NATURAL(1)
if tipo == 1:
tipo = 0
#New var to show value with thousands separator in the form
tipo1 = locale.format("%d", tipo, grouping=True)
#SI ARREND ES JURÍDICO(2)
if tipo == 2:
tipo = renta*ivajuridi/100
#New var to show value with thousands separator in the form
tipo1 = locale.format("%d", tipo, grouping=True)
total = locale.format("%d", renta+tipo, grouping=True)
#REPORTLAB FORM TABLA 3
data=[[desc, '', vlr], #0
[concepto, '', renta], #1
['', '', ''], #2
['', '', ''], #3
['', '', ''], #4
['', '', ''], #5
['', '', ''], #6
['Observaciones', 'SUBTOTAL', renta], #7
['', 'IVA', tipo], #8
[resolucion, 'TOTAL', total]] #9