IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Java Discussion :

Problème de boucle


Sujet :

Langage Java

  1. #1
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2014
    Messages
    180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mai 2014
    Messages : 180
    Points : 64
    Points
    64
    Par défaut Problème de boucle
    Hello Friends
    Alors voilà j'ai un petit problème :

    j'ai un texte :
    marque auto
    ff = "{audi}_{bmw}_sylda_{peugeot}"
    ee = "{user}/{audi}/script/{audi}_{bmw}_sylda_{peugeot}/{Driver}/{mazerrati}/{Porche}/listing"
    ff= "{user}/{audi}/script/{audi}_{bmw}_sylda_{peugeot}/{Driver}/{mazerrati}/{Porche}/temoin"
    ee = "{user}/{audi}/script/{audi}_{bmw}_sylda_{peugeot}/{Driver}/{mazerrati}/{Porche}/results"
    ff= "{user}/{audi}/script/{audi}_{bmw}_sylda_{peugeot}/{Driver}/{mazerrati}/{Porche}/UCI_cree"
    et j'aimerai en faîte afficher dans une liste tout ce qu'il y a entre { et }.
    donc j'aimerai en output :
    {audi} , {bmw}, {peugeot}, {user}, etcc


    J'ai fais un code mais je bloque :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
     
    import java.util.ArrayList;
     
     
    public class blabla {
     
    	public static void main(String[] args) {
     
    		String texte = "marque auto\n"+
    				"ff = {audi}_{bmw}_sylda_{peugeot}\n"+ 
    				"ee = {user}/{audi}/script/{audi}_{bmw}_sylda_{peugeot}/{Driver}/{mazerrati}/{Porche}/listing\n"+
    				"ff= {user}/{audi}/script/{audi}_{bmw}_sylda_{peugeot}/{Driver}/{mazerrati}/{Porche}/temoin\n"+
    				"ee = {user}/{audi}/script/{audi}_{bmw}_sylda_{peugeot}/{Driver}/{mazerrati}/{Porche}/results\n"+
    				"ff= {user}/{audi}/script/{audi}_{bmw}_sylda_{peugeot}/{Driver}/{mazerrati}/{Porche}/UCI_cree\n";
     
    		String VALUE_B ="{";
    		String VALUE_E = "}";
     
    		int a = 0;
    		int b = 0;
    		String c = "";
     
    		//System.out.println(texte );
     
    		// Creation d'une liste
    				ArrayList<String> Liste1 = new ArrayList<String>();
     
    				a = texte.indexOf(VALUE_B);
    				b = texte.indexOf(VALUE_E);
    				c = texte.substring(a, b+1);
     
    				//ajout de keys apres detection
    				Liste1.add(c);
     
    					System.out.println(c);
     
     
     
     
    	}
     
    }
    donc voilà en sortie j'arrive a voir {audi} mais c'est tout
    .
    je pense que je dois faire une boucle nan ??

  2. #2
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Salut

    Citation Envoyé par khalous91 Voir le message
    je pense que je dois faire une boucle nan ??
    Oui, évidemment (mais pas seulement). Tu as avais déjà posé la même question et que je t'avais donné le code avec les explications pour la résoudre, il y a plus d'un mois.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  3. #3
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2014
    Messages
    180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mai 2014
    Messages : 180
    Points : 64
    Points
    64
    Par défaut
    Oui je sais mais j'retrouve plus la discussion, j'ai du la supprimé pour cause de données professionnelles.

    mais l'idée est là non ?

    en gros : tant que il trouve des { et } il affiche ...

  4. #4
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par khalous91 Voir le message
    Oui je sais mais j'retrouve plus la discussion, j'ai du la supprimé pour cause de données professionnelles.
    Et le code que tu as fait dans ton stage, à partir de la solution que je t'ai donnée, tu l'as supprimé aussi ? Sans parler que apprendre se fonde entre autres sur retenir et mémoriser.

    Citation Envoyé par khalous91 Voir le message
    mais l'idée est là non ?

    en gros : tant que il trouve des { et } il affiche ...
    pour la méthode itérative, à base d'indexOf et substring, oui. Sinon il y a la méthode par expression régulière, qu'il me semble avoir vu passer il n'y a pas si longtemps que ça, et qu'il me semble ne pas avoir vu supprimée, pour le coup.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  5. #5
    Membre expérimenté Avatar de Nico02
    Homme Profil pro
    Developpeur Java/JEE
    Inscrit en
    Février 2011
    Messages
    728
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Developpeur Java/JEE
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2011
    Messages : 728
    Points : 1 622
    Points
    1 622
    Par défaut
    Salut,

    Tu as aussi la solution de l’expression régulière..

    Mais commences par écrire ta petite boucle et on verra après , ça sert à rien de te filer le truc tout fait si tu comprends pas ce que tu écris.

    edit : Grillé

  6. #6
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2014
    Messages
    180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mai 2014
    Messages : 180
    Points : 64
    Points
    64
    Par défaut
    J'ai fais sa pour l'instant :
    code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    import java.util.ArrayList;
     
     
    public class ChercheKeysTest2 {
     
    	public static void main(String[] args) {
     
    		String texte = "marque auto\n"+
    				"ff = {audi}_{bmw}_sylda_{peugeot}\n"+ 
    				"ee = {user}/{audi}/script/{audi}_{bmw}_sylda_{peugeot}/{Driver}/{mazerrati}/{Porche}/listing\n"+
    				"ff= {user}/{audi}/script/{audi}_{bmw}_sylda_{peugeot}/{Driver}/{mazerrati}/{Porche}/temoin\n"+
    				"ee = {user}/{audi}/script/{audi}_{bmw}_sylda_{peugeot}/{Driver}/{mazerrati}/{Porche}/results\n"+
    				"ff= {user}/{audi}/script/{audi}_{bmw}_sylda_{peugeot}/{Driver}/{mazerrati}/{Porche}/UCI_cree\n";
    		String VALUE_B ="{";
    		String VALUE_E = "}";
    		int ao = 0;
    	 	int po = 0;
     
    		ao = texte.indexOf(VALUE_B,po);
    		po = texte.indexOf(VALUE_E,ao);
     
    		while(ao >= 0 && po >= 0){           
     
     
    			// ce qu'il y a entre { }
    			String a = texte.substring(ao+1, po);
    			//System.out.println(a);
     
    			// Ce qu'il y a avant {etude}
    			String b = texte.substring(0, ao);
    			//System.out.println(b);
     
    			// Ce qu'il y a après {etude}
    			String c = texte.substring(po+1,texte.length());
     
     
     
    			if (a != null) {				
    				texte = b.concat(c);
    				po = po - (a.length()+2); 
     
    			}
    			ao = texte.indexOf(VALUE_B,po);
    			po = texte.indexOf(VALUE_E,ao);
     
    		}
    	 	System.out.println(texte);
     
     
    	}
     
    	}
    mais la sa me retire tout mes {..} bizarre !!

    Et le code que tu as fait dans ton stage, à partir de la solution que je t'ai donnée, tu l'as supprimé aussi ? Sans parler que apprendre se fonde entre autres sur retenir et mémoriser.
    oui c'est sûr mais petit à petit sa va rentrer a force de faire.
    pour la méthode itérative, à base d'indexOf et substring, oui. Sinon il y a la méthode par expression régulière, qu'il me semble avoir vu passer il n'y a pas si longtemps que ça, et qu'il me semble ne pas avoir vu supprimée, pour le coup.
    je vais y jeter un oeil

    Mais commences par écrire ta petite boucle et on verra après , ça sert à rien de te filer le truc tout fait si tu comprends pas ce que tu écris.
    j'ai fais une boucle là mais je n'y suis pas encore!

  7. #7
    Modérateur
    Avatar de wax78
    Homme Profil pro
    Chef programmeur
    Inscrit en
    Août 2006
    Messages
    4 075
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Belgique

    Informations professionnelles :
    Activité : Chef programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 4 075
    Points : 7 981
    Points
    7 981
    Par défaut
    Sinon, comme proposé précédement, utilise un Pattern et un matcher :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    String ee = "{user}/{a}/script/{audi}_{bmw}_sylda_{peugeot}/{D4ee687}{Driver}/{mazerrati}/{Porche}/listing";
    		Pattern p = Pattern.compile("\\{[\\w]*\\}"); // Peut être pas le plus optimale des regexp...
    		Matcher m = p.matcher(ee);
    		while (m.find()) {
    			System.out.println(m.group(0));
    }
    A n'utilisez que quand tu auras réussi avec ton propre algo...
    (Les "ça ne marche pas", même écrits sans faute(s), vous porteront discrédit ad vitam æternam et malheur pendant 7 ans)

    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  8. #8
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2014
    Messages
    180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mai 2014
    Messages : 180
    Points : 64
    Points
    64
    Par défaut
    Ah oui ... c'est beaucoup plus simple alors avec l'expression régulière merci
    sa me donne direct les {mots} mais faut que je réussisse avec une boucle car les boucles y'en a toujours ....

    donc code 1 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
     
     
    public class ChercheKeysTest2 {
     
    	public static void main(String[] args) {
     
    		String texte = "marque auto\n"+
    				"ff = {audi}_{bmw}_sylda_{peugeot}\n"+ 
    				"ee = {user}/{audi}/script/{audi}_{bmw}_sylda_{peugeot}/{Driver}/{mazerrati}/{Porche}/listing\n"+
    				"ff= {user}/{audi}/script/{audi}_{bmw}_sylda_{peugeot}/{Driver}/{mazerrati}/{Porche}/temoin\n"+
    				"ee = {user}/{audi}/script/{audi}_{bmw}_sylda_{peugeot}/{Driver}/{mazerrati}/{Porche}/results\n"+
    				"ff= {user}/{audi}/script/{audi}_{bmw}_sylda_{peugeot}/{Driver}/{mazerrati}/{Porche}/UCI_cree\n";
     
    		Pattern p = Pattern.compile("\\{[\\w]*\\}"); // Peut être pas le plus optimale des regexp...
    		Matcher m = p.matcher(texte);
    		while (m.find()) {
    			System.out.println(m.group(0));
     
    	}
     
     
    	}
    }
    pour le code 2 avec boucle je vais essayer e traiter ça .

  9. #9
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2014
    Messages
    180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mai 2014
    Messages : 180
    Points : 64
    Points
    64
    Par défaut
    Pouvez vous m'expliquez ce que veut dire :
    \\{[\\w]*\\}
    s'il vous plaît ?
    Merci

  10. #10
    Modérateur
    Avatar de wax78
    Homme Profil pro
    Chef programmeur
    Inscrit en
    Août 2006
    Messages
    4 075
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Belgique

    Informations professionnelles :
    Activité : Chef programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 4 075
    Points : 7 981
    Points
    7 981
    (Les "ça ne marche pas", même écrits sans faute(s), vous porteront discrédit ad vitam æternam et malheur pendant 7 ans)

    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  11. #11
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2014
    Messages
    180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mai 2014
    Messages : 180
    Points : 64
    Points
    64
    Par défaut
    merci wax78
    et dis moi j'aurai une autre question aussi au passage :
    si jamais j'ai dans un fichier xml ceci :
    <?xml version="1.0" encoding="utf-8"?>
    <parametters>
    <value name ="audi">
    "RS6"
    </value>
    <value name ="bmw">
    "X6"
    </value>
    <value name ="peugeot">
    "308"
    </value>
    <value name ="mazerrati">
    "italia"
    </value>
    <value name ="Porche">
    "911"
    </value>
    </parametters>
    donc j'ai bien 6 clés associés à 6 valeurs mais si jamais, je veux afficher dans une liste les clés qui n'ont pas de valeurs comment devrai-je faire svp :
    j'ai construit mon petit code mais je suis en difficulté! il me manque quelque chose là ...
    import java.util.HashMap;


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    public class ChercheKeysNonDefinies {
     
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		HashMap<String,String> map  = new HashMap<String,String>();
    	 String texte = "marque auto\n"+
    				"ff = {audi}_{bmw}_sylda_{peugeot}\n"+ 
    				"ee = {user}/{audi}/script/{audi}_{bmw}_sylda_{peugeot}/{Driver}/{mazerrati}/{Porche}/listing\n"+
    				"ff= {user}/{audi}/script/{audi}_{bmw}_sylda_{peugeot}/{Driver}/{mazerrati}/{Porche}/temoin\n"+
    				"ee = {user}/{audi}/script/{audi}_{bmw}_sylda_{peugeot}/{Driver}/{mazerrati}/{Porche}/results\n"+
    				"ff= {user}/{audi}/script/{audi}_{bmw}_sylda_{peugeot}/{Driver}/{mazerrati}/{Porche}/UCI_cree\n";
     
    		// je dois surement faire appel a mon fichier xml ici 
    		map.put("audi", "RS6");
    		map.put("bmw", "X6");
    		map.put("peugeot", "308");
    		map.put("mazerrati", "italia");
    		map.put("Porche", "911");
     
    		System.out.println(map); // là j'affiche mon couple clés/valeurs
     
    		// mais si je veux afficher les clés qui n'ont justement pas de valeurs !!!! 
     
     
     
     
    	}
     
    }

  12. #12
    Modérateur
    Avatar de wax78
    Homme Profil pro
    Chef programmeur
    Inscrit en
    Août 2006
    Messages
    4 075
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Belgique

    Informations professionnelles :
    Activité : Chef programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 4 075
    Points : 7 981
    Points
    7 981
    Par défaut
    Pour parcourir une hashmap tu peux te baser la dessus
    (Les "ça ne marche pas", même écrits sans faute(s), vous porteront discrédit ad vitam æternam et malheur pendant 7 ans)

    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  13. #13
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Et pour tester si une clef se trouve dans la map : Map.containsKey().
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  14. #14
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2014
    Messages
    180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mai 2014
    Messages : 180
    Points : 64
    Points
    64
    Par défaut
    Et pour tester si une clef se trouve dans la map : Map.containsKey().
    merci très utile j'ai plus qu'a faire une boucle alors pour qu'il detecte ceux qui n'ont pas de valeurs !

    merci aussi wax78

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème de boucles imbriquées
    Par Gnux dans le forum Algorithmes et structures de données
    Réponses: 9
    Dernier message: 09/12/2005, 20h26
  2. [Tableaux] Problème avec boucle
    Par MYster dans le forum Langage
    Réponses: 6
    Dernier message: 11/11/2005, 18h39
  3. Problème de boucle
    Par TheUltimaSephiroth dans le forum C
    Réponses: 8
    Dernier message: 10/10/2005, 13h58
  4. Problème de boucle
    Par Louis-Guillaume Morand dans le forum Langage SQL
    Réponses: 3
    Dernier message: 25/09/2005, 09h10
  5. Problème de boucle
    Par basclln dans le forum C++
    Réponses: 19
    Dernier message: 02/04/2005, 09h13

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo