<commit_before>package main

import (
	"net/http"
	"sort"
	"strconv"

	. "github.com/Deleplace/programming-idioms/pig"
	"github.com/gorilla/mux"
)

// CheatSheetMultipleFacade is the Facade for the Cheat Sheets with multiple languages.
type CheatSheetMultipleFacade struct {
	PageMeta    PageMeta
	UserProfile UserProfile
	Langs       []string
	Lines       []cheatSheetLineMulti
}

type cheatSheetLineMulti struct {
	IdiomID            int
	IdiomTitle         string
	IdiomLeadParagraph string

	// Depth represents the max number of impl for one language in ByLanguage
	Depth []struct{}

	ByLanguage []cheatSheetLineDocs
}

func (chsh *cheatSheetLineMulti) hasCell(langIndex, alt int) bool {
	return alt < len(chsh.Depth) &&
		langIndex < len(chsh.ByLanguage) &&
		alt < len(chsh.ByLanguage[langIndex])
}

func (chsh *cheatSheetLineMulti) computeDepth() {
	n := 0
	for _, lineDocs := range chsh.ByLanguage {
		if len(lineDocs) > n {
			n = len(lineDocs)
		}
	}
	chsh.Depth = make([]struct{}, n)
}

func cheatsheetDouble(w http.ResponseWriter, r *http.Request) error {
	vars := mux.Vars(r)
	langs := []string{vars["lang1"], vars["lang2"]}
	ctx := r.Context()

	// Security belt. Might be changed if needed.
	limit := 1000

	var lines []cheatSheetLineMulti

	byIdiomID := map[int][]cheatSheetLineDocs{}
	idiomTitles := map[int]string{}
	idiomLeadParagraphs := map[int]string{}
	for langIndex, lang := range langs {
		cheatsheetLines, err := dao.getCheatSheet(ctx, lang, limit)
		if err != nil {
			return PiError{err.Error(), http.StatusInternalServerError}
		}
		for _, line := range cheatsheetLines {
			idiomID, err := strconv.Atoi(string(line.IdiomID))
			if err != nil {
				return err
			}
			if _, exists := byIdiomID[idiomID]; exists {
				byIdiomID[idiomID][langIndex] = append(byIdiomID[idiomID][langIndex], line)
			} else {
				byIdiomID[idiomID] = make([]cheatSheetLineDocs, len(langs))
				byIdiomID[idiomID][langIndex] = cheatSheetLineDocs{line}<commit_msg>Cheatsheet multi: validate and normalize language names.<commit_after>package main

import (
	"fmt"
	"net/http"
	"sort"
	"strconv"

	. "github.com/Deleplace/programming-idioms/pig"
	"github.com/gorilla/mux"
)

// CheatSheetMultipleFacade is the Facade for the Cheat Sheets with multiple languages.
type CheatSheetMultipleFacade struct {
	PageMeta    PageMeta
	UserProfile UserProfile
	Langs       []string
	Lines       []cheatSheetLineMulti
}

type cheatSheetLineMulti struct {
	IdiomID            int
	IdiomTitle         string
	IdiomLeadParagraph string

	// Depth represents the max number of impl for one language in ByLanguage
	Depth []struct{}

	ByLanguage []cheatSheetLineDocs
}

func (chsh *cheatSheetLineMulti) hasCell(langIndex, alt int) bool {
	return alt < len(chsh.Depth) &&
		langIndex < len(chsh.ByLanguage) &&
		alt < len(chsh.ByLanguage[langIndex])
}

func (chsh *cheatSheetLineMulti) computeDepth() {
	n := 0
	for _, lineDocs := range chsh.ByLanguage {
		if len(lineDocs) > n {
			n = len(lineDocs)
		}
	}
	chsh.Depth = make([]struct{}, n)
}

func cheatsheetDouble(w http.ResponseWriter, r *http.Request) error {
	vars := mux.Vars(r)
	langs := []string{vars["lang1"], vars["lang2"]}
	ctx := r.Context()

	for i := range langs {
		lang := NormLang(langs[i])
		if !StringSliceContains(AllLanguages(), lang) {
			return PiError{fmt.Sprintf("Sorry, [%v] is currently not a supported language. Supported languages are %v.", langs[i], AllNiceLangs), http.StatusBadRequest}
		}
		langs[i] = lang
	}

	// Security belt. Might be changed if needed.
	limit := 1000

	var lines []cheatSheetLineMulti

	byIdiomID := map[int][]cheatSheetLineDocs{}
	idiomTitles := map[int]string{}
	idiomLeadParagraphs := map[int]string{}
	for langIndex, lang := range langs {
		cheatsheetLines, err := dao.getCheatSheet(ctx, lang, limit)
		if err != nil {
			return PiError{err.Error(), http.StatusInternalServerError}
		}
		for _, line := range cheatsheetLines {
			idiomID, err := strconv.Atoi(string(line.IdiomID))
			if err != nil {
				return err
			}
			if _, exists := byIdiomID[idiomID]; exists {
				byIdiomID[idiomID][langIndex] = append(byIdiomID[idiomID][langIndex], line)
			} else {
				byIdiomID[idiomID] = make([]cheatSheetLineDocs, len(langs))
				byIdiomID[idiomID][langIndex] = cheatSheetLineDocs{line}
{'fraction_non_alphanumeric': 0.12263489838822705, 'fraction_numerical': 0.003270263957019388, 'mean_word_length': 4.234718826405868, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6242269', 'n_tokens_mistral': 1603, 'n_tokens_neox': 1484, 'n_words': 351}