dissabte, 7 de juliol del 2012

La web de Bankinter dia 7 de juliol a les 16:30:



Answer:  The oerr utility says this about the ORA-00257 error:
ORA-00257: archiver error. Connect internal only, until freed.

Cause: The archiver process received an error while trying to archive a redo log. If the problem is not resolved soon, the database will stop executing transactions. The most likely cause of this message is the destination device is out of space to store the redo log file.

divendres, 8 de juny del 2012

Càrrega i anàlisi datamart de la despesa

Captures de pantalla projecte datamart econòmic de comptabilitat pressupostària

Càrrega amb SSIS

Anàlisi amb Tableau


diumenge, 15 d’abril del 2012

Pujar aplicació MVC 3 a Dinahosting

Conservo un compte a dinahosting degut al concurs webs al punt. Avui he pujat una BDD i una Aplicació Web (MVC 3). El procediment no és complicat:

  • La base de dades es crea des del taulell de control de dinahosting, dresprés t'hi pots connectar a ella des de l'SQLServer Management Studio. Cap problema. El nom de servidor me'l van dir des de dinahosting pel chat de suport.
  • Per pujar l'aplicació primer has de declarar una aplicació ASP.NET (des del taulell de control), després puges l'aplicació des del propi assistent de visual studio via FTP (cal haver fet un compte FTP).

Aquí està l'aplicació  http://www.joincar.cat/a/search/go :


De pas publico la caxonda consulta LINQ per obtenir les dades i el model de dades:






dijous, 5 d’abril del 2012

LightSwitch Custom Control: Tree lookup Operations

Here the second part of treeview custom control. This include lookup operations:


See also:

LightSwitch Custom Control: Tree CRUD Operations

For a recent project I have developed a treeview lightswitch custom control to edit a tree structure.
Here I share the code to do CRUD+CutAndPaste operations over a generic tree. I have also documented this tree sample project.




I will post a second part of project with tree lookups operations.

Don't forget to write a comment if this code us useful for you.

( Thanks to Karol Zadora )

diumenge, 2 d’octubre del 2011

django: moving business rules from views and forms to model

Since django 1.2 it is able to write validation code on model. When we work with modelforms, instance.full_clean() is called on form validation. But this code is not execute on save() method:

Note that full_clean() will not be called automatically when you call your model’s save() method, nor as a result of ModelForm validation. 

For this reason, I alltimes call clean() model method before save model. I invoke this call trhough pre_save signal.

For more business rules issolation, I write all them in a separate python module: rules.py.

This is models.py ---------------------------------------------------------------

from django.db import models

class Issue(models.Model):
    ....

    def clean(self):
        rules.Issue_clean(self)


from issues import rules
rules.connect()

This is rules.py ---------------------------------------------------------------

from issues.models import Issue


def connect():
    from django.db.models.signals import post_save, pre_save, pre_delete
    #issues
    pre_delete.connect(Issue_pre_delete, sender= Incidencia)
    pre_save.connect(Issue_pre_save, sender = Incidencia )
    post_save.connect(Issue_post_save, sender = Incidencia )


def Incidencia_clean( instance ):
    import datetime as dt

  errors = {}
    #dia i hora sempre informats    
    if not instance.dia_incidencia:
        errors.setdefault('dia_incidencia',[]).append(u'Falten Dades: Cal dia i franja')
       
    #dia i hora sempre informats    
    if not  instance.franja_incidencia:
        errors.setdefault('franja_incidencia',[]).append(u'Falten Dades: Cal dia i franja')
    #Només es poden posar incidències més ennlà de 7 dies
    if instance.dia_incidencia < ( dt.date.today() + dt.timedelta( days = -7) ):
        errors.setdefault('dia_incidencia 1',[]).append(u'''No es poden posar o modificar incidències amb més d' una setmana)''')
    #No incidències al futur.
    if instance.getDate() > datetime.now():
        errors.setdefault('dia_incidencia 2',[]).append(u'''Encara no pots posar incidències en aquesta classe. Encara no s'ha realitzat.''')
     
    #No incidencies alumne que és baixa:
    if instance.alumne.data_baixa is not None and instance.alumne.data_baixa < instance.dia_incidencia:
        errors.setdefault('dia_incidencia 3',[]).append(u'''L'alumne estava de baixa en aquesta data.''')
    if len( errors ) > 0:
        raise ValidationError(errors)


def Issue_pre_save(sender, instance, **kwargs):
    instance.clean()




In order to show errors on form, you should include this on form template:


{% if form.non_field_errors %}
      {% for error in form.non_field_errors %}
        {{error}}

      {% endfor %}
{% endif %}  

The reason is that model validation erros ara binded to non_field_errors error dictionary entry.

When you save or delete a model out of a form:


    try:
        issue.delete()
    except ValidationError, e:
        import itertools
        errors = list( itertools.chain( *e.message_dict.values() ) )


To add errors to a form dictionary on no modelforms:


        try:
            #provoco els errors per mostrar-los igualment al formulari.
            issue.clean()
        except ValidationError, e:
            form._errors = {}
            for _, v in e.message_dict.items():
                form._errors.setdefault(NON_FIELD_ERRORS, []).extend(  v  )


You can see samples on ghap project source code.

Here some samples:







dimecres, 21 de setembre del 2011

diumenge, 18 de setembre del 2011

Lightswitch TreeView Custom Control

Deprecated: GO TO  http://beutil.blogspot.com.es/2012/04/lightswitch-custom-control-tree-loojup.html
------------------------------------------

I have wrote 2 kinds of trees; lookup tree and screen tree.

First one is intended to replace combo lookup and the second to manage a large data tree.

You can download source code.

Thanks to Karol Zadora

Screen shots:

Lookup tree:




Screen Tree



dimarts, 26 de juliol del 2011

Si els cotxes els dissenyessim els informàtics

Una empresa d'automòbils vol dotar als seus vehicles d'un sistema automàtic d'encesa de llums quan les circumstàncies ambientals així ho requereixin.

L'informàtic aplica la enginyeria informàtica que ha aprés. Decideix fer la fase d'anàlisi. Aquí no hi ha usuari així que passem directament a la normativa legal vigent:

ARTÍCULO 100. Alumbrado de largo alcance o carretera


1. Todo vehículo equipado con luz de largo alcance o carretera que circule a más de 40 kilómetros por hora, entre el ocaso y la salida del sol, fuera de poblado, por vías insuficientemente iluminadas ....


... 3. Se entiende por vía insuficientemente iluminada aquella en la que, con vista normal, en algún punto de su calzada, no pueda leerse la placa de matricula a 10 metros o no se distinga un vehículo pintado de oscuro a 50 metros de distancia.

Ja està clar:

While clauEnContacte() {
   bool noLlegeixPlaca = comprovaPlacaCotxeDavant( 10 );
   bool noVeigVehicleFosc = ! hiHaVehicleFosc( 50 );
   cotxe.llumsEncessos = noLlegeixPlaca || noVeigVehicleFoscA50metres;
}

L'informàtic aplicant la seva lògica informàtica, decideix prescindir de la segona condició, per què? Si ets informàtic ja ho sabràs i si no ho ets t'ho explico: perquè no pot discernir entre que el vehicle no hi sigui o no el vegi (i per tant a de portar els llums encesos a no ser que hi hagi un vehicle fosc a menys de 50 metres). Com veieu també ha decidit parametritzar els metres (10 i 50) per si canvia la normativa.


While clauEnContacte() {
   bool noLlegeixPlaca = comprovaPlacaCotxeDavant(10);
   cotxe.llumsEncessos = noLlegeixPlaca;
}

Llavors decideix que s'ha d'esforçar més en la primera condició: ha ce comprovar si realment aconsegueix llegir [ al menys una matrícula | totes les matricules ] dels cotxes a menys de 10 metres:

bool comprovaPlacaCotxeDavant( int metres, bool comprovaTotsElsCotxes )

L'informàtic anota la necessitats mínimes de programari i maquinari:
* Linux
* Pentium IV amb 2 gigas de RAM
* Motion (per fer la foto de les matrícules)
* gcc (Compilador de C)
* OpenCV

La idea és la següent:
El motion captura una imatge d'alguna cosa que es mogui, un procés escrit amb C aïlla els cotxes i les matrícules gràcies a la llibreria OpenCV (http://blog.damiles.com/2008/11/basic-ocr-in-opencv/). Amb aquesta mateixa llibreria podem saber la distància del cotxe per la mida de les lletres de la matrícula.

Motion ---> Imatge ---> OpenCV ---> matricula.txt

L'informàtic se n'adona que el procés triga una mica així que decideix fer-lo asíncron:

//Prototipus
void callbackMatricula( bool noLlegeixPlaca );
...


while clauEnContacte() {
   comprovaPlacaCotxeDavant( callbackMatricula );
}


void callbackMatricula( bool noLlegeixPlaca ) {
   cotxe.llumsEncessos = noLlegeixPlaca;
}

Per últim l'informàtic se n'adona que està sempre donant per bona la lectura de l'OCR. Llavors amplia les especificacions de maquinari i programari:
* Modem i targeta 3g.
* Oracle 11g.

Crea un servi de captchas on són els propis usuaris Internet qui validen les matrícules dels cotxes. Per tant, a cada lectura li posa un Id i quan rep la lectura de l'OCR la compara amb la lectura del Captcha.

L'informàtic crea els serveis Web necessaris per pujar matrícula i comprovar matrícula.
L'informàtic amplia l'algorisme:


void comprovaPlacaCotxeDavant( void *callbackMatricula ) {
  foto = recull_foto_motion();
  GUID id = system.GUID.newGuid();
  strMatricula = openCV_matricula( foto );


  oracle( "insert into matricules( id, resultatCatcha, resultatOCR) values ('%1',Null,'%2')", id, strMatricula );
  pujaMatriculaCatcha( id, matricula, callbackMatriculaCatcha );
}


void callbackMatriculaCatcha( int id, strMatricula ) {
  recorset = Oracle( "Select * from matricules where id='%1' and resultatOCR='%2'", id, strMatricula);
  callbackMatricula( recorset == Nil );
}
Conclusió: No falleu els catches o provocareu un accident per enlluernament.

dissabte, 23 de juliol del 2011

Silverlight Application Navigation "Menú"

Al fer una nova solució Silverlight Application Navigation l'IDE ens prepara un projecte amb un petit menú amb dues Opcions: Home i About.

Si la nostra aplicació no té gaires 'pages' en podem tenir prou, però si en té moltes llavors necessitem un menú.

Una manera fàcil de fer un menú és amb un TabControl:

Per fer-ho cal:

A la MainPage.xaml posar els HiperLinkButtons dins un TabControl:


Modificar el codi MainPage.xalm.vb per tal que busqui els HyperLinkButtons dins el TabControl:


Private Sub ContentFrame_Navigated(ByVal sender As Object, ByVal e As NavigationEventArgs) Handles ContentFrame.Navigated
        Dim i = TabItemTaulesMestre.Content


        'Poso tots els links en una única llista
        Dim uiList As New List(Of UIElement)
        For Each tabItem In TabControlMenu.Items
            Dim tab = DirectCast(tabItem, TabItem)
            Dim GridItem = DirectCast(tab.Content, System.Windows.Controls.Grid)
            Dim linkStackPanelItem = DirectCast(GridItem.Children.Item(0), System.Windows.Controls.StackPanel)
            For Each child As UIElement In linkStackPanelItem.Children
                uiList.Add(child)
            Next
        Next


        For Each child As UIElement In uiList
            Dim hb As HyperlinkButton = TryCast(child, HyperlinkButton)
            If hb IsNot Nothing AndAlso hb.NavigateUri IsNot Nothing Then
                If hb.NavigateUri = e.Uri Then
                    VisualStateManager.GoToState(hb, "ActiveLink", True)
                Else
                    VisualStateManager.GoToState(hb, "InactiveLink", True)
                End If
            End If
        Next
    End Sub




Algú coneix una alternativa millor?
Penseu que aquestes estructures clàssiques de menús han de ser substituïdes per un altre tipus de navegació?