GMail a cette fonctionnalité où il vous avertira si vous essayez d'envoyer un e-mail qu'il pense pourrait avoir une pièce jointe.
Parce que GMail a détecté la chaîne see the attached
dans l'e-mail, mais sans pièce jointe réelle, il m'avertit par une boîte de dialogue OK/Annuler lorsque je clique sur le bouton Envoyer.
Nous avons un problème connexe sur Stack Overflow. Autrement dit, lorsqu'un utilisateur entre dans un message comme celui-ci :
mon problème est que je dois changer la base de données mais je ne vais pas créer une nouvelle connexion. exemple: DataSet dsMasterInfo = new DataSet (); Database db = DatabaseFactory.CreateDatabase ("ConnectionString"); DbCommand dbCommand = db.GetStoredProcCommand ("" uspGetMasterName ");
Cet utilisateur n'a pas formaté son code comme code !
Autrement dit, ils n'ont pas mis en retrait de 4 espaces par Markdown, ou utiliser le bouton de code (ou le raccourci clavier ctrl+k) qui fait cela pour eux.
Ainsi, notre système accepte de nombreuses modifications où les gens doivent entrer et formater manuellement le code pour les personnes qui ne sont pas en mesure de comprendre cela. Cela conduit à beaucoup de bellyaching . Nous avons amélioré l'aide de l'éditeur à plusieurs reprises, mais à moins de conduire jusqu'à la maison de l'utilisateur et d'appuyer sur les bons boutons de son clavier pour lui, nous ne savons pas quoi faire ensuite.
C'est pourquoi nous envisageons un avertissement de style Google GMail:
Vouliez-vous publier le code?
Vous avez écrit des choses qui, à notre avis, ressemblent à du code, mais vous ne les avez pas formatées en tant que code en mettant en retrait 4 espaces, à l'aide du bouton de code de la barre d'outils ou du ctrl+k commande de formatage de code.
Cependant, la présentation de cet avertissement nous oblige à détecter la présence de ce que nous pensons être du code non formaté dans une question . Qu'est-ce qu'un moyen simple et semi-fiable de le faire?
Une bonne solution serait probablement un modèle appris/statistique, mais voici quelques idées amusantes:
myFunc()
foo.bar = ptr->val
while (true) { bar[i]; }
/* multi-line comment */
+, *, &, &&, |, ||, <, >, ==, !=, >=, <=, >>, <<, ::, __
On pourrait garder une trace du nombre de fois où chacun d'eux apparaît, et ceux-ci pourraient être utilisés comme fonctionnalités dans un algorithme d'apprentissage automatique comme perceptron , comme le fait SpamAssassin.
Je serais curieux de voir quelles sont les mesures moyennes de l'anglais écrit d'un côté et du code de l'autre côté.
Peut-être que cela seul pourrait déjà faire la distinction entre le code et le reste. Au moins, je crois que le code, quelle que soit la langue, afficherait des mesures sensiblement différentes dans de nombreux cas.
La bonne nouvelle est que vous disposez déjà de nombreuses données sur lesquelles construire vos statistiques.
Ok, je suis de retour avec quelques données pour étayer mes hypothèses. :-)
J'ai fait un test rapide et sale sur votre propre post et sur le premier post que j'ai trouvé sur StackOverflow , avec un outil assez avancé: wc
.
Voici ce que j'avais après avoir exécuté wc
sur la partie texte et sur la partie code de ces deux exemples:
Voyons d'abord la partie anglaise :
Assez similaire, vous ne pensez pas?
Jetons maintenant un œil à la partie de code !
Voyez à quel point ces métriques ne sont pas si différentes, mais plus important encore, à quel point elles sont différentes des métriques anglaises? Et cela utilise simplement un outil limité. Je suis maintenant sûr que vous pouvez obtenir quelque chose de vraiment précis en mesurant plus de métriques (je pense en particulier aux statistiques de caractères).
Puis-je utiliser des cookies?
En règle générale, les chaînes de Markov sont utilisées pour générer du texte, mais elles peuvent également être utilisées pour prédire la similitude du texte (par C.E. Shannon 195 ) avec un modèle entraîné. Je recommande plusieurs chaînes Markov.
Pour chaque langue courante, formez une chaîne de Markov sur un large échantillon représentatif de code dans la langue. Ensuite, pour une publication Stack Overflow pour laquelle vous souhaitez détecter du code, procédez comme suit pour chacune des chaînes:
Pour chaque ligne, vous devez avoir une valeur réelle et une valeur la plus élevée. Divisez ACTUAL par HIGHEST. Cela vous donnera le score de fitness pour savoir si une ligne particulière est du code source. Cela associerait un numéro à chacune des lignes de l'exemple que vous avez donné:
my problem is I need to change the database but I don't won't to create // 0.0032
a new connection. example: // 0.0023
DataSet dsMasterInfo = new DataSet(); // 0.04
Database db = DatabaseFactory.CreateDatabase("ConnectionString"); // 0.05
DbCommand dbCommand = db.GetStoredProcCommand("uspGetMasterName"); // 0.04
Enfin, vous devrez sélectionner un seuil pour déterminer quand il y a du code dans la publication. Cela pourrait simplement être un nombre sélectionné par observation qui donne des performances élevées. Il pourrait également prendre en compte le nombre de lignes avec un score élevé.
Formation
Pour vous entraîner, procurez-vous un large échantillon représentatif de code dans la langue. Écrivez un programme pour parcourir le texte du code et associer chaque N-gramme du fichier (la plage de N doit être paramétrée) à la fréquence statistique du caractère suivant. Cela produira plusieurs états de caractères possibles qui suivent le bigramme, chacun étant associé à une probabilité. Par exemple, le bigramme "()" pourrait avoir les probabilités de caractère suivantes:
"()" 0.5-> ";"
"()" 0.2-> "."
"()" 0.3-> "{"
Le premier doit être lu, par exemple comme "La probabilité qu'un point-virgule suive une parenthèse vide est de 0,5".
Pour la formation, je recommande N-grammes de taille deux à cinq. À l'époque où j'ai fait des recherches à ce sujet , nous avons constaté que les N-grammes de taille deux à cinq fonctionnaient bien pour l'anglais. Comme une grande partie du code source est comme l'anglais, je suggère de commencer par cette plage, puis de l'ajuster pour trouver les valeurs de paramètres optimales au fur et à mesure que vous trouvez ce qui fonctionne.
Une mise en garde: le modèle va être affecté par des identificateurs, des noms de méthode, des espaces, etc. Par exemple, vous pouvez réduire tous les espaces inutiles. La présence d'espaces dans l'entrée (le message Stack Overflow) peut également être ignorée. Vous pouvez également ignorer la casse alphabétique, qui serait plus résistante face aux différentes conventions de dénomination des identifiants.
Pendant mes recherches , nous avons constaté que nos méthodes fonctionnaient bien aussi bien en espagnol qu'en anglais. Je ne vois pas pourquoi cela ne fonctionnerait pas aussi bien pour le code source. Le code source est encore plus structuré et prévisible que le langage humain.
Puis-je suggérer une approche radicalement différente? Sur SO la seule langue humaine autorisée est l'anglais, donc tout ce qui n'est pas anglais a 99,9% de chances d'être un extrait de code.
Donc, ma solution serait: utilisez l'un des nombreux vérificateurs de langue en anglais (assurez-vous qu'ils signalent également - à côté des fautes d'orthographe - des erreurs de syntaxe comme les points doubles ou des symboles non linguistiques comme #
ou ~
). Ensuite, toute ligne/paragraphe qui génère une grande quantité d'erreurs et d'avertissements devrait déclencher le "est ce code?" question.
Cette approche peut également être adaptée pour les sites StackExchange utilisant d'autres langues que l'anglais, bien sûr.
Juste mon 2 ¢ ...
Le pseudo-code poserait un véritable défi car tout langage de programmation dépend de caractères spéciaux comme '[]', ';', '()', etc. Comptez simplement l'occurrence de ces caractères spéciaux. Tout comme vous détecteriez un fichier binaire (plus de 5% d'un échantillon contient une valeur d'octet 0).
Je vais probablement obtenir quelques votes négatifs pour cela, mais je pense que vous abordez cela sous le mauvais angle.
Cette ligne m'a fait:
les gens doivent entrer et formater manuellement le code pour les personnes qui sont en quelque sorte incapables de comprendre cela
OMI, ce point de vue est un peu arrogant. Je trouve cela beaucoup dans la conception de logiciels où les programmeurs et les concepteurs sont ennuyés par les utilisateurs qui ne savent pas comment utiliser correctement le logiciel, lorsque le problème n'est pas l'utilisateur mais le logiciel lui-même - ou l'interface utilisateur au moins.
La cause première de ce problème n'est pas l'utilisateur mais le fait qu'il ne leur soit pas évident qu'ils peuvent le faire.
Que diriez-vous d'un changement dans l'interface utilisateur pour rendre cela plus évident? Ce sera sûrement:
Exemple:
Je pense que vous devrez peut-être cibler cela uniquement sur des langues spécifiques, en général, ce problème est probablement insoluble car vous pouvez obtenir des langues qui sont assez similaires à l'anglais (par exemple inform7 ). mais heureusement, les plus utilisés pouvaient être couverts assez facilement.
Ma première coupe serait de rechercher la séquence ";\n" qui vous donnerait une bonne correspondance pour C, C++, Java, C # et tout autre langage qui utilise une syntaxe similaire et est vraiment simple. Il est également moins susceptible d'être utilisé en anglais qu'un; sans nouvelle ligne
Quelqu'un a mentionné avoir regardé les balises, puis recherché la syntaxe pour cela, mais cela a été abattu car cela s'adresse aux nouveaux utilisateurs.
Une meilleure solution possible serait de rechercher des noms de langue dans le corps de la question, puis d'appliquer la même stratégie. Si je mentionne "Javascript", "Java" ou "C #", alors il y a de fortes chances que ce soit la question, et le code dans la question sera probablement dans cette langue.
Tout d'abord, exécutez la vérification orthographique, il trouvera très peu de mots anglais appropriés, mais il devrait y avoir beaucoup de mots que le correcteur orthographique suggérera de diviser.
Ensuite, il y a des signes de ponctuation/spéciaux qui ne sont pas typiques de l'anglais ordinaire, typiques du code:
something();
ne peut tout simplement pas être en anglais simple;$something
où something
n'est pas entièrement numérique;->
entre les mots sans espaces;.
entre les mots sans espace;Bien sûr, pour qu'il fonctionne bien, vous voudrez peut-être que le classificateur bayésien soit construit en plus de ces caractéristiques.
il existe plusieurs ensembles de langages qui partagent une syntaxe similaire. la plupart des langages ont été influencés par quelques langages, donc les langages [AMPL, AWK, csh, C++, C--, C #, Objective-C, BitC, D, Go, Java, JavaScript, Limbo, LPC, Perl, PHP, Pike, Processing [étaient tous influencés par C, donc si vous détectez C, vous détecterez probablement tous ces langages. vous n'avez donc qu'à écrire un modèle simple pour détecter ces ensembles de langues.
je diviserais également le texte en blocs, car le plus de code sera divisé par deux nouvelles lignes ou similaires des autres blocs de texte dans le message.
cela peut être fait facilement avec javascript (un échantillon incomplet super simple pour la famille c):
var txt = "my problem is I need to change the database but I don't won't to create a new connection. example:\n\nDataSet dsMasterInfo = new DataSet();Database db = DatabaseFactory.CreateDatabase("ConnectionString");DbCommand dbCommand = db.GetStoredProcCommand("uspGetMasterName");";
var blocks = txt.split(/\n\n/gi); console.dir(blocks);
var i = blocks.length;
var cReg = /if\s*\(.+?\)|.*(?:int|char|string|short|long).*?=.+|while\s*\(.+?\)/gi;
while ( i-- ){
var current = blocks[i];
if ( cReg.test( current ) ){
console.log("found code in block[" + i + "]");
}
}
Ce qui peut être le plus évolutif et nécessitera le moins d'ajustement manuel à long terme, car d'autres langages (qui semblent quelque peu différents des langages de programmation les plus utilisés actuellement) deviennent plus populaires et les langages actuellement utilisés deviennent moins populaires, c'est de faire quelque chose comme quoi Google Translate le fait (voir le paragraphe intitulé "Comment ça marche?"), au lieu de chercher certaines choses comme ab et a (), etc.
En d'autres termes, au lieu de penser manuellement aux modèles trouvés dans le code à rechercher, l'ordinateur peut le comprendre par lui-même . Cela peut être fait en ayant
beaucoup de code dans de nombreux langages de programmation différents
Suggestion: prenez automatiquement des échantillons de code à partir de référentiels de code source basés sur le Web comme Google Code ou Github, ou même à partir d'éléments sur Stackoverflow déjà marqués comme code
Remarque: il peut être judicieux d'analyser les commentaires de code
beaucoup de texte anglais extrait d'articles sur le web
et avoir une sorte d'algorithme automatiquement trouver des modèles dans le code qui ne sont pas en anglais, et vice versa, et utiliser ces modèles pour détecter ce qui est du code et ce qui ne l'est pas en exécutant l'algorithme sur les messages.
(Cependant, je ne sais pas comment un tel algorithme fonctionnerait. D'autres réponses à la question actuelle peuvent avoir des informations utiles pour cela.)
Ensuite, le système peut réexaminer le code de temps en temps pour tenir compte des changements dans la façon dont le code se présente à ce moment.
Comptez simplement les mots/caractères de ponctuation pour chaque ligne. L'anglais aura tendance à avoir 4 ou plus, code inférieur à 2.
Le paragraphe ci-dessus a 18 mots et 4 caractères de ponctuation, par exemple. Ce paragraphe a 19 mots et 4 ponctuations, donc dans les attentes.
Bien sûr, cela devrait être testé par rapport aux questions des débutants pauvres en anglais, et il se peut que dans ces cas, les statistiques soient biaisées.
Je m'attends à ce que [non-blanc]. [Blanc ou nouvelle ligne] soit très rare dans le code, mais commun en anglais, donc cela pourrait être compté comme des mots, pas de la ponctuation.
Je pense que le plus gros problème sera le code en ligne, où quelqu'un pose une question comme:
Si je dis pour (i = 0; i> 100; i ++) {} qu'est-ce que cela signifie?
C'est du code et de l'anglais, et devrait être marqué comme avec des tiques arrière:
Si je dis
for (i=0; i>100; i++) {}
qu'est-ce que cela signifie?
Je pense que vous devriez d'abord faire une distinction entre le code (suffisamment) formaté qui n'a besoin d'être désigné que comme tel, et le code (trop) mal formaté, qui a quand même besoin d'un formatage manuel.
Le code formaté a des lignes de rupture et une indentation. C'est-à-dire: si une ligne est précédée d'une seule ligne de rupture, vous avez un bon candidat. S'il y a des espaces blancs de premier plan en plus de cela, vous avez un très bon candidat.
Le texte normal utilise deux lignes de rupture ou deux espaces et une ligne de rupture pour la mise en forme, il existe donc un critère de distinction clair.
Dans le code LISP, vous ne trouverez pas de points-virgules, dans Ruby code vous ne trouverez peut-être pas de parenthèses, dans le pseudo-code vous ne trouverez peut-être pas grand-chose du tout. Mais dans n'importe quelle langue (non ésotérique) vous trouverez un code décent à mettre en forme avec des lignes de rupture et une indentation. Il n'y a rien d'aussi universel que cela. Parce qu'à la fin le code est écrit pour être lu par les humains.
Alors d'abord, recherche des lignes potentielles de code. De plus, les lignes de code viennent généralement en groupes. Si vous en avez un, il y a de fortes chances que celui ci-dessus ou ci-dessous soit également une ligne de code.
Une fois que vous avez sélectionné des lignes de code potentielles, vous pouvez les comparer à des critères quantifiables et choisir un certain seuil:
De plus, maintenant qu'il y a des programmeurs et des cs, la portée de stackoverflow est clairement réduite. On pourrait envisager de désigner toutes les balises de langue comme des langues. Et lors de la publication, vous serez invité à choisir au moins une balise de langue, choisissez le language-agnostic
tag ou pour l'omettre explicitement.
Dans le premier cas, vous savez quelles langues rechercher, dans le second cas, vous voudrez peut-être rechercher un pseudo-code et dans le dernier cas, il n'y aura probablement pas de code, car c'est une question liée à une technologie ou cadre ou autre.
Vous pouvez créer un analyseur pour chaque langue que vous souhaitez détecter (les définitions de langue pour ANTLR sont généralement faciles à trouver), puis exécuter chaque ligne de la question dans chaque analyseur. Si une ligne analyse correctement, vous avez probablement du code.
Le problème avec cela est que certaines phrases en anglais (langage naturel) peuvent être analysées en tant que code, vous pouvez donc également inclure certaines des autres idées, ou vous pouvez limiter les résultats positifs uniquement si plus d'une ou deux lignes consécutives analysent correctement avec le même analyseur de langue.
L'autre problème potentiel est que cela ne détectera probablement pas le pseudocode, mais cela peut être OK.