Sintaxi del llenguatge IV

De Wikijoan
Dreceres ràpides: navegació, cerca

Contingut

Introducció

Continuem en l'aprenentatge de la sintaxi de Javascrip. JS Advanced de W3Schools.

Referències

Desenvolupament

Els alumnes provaran amb l'ordre proposat algun dels exemples que s'han explicat a classe, i es faran provatures per tal de consolidar els coneixements.

Bateria d'exercicis proposats

(a classe veurem algun d'aquests exercicis)

Object Number

Conversió implícita de valors:

<!DOCTYPE html>
<html>
<body>
<p>A number divided by a string is not a number</p>
<p>A number divided by a numeric string is a number</p>
<p id="demo"></p>

<script>
//var y = 1000 / "1000"; //ho sap interpretar com a número
var y = 1000 / "asd"; //error, de fet dóna NaN
document.getElementById("demo").innerHTML = y + "<br />" + typeof y;
</script>

</body>
</html>

Trobar un número aleatori enter entre 5 i 20, inclosos

var num;

for (var i=0;i<100;i++) {
   num = Math.floor(5 + 16*Math.random()); //recorda que Math.random va del 0 al 0.99999...
   console.log (num);
}

Exercici de classe. Dibuixar la funció sinus, etiqueta canvas (17/10/2018)

Tenim un codi per dibuixar la funció sinus a aquesta url:

Objectiu:

  1. adaptar el codi a una pàgina web pròpia. Ha d'haver-hi tres fitxers: index.html, script.js i css.css
  2. localitzar en el codi el canvas, i els mètodes per poder dibuixar per pantalla.
  3. localitzar en el codi la funció sinus.
  4. En un altre exercici, dibuixar un triangle, un quadrat i un pentàgon.

Solució: Fitxer:Sine.zip

Expressions regulars

Prova aquest tester d'expressions regulars, et pot ser útil:

Exemple d'expressions regulars. regexp.js:

var str="The rain in SPAIN is a pain";
var patt1=/ain/ig;
print(str.match(patt1));

//ara vull introduir el pattern per teclat. Introduir ain
var cad_patt2=readline();
print(cad_patt2);
//new RegExp té dos arguments (dels quals el primer és obligatori, però no el segon)
//el primer és el pattern, i el segon els modificadors. En aquest cas,
//i significa insensible al case, i g fer un global match (trobar tots els valors sense mirar el case)
var patt2 = new RegExp(cad_patt2,"ig");
print(patt2);
print(str.match(patt2));

var patt=/SPAIN/g;
// o bé var ptt=new RegExp ("SPAIN");
var result=patt.test(str);
print(result); //true
var patt=/spain/g;
var result=patt.test(str);
print(result); //false
var patt=/spain/ig;
var result=patt.test(str);
print(result); //true
$ ./js regexp.js 
ain,AIN,ain
ain -> entro pel teclat
ain
/ain/gi
ain,AIN,ain

true
false
true

També hem utilitzat la funció test (http://www.w3schools.com/jsref/jsref_regexp_test.asp):

The test() method tests for a match in a string.

This method returns true if it finds a match, otherwise it returns false.
RegExpObject.test(string)

Un altres exemple:

//http://www.w3schools.com/jsref/jsref_obj_regexp.asp
var text="Què ha de fer el president a partir d'ara? Preguntes i respostes sobre com la pèrdua de suport electoral posa en qüestió el seu lideratge intern i extern i l'obliga a buscar aliances"; 
//comencen per p
var patt=/p[A-z]*\s/g;	
document.getElementById("parr").innerHTML = text.match(patt);

//comencen per P
var patt=/P[A-z]*\s/g;	
document.getElementById("parr").innerHTML = text.match(patt);

//comencen per p o P
var patt=/p[A-z]*\s/ig;	
document.getElementById("parr").innerHTML = text.match(patt);

En el cas /p[A-z]*\s/g significa que estem buscant una p, seguida d'un número indeterminat de lletres, i finalment un espai en blanc que ens determina el final de la paraula.

Fet amb SpiderMonkey:

js> var text="Què ha de fer el president a partir d'ara? Preguntes i respostes sobre com la pèrdua de suport electoral posa en qüestió el seu lideratge intern i extern i l'obliga a buscar aliances"; 
js> 
js> var patt=/p[A-z]*\s/g;  
js> print(text.match(patt));
president ,partir ,postes ,port ,posa

js> var patt=/p[A-z]*\s/gi;
js> print(text.match(patt));  
president ,partir ,Preguntes ,posa 

var patt=/\bp[A-z]*\s/g;  
js> print(text.match(patt)); 
president ,partir ,posa

Exemple codi postal

Validar codi postal. Regles: 5 dígits (ni més ni menys) amb un joc de proves complet.

Recorda:

Idees:

[0-9]
\d 	Find a digit
n{X} 	Matches any string that contains a sequence of X n's

solució:

var patt = /^\d{5}$/;
//var patt = /\d{5}/; -> no és correcte
//joc de proves
print('08025');
print(patt.test('08025')); //true
print('080257');
print(patt.test('080257')); //false
print('0802');
print(patt.test('0802')); //false
print('abcde');
print(patt.test('abcde')); //false
print('08c25');
print(patt.test('08c25')); //false

Codis postals de Barcelona:

var patt = /^08\d{3}$/;
//compte! no liar-se fent:
//var patt = /^[0]{1}[8]{1}\d{3}$/;

Exemple: data dd/mm/yy o dd/mm/yyyy

Un altre exemple. Comprovar que una cadena té el següent format de data: dd/mm/yy o dd/mm/yyyy també dd-mm-yy o dd-mm-yyyy). Els anys poden ser dos o quatre dígits, i el caràcter separador pot ser guió (-) o barra (/).

Solució 1:

print(/^\d{2}[-|/]\d{2}[-|/](\d{2}|\d{4})$/.test("20/88-203"));
console.log(/^\d{2}[-|/]\d{2}[-|/](\d{2}|\d{4})$/.test("20/88-203"));

Joc de proves:

console.log(/^\d{2}[-|/]\d{2}[-|/](\d{2}|\d{4})$/.test("20/88-203")); F
console.log(/^\d{2}[-|/]\d{2}[-|/](\d{2}|\d{4})$/.test("20/88-2034")); V
console.log(/^\d{2}[-|/]\d{2}[-|/](\d{2}|\d{4})$/.test("20/88/20")); V
console.log(/^\d{2}[-|/]\d{2}[-|/](\d{2}|\d{4})$/.test("20/888/2034")); F
console.log(/^\d{2}[-|/]\d{2}[-|/](\d{2}|\d{4})$/.test("2/8/1998")); F

Coses a millorar de la nostra expressió regular:

  1. que admeti un dígit en el dia o mes
  2. que tingui 2 '/' o dos '-'

millorem:

console.log(/^\d\d?[-|/]\d\d?[-|/](\d{2}|\d{4})$/.test("02/80/1998"));

millorem:

console.log(/(^\d\d?[-|/]\d\d?[-|/](\d{2}|\d{4})$|^\d\d?[-|/]\d\d?[-|/](\d{2}|\d{4})$)/.test("02/80/1998"));

Finalment:

console.log(/(^\d\d?\/\d\d?\/(\d{2}|\d{4})$|^\d\d?-\d\d?-(\d{2}|\d{4})$)/.test("02/80/1998"));

Joc de proves:

console.log(/(^\d\d?\/\d\d?\/(\d{2}|\d{4})$|^\d\d?-\d\d?-(\d{2}|\d{4})$)/.test("20/88-2034")); F
console.log(/(^\d\d?\/\d\d?\/(\d{2}|\d{4})$|^\d\d?-\d\d?-(\d{2}|\d{4})$)/.test("2/8/1998")); V
console.log(/(^\d\d?\/\d\d?\/(\d{2}|\d{4})$|^\d\d?-\d\d?-(\d{2}|\d{4})$)/.test("2/8/1998")); V

però

console.log(/(^\d\d?\/\d\d?\/(\d{2}|\d{4})$|^\d\d?-\d\d?-(\d{2}|\d{4})$)/.test("50/88/1998")); V

Encara queda per arreglar que el dia no pugui ser més gran que 31, i que el mes no pugui ser més gran que 12.

Exemple: NIF

Un altre exemple. Detecció d'un NIF:

<!DOCTYPE html>
<html>
<body>
<p id="parr1"></p>
<p id="parr2"></p>
<script>
var text= "35105018A";
//més o menys correcte
var patt = /[0-9]{8}[A-Z]{1}/; // també dóna correcte si faig var text= "aaa35105018A666";
//correcte del tot
//var patt = /^[0-9]{8}[A-Z]{1}$/	
document.getElementById("parr1").innerHTML = text;
document.getElementById("parr2").innerHTML = patt.test(text);
</script>

</body>
</html>

NOTA: Quan volem fer una expressions regulars amb Javascript hem de tenir ben present la referència, per exemple:

doncs a Internet, cercant per expressions regulars, podem tenir informació d'altres implementacions. Per exemple, per parlar d'un cas concret, els alumnes de l'assignatura de SAD (ASIX) estudien el proxy Squid, on es poden ficar regles mitjançant expressions regulars, però en aquest cas la implementació és diferent:

Exemple: Validar NIF, CIF, NIE segons la llei vigent

NOTA. Si copies i enganxes el codi directament de l'anterior enllaç, és possible que et doni un error del codi degut a què hi ha un caràcter especial (un guió normal que no és un guió normal). Això només es pot detectar amb el Firebug, per tant se't recomana que facis servir el Firebug o similar per depurar els errors. També utilitzem console.log() per enviar missatges a la consola, com ara comprovar els valors que tenen les nostres variables.

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
</head>
<body>
<h1>Comprovació del NIF, CIF, NIE</h1>
<p id="parr1">35105018B</p>

<script>
str = document.getElementById("parr1").innerHTML;
//alert(str);
console.log(str);
console.log(valida_nif_cif_nie( str));

//Retorna: 1 = NIF ok, 2 = CIF ok, 3 = NIE ok, -1 = NIF error, -2 = CIF error, -3 = NIE error, 0 = ??? error
function valida_nif_cif_nie( a )
{
	var temp = a.toUpperCase();
	var cadenadni = "TRWAGMYFPDXBNJZSQVHLCKE";
 
	if( temp!= '' )
	{
		//si no tiene un formato valido devuelve error
		if( ( !/^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$/.test( temp ) && !/^[T]{1}[A-Z0-9]{8}$/.test( temp ) ) && !/^[0-9]{8}[A-Z]{1}$/.test( temp ) )
		{
			return 0;
		}
 
		//comprobacion de NIFs estandar
		if( /^[0-9]{8}[A-Z]{1}$/.test( temp ) )
		{
			posicion = a.substring( 8,0 ) % 23;
			letra = cadenadni.charAt( posicion );
			var letradni = temp.charAt( 8 );
			if( letra == letradni )
			{
				return 1;
			}
			else
			{
				return -1;
			}
		}
 
 
		//algoritmo para comprobacion de codigos tipo CIF
		suma = parseInt(a.charAt(2))+parseInt(a.charAt(4))+parseInt(a.charAt(6));
 
		for( i = 1; i < 8; i += 2 )
		{
			temp1 = 2 * parseInt( a.charAt( i ) );
			temp1 += '';
			temp1 = temp1.substring(0,1);
			temp2 = 2 * parseInt( a.charAt( i ) );
			temp2 += '';
			temp2 = temp2.substring( 1,2 );
			if( temp2 == '' )
			{
				temp2 = '0';
			}
 
			suma += ( parseInt( temp1 ) + parseInt( temp2 ) );
		}
		suma += '';
		n = 10 -  parseInt( suma.substring( suma.length-1, suma.length ) );
 
		//comprobacion de NIFs especiales (se calculan como CIFs)
		if( /^[KLM]{1}/.test( temp ) )
		{
			if( a.charAt( 8 ) == String.fromCharCode( 64 + n ) )
			{
				return 1;
			}
			else
			{
				return -1;
			}
		}
 
		//comprobacion de CIFs
		if( /^[ABCDEFGHJNPQRSUVW]{1}/.test( temp ) )
		{
			temp = n + '';
			if( a.charAt( 8 ) == String.fromCharCode( 64 + n ) || a.charAt( 8 ) == parseInt( temp.substring( temp.length-1, temp.length ) ) )
			{
				return 2;
			}
			else
			{
				return -2;
			}
		}
 
		//comprobacion de NIEs
		//T
		if( /^[T]{1}[A-Z0-9]{8}$/.test( temp ) )
		{
			if( a.charAt( 8 ) == /^[T]{1}[A-Z0-9]{8}$/.test( temp ) )
			{
				return 3;
			}
			else
			{
				return -3;
			}
		}
		//XYZ
		if( /^[XYZ]{1}/.test( temp ) )
		{
			temp = temp.replace( 'X','0' )
			temp = temp.replace( 'Y','1' )
			temp = temp.replace( 'Z','2' )
			pos = temp.substring(0, 8) % 23;
 
			if( a.toUpperCase().charAt( 8 ) == cadenadni.substring( pos, pos + 1 ) )
			{
				return 3;
			}
			else
			{
				return -3;
			}
		}
	}
 
	return 0;
}
</script>
</body>
</html>

Exemple amb el format de dates

var text="23-1-2015";
var patt=/[0-9]{1,2}-[0-9]{1,2}-[0-9]{4}/;
print(patt.test(text)); 
var patt=/[0-9]{2}-[0-9]{2}-[0-9]{4}/;
print(patt.test(text)); 
var text="23-01-2015";
print(patt.test(text)); 
var text="23/01/2015";
print(patt.test(text)); 
var patt=/[0-9]{2}[-/][0-9]{2}[-/][0-9]{4}/;
print(patt.test(text)); 

Expressió regular per validar un email

A continuació et dono dos patrons per validar un correu electrònic.

^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$ -> funciona?? crec que no

^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,4})+$ -> funciona?? crec que no...

NOTA: actualment podem tenir noms de dominis de 2, 3, 4 o més caràctes (.es, .cat, .info, .hotel, etc). Aleshores faríem:

[a-zA-Z]{2,}

Hauries d'analitzar el significat de les diferents parts del patró, a partir de la referència. Hauries de dedicar-hi una bona estona si vols entendre correctament el seu funcionament. Pots practicar amb aquest tester:

o bé directament amb la teva funció:

function validarmail(email) {
    // if (/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3,4})+$/.test(email)) { //comprovar perquè no funciona...
    if (/^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/.test(email)) { //funciona
        return true;
    } else {
        return false;
    }
}

console.log(validarmail("jquintana@jaumebalmes.net")); //true
console.log(validarmail("_jquintana@jaumebalmes.net")); //true
console.log(validarmail("jquintana@jaumebalmesnet")); //false


Expressió regular per validar una targeta de crèdit

Formats vàlids:

regexp = /^[0-9]{4}(-|\s)[0-9]{4}(-|\s)[0-9]{4}(-|\s)[0-9]{4}$/;
//regexp = /^\d{4}(-|\s)\d{4}(-|\s)\d{4}(-|\s)\d{4}$/;
  
function is_creditCard(str)
{
 regexp = /^[0-9]{4}(-|\s)[0-9]{4}(-|\s)[0-9]{4}(-|\s)[0-9]{4}$/;
  
        if (regexp.test(str))
          {
            return true;
          }
        else
          {
            return false;
          }
}

//true
console.log(is_creditCard("3782-8224-6310-0067"));
//true
console.log(is_creditCard("3782 8224 6310 0067"));
//false
console.log(is_creditCard("3782*8224*6310*0067"));
//false
console.log(is_creditCard("37828224630006"));
//false
console.log(is_creditCard("3782822463000634"));

Si volem que "3782822463000634" (16 dígits) doni correcte, farem:

regexp = /^[0-9]{4}(-|\s)?[0-9]{4}(-|\s)?[0-9]{4}(-|\s)?[0-9]{4}$/;

Expressió regular per formatar una data

El format pot ser dd/mm/yyyy o dd/mm/yy, tenint en compte que els dies o mesos, poden ser començant per 0 o no. No ens podem passar de 31 per als dies, ni de 12 per als mesos.

function is_dateString(str)
{
	regexp = /^(3[01]|[12][0-9]|0?[1-9])\/(1[0-2]|0?[1-9])\/([0-9]{2})?[0-9]{2}$/;
  
	if (regexp.test(str))
	{
		return true;
	} else {
		return false;
	}
}

//true
console.log(is_dateString("01/01/2015"));
//true
console.log(is_dateString("1/1/2015"));
//false
console.log(is_dateString("30/13/2015"));
//false
console.log(is_dateString("32/12/2015"));
//true
console.log(is_dateString("28/05/2015"));
//false
console.log(is_dateString("28/05/015"));
//true
console.log(is_dateString("28/05/2015"));
//true
console.log(is_dateString("28/05/15"));
//true
console.log(is_dateString("28/05/3015")); //millora: que el primer dígit sigui un 1 o un 2

Si ens fixem només en la part del dia de la data:

//comprovació del dia del mes
regexp = /^(3[01]|[12][0-9]|0?[1-9])$/

//trues
print(regexp.test('4'));
print(regexp.test('04'));
print(regexp.test('12'));
print(regexp.test('23'));
print(regexp.test('30'));

//falses
print(regexp.test('35'));
print(regexp.test('300'));
print(regexp.test('00'));

Exercici de classe (format de fitxers) (23/10/2018)

La nostra col·lecció de fotografies segueix el següent patró:

yymmdd_hhmiss.jpg

on els formats admesos poden ser .jpg, .jpeg, .png (o bé .JPG, .JPEG, .PNG)

  1. Trobar l'expressió regular per saber si un fitxer té un format vàlid.
  2. Tenim un array amb una llista de 20 cadenes que representen fitxers. Construir (programàticament) dos arrays, un que es digui fitxers_valids[], i un altre que es digui fitxers_no_valids[]

solució:

var fitxers = [
    "20150215_124539.jpg",
    "200215_093848.jpg",
    "201215_124aaa.jpg",
    "2015_124539.jpg",
    "201809_124539ajpg",
    "lascosasdelavida.jpg",
    "100215_124539.jpg",
    "300215_124539.jpg",
    "400215_124539.jpg",
    "500215_124539.jpg",
    "600215_124539.jpg",
    "200215-124539.jpg",
    "700215_124539.jpg",
    "800215_124539.jpg",
    "900215_124539.jpg",
    "20pp0215_124539.jpg",
    "200215_1239.jpg",
    "200215_124539.bmp",
    "200215_124539jpg",
    "200215_do4539.jpg",
];
var fitxersValids = [];
var fitxersNoValids = [];
var pattern = /^\d{6}_\d{6}\.(jpg|jpeg|png)$/i;

for(i in fitxers){
    if (pattern.test(fitxers[i])){
        fitxersValids.push(fitxers[i]);
    } else {
        fitxersNoValids.push(fitxers[i]);
    }
}

console.log("Fitxers Vàlids");
for(i in fitxersValids){
    console.log(fitxersValids[i]);
}


console.log("\nFitxers no Vàlids");
for(i in fitxersNoValids){
    console.log(fitxersNoValids[i]);
}

NOTA: fixar-se que el punt separador és \. (amb contrabarra), doncs el punt senzill (.) té un significat especial en les expressions regulars.

Creació d'objectes

Crearem un objecte de tres maneres:

1. Creació directa de l'objecte (notació JSON):

var person={
	firstname:"John",
	lastname:"Doe",
	age:50,
	eyecolor:"blue",
	fullname : function() {
       return this.firstname + " " + this.lastname;
    }
};
console.log(person.firstname + " is " + person.age + " years");
console.log(person.fullname());

Podem pensar que un mètode d'un objecte és una propietat que el seu contingut és una funció.

2. Creem un objecte directament:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//CA" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>

<script>
var person=new Object();
person.firstname="John";
person.lastname="Doe";
person.age=50;
person.eyecolor="blue"; 
person.fullname = function() {
       return this.firstname + " " + this.lastname;
}

cosnole.log(person.firstname + " is " + person.age + " years old.");
console.log(person.fullname());
document.write(person.firstname + " is " + person.age + " years old.");ç
document.write(person.fullname());
</script>

</body>
</html>

3. Utilitzem un constructor per crear l'objecte: (si s'han de crear varis objectes, millor fer-ho d'aquesta manera)

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//CA" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<script>
function person(firstname,lastname,age,eyecolor) {
	this.firstname=firstname;
	this.lastname=lastname;
	this.age=age;
	this.eyecolor=eyecolor;
 
	this.changeName=fchangeName;
	this.changeAge=fchangeAge;

	function fchangeName(name) {
		this.lastname=name;
	}

	function fchangeAge(newage) {
		if (newage <= 0 ) {
		   document.write("edat ha de ser un número enter i positiu");
		} else {
		   this.age=newage;
		}
	}

}

myMother=new person("Sally","Rally",48,"green");
myMother.changeName("Doe");
myMother.changeAge(43);
document.write(myMother.lastname);
document.write('<br />');
document.write(myMother.age);
</script>

</body>
</html>

En aquest cas fixa't que hem definit dues funcions (o mètodes) sobre els objectes, changeName i changeAge, i dins del constructor hi ha la definició d'aquestes dues funcions: fchangeName i fchangeAge. Fixa't també que dins el constructor trobaràs les declaracions de les funcions, i després les definicions de les funcions.

Moltes vegades trobaràs:

this.changeName= function (name) {
   this.lastname=name;
}

però nosaltres hem preferit ficar:

this.changeName=fchangeName;

function fchangeName(name)
{
   this.lastname=name;
}

per donar a entendre que changeName és un mètode de l'objecte person, i que fchangeName és la funció que defineix aquest mètode dins el constructor.

L'avantatge d'utilitzar una funció constructora és que podem instanciar tants objectes com vulguem, només cal invocar al constructor.

Creació d'objectes. Mètodes de l'objecte i funcions internes al constructor

Partint de l'exemple anterior definirem la propetat fullname que és la concatenació del nom i del cognom. Definim la funció ffullName(nom,cognom) com una funció interna al constructor (el que fa és donar valor a la propietat fullname), però no podem cridar a la funció ffullName com si fos un mètode igual que fem amb fchangeAge, doncs no està definit:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//CA" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<script>
function person(firstname,lastname,age,eyecolor) {
	this.firstname=firstname;
	this.lastname=lastname;
	this.age=age;
	this.eyecolor=eyecolor;

	this.changeName=fchangeName;
	this.changeAge=fchangeAge;

	this.fullname = ffullName(this.firstname,this.lastname);

	function fchangeName(name) {
		this.lastname=name;
	}

	function fchangeAge(newage) {
		if (newage <= 0 ) {
		   document.write("edat ha de ser un número enter i positiu");
		} else {
		   this.age=newage;
		}
	}

	function ffullName(nom,cognom) {
		return nom + ' ' + cognom;
	}
}
myMother=new person("Sally","Rally",48,"green");
myMother.changeName("Doe");
myMother.changeAge(43);
document.write(myMother.lastname);
document.write('<br />');
document.write(myMother.age);
document.write('<br />');
document.write('fullname: ' + myMother.fullname);

//però no podem fer, doncs TypeError: myMother.fullname is not a function
myMother.fullName('aa','bb');
document.write('<br />');
document.write('fullname: ' + myMother.fullname);

myMother.ffullName('aa','bb'); //falla perquè ffullname és una funció privada de l'objecte. No és un mètode

</script>

</body>
</html>

NOTA: amb els canvis que hem fet ara s'ha d'actualitzar la funció fchangename de la següent manera:

function fchangeName(name) {
	this.lastname=name;
	this.fullname = ffullName(this.firstname,this.lastname);
}

Entrega

Els alumnes entregaran al Schoology tots els fitxers generats (fitxers html). S'empaquetaran tots aquests fitxers i es pujaran al Moodle dins del termini d'entrega de la pràctica.

Recorda la normativa per entregar les pràctiques al Google Classroom: ASIX-M10-UF2#Normativa_d.27entrega_de_les_pr.C3.A0ctiques_al_Google_Classroom


creat per Joan Quintana Compte, Octubre 2018

Eines de l'usuari
Espais de noms
Variants
Accions
Navegació
Institut Jaume Balmes
Màquines recreatives
CNC
Informàtica musical
joanillo.org Planet
Eines