"Fossies" - the Fresh Open Source Software Archive

Member "gambas-3.16.3/app/src/gambas3/tips/tips.it.txt" (7 Sep 2021, 16672 Bytes) of package /linux/misc/gambas-3.16.3.tar.bz2:


As a special service "Fossies" has tried to format the requested text file into HTML format (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file.

    1 [WELCOME]
    2 
    3 <p>Benvenuto in <b>Gambas</b> !</p>
    4 
    5 <p><b>Gambas</b> è un ambiente grafico di sviluppo basato su un interprete avanzato 
    6 <i>Basic</i>.</p>
    7 
    8 <p>L'obiettivo di <b>Gambas</b> è quello di permettere di creare programmi potenti 
    9 in maniera facile e veloce. Ma la responsabilità di creare programmi puliti è tutta <i>vostra</>...</p>
   10 
   11 <p>Spero vi piaccia!</p>
   12 
   13 <p align=right>Beno&icirc;t Minisini<br>
   14 <u>g4mba5@gmail.com</u></p><br><br><br>
   15 
   16 
   17 [STARTUP]
   18 
   19 <p>Ogni progetto deve avere una <i>classe di inizio</i>.
   20  Questa classe di inizio deve definire un metodo pubblico <i> (public)</i> e statico <i>(static)</i>
   21  denominato <i>Main</i> senza argomenti, che si comporterà come il metodo di inizio del tuo programma</p>
   22 
   23 <p>Puoi definire la classe di inizio cliccando su di essa con il tasto destro del mouse e selezionando <i>Classe di avvio</i>
   24 nel menù a cascata</p>
   25 
   26 <p>Non è necessario definire un metodo <i>Main</i> in un Form di avvio perché ne esiste già uno predefinito.</p>
   27 
   28 <p>Questo metodo predefinito inizializza il form e lo mostra, come in <i>Visual Basic&trade;</i>.</p>
   29 
   30 
   31 [OPEN]
   32 
   33 <p>L'Istruzione <b>OPEN</b> di <b>Gambas</b> non si comporta nella stessa maniera
   34  che in <i>Visual Basic</i>.
   35  Non ritorna il file come un <i>Integer</i>, ma come un ogetto <i>File</i>.</p>
   36 
   37 <p>In pratica, invece di digitare:</p>
   38 
   39 <pre>DIM handle AS Integer
   40 ...
   41 OPEN "ilmiofile" FOR READ AS #handle</pre>
   42 
   43 <p>Devi digitare :</p>
   44 
   45 <pre>DIM handle AS File
   46 ...
   47 handle = OPEN "ilmiofile" FOR READ</pre>
   48 
   49 
   50 [CATDIR]
   51 
   52 <p>Lo sapevi che puoi concatenare nomi di directory e nomi di file
   53 con l'operatore <b><tt>&/</tt></b>?
   54 Questo operatore aggiunge se necessario la <i>slash</i> ("/") in maniera tale che 
   55 l'indirizzo risultante sia perfetto.</p>
   56 
   57 <p>Per esempio :</p>
   58 
   59 <pre>PRINT "/home/gambas" &/ ".bashrc"
   60 /home/gambas/.bashrc
   61 
   62 PRINT "/home/gambas/" &/ "/tmp" &/ "foo.bar"
   63 /home/gambas/tmp/foo.bar
   64 </pre>
   65 
   66 <p>Non è stupendo ?</p>
   67 
   68 [EXEC]
   69 
   70 <p>Puoi realizzare un file eseguibile di tutto il tuo progetto.
   71  Seleziona <i>Crea eseguibile</i> nel menu  <i>Progetto</i>.</p>
   72 
   73 <p>Quando <b>Gambas</b> crea un file eseguibile, colloca il risultato direttamente
   74 nella directory del tuo progetto e il nome del file eseguibile sarà quello del 
   75 tuo progetto</p>
   76 
   77 
   78 [PATH]
   79 <p>
   80 I percorsi relativi hanno un significato speciale in <b>Gambas</b>.
   81 Sono sempre riferiti a file dentro il tuo progetto.
   82 <p>
   83 Non c'è il concetto di <i>directory corrente</i>, e nessuna parola chiave come
   84 <tt>CHDIR</tt> per cambiarla.
   85 <p>
   86 <b>Attenzione:</b> devi usare i percorsi relativi solo per accedere ai file di 
   87 progetto, perché i percorsi assoluti non funzioneranno quando crei l'eseguibile.
   88 
   89 
   90 [GLOBAL]
   91 
   92 Non ci sono <u>variabili globali</u> in <b><i>Gambas</i></b>!
   93 <p>
   94 Come sostituto, dichiarale nel modulo principale come <tt>PUBLIC</tt>.
   95 <p>
   96 Se non hai un modulo principale nel tuo progetto, ma un form principale, 
   97 allora dichiarale come <tt>STATIC PUBLIC</tt>.
   98 <p>
   99 Per accedere a queste variabili, devi usare il nome del modulo principale
  100 o form: <tt>MyMainModule.MyGlobalVariable</tt> o
  101 <tt>MyMainForm.MyGlobalVariable</tt>.
  102 
  103 [EMPTY]
  104 
  105 <p>Per sapere se una stringa è vuota non è necessario usare la funzione <b>Len()</b> .
  106  Puoi direttamente testare la stringa, visto che una stringa vuota è <b>FALSE</b> e una non vuota è <b>TRUE</b>.</p>
  107 
  108 <p>Per esempio, invece di :</p>
  109 
  110 <pre>IF Len(Lamiastringa) > 0 THEN ...
  111 IF Len(Lamiastringa) = 0 THEN ...</pre>
  112 
  113 <p>Puoi fare :</p>
  114 
  115 <pre>IF Lamiastringa THEN ...
  116 IF NOT Lamiastringa THEN ...</pre>
  117 
  118 
  119 [TRANSLATE]
  120 
  121 <h3>Traduzione</h3>
  122 
  123 <p>Le applicazioni Gambas sono completamente traducibili, a condizione
  124 che tu dica quali stringhe devono essere tradotte e quali no.</p>
  125 <p>Per contrassegnare le stringhe come traducibili, racchiudile tra parentesi tonde:<p>
  126 
  127 <pre>Print ("Traducimi")
  128 Print "Non tradurmi!"</pre>
  129 
  130 
  131 [SUBST]
  132 
  133 <h3>Subst$</h3>
  134 
  135 <p>La funzione <b><tt>Subst$()</tt></b> è molto utile per internazionalizzare la tua applicazione.</p>
  136 
  137 <p>Ci vogliono almeno due argomenti. Il primo è la maschera di testo su cui si applica la sostituzione.
  138 Gli altri sono gli argomenti di sostituzione, numerati a partire da uno.</p>
  139 
  140 <p>Ogni modello <tt>&X</tt> nella stringa di sostituzione verrà sostituito dall'argomento di sostituzione X.
  141 Per esempio:</p>
  142 
  143 <pre>Print Subst(("Sostituzione di &1, &2 e &3"),
  144   "primo", "secondo", "terzo")
  145 
  146 &rarr; Sostituzione di primo, secondo e terzo</pre>
  147 
  148 [EVENT]
  149 
  150 <p>Tutti i controlli e tutti gli oggetti che possono avere eventi,
  151  hanno un <i>Osservatore di eventi</i> e un <i>nome di gruppo</i> del evento.</p>
  152 
  153 <p>L'osservatore di eventi coglie tutti gli eventi prodotti dall'oggetto,
  154  e il nome del gruppo del evento è il prefisso del procedimento incaricato di gestire l'evento.</p>
  155 
  156 <p>Di default, questo osservatore di eventi è l'oggetto dove si è creato il controllo,
  157  e il nome di gruppo è il nome del controllo.</p>
  158 
  159 <p>In questo modo, un form riceve tutti gli eventi prodotti dai controlli che tu ci hai creato dentro.</p>
  160 
  161 <pre>' Gambas form
  162 
  163 DIM hButton AS Button
  164 
  165 PUBLIC SUB _new()
  166 &nbsp;&nbsp;...
  167 &nbsp;&nbsp;hButton = NEW Button(ME) AS "Ilmiopulsante"
  168 &nbsp;&nbsp;...
  169 END
  170 
  171 PUBLIC SUB Ilmiopulsante_Click()
  172 &nbsp;&nbsp;...
  173 END
  174 </pre>
  175 
  176 
  177 [GROUP]
  178 
  179 <p>Tutti i controlli hanno una proprietà <i>(Group)</i>.
  180  Quando questa proprietà è utilizzata, il prefisso del gestore di eventi è il nome del
  181  gruppo e non il nome  del controllo.</p>
  182 <p>Supponiamo di avere un <i>Button</i> chiamato <b>btnAzione</b> con il gestore di eventi <i>Click</i>
  183 seguente :</p>
  184 
  185 <pre>PUBLIC SUB btnAzione_Click()</pre>
  186 
  187 <p>Se definisci la proprietà <i>(Group)</i> di <b>btnAzione</b> come <i>IlMioGruppo</i>,
  188  Allora il gestore di eventi che riceverà gli eventi del pulsante sarà il seguente:</p>
  189 
  190 <pre>PUBLIC SUB IlMioGruppo_Click()</pre>
  191 
  192 <p>Questa proprietà permette di gestire vari eventi con una semplice funzione.
  193  E i controlli dello stesso gruppo non devono per forza essere dello stesso tipo !!!</p>
  194 
  195 <p><b>Nota :</b> I veterani del vecchio <i>Visual Basic</i> riconosceranno il concetto di <i>control array</i>,
  196  soltanto che qui viene implementato in un modo più potente. :-)</p>
  197 
  198 
  199 [FORM]
  200 
  201 <p>Un form è l'osservatore di eventi di se stesso, in questo modo puoi gestire direttamente i suoi eventi (<i>Resize</i>, <i>Activate</i>, ...)
  202 dentro il codice della sua stessa classe.</p>
  203 
  204 <p>In questo modo, i nuovi arrivati da <i>Visual Basic</i> non si sentiranno persi :-).</p>
  205 
  206 
  207 [EMBED]
  208 
  209 <p>Con <b><i>Gambas</i></b> puoi fare in modo che qualsiasi form venga
  210 racchiuso in un altro form!</p>
  211 
  212 <p>Per fare una cosa così utile devi soltanto inizializzare il form passando 
  213 un contenitore padre come ultimo argomento nel costruttore.</p>
  214 
  215 <p>Per esempio :</p>
  216 <p><tt>DIM hForm AS MyDialog<br>
  217 DIM hSuperControl AS MyForm<br><br>
  218 ' Crea un dialogo<br>
  219 hForm = NEW MyDialog<br>
  220 ' Inserisce un form in questo dialogo<br>
  221 ' Nota che questo form riceve due parametri prima del contenitore<br>
  222 hSuperControl = NEW MyForm(Param1, Param2, MyDialog)<br>
  223 ' Muove e ridimensiona il form<br>
  224 hSuperControl.Move(8, 8, 128, 64)</tt><br>
  225 
  226 <p>Ricorda che: un form racchiuso in un altro continua ad essere un form
  227  e quindi osservatore di eventi di se stesso.</p>
  228 
  229 
  230 [TAG]
  231 
  232 <p>Tutti i controlli hanno una proprietà chiamata <i>Tag</i>
  233  Questa proprietà è pensata per essere usata dai programmatori e può contenere qualsiasi dato 
  234 <b>VARIANT</b> che credi utile.</p>
  235 
  236 <p>Questo è molto utile quando vuoi differenziare controlli dello stesso gruppo nello stesso gestore di eventi.</p>
  237 
  238 
  239 [LAST]
  240 
  241 <p>La parola chiave <b>LAST</b> ritorna l'ultimo controllo che ha ricevuto un evento.
  242  E' molto utile quando vuoi scrivere un gestore di eventi 
  243 che sia indipendente dal nome del controllo.</p>
  244 
  245 <p>Supponiamo di voler scrivere un programma calcolatrice.
  246  Hai definito dieci pulsanti, uno per ogni numero e tutti con lo stesso <i>group</i> "Digit".
  247  Il valore del <i>Tag</i> di ogni controllo sarà il numero visualizzato da ogni pulsante.
  248  Il tuo gestore di eventi sarà più o meno così :</p>
  249 
  250 <p><tt>PUBLIC SUB Digit_Click()<br><br>
  251 &nbsp;&nbsp;Display = Display & LAST.Tag<br>
  252 &nbsp;&nbsp;RefreshDisplay<br><br>
  253 END</tt></p>
  254 
  255 
  256 [LEFT]
  257 
  258 <p>Le famose routine <b>Left$</b>, <b>Right$</b>, <b>Mid$</b> di <i>BASIC</i>
  259  hanno un comportamento molto utile in <b><i>Gambas</i></b>.</p>
  260 
  261 <p>Il secondo parametro di <b>Left$</b> e <b>Right$</b> è facoltativo, e per default è pari a uno.</p>
  262 
  263 <p><tt>Left$("Gambas")</tt> ritorna <tt>"G"</tt><br>
  264 <tt>Right$("Gambas")</tt> ritorna <tt>"s"</tt></p>
  265 
  266 <p>Il secondo parametro può essere negativo e in questo caso rappresenta il numero di caratteri da non ritornare.</p>
  267 
  268 <p><tt>Left$("Gambas", -2)</tt> ritorna <tt>"Gamb"</tt><br>
  269 <tt>Right$("Gambas", -2)</tt> ritorna <tt>"mbas"</tt></p>
  270 
  271 <p>Allo stesso modo, il terzo parametro di <b>Mid$</b> può essere negativo,
  272  e quindi rappresentare il numero di caratteri dalla fine della stringa da non ritornare.</p>
  273 
  274 <p><tt>Mid$("Gambas", 2, -2)</tt> ritorna <tt>"amb"</tt>
  275 
  276 
  277 [OBSERVER]
  278 
  279 <h3>Observer</h3>
  280 
  281 <p>La classe <b>Observer</b> ti consente di intercettare tutti gli eventi generati da un
  282 oggetto prima che vengano effettivamente inviati.</p>
  283 
  284 <pre>MyTextBox = New TextBox(Me) As "MyTextBox"
  285 MyObserver = New Observer(MyTextBox) As "MyObserver"
  286 ...
  287 Public Sub MyObserver_KeyPress()
  288   Debug "Got it first"
  289 End
  290 
  291 Public Sub MyTextBox_KeyPress()
  292   Debug "Got it next"
  293 End</pre>
  294 
  295 L'osservatore può annullare l'evento con <tt>Stop Event</tt> per prevenire l'oggetto dal 
  296 sollevarlo effettivamente.
  297 
  298 
  299 [STRING]
  300 
  301 <h3>UTF-8 Strings</h3>
  302 
  303 <p><b>Gambas</b> utilizza il set di caratteri <b>UTF-8</b> per rappresentare le stringhe in memoria.
  304 
  305 <p>Ma tutte le funzioni di stringa standard riguardano solo <b>ASCII</b>: 
  306 <tt>Left</tt>, <tt>Mid</tt>, <tt>Right</tt>, <tt>UCase</tt>...
  307 
  308 <p>Se si desidera gestire le stringhe UTF-8, è necessario utilizzare i metodi della classe statica
  309 <b>String</b>, che hanno lo stesso nome delle loro controparti standard.
  310 
  311 <pre>Print Len("bébé");; Left$("bébé", 3)
  312 &rarr; 6 bé
  313 
  314 Print String.Len("bébé");; String.Left("bébé", 3)
  315 &rarr; 4 béb</pre>
  316 
  317 
  318 [ASSIGNMENT]
  319 
  320 <h3>Assegnazioni</h3>
  321 
  322 <p><b>Gambas</b> implementa le scorciatoie di assegnazione a cui i programmatori C / C ++ sono abituati.
  323 
  324 <pre>MyVariable += 2
  325 MyVariable *= 4
  326 MyVariable &= "Great"</pre>
  327 è un equivalente di
  328 <pre>MyVariable = MyVariable + 2
  329 MyVariable = MyVariable * 4
  330 MyVariable = MyVariable & "Great"</pre>
  331 
  332 <p>E così via...
  333 
  334 
  335 [DEBUG]
  336 
  337 <h3>Debug</h3>
  338 
  339 <p>È possibile utilizzare l'istruzione <b><tt>Debug</tt></b> per stampare messaggi di debug sulla
  340 console (ovvero l'output di errore standard). Si comporta esattamente come l'istruzione <tt>Print</tt>.
  341 
  342 <p>Questi messaggi hanno come prefisso il nome della classe, il nome del metodo e il numero di
  343 riga dell'istruzione <tt>Debug</tt>. Se non si desidera il prefisso, è possibile utilizzare 
  344 l'istruzione <b><tt>Error</tt></b> anziché <tt>Debug</tt>.
  345 
  346 <p>I messaggi di debug vengono automaticamente rimossi durante la creazione di
  347 un eseguibile senza eseguire il debug delle informazioni.
  348 
  349 
  350 [TRY]
  351 
  352 <h3>Gestione degli errori (1)</h3>
  353 
  354 <p>La gestione degli errori in <b>Gambas</b> viene eseguita con le seguenti istruzioni: 
  355 <b><tt>Try</tt></b>, <b><tt>Error</tt></b>, <tt>Catch</tt>, and <tt>Finally</tt>.
  356 
  357 <p><tt>Try</tt> prova a eseguire una dichiarazione senza generare un errore. La parola chiave 
  358 <tt>Error</tt> viene utilizzata subito dopo per sapere se l'istruzione è stata eseguita correttamente.
  359 
  360 <pre>Try MyFile = Open "/etc/password" For Write
  361 If Error Then Print "Non posso fare quello che voglio!"</pre>
  362 
  363 
  364 [CATCH]
  365 
  366 <h3>Gestione degli errori (2)</h3>
  367 
  368 <p>La gestione degli errori in <b>Gambas</b> viene eseguita con le seguenti istruzioni: 
  369 <tt>Try</tt>, <tt>Error</tt>, <b><tt>Catch</tt></b>, and <tt>Finally</tt>.
  370 
  371 <p><tt>Catch</tt> indica l'inizio della parte di gestione degli errori di una funzione o procedura.
  372 È messo alla fine del codice della funzione.
  373 
  374 <p>La parte catch viene eseguita quando viene generato un errore tra l'inizio dell'esecuzione della funzione e la sua fine.
  375 
  376 <p>Se viene sollevato un errore durante l'esecuzione della parte catch, l'errore viene propagato normalmente. 
  377 
  378 <pre>Sub ProcessFile(FileName As String)
  379   ...
  380   Open FileName For Read As #hFile
  381   ...
  382   Close #hFile
  383   
  384 Catch ' Eseguito solo se c'è un errore
  385 
  386   Print "Impossibile elaborare il file "; FileName
  387 
  388 End</pre>
  389 
  390 
  391 [FINALLY]
  392 
  393 <h3>Gestione degli errori (3)</h3>
  394 
  395 <p>La gestione degli errori in <b>Gambas</b> viene eseguita con le seguenti istruzioni: 
  396 <tt>Try</tt>, <tt>Error</tt>, <tt>Catch</tt>, and <b><tt>Finally</tt></b>.
  397 
  398 <p><tt>Finally</tt> introduce il codice eseguito alla fine della funzione, anche se viene sollevato un errore durante l'esecuzione. 
  399 
  400 <p>La parte finally non è obbligatoria. Se c'è una parte catch nella funzione, la parte finally deve precederla. 
  401  
  402 <p>Se viene generato un errore durante l'esecuzione della parte finally, l'errore viene propagato normalmente.
  403 
  404 <pre>Sub ProcessFile(FileName As String)
  405   ...
  406   Open FileName For Read As #hFile
  407   ...
  408 Finally ' Viene sempre eseguito, anche se viene sollevato un errore
  409 
  410   Close #hFile
  411   
  412 Catch ' Eseguito solo se c'è un errore
  413   
  414   Print "Impossibile stampare il file "; FileName
  415   
  416 End</pre>
  417 
  418 
  419 [OPTIONAL]
  420 
  421 <h3>Optional</h3>
  422 
  423 <p>Le funzioni e le procedure in <b>Gambas</b> possono avere argomenti opzionali.</p>
  424 
  425 <p>Gli argomenti opzionali vengono semplicemente fatti mettendo la parola chiave <b><tt>Optional</tt></b> subito prima del nome dell'argomento.</p>
  426 
  427 <p>Gli argomenti opzionali possono avere anche un valore predefinito esplicito.</p>
  428 
  429 <pre>Private Sub MyFunction(Param AS String, Optional Optim AS String = "Default")
  430   ...
  431   Print "Necessario: "; param; ", Opzionale: "; optim
  432   ...
  433 End</pre>
  434 
  435 
  436 [ARRAY]
  437 
  438 <h3>For Each</h3>
  439 
  440 <p>In <b>Gambas</b> puoi facilmente scorrere un array, una raccolta o molte altre classi enumerabili con l'istruzione <b><tt>For Each</tt></b>.</p>
  441 
  442 <p>Per esempio:</p>
  443 
  444 <pre>Dim Xml As New XmlDocument
  445 Dim Node As XmlNode
  446 Dim I As Integer
  447 
  448 ' Apre un file XML
  449 Xml.Open("pokus.xml")
  450 ' I children sono indicizzati tramite [i], poiché si tratta di un array
  451 For I = 0 To Xml.Root.Children.Count - 1
  452   ' Gli attributi vengono ciclati tramite For Each, poiché si tratta di una collection
  453   For Each Node In Xml.Root.Children[i].Attributes
  454     Print Node.Name;; Node.Value
  455   Next
  456 Next</pre>
  457 
  458 
  459 [ICON]
  460 
  461 <h3>Icone di default</h3>
  462 
  463 <p>Puoi utilizzare le icone incorporate per una migliore GUI della tua applicazione, le icone sono disponibili in diverse dimensioni predefinite 
  464 (<tt>"small"</tt>, <tt>"medium"</tt>, <tt>"large"</tt>,...) o in dimensioni assolute (da 16x16 a 256x256).</p>
  465 
  466 <p>Per esempio:
  467 
  468 <pre>Image1.Picture = Picture["icon:/32/warning"]
  469 Image2.Picture = Picture["icon:/small/error"]
  470 </pre>
  471 
  472 <p><b>Attenzione:</b> è richiesto il componente <tt>gb.form</tt>.
  473 
  474 
  475 [SETTINGS]
  476 
  477 <h3>Settings</h3>
  478 
  479 <p>Se hai bisogno di memorizzare la configurazione del tuo programma (come la geometria dei tuoi form), allora sei un ragazzo fortunato. In <b>Gambas</b> è molto semplice ed elegante. :-)
  480 
  481 <p>Per salvare la posizione di un form:
  482 <pre>Settings.Write(TheForm)</pre>
  483 
  484 <p>Per richiamarlo:
  485 <pre>Settings.Read(TheForm)</pre>
  486 
  487 Per salvare qualsiasi impostazione:
  488 <pre>Settings["Slot/Key"] = Value</pre>
  489 
  490 E per rileggerne le impostazioni:
  491 <pre>Value = Settings["Slot/Key", DefaultValue]</pre>
  492 
  493 Queste impostazioni sono memorizzate nel file <tt>~/.config/gambas3/&lt;MyApplication&gt;.conf</tt>,
  494 dove <tt>&lt;MyApplication&gt;</tt> è il nome del tuo progetto.
  495 
  496 <p><b>Attenzione:</b> è richiesto il componente <tt>gb.settings</tt>.
  497 
  498 
  499 [EDITOR]
  500 
  501 <p>Ecco alcuni suggerimenti per l'editor...</p>
  502 
  503 <h3>Due tipi di commenti</h3>
  504 
  505 <pre>' Commento normale</pre>
  506 <b><pre>'' Commento in grassetto</pre></b>
  507 
  508 <p>I commenti in grassetto sono usati per documentare il tuo codice.</p>
  509 
  510 <h3>Come utilizzare i frammenti di codice</h3>
  511 
  512 <p>Digita <tt>main</tt> quindi il tasto <b>TAB</b>. Una funzione statica e pubblica di avvio <tt>Main</tt> viene automaticamente inserita nel codice.
  513 
  514 <p>Digita <tt>ds</tt> quindi il tasto <b>TAB</b>. Una dichiarazione locale di variabile stringa viene inserita automaticamente ed è possibile digitare immediatamente il nome della variabile.
  515 
  516 <p>I frammenti di codice sono completamente configurabili dalla finestra di dialogo Preferenze del menu Strumenti dell'IDE.
  517 
  518 
  519 [END]
  520 
  521 <p>Hai letto tutti i suggerimenti del giorno. Spero che ora tu sia un esperto di <b>Gambas</b> ! :-)</p>
  522 
  523 <p>Se vuoi contribuire, invia i nuovi consigli al seguente indirizzo :</p>
  524 <p><u>user@lists.gambas-basic.org</u></p>
  525 
  526 <p>Grazie in anticipo !</p> 
  527