рд░реЛрд╕реЗрдЯрд╛ рдХреЛрдб: рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛рдУрдВ рдореЗрдВ рдХреЛрдб рдХреА рд▓рдВрдмрд╛рдИ рдХреЛ рдорд╛рдкрддреЗ рд╣реИрдВ, рдПрдХ рджреВрд╕рд░реЗ рд╕реЗ рднрд╛рд╖рд╛рдУрдВ рдХреА рдирд┐рдХрдЯрддрд╛ рдХрд╛ рдЕрдзреНрдпрдпрди рдХрд░рддреЗ рд╣реИрдВ


рдЖрдк рдореЗрд░реЗ рдмреНрд▓реЙрдЧ рдкрд░ рдореВрд▓ рдкреЛрд╕реНрдЯ рдореЗрдВ рдХреЛрдб рдФрд░ рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рде рдлрд╛рдЗрд▓ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ

рдПрдХ рдмрд╣реБрдд рд╣реА рджрд┐рд▓рдЪрд╕реНрдк рдкрд░рд┐рдпреЛрдЬрдирд╛ рд╣реИ - " рд░реЛрд╕реЗрдЯрд╛ рдХреЛрдб" ред рдЙрдирдХрд╛ рд▓рдХреНрд╖реНрдп "рдЕрд▓рдЧ-рдЕрд▓рдЧ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛рдУрдВ рдХреА рд╕рдмрд╕реЗ рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рд╕рдорд╛рди рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЗ рд╕рдорд╛рдзрд╛рди рдХреЛ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдирд╛ рд╣реИ рддрд╛рдХрд┐ рдЙрдирдХреЗ рд╕рд╛рдорд╛рдиреНрдп рд╕реНрдерд╛рдиреЛрдВ рдФрд░ рдорддрднреЗрджреЛрдВ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХреЗ рдФрд░ рдПрдХ рдРрд╕реЗ рд╡реНрдпрдХреНрддрд┐ рдХреА рдорджрдж рдХрд░ рд╕рдХреЗрдВ, рдЬрд┐рд╕рдХреЗ рдкрд╛рд╕ рд╕реАрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рдзрд┐ рдХреЗ рд╕рд╛рде рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХрд╛ рдЬреНрдЮрд╛рди рд╣реЛред"

рдпрд╣ рд╕рдВрд╕рд╛рдзрди рд╡рд┐рднрд┐рдиреНрди рднрд╛рд╖рд╛рдУрдВ рдореЗрдВ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЛрдб рдХреА рддреБрд▓рдирд╛ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдЕрдиреВрдард╛ рдЕрд╡рд╕рд░ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рд╣рдо рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рдХрд░реЗрдВрдЧреЗред рдпрд╣ рдЬреЙрди рдореИрдХрд▓реЗрди рджреНрд╡рд╛рд░рд╛ " 14 рднрд╛рд╖рд╛рдУрдВ рдореЗрдВ рдХреЛрдб рд▓рдВрдмрд╛рдИ рдорд╛рдкреА рдЧрдИ" рд▓реЗрдЦ рдХрд╛ рдкреВрд░реНрдг рд╕рдВрд╢реЛрдзрди рдФрд░ рд╢реЛрдзрди рд╣реИред

рдбреЗрдЯрд╛ рдЖрдпрд╛рдд рдФрд░ рдкрд╛рд░реНрд╕ рдХрд░рдирд╛


рдЖрдЗрдП рдЖрдпрд╛рдд рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдПрдХ рд╕рдВрд╢реЛрдзрди рдХрд░рдХреЗ рд╢реБрд░реВ рдХрд░реЗрдВ рдЬреЛ рднрд╡рд┐рд╖реНрдп рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рдбреЗрдЯрд╛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░реЗрдЧрд╛ рддрд╛рдХрд┐ рд╕рд░реНрд╡рд░ рд╕реЗ рдмрд╛рдж рдореЗрдВ рдЗрд╕рдХрд╛ рдЕрдиреБрд░реЛрдз рди рдХрд░реЗрдВред

Clear[importOnce]; importOnce[args___]:=importOnce[args]=Import[args]; If[FileExistsQ[#], Get[#], Null]&@FileNameJoin[{NotebookDirectory[], "importOnce.mx"}] 

рдбреЗрдЯрд╛ рдЖрдпрд╛рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдкрд╛рд░реНрд╕рд░ рдмрдирд╛рдПрдВред

 Clear[createPageLinkDataset]; createPageLinkDataset[baseLink_]:=createPageLinkDataset[baseLink]=Cases[Cases[Import[baseLink, "XMLObject"], XMLElement["div", {"class"->"mw-content-ltr", "dir"->"ltr", "lang"->"en"}, data_]:>data, Infinity], XMLElement["li", {}, {XMLElement["a", {___, "href"->link_, ___}, {name_}]}]:><|"name"->name, "link"->"http://rosettacode.org"<>link|>, Infinity]; If[FileExistsQ[#], Get[#], Null]&@FileNameJoin[{NotebookDirectory[], "createPageLinkDataset.mx"}] 

рд╣рдо рдкрд░рд┐рдпреЛрдЬрдирд╛ рджреНрд╡рд╛рд░рд╛ рд╕рдорд░реНрдерд┐рдд рд╕рднреА рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛рдУрдВ рдХреА рд╕реВрдЪреА рдЖрдпрд╛рдд рдХрд░рддреЗ рд╣реИрдВ (рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЙрдирдореЗрдВ рд╕реЗ 750 рд╕реЗ рдЕрдзрд┐рдХ рд╣реИрдВ):

 $Languages=createPageLinkDataset["http://rosettacode.org/wiki/Category:Programming_Languages"]; Dataset@$Languages 



рд╣рдо рдПрдХ рд▓рд┐рдВрдХ рдореЗрдВ рдирд╛рдо рдХрд╛ рдЕрдиреБрд╡рд╛рдж рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрдп рдХрд░реЗрдВрдЧреЗ рдФрд░ рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд, рдпрд╣ рдмрд╛рдж рдореЗрдВ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛:

 langLinkToName[link_String]:=langLinkToName[link]=SelectFirst[$Languages, #[["link"]]==link&]["name"]; langNameToLink[name_String]:=langNameToLink[name]=SelectFirst[$Languages, #[["name"]]==name&]["link"]; 

рд╣рдо рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛рдУрдВ рдореЗрдВ рд╣рд▓ рдХрд┐рдП рдЧрдП рдХрд╛рд░реНрдпреЛрдВ рдХреА рд╕реВрдЪреА рдХреЛ рд▓реЛрдб рдХрд░реЗрдВрдЧреЗред рдкрд╛рд░реНрд╕рд┐рдВрдЧ рдХреЛ рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рддрд╛рдХрд┐ рдкреГрд╖реНрдареЛрдВ рдХреЗ рд╕рднреА рд▓рд┐рдВрдХ рдХрд╛рд░реНрдп рди рд╣реЛрдВред рд╣рдо рдЙрдиреНрд╣реЗрдВ рдмрд╛рдж рдореЗрдВ рд╕рд╛рдл рдХрд░реЗрдВрдЧреЗред

 $LangTasksAllPre=Map[<|"name"->#["name"], "link"->#["link"], "tasks"->createPageLinkDataset[#["link"]][[All, "link"]]|>&, $Languages]; Dataset@$LangTasksAllPre 



рд╣рдо рдЙрди рд╕рднреА рд╕рдВрднрд╛рд╡рд┐рдд рдХрд╛рд░реНрдпреЛрдВ рдХреА рд╕реВрдЪреА рдХреА рдЧрдгрдирд╛ рдХрд░рддреЗ рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рд╣рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ (рдЙрдирдореЗрдВ рд╕реЗ рдХреЗрд╡рд▓ 2600 рд╕реЗ рдЕрдзрд┐рдХ рд╣реИрдВ):

 $TasksPre=DeleteDuplicates[Flatten[$LangTasksAllPre[[;;, "tasks"]]]]; Length[$TasksPre] 



рдЖрдЗрдП рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдмрдирд╛рдПрдВ рдЬреЛ рдХрд╛рд░реНрдп рдкреГрд╖реНрда рдкрд░ рд╕рднреА рдХреЛрдб рдЕрдВрд╢реЛрдВ рдХреЛ рдХреИрдкреНрдЪрд░ рдХрд░рддрд╛ рд╣реИред

 ClearAll[codeExtractor]; codeExtractor[link_String]:=Module[{code, positions, rawData}, code=importOnce[link, "XMLObject"]; positions=Map[{#[[1, 1;;-2]], Partition[#[[;;, -1]], 2, 1]}&, DeleteCases[ Gather[ Position[code, XMLElement["h2", _, title_]], And[Length[#1]==Length[#2], #1[[1;;-2]]==#2[[1;;-2]]]&], x_/; Length[x]==1]]; rawData=Framed/@Flatten[Map[ With[{pos=#[[1]]}, Map[Extract[code, pos][[#[[1]];;#[[2]]-1]]&, #[[2]]]]&, positions], 1]; Association@DeleteCases[Map[langLinkToName[("link"/.#)]->("code"/.#)&, Map[ KeyValueMap[If[#1==="link", #1->#2[[1]], #1->#2]&, Merge[SequenceSplit[Cases[#, Highlighted[x_, ___]:>x, Infinity], {"Output"}][[1]], Identity]]&, rawData/.{XMLElement["h2", _, title_]:>Cases[title, XMLElement["a", {___, "href"->linkInner_/; MemberQ[$Languages[[;;, "link"]], "http://rosettacode.org"<>linkInner], ___}, {___}]:>Highlighted[<|"link"->"http://rosettacode.org"<>linkInner|>], Infinity], XMLElement["div", {}, x_/; Not[FreeQ[x, "Output:"]]]:>Highlighted["Output"], XMLElement["pre", _, code_]:>Highlighted[<|"code"->Check[StringJoin@Flatten[code//.XMLElement["span", _, codeFragment_]:>codeFragment//.XMLElement["br", {"clear"->"none"}, {}]:>"\n"//.XMLElement["a", {___}, codeFragment_]:>codeFragment//.XMLElement["b", {}, {x_}]:>x//.XMLElement["big", {}, {x_}]:>x//.XMLElement["sup", {}, x_]:>Flatten[x]//.XMLElement["sub", {}, x_]:>Flatten[x]//.XMLElement[_, {___}, x_]:>Flatten[x]], Echo[StringJoin@Flatten[code//.XMLElement["span", _, codeFragment_]:>codeFragment//.XMLElement["br", {"clear"->"none"}, {}]:>"\n"//.XMLElement["a", {___}, codeFragment_]:>codeFragment//.XMLElement["b", {}, {x_}]:>x//.XMLElement["big", {}, {x_}]:>x//.XMLElement["sup", {}, x_]:>Flatten[x]//.XMLElement["sub", {}, x_]:>Flatten[x]//.XMLElement[_, {___}, x_]:>Flatten[x]]]]|>, Background->Red]} ]], _->"code"]]; 

рдЕрдм рд╣рдо рд╕рднреА рдкреГрд╖реНрдареЛрдВ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░реЗрдВрдЧреЗ:

 ClearAll[taskCodes]; taskCodes[link_]:=taskCodes[link]=Check[codeExtractor[link], Echo[link]]; If[FileExistsQ[#], Get[#], taskCodes/@$TasksPre; DumpSave[#, taskCodes]]&@FileNameJoin[{NotebookDirectory[], "taskCodes.mx"}]; 

рдлрд╝рдВрдХреНрд╢рди рдХреНрдпрд╛ рдкреИрджрд╛ рдХрд░рддрд╛ рд╣реИ рдЗрд╕рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг:

 Dataset[taskCodes[$TasksPre[[20]]]] 

рд▓рдВрдмреА рддрд╕реНрд╡реАрд░


рдХрд╛рд░реНрдп рдкреГрд╖реНрда (рдХреЛрдб рдХреЗ рдХрдо рд╕реЗ рдХрдо рдПрдХ рдЯреБрдХрдбрд╝реЗ рд╡рд╛рд▓реЗ) рдХрд╛ рдЪрдпрди рдХрд░реЗрдВ:

 $taskLangs=DeleteCases[{#, taskCodes[#]}&/@$TasksPre, {_, <||>}]; 

 $langTasks=Map[<|"name"->#[["name"]], "link"->#[["link"]], "tasks"->With[{lang=#[["name"]]}, Select[$taskLangs, MemberQ[Keys[#[[2]]], lang]&][[;;, 1]]]|>&, $Languages]; Dataset[$langTasks] 



рдХрд╛рд░реНрдпреЛрдВ рдФрд░ рдХрд╛рд░реНрдпреЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рдЬреЛ рд▓рд┐рдВрдХ рдореЗрдВ рдХрд╛рд░реНрдп рдирд╛рдо рдХрд╛ рдЕрдиреБрд╡рд╛рдж рдХрд░рддреА рд╣реИ, рдФрд░ рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд:

 $Tasks=<|"name"->StringReplace[URLDecode[StringReplace[#, "http://rosettacode.org/wiki/"->""]], {"_"->" ", "/"->" -> "}], "link"->#|>&/@$taskLangs[[;;, 1]]; taskLinkToName[link_String]:=langLinkToName[link]=SelectFirst[$Tasks, #[["link"]]==link&]["name"]; taskNameToLink[name_String]:=langNameToLink[name]=SelectFirst[$Tasks, #[["name"]]==name&]["link"]; 

рд╕рд░рд▓ рдЖрдБрдХрдбрд╝реЗ


рдХрдИ рднрд╛рд╖рд╛рдУрдВ рдХреЗ рд▓рд┐рдП, рдЕрднреА рднреА рдХреЛрдИ рд╕рдорд╕реНрдпрд╛ рд╣рд▓ рдирд╣реАрдВ рд╣реБрдИ рд╣реИ:

 WordCloud[1/StringLength[#]->#&/@Select[$langTasks, Length[#["tasks"]]==0&][[All, "name"]], ImageSize->{1200, 800}, MaxItems->All, WordOrientation->{{-Pi/4, Pi/4}}, FontTracking->"Extended", Background->GrayLevel[0.98], FontFamily->"Intro"] 



рдЙрди рднрд╛рд╖рд╛рдУрдВ рдХреА рд╕реВрдЪреА, рдЬрд┐рдиреНрд╣реЛрдВрдиреЗ рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рд╣рд▓ рдХрд┐рдпрд╛ рд╣реИ:

 $LanguagesWithTasks=Select[$langTasks, Length[#["tasks"]]=!=0&][[All, "name"]]; Length[$LanguagesWithTasks] 



рднрд╛рд╖рд╛ рджреНрд╡рд╛рд░рд╛ рд╣рд▓ рдХреА рдЧрдИ рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХрд╛ рд╡рд┐рддрд░рдг:

 Histogram[Length/@$langTasks[[;;, "tasks"]], 50, PlotRange->All, BarOrigin->Bottom, AspectRatio->1/2, ImageSize->700, Background->White, Frame->True, GridLines->Automatic, FrameLabel->Map[Style[#, 20]&, {" ", lg[" "]}], ScalingFunctions->"Log10", PlotLabel->Style["     ", 20]] 



рд╣рд▓ рдХрд┐рдП рдЧрдП рдХрд╛рд░реНрдпреЛрдВ рджреНрд╡рд╛рд░рд╛ рднрд╛рд╖рд╛рдУрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХрд╛ рд╡рд┐рддрд░рдг:

 Histogram[Length/@$taskLangs[[;;, 2]], 50, PlotRange->All, AspectRatio->1/2, ImageSize->700, Background->White, Frame->True, GridLines->Automatic, FrameLabel->Map[Style[#, 20]&, {" ", " "}], PlotLabel->Style["     ", 20]] 



рд╡реЗ рднрд╛рд╖рд╛рдПрдБ рдЬрд┐рдирдореЗрдВ рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рд╣рд▓ рдХреА рдЧрдИ рд╕рдорд╕реНрдпрд╛рдПрдВ рд╣реИрдВ:

 BarChart[#1[[;;, 2]], PlotRangePadding->0, BarSpacing -> 0.1, BarOrigin -> Left, AspectRatio -> 1, ImageSize -> 1000, ChartLabels -> #1[[;;, 1]], Frame -> True, GridLines -> {Range[0, 10^3, 50], None}, ColorFunction -> ColorData["Rainbow"], FrameLabel->{{None, None}, Style[#, FontFamily->"Open Sans Light", 16]&/@{"  ", "  "}}, FrameTicks->{Automatic, {All, All}}, Background->White] &@DeleteCases[SortBy[{#[["name"]], Length[#[["tasks"]]]}&/@$langTasks, Last], {_, x_/; x<200}] 



рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛рдУрдВ рдХреА рд╕рдмрд╕реЗ рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рд╣рд▓ рдХрд┐рдП рдЧрдП рдХрд╛рд░реНрдп:

 BarChart[#1[[;;, 2]], PlotRangePadding->0, BarSpacing -> 0.2, BarOrigin -> Left, AspectRatio -> 1.6, ImageSize -> 1000, ChartLabels -> #1[[;;, 1]], Frame -> True, GridLines -> {Range[0, 10^3, 50], None}, ColorFunction -> ColorData["Rainbow"], FrameLabel->{{None, None}, Style[#, FontFamily->"Open Sans Light", 16]&/@{"  ", "  "}}, FrameTicks->{Automatic, {All, All}}, Background->White] &@DeleteCases[SortBy[{taskLinkToName[#[[1]]], Length[#[[2]]]}&/@$taskLangs, Last], {_, x_/; x<100}] 



рдХрд╛рд░реНрдп рдЬреЛ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛рдУрдВ рдХреЗ рджрд┐рдП рдЧрдП рд╕реЗрдЯ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдорд╛рдзрд╛рди рд╣реИ


рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдЬреЛ рдПрдХ рдмрд╛рд░ рдореЗрдВ рдПрдХ рдпрд╛ рдЕрдзрд┐рдХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛рдУрдВ рдореЗрдВ рд╣рд▓ рдХрд┐рдП рдЧрдП рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИ:

 commonTasks[lang_String]:=commonTasks[lang]=Sort[SelectFirst[$langTasks, #["name"]==lang&][["tasks"]]]; commonTasks["Mathematica"]:=commonTasks["Mathematica"]=Union[commonTasks["Wolfram Language"], Sort[SelectFirst[$langTasks, #["name"]=="Mathematica"&][["tasks"]]]]; commonTasks[lang_List]:=commonTasks[lang]=Sort[Intersection@@(commonTasks/@lang)]; 

рдкрд╣рд▓реЗ 25 рд╕рдмрд╕реЗ рд▓реЛрдХрдкреНрд░рд┐рдп рднрд╛рд╖рд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрдп (рдлрд╝реЙрдиреНрдЯ рдЖрдХрд╛рд░ рдЙрди рднрд╛рд╖рд╛рдУрдВ рдХреА рд╕рд╛рдкреЗрдХреНрд╖ рд╕рдВрдЦреНрдпрд╛ рд╕реЗ рдореЗрд▓ рдЦрд╛рддрд╛ рд╣реИ рдЬрд┐рдирдореЗрдВ рд╕рдорд╕реНрдпрд╛ рд╣рд▓ рд╣реЛ рдЧрдИ рд╣реИ):

 WordCloud[With[{tasks=taskLinkToName/@commonTasks[SortBy[{#[["name"]], Length[#[["tasks"]]]}&/@$langTasks, Last][[-25;;-1]][[;;, 1]]]}, Transpose@{tasks, tasks/.Rule@@@SortBy[{taskLinkToName[#[[1]]], Length[#[[2]]]}&/@$taskLangs, Last]}], ImageSize->{1000, 1000}, MaxItems->All, WordOrientation->{{-Pi/4, Pi/4, 0, Pi/2}}, Background->GrayLevel[0.98], FontFamily->"Intro"] 



рдХреЛрдб рдХреА рд▓рдВрдмрд╛рдИ рдорд╛рдкрдиреЗ рдХрд╛ рдХрд╛рд░реНрдп


рдЕрдЧрд▓рд╛, рд╣рдореЗрдВ рдХреЛрдб рд▓рдВрдмрд╛рдИ рдХрд╛ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдореАрдЯреНрд░рд┐рдХ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЖрдорддреМрд░ рдкрд░ рдпрд╣ рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдХреЛрдб рдХреА рд╕рдВрдЦреНрдпрд╛ рд╣реИ:

 SetAttributes[lineCount, Listable] lineCount[str_String]:=StringCount[StringReplace[StringReplace[str, {" "->"", "\t"->""}], "\n"..->"\n"], "\n"]+1; 

рд▓реЗрдХрд┐рди рдЪреВрдВрдХрд┐ рдпрд╣ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЛрдб рдХреЗ рдорд╛рд░реНрдХрдЕрдк рд╕реЗ рдХрд╛рдлреА рдкреНрд░рднрд╛рд╡рд┐рдд рд╣реЛрддрд╛ рд╣реИ (рдЕрдВрдд рдореЗрдВ, рдХрд╣рддреЗ рд╣реИрдВ, рд╡реБрд▓реНрдлрд░рд╛рдо рд▓реИрдВрдЧрд┐рдПрдЬ ( рдореИрдереЗрдореЗрдЯрд┐рдХрд╛ ) рдореЗрдВ рдЖрдк рдПрдХ рдмрд╛рд░ рдореЗрдВ рдПрдХ рдкрдВрдХреНрддрд┐ рдореЗрдВ рдХрдИ рдХрдорд╛рдВрдб рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ), рд╣рдо рдЙрди рд╡рд░реНрдгреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ рдЬреЛ рдореАрдЯреНрд░рд┐рдХ рдХреЗ рд░реВрдк рдореЗрдВ рд╕реНрдерд╛рди рдирд╣реАрдВ рд╣реИрдВред

 SetAttributes[characterCount, Listable] characterCount[str_String]:=StringLength[StringReplace[str, WhitespaceCharacter->""]]; 

рдРрд╕рд╛ рдореАрдЯреНрд░рд┐рдХ рдЕрдкрдиреЗ рд▓рдВрдмреЗ рд╡рд░реНрдгрдирд╛рддреНрдордХ рдЖрджреЗрд╢ рдирд╛рдореЛрдВ (рдЬреЛ рдЗрд╕ рдмреНрд▓реЙрдЧ рдХреЗ рдмрд╛рд╣рд░ рдирд┐рд╕реНрд╕рдВрджреЗрд╣ рдПрдХ рдмрдбрд╝рд╛ рдкреНрд▓рд╕ рд╣реИ) рдХреЗ рд╕рд╛рде рдЧрдгрд┐рддрдЬреНрдЮ рдХреЗ рд╣рд╛рдереЛрдВ рдореЗрдВ рдирд╣реАрдВ рдЦреЗрд▓рддрд╛ рд╣реИ; рдЗрд╕рд▓рд┐рдП, рд╣рдо рднреА рдЧрд┐рдирддреА рдЯреЛрдХрди ("рдкреНрд░рддреАрдХрд╛рддреНрдордХ") рд╡рд╕реНрддреБрдУрдВ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдПрдХ рдореАрдЯреНрд░рд┐рдХ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рд╣рдо рдХрд┐рд╕реА рднреА рд╡рд░реНрдг рджреНрд╡рд╛рд░рд╛ рдЕрд▓рдЧ рдХрд┐рдП рдЧрдП рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╢рдмреНрджреЛрдВ рдХреЛ рд▓реЗрдВрдЧреЗ рдЬреЛ рдХрд┐ рдПрдХ рдЕрдХреНрд╖рд░ рдирд╣реАрдВ рд╣реИред рдкрддреНрд░ред

 SetAttributes[tokens, Listable] tokens[str_String]:=DeleteCases[StringSplit[str, Complement[Characters@FromCharacterCode[Range[1, 127]], CharacterRange["a", "z"], CharacterRange["A", "Z"], CharacterRange["0", "9"], {"."}]], ""]; tokenCount[str_String]:=Length[tokens[str]]; 

рдХреЛрдб рд▓рдВрдмрд╛рдИ рдорд╛рдк


рд╣рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рдХрд╛рд░реНрдп рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХ рдбреЗрдЯрд╛ рд╕реЗрдЯ рдорд┐рд▓рддрд╛ рд╣реИ:

 $taskData=Map[<|"name"->#[[1]], "lineCount"->Map[lineCount, #[[2]]], "characterCount"->Map[characterCount, #[[2]]], "tokens"->Map[Flatten[tokens[#]]&, #[[2]]]|>&, $taskLangs]; Dataset[$taskData] 



рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдЬреЛ рдЙрд╕ рдкрд░ рд╣рд▓ рдХрд┐рдП рдЧрдП рд╕рднреА рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рднрд╛рд╖рд╛ рдХреЗ рд▓рд┐рдП рдЖрдВрдХрдбрд╝реЗ рдПрдХрддреНрд░ рдХрд░рддрд╛ рд╣реИ:

 Clear[langData]; langData[name_]:=langData[name]=<|"name"->name, "lineCount"->If[name==="Mathematica", DeleteMissing[AssociationThread[#[[;;, "name"]]->Lookup[#[[;;, "lineCount"]], name]]]~Join~DeleteMissing[AssociationThread[#[[;;, "name"]]->Lookup[#[[;;, "lineCount"]], "Wolfram Language"]]], AssociationThread[#[[;;, "name"]]->Lookup[#[[;;, "lineCount"]], name]]], "characterCount"->If[name==="Mathematica", DeleteMissing[AssociationThread[#[[;;, "name"]]->Lookup[#[[;;, "characterCount"]], name]]]~Join~DeleteMissing[AssociationThread[#[[;;, "name"]]->Lookup[#[[;;, "characterCount"]], "Wolfram Language"]]], AssociationThread[#[[;;, "name"]]->Lookup[#[[;;, "characterCount"]], name]]], "tokens"->If[name==="Mathematica", DeleteMissing[AssociationThread[#[[;;, "name"]]->Lookup[#[[;;, "tokens"]], name]]]~Join~DeleteMissing[AssociationThread[#[[;;, "name"]]->Lookup[#[[;;, "tokens"]], "Wolfram Language"]]], AssociationThread[#[[;;, "name"]]->Lookup[#[[;;, "tokens"]], name]]]|>&@(With[{task=#}, SelectFirst[$taskData, #[["name"]]==task&]]&/@commonTasks[name]); Map[langData, $LanguagesWithTasks]; 

рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдЬреЛ рд╕рднреА рд╕рд╛рдорд╛рдиреНрдп рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рджреЛ (рдпрд╛ рдЕрдзрд┐рдХ) рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛рдУрдВ рдХреЗ рд▓рд┐рдП рддреБрд▓рдирд╛ рдореИрдЯреНрд░рд┐рдХреНрд╕ рдХреА рддреБрд▓рдирд╛ рдХрд░рддрд╛ рд╣реИ:

 ClearAll[compareLanguagesData, compareLanguages]; compareLanguagesData[langs_List/; Length[langs]>=2]:=compareLanguagesData[langs]=Module[{tasks, data}, tasks=commonTasks[langs]; data=langData/@langs; <|"lineCount"->Transpose[Lookup[#[["lineCount"]], tasks][[;;, 1]]&/@data], "characterCount"->Transpose[Lookup[#[["characterCount"]], tasks][[;;, 1]]&/@data], "tokensCount"->Transpose[Lookup[Map[Length, #[["tokens"]]], tasks]&/@data]|> ]; compareLanguages[langs_List/; Length[langs]>=2, function_]:=Module[{data}, data=compareLanguagesData[langs]; Map[Map[function, #]&, data] ]; 

рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдФрд░ рджреГрд╢реНрдп


рдЕрдм рд╣рдо рдмрд╣реБрдд рд╕рд╛рд░реЗ рд╡рд┐рд╢реНрд▓реЗрд╖рд┐рдХреА рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдкреВрд░реНрдг рд╕рдВрдХреЗрддрдХреЛрдВ рдХреА рддреБрд▓рдирд╛ рдХрд░рддреЗ рд╣реИрдВред рдиреАрдЪреЗ рджрд┐рдпрд╛ рдЧрдпрд╛ рдлрд╝рдВрдХреНрд╢рди рдПрдХ рдЧреНрд░рд╛рдлрд╝ рдмрдирд╛рддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдбреЙрдЯреНрд╕ рджреЛ рднрд╛рд╖рд╛рдУрдВ рдХреЗ рд▓рд┐рдП рд╕рдВрдмрдВрдзрд┐рдд рдорд╛рди рджрд┐рдЦрд╛рддреЗ рд╣реИрдВред рдпрджрд┐ рдмрд┐рдВрджреБ рд╡рд┐рдХрд░реНрдг рд░реЗрдЦрд╛ рдХреЗ рдиреАрдЪреЗ рд╣реИ (рдХреБрд▓реНрд╣рд╛рдбрд╝рд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдкреИрдорд╛рдиреЗ рдЕрд▓рдЧ рд╣реИ, рддреЛ рдЕрдХреНрд╕рд░ рдпрджрд┐ рдХреЛрдб рдХреА рд▓рдВрдмрд╛рдИ рдмрд╣реБрдд рднрд┐рдиреНрди рд╣реЛрддреА рд╣реИ), рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдиреАрдЪреЗ рд╕реЗ рднрд╛рд╖рд╛ "рдЬреАрддрд╛", рдЕрдиреНрдпрдерд╛ рднрд╛рд╖рд╛ "рдКрдкрд░ рд╕реЗ" рд╣реИред

 compareGraphic[{lang1_, lang2_}]:= Grid[{#[[1;;2]], {#[[3]], SpanFromLeft}}&@KeyValueMap[Graphics[{Map[{If[#[[1]]<#[[2]], Orange, Darker@Green], Point[#]}&, #2], AbsoluteThickness[2], Gray, InfiniteLine[{{0, 0}, {1, 1}}]}, PlotRangePadding->0, GridLines->Automatic, AspectRatio->1, PlotRange->All, Frame->True, ImageSize->500, Background->White, FrameLabel->(Style[#/."Mathematica"->"Wolfram Language (Mathematica)", 16, FontFamily->"Open Sans Light"]&/@{lang1, lang2}), PlotLabel->(Style[(#1/.{"lineCount"->"  ", "characterCount"->"   ", "tokensCount"->"   "}), 20, FontFamily->"Open Sans Light"])]&, compareLanguages[{lang1, lang2}, Identity]], Background->White] 

рдЖрдк рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рд╡реБрд▓реНрдлрд░рд╛рдо рднрд╛рд╖рд╛ рдХреЛрдб рд╣рдореЗрд╢рд╛ C рдХреЛрдб рд╕реЗ рд▓рдЧрднрдЧ рдЫреЛрдЯрд╛ рд╣реЛрддрд╛ рд╣реИ:

 compareGraphic[{"Mathematica", "C"}] 



рдпрд╛ рдкрд╛рдпрдерди:

 compareGraphic[{"Mathematica", "Python"}] 



рдФрд░ рдпрд╣рд╛рдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХреЛрдЯрд▓рд┐рди рдФрд░ рдЬрд╛рд╡рд╛ рдЕрдирд┐рд╡рд╛рд░реНрдп рд░реВрдк рд╕реЗ рдХреЛрдб рд▓рдВрдмрд╛рдИ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ "рд╕рдорд╛рди" рд╣реИрдВ:

 compareGraphic[{"Kotlin", "Java"}] 



рдЗрд╕ рдЧреНрд░рд╛рдлрд┐рдХ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХреЛ рдФрд░ рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реАрдкреВрд░реНрдг рдмрдирд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:

 comparePlot[{lang1_, lang2_}]:= Grid[{#[[1;;2]], {#[[3]], SpanFromLeft}}&@KeyValueMap[ListLinePlot[Sort@#2, GridLines->Automatic, AspectRatio->1, PlotRange->{Automatic, {0, 2}}, Frame->True, ImageSize->500, Background->White, FrameLabel->(Style[#/."Mathematica"->"Wolfram Language (Mathematica)", 16, FontFamily->"Open Sans Light"]&/@{lang1, lang2}), PlotLabel->(Style[(#1/.{"lineCount"->"  ", "characterCount"->"   ", "tokensCount"->"   "}), 20, FontFamily->"Open Sans Light"]), ColorFunction->(If[#2>1, Orange, Darker@Green]&), ColorFunctionScaling->False, PlotStyle->AbsoluteThickness[3]]&, compareLanguages[{lang1, lang2}, Divide[#[[1]], #[[2]]]&]], Background->White] 

 comparePlot[{"Mathematica", "R"}] 



 comparePlot[{"BASIC", "ALGOL 68"}] 



рд╣рдо рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ "рд▓реЛрдХрдкреНрд░рд┐рдп" рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛рдУрдВ рдХреА рд╕реВрдЪреА рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░реЗрдЧрд╛ (рдЬреЛ рд╕рдмрд╕реЗ рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рд╣рд▓ рдХрд┐рдП рдЧрдП рдХрд╛рд░реНрдп рд╣реИрдВ):

 Clear[$popularLanguages]; $popularLanguages[n_/; n>2]:=$popularLanguages[n]=Reverse[SortBy[{#[["name"]], Length[#[["tasks"]]]}&/@$langTasks, Last][[-n;;-1]]] 

 $popularLanguages[25] 



рд╣рдо рдкрд╣рд▓реЗ 350 рднрд╛рд╖рд╛рдУрдВ рдХреА рд╕реВрдЪреА рдХреА рдХрд▓реНрдкрдирд╛ рдХрд░рддреЗ рд╣реИрдВ (рдЗрд╕ рддрд░рд╣ рдЗрд╕ рдкреЛрд╕реНрдЯ рдХреЗ рд▓рд┐рдП рд╕реНрдХреНрд░реАрдирд╕реЗрд╡рд░ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рдерд╛):

 WordCloud[$popularLanguages[350], ColorNegate@Binarize@ImageCrop@Import@"D:\\YandexDisk\\WolframMathematicaRuFiles\\388-3885229_rosetta-stone-silhouette-stone-silhouette-png-transparent-png.png", ImageSize->1000, MaxItems->All, WordOrientation->{{-Pi/4, Pi/4}}, FontTracking->"Extended", Background->GrayLevel[0.98], FontFamily->"Intro"] 



рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдЬреЛ n рдкрд╣рд▓реА рд▓реЛрдХрдкреНрд░рд┐рдп рднрд╛рд╖рд╛рдУрдВ рдХреЗ рд▓рд┐рдП рд╡рд┐рднрд┐рдиреНрди рдореИрдЯреНрд░рд┐рдХреНрд╕ рдореЗрдВ рдХреЛрдб рд▓рдВрдмрд╛рдИ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИ:

 ClearAll[langMetricsGrid]; langMetricsGrid[n_Integer, type_, OptionsPattern[{"SortQ"->True, "measureFunction"->Mean}]]:=Module[{$nPL, $pl, tableData, scale, notSortedTableData, order, fullTableData, min, max, orderedMeans, meanFunction}, $nPL=n; meanFunction[{lang1_, lang2_}]:=Quiet[Map[Median[N[#]]&, compareLanguages[{lang1, lang2}, Divide[#[[1]], #[[2]]]&]/.ComplexInfinity->Nothing/.Indeterminate->Nothing]]; $pl=$popularLanguages[$nPL][[;;, 1]]; tableData=Quiet@Table[If[i==j, "", meanFunction[{$pl[[i]], $pl[[j]]}][[type]]], {i, 1, $nPL}, {j, 1, $nPL}]; order=If[OptionValue["SortQ"], Ordering[tableData, All, OptionValue["measureFunction"][#1/.""->Nothing]<OptionValue["measureFunction"][#2/.""->Nothing]&], Range[1, $nPL]]; orderedMeans=Round[If[OptionValue["SortQ"], Map[Mean, tableData/.""->Nothing][[order]], Map[Mean, tableData/.""->Nothing]], 1/1000]//N; {min, max}=MinMax[Cases[Flatten[tableData], _?NumericQ]]; scale=Function[Evaluate[Rescale[#, {min, max}, {0, 1}]]]; fullTableData=Transpose[{{""}~Join~$pl[[order]]}~Join~{{""}~Join~orderedMeans}~Join~Transpose[{Map[Rotate[#, 90Degree]&, $pl]}~Join~ReplaceAll[tableData, x_?NumericQ:>Item[Round[x, 1/100]//N, Background->Which[x<1, LightGreen, x==1, LightBlue, x>1, LightRed]]][[order]]/.""->Item["", Background->Gray]]]; Framed[Labeled[Style[Row[{"    ", Style[type/.{"lineCount"->" ", "characterCount"->"  ", "tokensCount"->"  "}, Bold], "\n      "}], 22, FontFamily->"Open Sans Light", TextAlignment->Center], Grid[fullTableData, Background->White, ItemStyle->Directive[FontSize -> 12, FontFamily->"Open Sans Light"], Dividers->White]], FrameStyle->None, Background->White]]; 

рд╡рд┐рднрд┐рдиреНрди рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛рдУрдВ рдореЗрдВ рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдореЗрдВ рдХреЛрдб рдХреА рд▓рд╛рдЗрдиреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЗ рдЕрдиреБрдкрд╛рдд рдХрд╛ рдФрд╕рдд рдореВрд▓реНрдп:

 langMetricsGrid[25, "lineCount", "SortQ"->False] 



рдпрджрд┐ рдЖрдк "рдФрд╕рдд" рдХреЙрд▓рдо рджреНрд╡рд╛рд░рд╛ рддрд╛рд▓рд┐рдХрд╛ рдХреЛ рд╕реЙрд░реНрдЯ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рдЕрдзрд┐рдХ рд╕реНрдкрд╖реНрдЯ рд╣реЛрдЧрд╛ - рд╡реЛрд▓реНрдлреНрд░рд╛рдо рднрд╛рд╖рд╛ (рдЧрдгрд┐рдд) рд▓реАрдб:

 langMetricsGrid[25, "lineCount", "SortQ"->True] 



рд╡рд┐рднрд┐рдиреНрди рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛рдУрдВ рдореЗрдВ рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдореЗрдВ рдХреЛрдб рдореЗрдВ рд╡рд░реНрдгреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЗ рдЕрдиреБрдкрд╛рдд рдХрд╛ рдФрд╕рдд рдореВрд▓реНрдп:

 langMetricsGrid[25, "characterCount", "SortQ"->True] 



рд╡рд┐рднрд┐рдиреНрди рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛рдУрдВ рдореЗрдВ рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдореЗрдВ рдХреЛрдб рдореЗрдВ рдЯреЛрдХрди рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЗ рдЕрдиреБрдкрд╛рдд рдХрд╛ рдФрд╕рдд рдореВрд▓реНрдп:

 langMetricsGrid[25, "tokensCount", "SortQ"->True] 



рдкрд╣рд▓реЗ 50 рд╕рдмрд╕реЗ рд▓реЛрдХрдкреНрд░рд┐рдп рднрд╛рд╖рд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рд╣реА рдЯреЗрдмрд▓ рдмрдирд╛рдИ рдЬрд╛ рд╕рдХрддреА рд╣реИ, рдХрд╣рддреЗ рд╣реИрдВ:

 langMetricsGrid[50, "lineCount", "SortQ"->True] langMetricsGrid[50, "characterCount", "SortQ"->True] langMetricsGrid[50, "tokensCount", "SortQ"->True] 







рд╣рдо рдПрдХ рд╣реА рдЬрд╛рдирдХрд╛рд░реА рдХреЛ рдФрд░ рдЕрдзрд┐рдХ рдХреЙрдореНрдкреИрдХреНрдЯ рд░реВрдк рд╕реЗ рдХрд▓реНрдкрдирд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ - рдПрдХ рдореВрдВрдЫ рд╡рд╛рд▓реЗ рдмреЙрдХреНрд╕ рдХреЗ рд░реВрдк рдореЗрдВ (рдмреЙрдХреНрд╕-рдПрдВрдб-рд╡реНрд╣рд┐рдХрд░реНрд╕ рдбрд╛рдпрдЧреНрд░рд╛рдо):

 ClearAll[langMetricsBoxWhiskerChart]; langMetricsBoxWhiskerChart[n_Integer, type_, OptionsPattern[{"SortQ"->True, "measureFunction"->Mean}]]:=Module[{$nPL, $pl, tableData, scale, notSortedTableData, order, fullTableData, min, max, orderedMeans, meanFunction}, $nPL=n; meanFunction[{lang1_, lang2_}]:=Quiet[Map[Median[N[#]]&, compareLanguages[{lang1, lang2}, Divide[#[[1]], #[[2]]]&]/.ComplexInfinity->Nothing/.Indeterminate->Nothing]]; $pl=Reverse@$popularLanguages[$nPL][[;;, 1]]; tableData=Quiet@Table[If[i==j, "", meanFunction[{$pl[[i]], $pl[[j]]}][[type]]], {i, 1, $nPL}, {j, 1, $nPL}]; order=If[OptionValue["SortQ"], Ordering[tableData, All, OptionValue["measureFunction"][#1/.""->Nothing]>OptionValue["measureFunction"][#2/.""->Nothing]&], Range[1, $nPL]]; Framed[Labeled[Style[Row[{"    ", Style[type/.{"lineCount"->" ", "characterCount"->"  ", "tokensCount"->"  "}, Bold], "\n      "}], 22, FontFamily->"Open Sans Light", TextAlignment->Center], BoxWhiskerChart[tableData[[order]], "Outliers", ChartLabels->$pl[[order]], BarOrigin->Left, ImageSize->1000, AspectRatio->1, GridLines->{Range[0, 20, 1/2], None}, FrameTicks->{Range[0, 20, 0.5], Automatic}, PlotRangePadding->0, PlotRange->{{0, 8}, Automatic}, Background->White] ], FrameStyle->None, Background->White]]; 

рднрд╛рд╖рд╛рдПрдВ рд▓реЛрдХрдкреНрд░рд┐рдпрддрд╛ рджреНрд╡рд╛рд░рд╛ рдХреНрд░рдордмрджреНрдз рд╣реЛрддреА рд╣реИрдВ (рдЖрд░реЗрдЦ рднрд╛рд╖рд╛рдУрдВ рдХреЗ рдмреАрдЪ рдХреЛрдб рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХрд╛ рдЕрдиреБрдкрд╛рдд рджрд┐рдЦрд╛рддрд╛ рд╣реИ):

 langMetricsBoxWhiskerChart[80, "lineCount", "SortQ"->False] 



рдФрд╕рдд рдореВрд▓реНрдп рджреНрд╡рд╛рд░рд╛:

 langMetricsBoxWhiskerChart[80, "lineCount", "SortQ"->True] 



рдЕрдВрдд рдореЗрдВ, рд╡рд░реНрдг рдФрд░ рдЯреЛрдХрди рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЪрд╛рд░реНрдЯ:

 langMetricsBoxWhiskerChart[80, "characterCount", "SortQ"->True] langMetricsBoxWhiskerChart[80, "tokensCount", "SortQ"->True] 





рдЖрдЗрдП рджреЗрдЦреЗрдВ рдХрд┐ рд╡рд┐рднрд┐рдиреНрди рднрд╛рд╖рд╛рдУрдВ рдореЗрдВ рдХреМрди рд╕реЗ рдЯреЛрдХрди рд▓реЛрдХрдкреНрд░рд┐рдп рд╣реИрдВ:

 languagePopularTokens[lang_, nMin_:50]:=Framed[Labeled[Style[Row[{"   ", Style[lang, Bold]}], FontFamily->"Open Sans Light", 24], WordCloud[Cases[SortBy[Tally[Flatten[Values[langData[lang][["tokens"]]]]], -Last[#]&], {x_/; (StringLength[x]>1&&StringMatchQ[x, RegularExpression["[a-zA-Z0-9.]+"]]&&Not[StringMatchQ[x, RegularExpression["[0-9.]+"]]]), y_/; y>nMin}], ImageSize->{1000, 500}, MaxItems->200, WordOrientation->{{-Pi/4, Pi/4}}, Background->GrayLevel[0.98]]], FrameStyle->None, Background->White] 

 clouds=Grid[{Image[#, ImageSize->All]&@Rasterize[languagePopularTokens[#, 10]]}&/@{"Mathematica", "C", "Python", "Go", "JavaScript"}] 



рдФрд░ рдЕрдВрдд рдореЗрдВ, рдЙрдирдХреЗ рдЯреЛрдХрди рдХреА рдирд┐рдХрдЯрддрд╛ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рднрд╛рд╖рд╛рдУрдВ рдХреА рдПрдХ рдмрд╣реБрдд рд╣реА рджрд┐рд▓рдЪрд╕реНрдк рддреБрд▓рдирд╛ред

LangSimilarity рдлрд╝рдВрдХреНрд╢рди рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ: рдкрд╣рд▓рд╛, "рд╕рд╛рд░реНрдердХ рдЯреЛрдХрди" рдЪреБрдиреЗ рдЧрдП рд╣реИрдВ (рдЬрд┐рдиреНрд╣реЗрдВ рдХрдо рд╕реЗ рдХрдо 2 рд╡рд░реНрдгреЛрдВ рдХреА рд▓рдВрдмрд╛рдИ рд╡рд╛рд▓реЗ рд▓реИрдЯрд┐рди рд╡рд░реНрдгреЛрдВ рдХреЗ рд╕рднреА рддрд╛рд░ рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдПрдХ рдЕрд╡рдзрд┐ рд╢рд╛рдорд┐рд▓ рд╣реЛ рд╕рдХрддреА рд╣реИ); рдлрд┐рд░ рдЯреЛрдХрди рднрд╛рд╖рд╛ рд▓реИрдВрдЧ 1 рдФрд░ рд▓реИрдВрдЧ 2 рдХреА рдПрдХ рдЬреЛрдбрд╝реА рдХреЗ рд▓рд┐рдП рдЦреЛрдЬреЗ рдЬрд╛рддреЗ рд╣реИрдВ; рдЙрд╕рдХреЗ рдмрд╛рдж, рдЙрдирдХреЗ "рд╕рдорд╛рдирддрд╛" рдХреЗ рдорд╛рдк рдХреЛ рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ, рдПрдХ рджреВрд╕рд░реЗ рдХреЗ рдмреАрдЪ рдЯреЛрдХрди рдХреА рдирд┐рдХрдЯрддрд╛ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд░рд╛рд╢рд┐ рджреНрд╡рд╛рд░рд╛ рдЯреЛрдХрди рдХреЗ рджреЛ рд╕реЗрдЯреЛрдВ рдХреЗ рдЬреИрдХреНрд╡рд╛рд░реНрдб рдХреЗ рдЙрддреНрдкрд╛рдж рдХреЗ рд░реВрдк рдореЗрдВ (рдлрд╛рд░реНрдо рдХреЗ рддрддреНрд╡реЛрдВ рдХрд╛ рдпреЛрдЧ)  fracw1+w21+ textAbs left[w1тИТw2 right]рдЬрд╣рд╛рдБ w1,w2рдХреНрд░рдорд╢рдГ lang1 рдФрд░ lang2 рднрд╛рд╖рд╛ рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЗ рд╕рднреА рд╕рдорд╛рдзрд╛рдиреЛрдВ рдореЗрдВ рдЯреЛрдХрди рджрд┐рдЦрд╛рд╡реЗ рдХрд╛ рдпреЛрдЧ рд╣реИ)ред

 Clear[langSimilarity]; langSimilarity[{lang1_,lang2_},clearTokens_]:=langSimilarity@@(Sort[{lang1,lang2}]~Join~{clearTokens}); langSimilarity[lang1_,lang2_,clearTokens_:False]:=langSimilarity[lang1,lang2,clearTokens]=Module[{tokens,t1,t2,t1W,t2W,intersection}, tokens[lang_]:=Module[{values,tokensPre,allValues,replacements,n}, values=Values[langData[lang][["tokens"]]]; n=Length[values]; allValues=DeleteDuplicates[Flatten[values]]; tokensPre=If[clearTokens,Cases[allValues,x_/;(StringLength[x]>1&&StringMatchQ[x,RegularExpression["[a-zA-Z0-9._$]+"]]&&Not[StringMatchQ[x,RegularExpression["[0-9.,eE]+"]]])],allValues]; replacements=Dispatch@ Thread[Complement[allValues,tokensPre]->Nothing]; Cases[Tally@Flatten@(values/.replacements),{t_,x_/;x>=n/10}:>{t,x}]]; {t1,t2}=tokens/@{lang1,lang2}; {t1W,t2W}=Dispatch/@{Rule@@@t1,Rule@@@t2}; intersection=Intersection[t1[[;;,1]],t2[[;;,1]]]; Times@@{Total[(#[[1]]+#[[2]])/(1+Abs[#[[1]]-#[[2]]])&/@Transpose@N[{intersection/.t1W,intersection/.t2W}]],Length[intersection]/Length[Union[t1[[;;,1]],t2[[;;,1]]]]}] 

 ClearAll[langSimilarityGrid]; langSimilarityGrid[n_Integer, OptionsPattern[{"SortQ" -> True, "measureFunction" -> Mean, "clearTokens" -> True}]] := Module[{$nPL, $pl, tableData, notSortedTableData, order, fullTableData, min, max, orderedMeans, median, rescale}, $nPL = n; $pl = $popularLanguages[$nPL][[;; , 1]]; tableData = Quiet@Table[ If[i == j, "", langSimilarity[{$pl[[i]], $pl[[j]]}, OptionValue["clearTokens"]]], {i, 1, $nPL}, {j, 1, $nPL}]; {min, max} = MinMax[Flatten[tableData] /. "" -> Nothing]; median = 10^Median@Log10@Flatten[tableData /. "" -> Nothing]; rescale = Function[Evaluate[Rescale[#, {median, max}, {0, 1}]]]; order = If[OptionValue["SortQ"], Ordering[tableData, All, OptionValue["measureFunction"][#1 /. "" -> Nothing] > OptionValue["measureFunction"][#2 /. "" -> Nothing] &], Range[1, $nPL]]; fullTableData = Transpose[{{""}~Join~$pl[[order]]}~Join~ Transpose[{Map[Rotate[#, 90 Degree] &, $pl]}~Join~ ReplaceAll[tableData[[order]], x_?NumericQ :> Item[Style[Round[x, 1], If[x < median, Black, White]], Background -> If[x < median, LightGray, ColorData["Rainbow"][rescale[x]]]]] /. "" -> Item["", Background -> Gray]]]; Framed[ Labeled[Style[ Row[{"      (  )", "\n", "(", Style[If[OptionValue["clearTokens"], "  ", "   "], Bold], ")"}], 22, FontFamily -> "Open Sans Light", TextAlignment -> Center], Grid[fullTableData, Background -> White, ItemStyle -> Directive[FontSize -> 12, FontFamily -> "Open Sans Light"], Dividers -> White]], FrameStyle -> None, Background -> White]]; 

UPD: рдПрдХ рдореВрд▓реНрдпрд╡рд╛рди рдЯрд┐рдкреНрдкрдгреА рдХреЗ рдмрд╛рдж, рдЗрдХрдЯреНрдареЗ рджреЛ рддрд╛рд▓рд┐рдХрд╛рдУрдВ рдХреЛ рдмрдирд╛рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛ рдЧрдпрд╛: рдкрд░рд┐рдгрд╛рдо рдХреЛ рдХрдо рд╕реЗ рдХрдо рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдХрд┐рд╕реА рднреА рдкреНрд░рдХрд╛рд░ рдХреА рд╕рдлрд╛рдИ рдХреЗ рдмрд┐рдирд╛, рд╕рд╛рдл рдЯреЛрдХрди рдФрд░ рд╕рднреА рдЯреЛрдХрди рдХреЗ рд╕рд╛рдеред рдкрд░рд┐рдгрд╛рдо рдереЛрдбрд╝рд╛ рдЕрд▓рдЧ рд╣реИ, рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдЕрдкрдиреЗ рд▓рд┐рдП рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдХреБрдЫ рдирд┐рд░реНрднрд░рддрд╛рдПрдВ рд╕реНрдкрд╖реНрдЯ рд╣реЛ рдЧрдИ рд╣реИрдВред

рдпрд╣рд╛рдБ рдкрд░ рд╣рдореЗрдВ рдЬреЛ рдорд┐рд▓рддрд╛ рд╣реИ (рдЕрдирд░реАрдб рдЯреЗрдмрд▓):

 langSimilarityGrid[30, "SortQ" -> False, "clearTokens" -> True] langSimilarityGrid[30, "SortQ" -> False, "clearTokens" -> False] 




рдХреНрд░рдордмрджреНрдз рддрд╛рд▓рд┐рдХрд╛ (рдЕрдиреНрдп рднрд╛рд╖рд╛рдУрдВ рдХреЗ рд╕рд╛рде рдФрд╕рдд рд╕рдорд╛рдирддрд╛ рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ - рдЙрдЪреНрдЪрддрд░ рд░реЗрдЦрд╛, рдЗрд╕ рднрд╛рд╖рд╛ рдХреА рдЕрдиреНрдп рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛рдУрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдЬрд┐рддрдиреА рдЕрдзрд┐рдХ рд╣реЛрдЧреА:

 langSimilarityGrid[30, "SortQ"->True, "clearTokens" -> True] langSimilarityGrid[30, "SortQ"->True, "clearTokens" -> False] 




рдЕрдВрдд рдореЗрдВ, рд▓реЛрдХрдкреНрд░рд┐рдпрддрд╛ рдореЗрдВ рдкрд╣рд▓реЗ 50 рднрд╛рд╖рд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рдмрдбрд╝реА рддрд╛рд▓рд┐рдХрд╛ред

рдпрд╣ рдЙрдореНрдореАрдж рдХреА рдЬрд╛рддреА рд╣реИ рдХрд┐ рдЬрд╛рд╡рд╛, рд╕реА, рд╕реА ++, рд╕реА # рдЬреИрд╕реА "рдкреНрд░рдореБрдЦ" рднрд╛рд╖рд╛рдПрдВ рд╢реАрд░реНрд╖ рдкрд░ рд╣реИрдВред рд░реИрдХреЗрдЯ (рдкрд╣рд▓реЗ PLTScheme) рдерд╛, рдЬрд┐рд╕рдХрд╛ рдПрдХ рдЙрджреНрджреЗрд╢реНрдп рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛рдУрдВ рдХрд╛ рдирд┐рд░реНрдорд╛рдг, рд╡рд┐рдХрд╛рд╕ рдФрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИред

рджрд┐рд▓рдЪрд╕реНрдк рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рд╡реБрд▓реНрдлрд░рд╛рдо рднрд╛рд╖рд╛ рдЕрдирд┐рд╡рд╛рд░реНрдп рд░реВрдк рд╕реЗ рдПрдХ рдЕрд▓рдЧ рднрд╛рд╖рд╛ рд╣реИред

рднрд╛рд╖рд╛рдУрдВ рдХреЗ рдмреАрдЪ рдХреЗ рд▓рд┐рдВрдХ рднреА рджрд┐рдЦрд╛рдИ рджреЗрддреЗ рд╣реИрдВ, рдорд╛рди рд▓реЗрдВ рдХрд┐ рдЬрд╛рд╡рд╛ рдФрд░ рд╕реА #, рдЧреЛ рдФрд░ рд╕реА, рд╕реА рдФрд░ рдЬрд╛рд╡рд╛, рд╣рд╛рд╕реНрдХреЗрд▓ рдФрд░ рдЬрд╛рд╡рд╛, рдХреЛрдЯрд▓рд┐рди рдФрд░ рдЬрд╛рд╡рд╛, рдкрд╛рдпрдерди рдФрд░ рдлрд┐рдХреНрд╕, рдкрд╛рдпрдерди рдФрд░ рд░реИрдХреЗрдЯ рдХреЗ рдмреАрдЪ рдХреА рдХрдбрд╝реА рдФрд░ рдмрд╣реБрдд рдХреБрдЫ рджрд┐рдЦрд╛рдИ рджреЗрддрд╛ рд╣реИред

 langSimilarityGrid[50, "SortQ"->True, "clearTokens" -> True] langSimilarityGrid[50, "SortQ"->True, "clearTokens" -> False] 




рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдпрд╣ рдЕрдзреНрдпрдпрди рдЖрдкрдХреЗ рд▓рд┐рдП рджрд┐рд▓рдЪрд╕реНрдк рд╣реЛрдЧрд╛ рдФрд░ рдЖрдк рдХреБрдЫ рдирдпрд╛ рдЦреЛрдЬ рд╕рдХреЗрдВрдЧреЗред рдореЗрд░реЗ рд▓рд┐рдП, рдПрдХ рд╡реНрдпрдХреНрддрд┐ рдХреЗ рд░реВрдк рдореЗрдВ рдЬреЛ рд▓рдЧрд╛рддрд╛рд░ рд╡реБрд▓реНрдлрд░рд╛рдо рднрд╛рд╖рд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рдпрд╣ рдЬрд╛рдирдХрд░ рдЕрдЪреНрдЫрд╛ рд▓рдЧрд╛ рдХрд┐ рдпрд╣ рдПрдХ рдУрд░ рд╕рдмрд╕реЗ "рдХреЙрдореНрдкреИрдХреНрдЯ" рднрд╛рд╖рд╛ рд╣реИ, рджреВрд╕рд░реА рдУрд░, рдЗрд╕рдХрд╛ рдЙрджреНрджреЗрд╢реНрдп рдЕрдиреНрдп рднрд╛рд╖рд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдЗрд╕рдХрд╛ "рдЕрд╕рдорд╛рдирддрд╛", рдЬрд╛рд╣рд┐рд░ рд╣реИ, рдЗрд╕реЗ рдереЛрдбрд╝рд╛ рдФрд░ рдореБрд╢реНрдХрд┐рд▓ рдмрдирд╛ рджреЗрддрд╛ рд╣реИред
рд╡реБрд▓реНрдлреНрд░рд╛рдо рднрд╛рд╖рд╛ рдореЗрдВ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреИрд╕реЗ рд╕реАрдЦрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ?
рд╕рд╛рдкреНрддрд╛рд╣рд┐рдХ рд╡реЗрдмрд┐рдирд╛рд░ рджреЗрдЦреЗрдВ ред
рдирдП рдкрд╛рдареНрдпрдХреНрд░рдореЛрдВ рдХреЗ рд▓рд┐рдП рдкрдВрдЬреАрдХрд░рдг ред рдСрдирд▓рд╛рдЗрди рдХреЛрд░реНрд╕ рддреИрдпрд╛рд░ рд╣реИред

Source: https://habr.com/ru/post/hi471244/


All Articles