Junior winter vacation study spark experiment report 2

Posted by chard on Tue, 18 Jan 2022 22:01:43 +0100

Experiment 2 primary practice of scala programming

1. Calculation series

Please program, calculate and output the sum Sn of the first n items of the following series in the form of script until Sn is just greater than or equal to Q, where q is an integer greater than 0, and its value is input through the keyboard.

 

For example, if the value of Q is 50.0, the output should be: Sn=50.416695. Please save the source file as exercise2-1 Scala, test run in REPL mode, test example: when q=1, Sn=2; When q=30, Sn=30.891459; When q=50, Sn=50.416695.

 

import io.StdIn._

var Sn:Float = 0

var n:Float = 1

println("Please input q:")

val q = readInt()

while (Sn < q ){

       Sn += ( n + 1 ) / n

       n += 1

}

println(s"Sn=$Sn")

 

2. Simulation drawing

For a graphics rendering program, the following levels are used to abstract various entities.

Define the characteristics of a Drawable, which includes a draw method, which is implemented as the string representation of the output object by default.

Define a Point class to represent points, which is mixed with Drawable characteristics, and contains a shift method for moving points.

The abstract class of all graphic entities is Shape, and its constructor includes a Point type to represent the specific location of the graphic (the specific meaning is different for different specific graphics).

The Shape class has a concrete method moveTo and an abstract method zoom. moveTo moves the graph from the current position to a new position. The moveTo of various concrete graphs may be different. Zoom method realizes the zoom of graphics and accepts a floating-point zoom multiple parameter. The zoom implementation is different for different specific graphics.

The specific Shape types that inherit the Shape class include Line class and Circle class.

The first parameter of the Line class represents its position, and the second parameter represents another endpoint. When the Line is zoomed, the position of the point remains unchanged, and the length is zoomed by multiple (note that the information of the two endpoints is also changed when zooming). In addition, the move behavior of the Line affects the other endpoint, so the move method needs to be overloaded.

The first parameter of Circle class represents its center and position, and the other parameter represents its radius. When Circle is scaled, the position parameter remains unchanged, and the radius is scaled by multiple.

In addition, the straight Line class Line and the Circle class Circle are mixed with the Drawable feature, which requires the overload implementation of the draw. The information style of the draw output of the Line class is "Line: coordinates of the first endpoint -- coordinates of the second endpoint", and the information style of the draw output of the Circle class is "Circle center: coordinates of the center of the Circle, R = radius".

The following code has given the definitions of Drawable and Point, as well as the implementation of the main function of the program entry. Please complete the definitions of Shape class, Line class and Circle class.

 

 

 

case class Point(var x:Double,var y:Double) extends Drawable{

       def shift (deltaX:Double,deltaY:Double) {

              x+=deltaX;

              y+=deltaY

       }

}

trait Drawable{

       def draw(){

              println(this.toString)

       }

}

abstract class Shape(var location:Point){

       //location yes Shape A variable field for

       def moveTo(newLocation:Point){

              //By default, only the location is modified

              location = newLocation

       }

        def zoom(scale:Double)

}

class Line(beginPoint:Point,var endPoint:Point) extends Shape(beginPoint) with Drawable{

       override def draw(){

              println(s"Line:(${location.x},${location.y})--(${endPoint.x},${endPoint.y})")

       } //Reload in specified format click

       override def moveTo(newLocation:Point){

              endPoint.shift(newLocation.x - location.x,newLocation.y -location.y) //When moving in a straight line, move the other endpoint first

              location = newLocation //Move position

       }

       override def zoom(scale:Double){

             val midPoint = Point((endPoint.x + location.x)/2,(endPoint.y + location.y)/2) //Find the midpoint and scale by the midpoint

              location.x = midPoint.x + scale * (location.x - midPoint.x)

              location.y = midPoint.y + scale * (location.y -midPoint.y)

              endPoint.x = midPoint.x + scale * (endPoint.x - midPoint.x)

              endPoint.y = midPoint.y + scale * (endPoint.y -midPoint.y)

       }

}

class Circle(center:Point,var radius:Double) extends Shape(center) with Drawable{

       override def draw(){//Reload in specified format click

              println(s"Circle center:(${location.x},${location.y}),R=$radius")

       }

       override def zoom(scale:Double){

              radius = radius*scale //The scaling of the circle only modifies the radius

       }

}

object MyDraw{

       def main(args: Array[String]) {

             val p=new Point(10,30)

              p.draw;

              val line1 = new Line(Point(0,0),Point(20,20))

              line1.draw

              line1.moveTo(Point(5,5))

              line1.draw

              line1.zoom(2)

              line1.draw

              val cir= new Circle(Point(10,10),5)

              cir.draw

              cir.moveTo(Point(30,20))

              cir.draw

              cir.zoom(0.5)

              cir.draw

       }

}

 

 

3. Statistics of student achievement

The format of student's grade list is as follows. The first line is the header, and the meaning of each field is student number, gender, course name 1, course name 2, etc. each line behind represents the information of a student, and the fields are separated by a blank character

 

Given any list in the above format (the number of courses in different lists may be different), it is required to use functional programming as far as possible to count the average score, minimum score and maximum score of each course; In addition, the average score, minimum score and maximum score of each course shall be counted separately according to male and female students.

 

 

 

 

 

Test data 1:

 

Test data 2:

 

object scoreReport{

       def main(args: Array[String]) {

             val inputFile = scala.io.Source.fromFile("F:\\spark-experiment/test2.txt")

             //"\\s+"Is a string regular expression that divides each line into white space characters (including spaces)/Tab) separate

              // Since multiple traversals may be involved, the same as toList take Iterator pretend List

              // originalData The type of is List[Array[String]]

              val originalData = inputFile.getLines.map{_.split("\\s+")} .toList

              val courseNames = originalData.head.drop(2) //Get the course name in the first row

              val allStudents = originalData.tail // Remove the remaining data in the first row

             val courseNum = courseNames.length

              // Statistics function. The parameter is the row that needs common statistics

              //External variables are used courseNum,It belongs to closure function

              def statistc(lines:List[Array[String]])= {

                     // for The derivation generates a triple for each course, representing the total score, the lowest score and the highest score respectively

                     (for(i<- 2 to courseNum+1) yield {

                            // Take out the columns to be counted

                           val temp = lines map {elem=>elem(i).toDouble}

                            (temp.sum,temp.min,temp.max)

                     }) map {case (total,min,max) => (total/lines.length,min,max)} // the last one map yes for The total score is changed to the average score

              }

              // Output result function

              def printResult(theresult:Seq[(Double,Double,Double)]){

                     // Call before traversing zip Method combines the course name container and the result container, and the combined result is a binary container

                     (courseNames zip theresult) foreach {

                            case (course,result)=>

                            println(f"${course+":"}%-10s${result._1}%5.2f${result._2}%8.2f${result._3}%8.2f")

                     }

              }

              // Call two functions respectively to count all students and output the results

              val allResult = statistc(allStudents)

              println("course average min max")

              printResult(allResult)

 

             //Divided into two containers by gender

             val (maleLines,femaleLines) = allStudents partition {_(1)=="male"}

              // Call two functions respectively to count male students and output the results

              val maleResult = statistc(maleLines)

              println("course average min max")

              printResult(maleResult)

              // Call two functions respectively to count male students and output the results

              val femaleResult = statistc(femaleLines)

              println("course average min max")

              printResult(femaleResult)

       }

}