• No se han encontrado resultados

Euskal haur antzerkigintzaren panorama historikoa

In document '''' TEATRO INFANTIL. (página 173-200)

B. En cuanto al llamado texto espectacular se observan también algunos aspectos que definen la especificidad del teatro infantil y

8. Euskal haur antzerkigintzaren panorama historikoa

fmt.Println(cityForPopulation)

map[12610000:Istanbul 11290000:Beijing 12690000:Mumbai 11620000:Karachi]

We begin by creating the inverted map—so whereaspopulationForCityis of type map[string]int, thecityForPopulation map is of type map[int]string. Then we iterate over the original map and insert items into the inverted map using the original map’s values as keys and its keys as values.

Of course, map inversion will fail if the values are not all unique—essentially what happens is that the last occurrence of a nonunique value that is encoun-tered is the one who’s key is stored (as a value) in the inverted map. This prob-lem can be addressed by creating an inverted map that has multivalued values, so for this example, of typemap[int][]string(intkeys and[]stringvalues). We will see a practical example of this shortly (§4.4.2,➤ 174).

4.4. Examples

In this section we will review two small examples, the first illustrating one- and two-dimensional slices, and the second illustrating maps, including map inver-sion where the map’s values may not be unique, as well as slices and sorting.

4.4.1. Example: Guess Separator

In some situations we might receive a whole bunch of data files for processing where each file has one record per line, but where different files might use dif-ferent separators (e.g., tabs or whitespace or “*”s). To be able to process such files in bulk we need to be able to determine the separator used for each file.

The guess_separator example shown in this section (in file guess_separator/

guess_separator.go) attempts to identify the separator for the file it is given to work on.

Here is an example of a typical run:

$ ./guess_separator information.dat tab-separated

The program reads in the first five lines (or as many lines as the file contains if fewer than five) and uses these to guess the separator that is being used.

As usual, we will review themain()function and the functions it calls (apart from one that’s routine), and we will skip the imports.

ptg7913109 func main() {

if len(os.Args) == 1 || os.Args[1] == "-h" || os.Args[1] == "--help" { fmt.Printf("usage: %s file\n", filepath.Base(os.Args[0]))

os.Exit(1) }

separators := []string{"\t", "*", "|", "•"} linesRead, lines := readUpToNLines(os.Args[1], 5) counts := createCounts(lines, separators, linesRead) separator := guessSep(counts, separators, linesRead) report(separator)

}

Themain()function begins by checking that a file has been given on the com-mand line, and if one hasn’t, the function outputs a usage message and termi-nates the program.

We create a[]stringto hold the separators we are interested in; for whitespace-separated files we will adopt the convention that the separator is""(the emp-ty string).

The first real processing is to read in the first five lines of the file. The readUpToN-Lines()function isn’t shown since we have already seen examples of how to read lines from a file (and will see another example in the next subsection). The only thing that is unusual about thereadUpToNLines()function is that it reads only the number of lines specified—or fewer if the file has fewer lines—and returns the number of lines it actually read as well as the lines themselves.

We will discuss the remaining functions thatmain() calls when we show their source code, starting with thecreateCounts()function.

func createCounts(lines, separators []string, linesRead int) [][]int { counts := make([][]int, len(separators))

for sepIndex := range separators {

counts[sepIndex] = make([]int, linesRead) for lineIndex, line := range lines { counts[sepIndex][lineIndex] =

strings.Count(line, separators[sepIndex]) }

}

return counts }

The purpose of thecreateCounts()function is to populate a matrix that holds the counts of each separator for each line that was read.

ptg7913109 The function begins by creating a slice of slices of ints with the same number

of slices as there are separators. If there are four separators, this setscountsto the slice[nil nil nil nil]. The outerforloop replaces eachnilwith an[]intthat has as many items as the number of lines read. So eachnilgets replaced with [0 0 0 0 0], since Go always initializes with a type’s zero value.

The innerforloop is used to populate thecounts. For each line the number of occurrences of each separator is counted andcountsis updated accordingly. The strings.Count()function returns the number of occurrences of its second string argument that occur in its first string argument.

For example, given a tab-separated file which had some bullets, spaces, and stars in some of its fields we might get acountsmatrix of [[3 3 3 3 3] [0 0 4 3 0]

[0 0 0 0 0] [1 2 2 0 0]]. Eachcountsitem is an[]intwhich contains the counts for the corresponding separator (tab, star, bar, bullet) for each of the five lines. So in this case every line has three tabs, a couple of lines have stars (four in one, three in another), three lines have bullets, and no lines have vertical bars. To us as human readers it is obvious that here the separator is a tab, but of course, the program must discover this for itself, and it does so using theguessSep() function.

func guessSep(counts [][]int, separators []string, linesRead int) string { for sepIndex := range separators {

same := true

count := counts[sepIndex][0]

for lineIndex := 1; lineIndex < linesRead; lineIndex++ { if counts[sepIndex][lineIndex] != count {

same = false break }

}

if count > 0 && same {

return separators[sepIndex]

} }

return ""

}

This function’s purpose is to find the first[]intin thecountsslices whose counts are all the same—and nonzero.

The function iterates over each “row” incounts(one per separator), and initially assumes that all the row’s counts are the same. It sets the initial count to the first count, that is, to the number of times the separator occurs in the first line that was read. Then it iterates over the rest, that is, over the separator counts for each of the other lines that was read. If a different count is encountered the innerforloop is broken out of and the next separator tried. If the innerforloop

ptg7913109 completes without settingsametofalse, and the count is greater than zero, we

have found what we want and immediately return it. If no separator matches we return an empty string—this is our convention to mean that the fields are whitespace-separated, or not separated at all.

func report(separator string) { switch separator {

case "":

fmt.Println("whitespace-separated or not separated at all") case "\t":

fmt.Println("tab-separated") default:

fmt.Printf("%s-separated\n", separator) }

}

Thereport() function is trivial, writing a simple description of the separator used by the file that was read.

This example has shown both one- and two-dimensional slices (separators,lines, and counts) in typical use. In the next example we will look at maps, slices, and sorting.

In document '''' TEATRO INFANTIL. (página 173-200)