OpenAmplify utviklerens dagbok - del to: Forfattersammenligninger

I del en av Developer Diary, vurderte jeg hva som trengs for å sende en forespørsel til OpenAmplify-tjenesten. Denne uken skal jeg forklare hvordan jeg bruker OpenAmplify-resultatene for å sammenligne forfatterdemografi og stiler mellom to enkeltdokumenter. Nøkkelen til alt arbeidet mitt herfra er at når jeg henter resultatene fra OpenAmplify, laster jeg dem inn i en XDocument-forekomst, som lar meg bruke LINQ.

Hvis du ikke er kjent med LINQ, er en av de største misforståelsene ideen om at den bare er for spørring av databaser. I virkeligheten er LINQ ganske enkelt et spørrespråk bakt i VB.NET og C #. Når du bruker LINQ, kan forskjellige "leverandører" kobles til som tillater spørsmål til forskjellige datalagre. Mens leverandøren av SQL Server ("LINQ til SQL") er en av de mest fremtredende, er den ikke den eneste som er tilgjengelig. I forbindelse med dette prosjektet vil vi bruke LINQ til Objekter (som opererer på objekter som implementerer IEnumerable-grensesnittet) og LINQ til XML. Hvis du ønsker mer informasjon om LINQ, anbefaler jeg boken Essential LINQ av Charline Calvert og Dinesh Kulkarni.

La oss komme i gang. Først vil jeg se på forfatterdelen av OpenAmplify-resultatene for å få et inntrykk av hvordan du kan sammenligne dem på riktig måte. For denne øvelsen er det jeg kaller "forfatterinformasjon" egentlig seksjonene "Demografisk analyse" og "stilanalyse" i OpenAmplify-utdataene. Ved å kombinere de to seksjonene får vi seks resultater:

  • Flamboyance - Bruker teksten mange uvanlige ord eller mindre vanlige strukturer og komponenter i grammatikk?
  • Slang - Bruker teksten mange ord utenom "riktig språk?"
  • Alder - Fortrinnets og tiltenkte publikums omtrentlige alder.
  • Kjønn - En gjetning på forfatteren eller publikumets kjønn.
  • Utdanning - En tilnærming av forfatter- eller publikumsutdanningsnivå.
  • Språk - Hvilket språk teksten er skrevet på.
Hva slags sammenligning ser jeg etter? Når det gjelder søknaden min (Rat Catcher), vil jeg presentere brukeren med en enkel prosentandel slik at koden min vil produsere et flottørobjekt med en verdi mellom 0 og 100, hvor 100 er et perfekt match og 0 er et perfekt ikke- kamp. Jeg ser ikke noen grunn til å vekte noen komponent tyngre enn en annen, bortsett fra "Språk." Hvis språkene ikke er like, ser jeg ingen grunn til å se på noe annet. Jeg vil returnere 0 i så fall og være ferdig med det. Når det er sagt, er det ganske enkelt å tildele en vekt til noen av komponentene, om ønskelig.

Hvert element i sammenligningen inneholder et "Navn" -element, som gir en engelsk tekstverdi som beskriver resultatet. For eksempel kan jeg få følgende tekstresultater for analysen "Utdanning":

  • Undecided
  • Pre-Sekundær
  • sekundær
  • Høyskole
  • Postgraduate

Jeg vil sammenligne disse verdiene for et treff, og gi 1/6 av 100% kreditt (ca. 16, 6%) til ethvert element med et samsvarende navn.

I tillegg inneholder alle komponentene en numerisk verdi. Noen ganger gir tallet ytterligere granularitet, noen ganger gjør det ikke. I dette prosjektet sammenligner Rat Catcher et "rent" kildedokument med funnet internettdokumenter som ikke er "rene." Sammenligningsdokumentene inneholder data som navigasjon, annonser og tilleggstekst som ikke er relevant for sammenligningen. Jeg forstår at en nøyaktig samsvar er nesten umulig å begynne med (med mindre dokumentet som er funnet er et ikke-webside-dokument), så jeg vil ignorere mangelfullhet.

Noen applikasjoner - for eksempel et juridisk oppdagelsesverktøy som ønsker å knytte relaterte dokumenter som er funnet på en stevet server til en annen - kan være nødvendig å undersøke skalarresultatene. Disse applikasjonene kan også gi "delvis kreditt" for naboverdiene. Hvis for eksempel poengsummen "Utdanning" i ett dokument inneholder "videregående" og "høyskole", kan det være at sammenligningsdokumentet må gi halvparten så mye kreditt som normalt gitt.

For Rat Catchers formål er en enkel sammenligning mer enn tilstrekkelig. La oss se på koden:

 private float CompareOpenAmplifyAuthors (XDocument originalXml, XDocument sammenligneToXml) 

{

float resultat = 0;

var originalDemographicNodes = fra node i originalXml.Root.Element ("AmplifyReturn"). Element ("Demografi"). Elementer ()

velg node;

var originalStyleNodes = (

fra node i originalXml.Root.Element ("AmplifyReturn"). Element ("Styles"). Elementer ()

Velg node);
 foreach (var node i originalDemographicNodes) 

{

var comparToNode = sammenligneToXml.Root.Element ("AmplifyReturn"). Element ("Demografi"). Element (node.navn);

if (sammenlignToNode.Element ("Navn"). Verdi.ToLower () == node.Element ("Navn"). Verdi.ToLower ())

{

resultat + = ((flyte) 100) / 6;

}

ellers

{

if (node.Name == "Språk")

{

retur 0;

}

}

}
 foreach (var node i originalStyleNodes) 

{

var comparToNode = sammenligneToXml.Root.Element ("AmplifyReturn"). Element ("Styles"). Element (node.Name);

if (sammenligneToNode.Element ("Navn"). Verdi == node.Element ("Navn"). Verdi)

{

resultat + = ((flyte) 100) / 6;

}

}
 resultat = Math.Min (100, resultat); 
 tilbake resultat; } 

Som du ser, aksepterer jeg først to XDocument-objekter, originalXml og sammenligneToXml, for å jobbe med og initialisere resultatvariabelen til 0. Deretter velger jeg bare "Demografikk" og "Stil" -delene i den opprinnelige XML i separate oppregninger. Derfra itererer jeg over de opprinnelige Demografiske og stiloppregningene og finner en node i sammenligningen XML med samme elementnavn.

I begge tilfeller, hvis verdiene til "Navn" -elementet samsvarer, legger jeg 100/6 til resultatet. Du vil merke deg at i sammenligningen "Demografi", hvis "Navn" -elementet ikke samsvarer og det er for "Språk" -komponenten, returnerer jeg umiddelbart 0 og implementerer logikken min om at "Språk" er en kritisk kamp. Til slutt trimmer jeg antallet opp for å sikre at det ikke er mer enn 100 (på grunn av potensielle avrundingsproblemer) og returnerer det.

Er dette den mest elegante koden som er mulig? Ikke i det hele tatt. Selv om det er fullstendig mulig å uttrykke dette i ett til tre LINQ-utsagn, er det grunner til at du ikke vil:

  • Lesbarhet - Det vil være en veldig lang LINQ-uttalelse, og enhver elegansefordel vil fort gå tapt.
  • Ingen hastighetsfordel - Ofte er elegant kode mye raskere enn brute force code. I dette tilfellet sammenligner jeg seks verdier; hvor mye fart vil elegansen gi meg?
  • Vedlikehold - Altfor ofte blir elegante løsninger vedlikeholdsmareritt. Det er en fin linje mellom elegant og for smart. Du vil ikke finne ut tre måneder fra prosjektet, og deretter oppdage at du har et problem.

Det jeg har oppdaget så langt, er at jeg med litt LINQ kunne gjøre det enkelt å gjøre oppslagene jeg trenger for å gjøre en god sammenligning mellom forfattere. Neste uke skal jeg gå videre til den virkelige bjørnen - sammenligning av emnets intensjoner som er nødvendige for å gi muligheten til å sammenligne betydningen av to dokumenter.

J.Ja

© Copyright 2020 | mobilegn.com