Monthly Archives: February 2020

程序代写代做|graph junit Java data structure|algorithm CSC8002 Assessed Coursework Student Support Application

CSC8002 Assessed Coursework Student Support Application
The deliverable for this coursework must be submitted via NESS on or before: • 14.30 on Monday 9th March 2020
This is a hard deadline. Work uploaded after this time (even by 1 second) will be flagged as late. Make sure you submit AT LEAST 15 minutes before this deadline.
1. Aim
The aim of this coursework is for you to practice the design principles covered in lectures. You will develop interfaces and classes to demonstrate that you have learned and understood the module material, including:
• appropriate overriding of Object class methods, including overriding toString and providing a static valueOf method when appropriate
• design of interface-based hierarchies, programming through interfaces and late binding
• the use of factories to control instantiation of objects, including how to guarantee the instantiation of unique instances
• defensive programming including the use of immutability
• the use of appropriate interfaces and classes from the Collections framework
The coursework is not algorithmically challenging. The focus is on good design and good practice.
The coursework is not about development of an end-user application. You are developing interfaces and classes that could be used for the development of an application. You should not develop a graphical user interface or a command line interface. They are not necessary and you will be given no credit for doing so. You should provide test cases for your interfaces and classes. You should submit both your solution and the classes that you use to test the solution.
Note the student support system specified below is a deliberate simplification. It is not an accurate model of real world University systems. Your solution should correspond to the simplicity of the specification. You risk losing marks if you attempt to provide a more realistic model or provide a solution that is more complicated than necessary.

2. System overview
A University Department needs a set of interfaces and classes to manage student data.
The Department has different types of students. These are undergraduate (UG), postgraduate taught (PGT) and postgraduate research (PGR) students. Students cannot be more than one type. For this coursework, the significant difference between undergraduate and postgraduate taught students is that undergraduate students take 120 credits worth of courses in a year whereas postgraduate taught students take 180. Furthermore, the pass mark for undergraduate modules is 40% but for postgraduate taught modules is 50%. Postgraduate research students have a supervisor but do not register for modules.
The University needs to maintain a record of modules and supervisors for students in an academic year. The system should allow module and supervisor information to be read from appropriately defined data files. The files should contain one data entry per line with fields separated by a comma e.g. CSC8002, Advanced Programming, 20. The system should allow an appropriate number of modules to be added to a student record and to record whether or not a student is correctly registered (are they taking the right number of credits or do they have a supervisor allocated).
In addition, the University needs to be able to issue smart cards and login ID’s to all students on their courses. The following provides more detail on the required functionality:
noOfStudents (typeOfStudent)
This method returns the number of students of the specified type that are currently enrolled.
registerStudent (Student)
This method registers a new student onto the system and allocates a student ID (see below).
amendStudentData(studentID, studentData) This method changes a student record.
terminateStudent (studentID)
This method removes the student record associated with the given student number. In effect, the student is leaving the University.
When issuing a smart card, the following rules must be observed.
• An undergraduate student must be at least 17 years old.
• A postgraduate student must be at least 20 years old.
• A student cannot be issued with more than one smartcard (i.e. do not try to deal with
lost cards!).

3. Implementation
To complete the system outlined in Section 2 you will need to provide interfaces and classes for the functionality described in this section. You must also use Junit testing to unit test your solution.
Student
All students have the following public functionality:
• a method to get the student’s ID.
• a method to get the student’s type (UG, PGT, or PGR).
• a method to list the modules that the student is registered for. A module consists of a
name (e.g. Programming 2), a module code (e.g. CSC1022) and the number of credits
associated with the module (e.g. 20).
• A method which returns true if the student is currently registered for enough credits
(120 for undergraduate, 180 for postgraduate taught, 0 for postgraduate research) and false otherwise.
• Postgraduate research students have a method to return the name of their supervisor (a Name)
You must provide an appropriate hierarchy for students.
Student ID
A student ID has two components – a single letter followed by a four digit number. For example:
• a1234
You must provide access to each component and an appropriate string representation of the ID.
Student ID’s are unique. You must guarantee that no two students have the same ID.
Smart Card
A Smart Card has the student’s name (comprising a first and last name), the date of birth of the student, a unique Smart Card number and a date of issue.
The Smart Card number has three components. The first component is the concatenation of the initial of the first name of the student with the initial of the last name of the student. The second component is the year of issue of the card. The third component is an arbitrary serial number. For example, the string representation of the Smart Card number for a card issued to John Smith in 2018 would have the form:
• JS-2018-10

where the 10 is a serial number that, with the initials and year, guarantees the uniqueness of the card number as a whole.
Your smart card class must provide methods to access the student’s name, the student’s date of birth, the student ID and the date of issue of the Card.
You should provide appropriate classes for a student’s name and for a smart card number.
You must guarantee the uniqueness of smart card numbers.
You should use the java.util.Date class to represent dates. However, you must not use deprecated methods of the Date class. So, for example, in your test classes use java.util.Calendar to construct dates of birth and dates of issue of Smart Cards. You can assume default time zone and locale.
Note: Java 8 provides a much more satisfactory way of handling dates and time with immutable classes. However, in this coursework I want to see that you can use sub-optimal classes such as Date and so its use in this project is mandatory.
The smart card should have the following private method:
• setExpiryDate(); which sets an expiry date for the card. If the smart card is held by a UG student, the expiry date is set to the issue date plus four years. If the smart card is held by a PGT student, the expiry date is set to the issue date plus two years. If the smart card is held by a PGR student, the expiry date is set to the issue date plus five years.
The smart card should have the following public method:
• getExpiryDate(); which returns the expiry date of the card.
4. Deliverable
Your solution should include your interfaces and classes that comprise the implementation of the system and types outlined in Sections 2 and 3. In addition, you should provide separate test classes that demonstrate testing of your solution.
You must submit your solution through NESS as a single zip file that contains your Java source code files.
5. Assessment
In this coursework you should demonstrate:

• the sensible use of Java inheritance mechanisms,
• an understanding of how to declare and use interfaces,
• the ability to handle collections of objects,
• the use of late binding,
• the use of defensive programming, including use of immutability and appropriate
error handling,
• an understanding of when and how to override Object methods,
• the implementation of object factories.
Marks will be allocated for
• overall structure and implementation of the solution (e.g. interfaces, classes and their relationships)
• correct implementation of rules specified in Sections 2 and 3
• choice and use of appropriate data structures
• following good practice guidance: defensive programming, use of immutability,
appropriate overriding of Object methods, etc.
• use of object factories where appropriate.
• evidence of testing by implementation of appropriate test classes that test the normal
case, boundary conditions, and exceptional cases
6. Style guidelines
Adopt a consistent style, do not violate naming conventions (e.g. when to use upper/lower case letters in class, method and variable names) and make appropriate use of whitespace (indentation and other spacing).
7. Further notes
Start early!! This is not a project to hack together during the last 1-2 days before the deadline.
Break the coursework down into separate tasks. Start with the simpler classes first (e.g. Module, Name, StudentID, SmartCardNumber and SmartCard) but leave the imposition of uniqueness and immutability until we cover these topics in lectures. You can implement the different types of student before implementing the management system class. Unit test classes as you progress through the coursework.
For each class you implement you should consider:
• whether to override Object methods (equals, toString etc.),
• whether to use an interface-based hierarchy, and
• whether the class should be immutable.
• whether to use an object factory.

You may have to defer parts of the coursework (or the implementation of certain aspects of a class) until we have covered material in lectures. In this case, you can make a start with a simpler solution that can be extended later.

C语言编程|ENG5009|高级编程

ENG5009 Advanced Control 5 Assignment
Introduction
This assignment is presented as a challenge within control engineering.
The first part of the assignment are the answers you obtained from the lab sheets provided. The results from the lab sheets are to be included as an appendix to the final hand in.
The second part of the assignment is to follow the steps below and capture the required data.
The final stage of the assignment is to create a controller based on either fuzzy logic, a Neural network or a combination of both, or any other suitable controller that can be justified, that is able to guide a robot to a particular point (within 0.05m radius of the point) while avoiding obstacles.
The method you use is to be presented in a report with results presented and discussed. The report should cover a short description of the controller, the relevant input/outputs stages, the test procedure you carried out (with justification of the test cases used) and provide the results. Improvements to the system developed should also be included.
The report should be a MAXIMUM of 10 pages (not including appendices).
A guide to the marking of the report is available on Moodle.
Provided Resources
All resources that have been used in the labs to date will be available. You are also free to use the Fuzzy Logic Toolbox, as long as justification of the methods used is made.
Task 1
Develop a controller that is able to drive the robot to a selected point. The position of the robot can be assumed to be accurately know via the x(19) and x(20) states.
The first stage of developing this controller is to establish the direction that the robot is required to drive in. To achieve this you can use the following code to work out the required heading.
function [at_waypoint, desired_psi] = los_auto(cur_x,cur_y,desired_pt) % set waypoint
waypoint = desired_pt;
% check to see if in acceptance radius
cur_radius = sqrt(((cur_x-waypoint(1))^2)+((cur_y-waypoint(2))^2));
if (cur_radius < 0.1), at_waypoint = 1; else at_waypoint = 0; end; % Calculate heading psi_cal=atan2((waypoint(2)-cur_y),(waypoint(1)-cur_x)); if isnan(psi_cal), if (waypoint(2)-cur_y)>=0,
desired_psi = pi/2;
else

desired_psi = -pi/2;
end;
else
desired_psi = psi_cal;
end;
Once implemented provide a plot showing the robot driving to the following points (with no obstacles) ((x,y)): (0 3), (1 2), (-1 4), (-1 -2), (-0.2 2)
Task 2
Develop a controller that is able to drive a robot along a path, while avoiding the obstacles: (-1 -1) (-1 -4) (3 -1) (0 1) (-2 -1)
A map of the area is provided below with the start point marked in blue (x = -2m y = -1m).

Go语言程序设计|澳洲编程|面向对象|Go语言

COMP226 Assignment 1: Reconstruct a Limit Order Book
Continuous Assessment Number
1 (of 2)
Weighting
10%
Assignment Circulated
09:00 Tuesday 18 February 2020 (updated 2020-02-20)
Deadline
17:00 Friday 6 March 2020
Submission Mode
Electronic only
http://www.csc.liv.ac.uk/cgi-bin/submit.pl
Submit a single file “MWS-username.R”, where MWS-username should be replaced with your MWS username.
Learning Outcomes Assessed
Have an understanding of market microstructure and its impact on trading.
Goal of Assignment
Reconstruct a limit order book from order messages
Marking Criteria
Code correctness (85%); Code readability (15%)
Submission necessary in order to satisfy module requirements
No
Late Submission Penalty
Standard UoL policy; resubmissions after the deadline will NOT be considered.
Expected time taken
Roughly 8-12 hours
Warning
Your code will be put through the department’s automatic plagiarism and collusion detection system. Student’s found to have plagiarized or colluded will likely receive a mark of zero. Do not discuss or show your work to others. In previous years, two students had their studies terminated and left without a degree because of plagiarism.
Rscript from Rstudio
In this assigment, we use Rscript (which is provided by R) to run our code, e.g., Rscript skeleton.R input/book_1.csv input/empty.txt
In R studio, you can call Rscript from the “terminal” tab (as opposed to the “console”). On Windows, use Rscript.exe not Rscript:
Rscript.exe skeleton.R input/book_1.csv input/empty.txt

Distributed code and sample input and output data
As a first step, please download comp226_a1.zip comp226_a1_v3.zip from: https://student.csc.liv.ac.uk/internal/modules/comp226/_downloads/comp226_a1_v3.zip
Then unzip comp226_a1.zip, which will yield the following contents in the directory comp226_a1:
comp226_a1
├── input
│ ├── book_1.csv
│ ├── book_2.csv
│ ├── book_3.csv
│ ├── empty.txt
│ ├── message_a.txt
│ ├── message_ar.txt
│ ├── message_arc.txt
│ ├── message_ex_add.txt
│ ├── message_ex_cross.txt
│ ├── message_ex_reduce.txt
│ └── message_ex_same_price.txt
├── output
│ ├── book_1-message_a.out
│ ├── book_1-message_ar.out
│ ├── book_1-message_arc.out
│ ├── book_2-message_a.out
│ ├── book_2-message_ar.out
│ ├── book_2-message_arc.out
│ ├── book_3-message_a.out
│ ├── book_3-message_ar.out
│ └── book_3-message_arc.out
└── skeleton.R
2 directories, 21 files
Brief summary
The starting point for the assignment is a code skeleton, provided in a file called skeleton.R. This file runs without error, but does not produce the desired output because it contains 6 empty functions. To complete the assignment you will need to correctly complete these 6 functions.
You should submit a single R file that contains your implementation of some or ideally all of these 6 functions. Your submission will be marked via a combination of:
• automated tests (for code correctness, 85%, breakdown by function given below); and
• human visual inspection (for code readability, 15%, in particular, for appropriate naming of variables and functions (5%), good use of comments (5%), and sensible, consistent code formatting (5%)).
Correct sample output is provided so that you can check whether your code implemetations produces the correct output.

skeleton.R versus solution.R
You are given skeleton.R, which you should extend by implementing 6 functions. Throughout this handout, we also generate example output using a file solution.R that contains a correct implementation of all 6 of these functions. Obviously, you are not given the file solution.R, however the example output will be helpful for checking that your function implementations work correctly.
Two sets of functions to implement
As described in detail in the rest of this document, you are required to implement the following 6 functions. The percentage in square brackets correspond to the breakdown of the correctness marks by function.
Limit order book stats:
1. book.total_volume <- function(book) [10%] 2. book.best_prices <- function(book) [10%] 3. book.midprice <- function(book) [10%] 4. book.spread <- function(book) [10%] Updating the limit order book: 5. book.reduce <- function(book, message) [15%] 6. book.add <- function(book, message) [30%] Running skeleton.R An example of calling skeleton.R follows. Rscript skeleton.R input/book_1.csv input/empty.txt As seen in this example, skeleton.R takes as arguments the path to two input files: 1. initial order book (input/book_1.csv in the example) 2. order messages to be processed (input/empty.txt in the example) Note: the order of the arguments matters. Let’s see part of the source code and the output that it produces. Warning Do not make changes to the rest of the code in skeleton.R, only implement these 6 functions. Penalties may be applied if other changes are present in your submission. if (! { interactive()) options (warn= ) -1 args <- commandArgs(trailingOnly = TRUE) if( ( ) 2){ ( “)
}
book_path <- args[1]; data_path <- args[2] if (! (data_path) ! (book_path)) { () book <- book.load(book_path) book <- book.reconstruct(data.load(data_path), init=book) book.summarise(book) } length args != stop “Must provide two arguments: file.exists || file.exists stop “File does not exist at path provided.” } So in short, this part of the code: • checks that there are two command line arguments • assigns them to the appropriate variables (the first to the initial book file path, the second to the message file path) • loads the initial book • reconstructs the book according to the messages • prints out the book • prints out the book stats Let’s see the output for the example above: $ Rscript skeleton.R input/book_1.csv input/empty.txt $ask oid price size 1 a 105 100 $bid oid price size 1 b 95 100 Total volume: Best prices: Mid-price: Spread: Now let’s see what the output would look like for a correct implementation: $ Rscript solution.R input/book_1.csv input/empty.txt $ask oid price size 1 a 105 100 $bid oid price size 1 b 95 100 Total volume: Best prices: Mid-price: Spread: 10 100 100 95 105 100 You will see that now the order book stats have been included in the output, because the four related functions that are empty in skeleton.R have been implemented in solution.R. The initial order book Here is the contents of input/book_1.csv, which is one of the 3 provided examples of an initial book: Let’s justify the columns to help parse this input: The first row is a header row. Every subsequent row contains a limit order, which is described by the following fields: • oid (order id) is stored in the book and used to process (partial) cancellations of orders that arise in “reduce” messages, described below; • side identifies whether this is a bid (‘B’ for buy) or an ask (‘S’ for sell); • price and size are self-explanatory. Existing code in skeleton.R will read in a file like input/book_1.csv and create the corresponding two (possibly empty) orders book as two data frames that will be stored in the list book, a version of which will be passed to all of the six functions that you are required to implement. Note that if we now change the message file to a non-empty one, skeleton.R will produce the same output (since it doesn’t parse the messages; you need to write the code, functions 5 and 6, to do that): oid,side,price,size a,S, , b,B, , 105 100 95 100 oid side price size a S 105 100 b B 95 100 $ Rscript skeleton.R input/book_1.csv input/message_a.txt $ask oid price size 1 a 105 100 $bid oid price size 1 b 95 100 Total volume: Best prices: Mid-price: Spread: If correct message parsing and book updating is implemented, book would be updated according to input/adds_only.txt to give the following output: $ Rscript solution.R input/book_1.csv input/message_a.txt $ask oid price size 8a 7o 6r 5k 4q 3m 2j 1n $bid oid price size 1b 2l 3p 4s Total volume: Best prices: Mid-price: .5 Spread: 1 105 104 102 100 292 194 99 98 98 97 96 71 166 88 132 375 95 95 94 91 100 29 87 102 318 1418 95 96 95 Before we go into details on the message format and reconstructing the order book, let’s discuss the first four functions that compute the book stats, which we also see correctly computed in this example. Computing limit order book stats The first four of the functions that you need to implement compute limit order book stats, and can be developed and tested without parsing the order messages at all. In particular, you can develop and test the first four functions using an empty message file, input/empty.txt, as in the first example above. The return values of the four functions should be as follows (where as usual in R single numbers are actually numeric vectors of length 1): • book.total_volumes should return a list with two named elements, bid, which should contain the total volume in the bid book, and ask, which should contain the total volume in the ask book; • book.best_prices <- function(book) should return a list with two named elements, bid, which should contain the best bid price, and ask, which should contain the best ask price; • book.midprice should the midprice of the book; • book.spread should the spread of the book; You should check that the output of these functions in the example above that uses solution.R are what you expect them to be. We now move on to the reconstructing the order book from the messages in the input message file. Reconstructing the order book from messages You do not need to look into the details of the (fully implemented) functions book.reconstruct or book.handle that manage the reconstruction the book from the starting initial book according to the messages. In the next section, we describe that there are two types of message, “Add” messages and “Reduce” messages. All you need to know to complete the assignment is that messages in the input file are processed in order, i.e., line by line, with “Add” messages passed to book.add and “Reduce” messages passed to book.reduce, along with the current book in both cases. Message Format The market data log contains one message per line (terminated by a single linefeed character, ‘\n’), and each message is a series of fields separated by spaces. There are two types of messages: “Add” and “Reduce” messages. Here’s an example, which contains an “Add” message followed by a “Reduce” message: An “Add” message looks like this: ‘A’ oid side price size • ‘A’: fixed string identifying this as an “Add” message; • oid: “order id” used by subsequent “Reduce” messages; • side: ‘B’ for a buy order (a bid), and an ‘S’ for a sell order (an ask); • price: limit price of this order; • size: size of this order. A “Reduce” message looks like this: ‘R’ oid size • ‘R’: fixed string identifying this as a “Reduce” message; • oid: “order id” identifies the order to be reduced; • size: amount by which to reduce the size of the order (not the new size of the order); if size is equal to or greater than the existing size of the order, the order is removed from the book. Processing messages “Reduce” messages will affect at most one existing limit order in the book. “Add” messages will either: • not cross the spread and then add a single row to the book (orders at the same price are stored separately to preserve their distinct “oid”s); • cross the spread and in that case can affect any number of orders on the other side of the book (and may or may not result in a remaining limit order for residual volume). A c S 97 36 R a 50 The provided example message files are split into cases that include crosses and those that don’t to help you develop your code incrementally and test it on inputs of differing difficulty. We do an example of each case, one by one. In each example we start from input/book_1.csv; we only show this initial book in the first case. Example of processing a reduce message $ Rscript solution.R input/book_1.csv input/empty.txt $ask oid price size 1 a 105 100 $bid oid price size 1 b 95 100 Total volume: 100 100 Best prices: 95 105 Mid-price: 100 Spread: 10 $ cat input/message_ex_reduce.txt R a 50 $ Rscript solution.R input/book_1.csv input/message_ex_reduce.txt $ask oid price size 1 a 105 50 $bid oid price size 1 b 95 100 Total volume: 100 50 Best prices: 95 105 Mid-price: 100 Spread: 10 Example of processing an add (non-crossing) message $ cat input/message_ex_add.txt A c S 97 36 $ Rscript solution.R input/book_1.csv input/message_ex_add.txt $ask oid price size 2 a 105 100 1 c 97 36 $bid oid price size 1 b 95 100 Total volume: 100 136 Best prices: 95 97 Mid-price: 96 Spread: 2 Example of processing a crossing add message $ cat input/message_ex_cross.txt A c B 106 101 $ Rscript solution.R input/book_1.csv input/message_ex_cross.txt $ask [1] oid price size <0 rows> (or 0-length row.names)
$bid
oid price size
1 c 106 1
2 b 95 100
Total volume: 101 0
Best prices: 106 NA
Mid-price: NA
Spread: NA
Sample output
We provide sample output for 9 cases, namely all combinations of the following 3 initial books and 3 message files.
The 3 initial books are found in the input subdirectory and are called:
• book_1.csv • book_2.csv • book_3.csv

The 3 message files are also found in the input subdirectory and are called:
file
messages_a.txt
add messages only, i.e., requires book.add but not book.reduce; for all three initial books, none of the messages cross the spreed
messages_ar.txt
add and reduce messages, but for the initial book book_3.csv, no add message crosses the spread
messages_arc.txt
add and reduce messages, with some adds that cross the spread for all three initial books
The 9 output files can be found in the output subdirectory of the comp226_a1 directory.
output
├── book_1-message_a.out
├── book_1-message_ar.out
├── book_1-message_arc.out
├── book_2-message_a.out
├── book_2-message_ar.out
├── book_2-message_arc.out
├── book_3-message_a.out
├── book_3-message_ar.out
└── book_3-message_arc.out
0 directories, 9 files
Hints for order book stats
For book.spread and book.midprice a nice implementation would use book.best_prices, which you should then implement first.
Hints for book.add and book.reduce
A possible way to implement book.add and book.reduce that makes use of the different
example message files is the following:
• First, do a partial implementation of book.add, namely implement add messages that do not cross. Check your implementation with message_a.txt.
• Next, implement book.reduce fully. Check your combined (partial) implementation of book.add and book.reduce with message_ar.txt and book_3.csv (only this combination with message_ar.txt has no crosses).
• Finally, complete the implementation of book.add to deal with crosses. Check your implementation with message_arc.txt and any initial book or with message_ar.txt and book_1.csv or book_2.csv.
Hint on book.sort
In comp226_a1_v3 there is a book.sort method, with sort code as follows:
book.sort <- (book, sort_bid=T, sort_ask=T) { if (sort_ask && (book$ask) >= 1) {
book$ask <- book$ask[order(book$ask$price, nchar(book$ask$oid), book$ask$oid, function nrow decreasing=F),] row.names(book$ask) <- 1:nrow(book$ask) } if (sort_bid && nrow(book$bid) >= 1) {
book$bid <- book$bid[order(-book$bid$price, nchar(book$bid$oid), book$bid$oid, decreasing=F),] row.names(book$bid) <- 1:nrow(book$bid) } book } This method will ensure that limit orders are sorted first by price and second by time of arrival (so that for two orders at the same price, the older one is nearer the top of the book). You are welcome (and encouraged) to use book.sort in your own implementations. In particualar, by using it you can avoid having to find exactly where to place an order in the book. Hint on using logging in book.reconstruct In comp226_a1_v3 a logging option has been added to book.reconstruct: book.reconstruct <- function(data, init=NULL, log=F) { ( ( book <- }, 1:nrow(data), init, ) book.sort(book) } if if nrow (data) 0) return(book) (init init <- book.init() ( (b, i) { new_book <- book.handle(b, data[i,]) if( ){ (“Step”, i, “\n\n”) book.summarise(new_book, with_stats=F) cat(“====================\n\n”) } new_book == is.null )) Reduce function log cat You can turn on logging by changing log=F to log=T. Then book.summarise will be used to give output after each message is processed by book.reconstruct. Hint on stringsAsFactors=FALSE Notice the use of` stringsAsFactors=FALSE in the book.load function (similarly in data.load) from skeleton.R. book.load <- function(path) { df <- read.table( path, fill=NA, stringsAsFactors=FALSE, header=TRUE, sep=’,’ ) book.sort(list( =df[df , c( , , , =df[df , c( , , )) } “size”)] “size”)] ask bid $side $side == == “S” “B” “oid” “oid” “price” “price” Its use here is not optional, it is necessary and what ensures that the oid column of book$bid and book$ask have type character. It is also crucial that you make sure that you ensure that the type of your oid columns in your books remain character rather than factors. The following examples will explain the use of stringsAsFactors and help you to achieve this. First we introduce a function that will check the type of this column on different data frames that we will construct: check <- (df) { checks <- c( , check, eval(parse(text=check))), ‘\n’) function “is.character(df$oid )” “is.factor(df$oid)” ) for (check in checks) cat(sprintf(“%20s: %5s”, } Now let’s use this function to explore different cases. First we look at the case of reading a csv. What about creating a data.frame? What about using rbind? > check(read.csv(
is.character(df ): FALSE
is.factor(df ): TRUE
> check(read.csv(
is.character(df ): TRUE
is.factor(df ): FALSE
, stringsAsFactors=FALSE))
‘input/book_1.csv’))
$oid $oid
‘input/book_1.csv’
$oid $oid
> check(data.frame(oid=”a”, price=1))
is.character(df ): FALSE
is.factor(df ): TRUE
> check(data.frame(oid=”a”, price=1, stringsAsFactors=FALSE))
is.character(df ): TRUE
is.factor(df ): FALSE
$oid $oid
$oid $oid

> empty_df <- data.frame(oid=character(0), =numeric(0 > non_empty_df <- data.frame(oid=”a”, =1, =FALSE) > check(rbind(empty_df, data.frame(oid=”a”, price=1)))
is.character(df ): FALSE
is.factor(df ): TRUE
> check(rbind(empty_df, non_empty_df))
is.character(df ): TRUE
is.factor(df ): FALSE
> check(rbind(non_empty_df, data.frame(oid=”a”, price=1)))
is.character(df ): TRUE
is.factor(df ): FALSE
price
))
$oid $oid
$oid $oid
stringsAsFactors
$oid $oid
price
Note that with a non-empty data frame, the existing type persists! However, when the data.frame is empty the type of the oid column is malleable and it is crucial to use stringsAsFactors=FALSE. We see the same behaviour when we rbind a list with a data.frame.
> check(rbind(empty_df, list(oid=”a”, price=1)))
is.character(df ): FALSE
is.factor(df ): TRUE
> check(rbind(empty_df, list(oid=”a”, price=1), stringsAsFactors=FALSE))
is.character(df ): TRUE
is.factor(df ): FALSE
> check(rbind(non_empty_df, list(oid=”a”, price=1)))
is.character(df ): TRUE
is.factor(df ): FALSE
$oid $oid
$oid $oid
$oid $oid
Again, it is crucial to use stringsAsFactors=FALSE when the data.frame is empty. I suggest to use it in every case.
Submission
Remember to submit a single “MWS-username.R” file, where MWS-username should be replaced with your MWS username.

SPARK代写|JAVA代写|作业代写|数据挖掘|推荐系统

Posted on February 26, 2020 by mac

Spotify Music Recommendation System by XXX¶
I desing a Spotify Muisc Recommendation System
• Load and display the data
• DATA Analysis and Processing
• Build Popularity-based Computing model and Machine Learning model —— ALS
▪ ‘prediction’ is the number of unique customers that have listened to the same track
▪ After cross the dataset randomly we generate a recommendation model to recommend spotiy music
▪ Recommendation Model From Explicit Rating

1. Load and display the data¶
In [6]:
!pip install ipython-sql

Collecting ipython-sql
Downloading https://files.pythonhosted.org/packages/ab/df/427e7cf05ffc67e78672ad57dce2436c1e825129033effe6fcaf804d0c60/ipython_sql-0.3.9-py2.py3-none-any.whl
Requirement already satisfied: ipython-genutils>=0.1.0 in /Users/charles/opt/anaconda3/lib/python3.7/site-packages (from ipython-sql) (0.2.0)
Collecting prettytable (from ipython-sql)
Downloading https://files.pythonhosted.org/packages/ef/30/4b0746848746ed5941f052479e7c23d2b56d174b82f4fd34a25e389831f5/prettytable-0.7.2.tar.bz2
Requirement already satisfied: ipython>=1.0 in /Users/charles/opt/anaconda3/lib/python3.7/site-packages (from ipython-sql) (7.8.0)
Requirement already satisfied: sqlalchemy>=0.6.7 in /Users/charles/opt/anaconda3/lib/python3.7/site-packages (from ipython-sql) (1.3.9)
Requirement already satisfied: six in /Users/charles/opt/anaconda3/lib/python3.7/site-packages (from ipython-sql) (1.13.0)
Collecting sqlparse (from ipython-sql)
Downloading https://files.pythonhosted.org/packages/ef/53/900f7d2a54557c6a37886585a91336520e5539e3ae2423ff1102daf4f3a7/sqlparse-0.3.0-py2.py3-none-any.whl
Requirement already satisfied: decorator in /Users/charles/opt/anaconda3/lib/python3.7/site-packages (from ipython>=1.0->ipython-sql) (4.4.0)
Requirement already satisfied: backcall in /Users/charles/opt/anaconda3/lib/python3.7/site-packages (from ipython>=1.0->ipython-sql) (0.1.0)
Requirement already satisfied: pickleshare in /Users/charles/opt/anaconda3/lib/python3.7/site-packages (from ipython>=1.0->ipython-sql) (0.7.5)
Requirement already satisfied: appnope; sys_platform == “darwin” in /Users/charles/opt/anaconda3/lib/python3.7/site-packages (from ipython>=1.0->ipython-sql) (0.1.0)
Requirement already satisfied: pexpect; sys_platform != “win32” in /Users/charles/opt/anaconda3/lib/python3.7/site-packages (from ipython>=1.0->ipython-sql) (4.7.0)
Requirement already satisfied: traitlets>=4.2 in /Users/charles/opt/anaconda3/lib/python3.7/site-packages (from ipython>=1.0->ipython-sql) (4.3.3)
Requirement already satisfied: jedi>=0.10 in /Users/charles/opt/anaconda3/lib/python3.7/site-packages (from ipython>=1.0->ipython-sql) (0.15.1)
Requirement already satisfied: prompt-toolkit<2.1.0,>=2.0.0 in /Users/charles/opt/anaconda3/lib/python3.7/site-packages (from ipython>=1.0->ipython-sql) (2.0.10)
Requirement already satisfied: pygments in /Users/charles/opt/anaconda3/lib/python3.7/site-packages (from ipython>=1.0->ipython-sql) (2.4.2)
Requirement already satisfied: setuptools>=18.5 in /Users/charles/opt/anaconda3/lib/python3.7/site-packages (from ipython>=1.0->ipython-sql) (41.4.0)
Requirement already satisfied: ptyprocess>=0.5 in /Users/charles/opt/anaconda3/lib/python3.7/site-packages (from pexpect; sys_platform != “win32”->ipython>=1.0->ipython-sql) (0.6.0)
Requirement already satisfied: parso>=0.5.0 in /Users/charles/opt/anaconda3/lib/python3.7/site-packages (from jedi>=0.10->ipython>=1.0->ipython-sql) (0.5.1)
Requirement already satisfied: wcwidth in /Users/charles/opt/anaconda3/lib/python3.7/site-packages (from prompt-toolkit<2.1.0,>=2.0.0->ipython>=1.0->ipython-sql) (0.1.7)
Building wheels for collected packages: prettytable
Building wheel for prettytable (setup.py) … done
Created wheel for prettytable: filename=prettytable-0.7.2-cp37-none-any.whl size=13700 sha256=b762a142ce99915d70b32db5de42610976c9d0ab2ed41b5308b1fa8c1a1407c0
Stored in directory: /Users/charles/Library/Caches/pip/wheels/80/34/1c/3967380d9676d162cb59513bd9dc862d0584e045a162095606
Successfully built prettytable
Installing collected packages: prettytable, sqlparse, ipython-sql
Successfully installed ipython-sql-0.3.9 prettytable-0.7.2 sqlparse-0.3.0
In [2]:
#!pip install pyspark
from pyspark.sql import SQLContext
sqlContext = SQLContext(sc)
In [3]:
musicDataFrame = sqlContext.read.format(“csv”).options(header=’true’, inferSchema=’true’).load(“./music.csv”)
In [4]:
musicDataFrame.show(5)

+——-+——————–+———–+——+
|TrackId| Title| Artist|Length|
+——-+——————–+———–+——+
| 0| Caught Up In You|.38 Special| 200|
| 1| Fantasy Girl|.38 Special| 219|
| 2| Hold On Loosely|.38 Special| 253|
| 3|Hold On Loosely …|.38 Special| 154|
| 4| Art For Arts Sake| 10cc| 341|
+——-+——————–+———–+——+
only showing top 5 rows

In [5]:
trackDataFrame = sqlContext.read.format(“csv”).options(header=’true’, inferSchema=’true’).load(“./tracks.csv”)
trackDataFrame.printSchema()

root
|– EventID: integer (nullable = true)
|– CustID: integer (nullable = true)
|– TrackId: integer (nullable = true)
|– DateTime: string (nullable = true)
|– Mobile: integer (nullable = true)
|– ZipCode: integer (nullable = true)

In [6]:
musicDataFrame.printSchema()
customerDataFrame = sqlContext.read.format(“csv”).options(header=’true’, inferSchema=’true’).load(“./cust.csv”)
customerDataFrame.printSchema()

root
|– TrackId: integer (nullable = true)
|– Title: string (nullable = true)
|– Artist: string (nullable = true)
|– Length: integer (nullable = true)

root
|– CustID: integer (nullable = true)
|– Name: string (nullable = true)
|– Gender: integer (nullable = true)
|– Address: string (nullable = true)
|– zip: integer (nullable = true)
|– SignDate: string (nullable = true)
|– Status: integer (nullable = true)
|– Level: integer (nullable = true)
|– Campaign: integer (nullable = true)
|– LinkedWithApps: integer (nullable = true)

In [7]:
customerDataFrame.printSchema()

root
|– CustID: integer (nullable = true)
|– Name: string (nullable = true)
|– Gender: integer (nullable = true)
|– Address: string (nullable = true)
|– zip: integer (nullable = true)
|– SignDate: string (nullable = true)
|– Status: integer (nullable = true)
|– Level: integer (nullable = true)
|– Campaign: integer (nullable = true)
|– LinkedWithApps: integer (nullable = true)

In [8]:
customerDataFrame.show(5)

+——+————-+——+——————–+—–+———-+——+—–+——–+————–+
|CustID| Name|Gender| Address| zip| SignDate|Status|Level|Campaign|LinkedWithApps|
+——+————-+——+——————–+—–+———-+——+—–+——–+————–+
| 0|Gregory Koval| 0|13004 Easy Cider …|72132|06/04/2013| 1| 1| 1| 0|
| 1|Robert Gordon| 0|10497 Thunder Hic…|17307|07/27/2013| 1| 1| 1| 0|
| 2|Paula Peltier| 0|10084 Easy Gate Bend|66216|01/13/2013| 1| 0| 4| 1|
| 3|Francine Gray| 0|54845 Bent Pony H…|36690|07/11/2013| 1| 1| 1| 1|
| 4| David Garcia| 0|8551 Tawny Fox Villa|61377|09/09/2012| 1| 0| 1| 1|
+——+————-+——+——————–+—–+———-+——+—–+——–+————–+
only showing top 5 rows

2. Analysis and Process data in csv file¶
In [13]:
from pyspark.sql.functions import col
rid = “TrackID”
Ls = “MTrackID”
MN= musicDataFrame.select(“*”).withColumnRenamed(rid,Ls)
MN.show(5)

+——–+——————–+———–+——+
|MTrackID| Title| Artist|Length|
+——–+——————–+———–+——+
| 0| Caught Up In You|.38 Special| 200|
| 1| Fantasy Girl|.38 Special| 219|
| 2| Hold On Loosely|.38 Special| 253|
| 3|Hold On Loosely …|.38 Special| 154|
| 4| Art For Arts Sake| 10cc| 341|
+——–+——————–+———–+——+
only showing top 5 rows

In [15]:
CN = customerDataFrame.select(“*”).withColumnRenamed(“CustID”,’CCustID’)
CN.show(5)
track_custJoin=trackDataFrame.join(CN, trackDataFrame.CustID == CN.CCustID, “left_outer”)
want_tocheck = “left_outer”
togeth_way = track_custJoin.join(MN,track_custJoin.TrackId == MN.MTrackID,want_tocheck)

+——-+————-+——+——————–+—–+———-+——+—–+——–+————–+
|CCustID| Name|Gender| Address| zip| SignDate|Status|Level|Campaign|LinkedWithApps|
+——-+————-+——+——————–+—–+———-+——+—–+——–+————–+
| 0|Gregory Koval| 0|13004 Easy Cider …|72132|06/04/2013| 1| 1| 1| 0|
| 1|Robert Gordon| 0|10497 Thunder Hic…|17307|07/27/2013| 1| 1| 1| 0|
| 2|Paula Peltier| 0|10084 Easy Gate Bend|66216|01/13/2013| 1| 0| 4| 1|
| 3|Francine Gray| 0|54845 Bent Pony H…|36690|07/11/2013| 1| 1| 1| 1|
| 4| David Garcia| 0|8551 Tawny Fox Villa|61377|09/09/2012| 1| 0| 1| 1|
+——-+————-+——+——————–+—–+———-+——+—–+——–+————–+
only showing top 5 rows

In [16]:
togeth_way.show(5)

+——-+——+——-+————–+——+——-+——-+—————+——+——————–+—–+———-+——+—–+——–+————–+——–+——————–+——————–+——+
|EventID|CustID|TrackId| DateTime|Mobile|ZipCode|CCustID| Name|Gender| Address| zip| SignDate|Status|Level|Campaign|LinkedWithApps|MTrackID| Title| Artist|Length|
+——-+——+——-+————–+——+——-+——-+—————+——+——————–+—–+———-+——+—–+——–+————–+——–+——————–+——————–+——+
| 0| 48| 453| 10/23/14 3:26| 0| 72132| 48| Lucas Pizano| 0|2723 Stony Beaver…|99256|11/02/2012| 1| 0| 3| 1| 453| Strange Magic|Electric Light Or…| 170|
| 1| 1081| 19|10/15/14 18:32| 1| 17307| 1081|Kenneth Rodgers| 0|74413 Heather Elm…|30301|05/14/2013| 0| 1| 1| 1| 19| Money Talks| AC/DC| 323|
| 2| 532| 36|12/10/14 15:33| 1| 66216| 532| Carlos Kirk| 0|14 Hidden Bear Ci…|90745|07/14/2013| 0| 2| 1| 1| 36| Big Ten Inch Record| Aerosmith| 204|
| 3| 2641| 822| 10/20/14 2:24| 1| 36690| 2641| Charlene Boyd| 0|5967 Stony Branch…| 4645|03/26/2013| 1| 1| 1| 0| 822| The Ripper| Judas Priest| 122|
| 4| 2251| 338| 11/18/14 7:16| 1| 61377| 2251| Mary Decker| 0|16355 Pretty Pand…|40580|06/23/2013| 1| 1| 0| 1| 338|Welcome To The Bo…| David & David| 269|
+——-+——+——-+————–+——+——-+——-+—————+——+——————–+—–+———-+——+—–+——–+————–+——–+——————–+——————–+——+
only showing top 5 rows

The costumers 0 listened 1617 out of 1715 we can see in the data table. This is really a great way to distinguish the answer.
In [17]:
from pyspark.sql.functions import split
togeth_way.createOrReplaceTempView(“togeth_way”)
split_datetime = split(togeth_way[‘DateTime’], ‘ ‘)
In [18]:
Date = ‘Date’
Time = ‘Time’
togeth_way = togeth_way.withColumn(Date + ‘L’, split_datetime.getItem(0))
togeth_way = togeth_way.withColumn(Time + ‘L’, split_datetime.getItem(1))
In [20]:
togeth_way.createOrReplaceTempView(“togeth_way”)
result_sheet = sqlContext.sql(“””SELECT CustId, Name, TrackId, Title, Length, Mobile, Gender, DateL, TimeL FROM togeth_way”””)
In [21]:
result_sheet.show(5)

+——+—————+——-+——————–+——+——+——+——–+—–+
|CustId| Name|TrackId| Title|Length|Mobile|Gender| DateL|TimeL|
+——+—————+——-+——————–+——+——+——+——–+—–+
| 48| Lucas Pizano| 453| Strange Magic| 170| 0| 0|10/23/14| 3:26|
| 1081|Kenneth Rodgers| 19| Money Talks| 323| 1| 0|10/15/14|18:32|
| 532| Carlos Kirk| 36| Big Ten Inch Record| 204| 1| 0|12/10/14|15:33|
| 2641| Charlene Boyd| 822| The Ripper| 122| 1| 0|10/20/14| 2:24|
| 2251| Mary Decker| 338|Welcome To The Bo…| 269| 1| 0|11/18/14| 7:16|
+——+—————+——-+——————–+——+——+——+——–+—–+
only showing top 5 rows

In [22]:
result_sheet = sqlContext.sql(“””SELECT CustId, Name, TrackId, Title, Length, Mobile, Gender, DateL, TimeL FROM togeth_way”””)
from pyspark.sql.functions import to_date, to_timestamp,to_utc_timestamp,hour
result_sheet=result_sheet.withColumn(“DateL”, to_date(“DateL”, “MM/dd/yy”))
result_sheet=result_sheet.withColumn(“HourL”, hour(“TimeL”))
result_sheet.createOrReplaceTempView(“result_sheet”)
In [23]:
s = “we return in a 5 line string dataframe”
result_sheet.show(5)

+——+—————+——-+——————–+——+——+——+———-+—–+—–+
|CustId| Name|TrackId| Title|Length|Mobile|Gender| DateL|TimeL|HourL|
+——+—————+——-+——————–+——+——+——+———-+—–+—–+
| 48| Lucas Pizano| 453| Strange Magic| 170| 0| 0|2014-10-23| 3:26| 3|
| 1081|Kenneth Rodgers| 19| Money Talks| 323| 1| 0|2014-10-15|18:32| 18|
| 532| Carlos Kirk| 36| Big Ten Inch Record| 204| 1| 0|2014-12-10|15:33| 15|
| 2641| Charlene Boyd| 822| The Ripper| 122| 1| 0|2014-10-20| 2:24| 2|
| 2251| Mary Decker| 338|Welcome To The Bo…| 269| 1| 0|2014-11-18| 7:16| 7|
+——+—————+——-+——————–+——+——+——+———-+—–+—–+
only showing top 5 rows

In [24]:
togeth_way = togeth_way.withColumn(‘DateL’, split_datetime.getItem(0))
togeth_way = togeth_way.withColumn(‘TimeL’, split_datetime.getItem(1))
s = “we return in a 5 line string dataframe”
togeth_way.show(5)

+——-+——+——-+————–+——+——-+——-+—————+——+——————–+—–+———-+——+—–+——–+————–+——–+——————–+——————–+——+——–+—–+
|EventID|CustID|TrackId| DateTime|Mobile|ZipCode|CCustID| Name|Gender| Address| zip| SignDate|Status|Level|Campaign|LinkedWithApps|MTrackID| Title| Artist|Length| DateL|TimeL|
+——-+——+——-+————–+——+——-+——-+—————+——+——————–+—–+———-+——+—–+——–+————–+——–+——————–+——————–+——+——–+—–+
| 0| 48| 453| 10/23/14 3:26| 0| 72132| 48| Lucas Pizano| 0|2723 Stony Beaver…|99256|11/02/2012| 1| 0| 3| 1| 453| Strange Magic|Electric Light Or…| 170|10/23/14| 3:26|
| 1| 1081| 19|10/15/14 18:32| 1| 17307| 1081|Kenneth Rodgers| 0|74413 Heather Elm…|30301|05/14/2013| 0| 1| 1| 1| 19| Money Talks| AC/DC| 323|10/15/14|18:32|
| 2| 532| 36|12/10/14 15:33| 1| 66216| 532| Carlos Kirk| 0|14 Hidden Bear Ci…|90745|07/14/2013| 0| 2| 1| 1| 36| Big Ten Inch Record| Aerosmith| 204|12/10/14|15:33|
| 3| 2641| 822| 10/20/14 2:24| 1| 36690| 2641| Charlene Boyd| 0|5967 Stony Branch…| 4645|03/26/2013| 1| 1| 1| 0| 822| The Ripper| Judas Priest| 122|10/20/14| 2:24|
| 4| 2251| 338| 11/18/14 7:16| 1| 61377| 2251| Mary Decker| 0|16355 Pretty Pand…|40580|06/23/2013| 1| 1| 0| 1| 338|Welcome To The Bo…| David & David| 269|11/18/14| 7:16|
+——-+——+——-+————–+——+——-+——-+—————+——+——————–+—–+———-+——+—–+——–+————–+——–+——————–+——————–+——+——–+—–+
only showing top 5 rows

It turns out that the customers are more likely to listen to the music at night before bedtime
As a result, The system can be boiled down to two concepts: Exploit and explore. When Spotify exploits, it’s using the information it knows about you, the user. It takes into account your music listening history, which songs you’ve skipped, what playlists you’ve made, your activity on the platform’s social features, and even your location. But when Spotify explores, it uses the information about the rest of the world, like playlists and artists similar to your taste in music but you haven’t heard yet, the popularity of other artists, and more.
The solution is to analyze the audio itself and train algorithms to learn to recognize different aspects of the music. Some experiments by Dieleman identified aspects of the song as distorted guitars, while others identified more abstract ideas such as genres.
In [42]:
from pyspark.sql import DataFrameWriter

result_writer = DataFrameWriter(result_sheet)
result_writer.saveAsTable(‘result_sheet’,format=’parquet’, mode=’overwrite’,path=’./files’)

3. Build Popularity-based Benchmark model and Machine Learning model (ALS)¶
In [26]:
#for week 41 to 50 through the training benchmark
wantsql = ‘select CustId, TrackID, sum(case when Length>0 then 1 else 0 end) as rating’
wantsql = wantsql + ‘ from result_sheet where weekofyear(DateL)<=51 and weekofyear(DateL)>=40 group by CustId, TrackID’
rit =spark.sql(wantsql)

rit.createOrReplaceTempView(“rating_im_train”)

We think the ideal solution is to improve the user interface to Observe user behavior. Implicit ratings include metrics of interest, such as whether a user reads An article, and if so, how much time a user spent reading it. Therefore, how much time is spent is a very important concept. In music, how much time users spend listening to this song is also a very important concept. The main motivation for using implicit ratings is that it eliminates the cost of assessors and assessors.
Each implicit score may contain values less than “value” Clear hierarchy, but appropriate cost-benefit tradeoffs for different types of implicit data Determined based on experience
Just as important as Spotify’s ability to exploit or explore is how the app explains its choices to users. Each label for shelves like “Jump back in” or “More of what you like” tells the user why those specific playlists are being recommended. Spotify has found that explanation is critical to users trusting explanations, according to the 2018 research paper on BaRT.
Three types of implicit data: read / not read, save / delete, and copy / not copy

3.1 Recommendation Model from Implicit Ratings: Train-Week 40-51, Test-Week 52 and 53¶

‘rating’ is Customer #i has listened to the Song #j in a total of n times over the period of t, which n is the raing
In [27]:
rit.show(5)

+——+——-+——+
|CustId|TrackID|rating|
+——+——-+——+
| 743| 39| 1|
| 46| 561| 1|
| 1762| 448| 1|
| 3| 89| 2|
| 2211| 158| 1|
+——+——-+——+
only showing top 5 rows

In [29]:
real_sql = “select CustId, TrackID, sum(case when Length>0 then 1 else 0 end) as rating”
sec = ” from result_sheet”
real_sql = real_sql + sec + ” where weekofyear(DateL)>51 group by CustId, TrackID”
rite=spark.sql(real_sql)
rite.createOrReplaceTempView(“rating_im_test”)
In [30]:
rite.show(5)

+——+——-+——+
|CustId|TrackID|rating|
+——+——-+——+
| 621| 1112| 1|
| 722| 1177| 1|
| 4844| 1011| 1|
| 2604| 800| 1|
| 1739| 923| 1|
+——+——-+——+
only showing top 5 rows

1. total 1060 customer has listened to song 0 in a total of 1 time in the test-set period, so rating is 1
2. CustId 621 has listened to song 3 in a total of 3 times in the test-set period, so rating is 1
3. CustId 722 has listened to song 2 in a total of 4 times in the test-set period, so rating is 1
4. CustId 4844 has listened to song 1 in a total of 3 times in the test-set period, so rating is 1
In [32]:
Furl = ‘select TrackID, count(*) as prediction ‘
se = ‘from rating_im_train ‘
ed = ‘group by TrackID’
md = spark.sql(Furl+se+ed)
Furl = Furl + se + ed
md.createOrReplaceTempView(“model”)

‘prediction’ is the number of unique customers that have listened to the same track
In [33]:
md.show(5)

+——-+———-+
|TrackID|prediction|
+——-+———-+
| 1088| 302|
| 148| 804|
| 833| 346|
| 463| 464|
| 471| 439|
+——-+———-+
only showing top 5 rows

In [39]:
st = ‘select t.*, m.prediction from rating_im_test t left join’
ed = ‘ model m on t.TrackId=m.TrackId’
prd = spark.sql(st + ed)
st = st + ed
prd.createOrReplaceTempView(“predictions”)
In [40]:
prd.show(5)

+——+——-+——+———-+
|CustId|TrackID|rating|prediction|
+——+——-+——+———-+
| 621| 1112| 1| 327|
| 722| 1177| 1| 285|
| 4844| 1011| 1| 324|
| 2604| 800| 1| 386|
| 1739| 923| 1| 339|
+——+——-+——+———-+
only showing top 5 rows

1. (Count (TrackID) as (CustId’s partition) -1) as the denominator => CustId # 621 listened to a total of 1112 unique tracks
2. Decrease 1, because we need 0% to 100%, so (numerator-1) / (denominator-1)
3. Spotify’s sweet spot for understanding whether a person likes a song or not seems to be 30 seconds.
4. (Ranking () Exceeded (divided by predicted desc in order of CustId) -1) As a numerator => Create ranking based on prediction (total number of unique customers by total number of songs)
5. rankui = 0% will mean that program i is predicted to be most desired by user u, and therefore precedes all other programs in the list. Rankui = 100%, on the other hand, indicates that program i is predicted to be the program that user u dislikes the most and is therefore at the end of the list.
In [42]:
st_c = “select CustId, TrackID, rating, ”
last = ” (rank() over (partition by CustId order by prediction desc)-1)*1.0/(count(TrackID) over (partition by CustId)-1) as p_rank from predictions”
EEPP_m =spark.sql(st_c+last)
st_c = st_c + last
EEPP_m.createOrReplaceTempView(“EPR_evaluation”)
In [43]:
EEPP_m.show(5)

+——+——-+——+——————–+
|CustId|TrackID|rating| p_rank|
+——+——-+——+——————–+
| 148| 2| 1| 0E-22|
| 148| 6| 1|0.021739130434782…|
| 148| 14| 1|0.043478260869565…|
| 148| 15| 1|0.065217391304347…|
| 148| 54| 1|0.086956521739130…|
+——+——-+——+——————–+
only showing top 5 rows

In [44]:
ans1 = “select sum(p_rank*rating)/sum(rating) as p_EPR from EPR_evaluation”
r_ans = ans1
ans1 += “;related to sum + 1”
result = spark.sql(r_ans)
In [45]:
result.show

+——–+
| p_EPR|
+——–+
|0.494389|
+——–+

if erp >= 0.5 then means random algorithm is better than erp algorithm
In [48]:
from pyspark.ml.evaluation import Evaluator

class we_need_for_evaluate(Evaluator):
def _evaluate(self, predictions):
prd.createOrReplaceTempView(“predictions”)
st = “select sum(p_rank*rating)/sum(rating) as p_EPR”
st1 = ” from (select CustId, TrackID, rating, ”
st2 = ” (rank() over (partition by CustId order by prediction desc)-1)*1.0/(count(TrackID) over (partition by CustId)-1) as p_rank from predictions)”
rt = spark.sql(st+st1+st2).collect()[0][0]
sum = 0
sum = (0 + sum)/2
return float(rt)
In [100]:
from pyspark.ml.recommendation import ALS
from pyspark.ml.evaluation import RegressionEvaluator
r_inc = 5
dda = 30
ddm = 5
ddr = 50
epr_evaluator = we_need_for_evaluate()
atlas_std= ALS(alpha=dda, maxIter=ddm, rank=ddr, regParam=0.1, userCol=”CustId”, itemCol=”TrackID”, ratingCol=”rating”, coldStartStrategy=”drop”, implicitPrefs=True, nonnegative=False)
r_inc = r_inc + 1
for j in range(1,10):
r_inc = r_inc + 1
for k in range(1,10):
r_inc = r_inc – 1
model_atls = atlas_std.fit(rit)
read_answer = “select a from a real answer”
pred_atlas = model_atls.transform(rite)
watch_out = “A existing results”
r_inc = r_inc + 1
for j in range(1,10):
r_inc = r_inc + 1
for k in range(1,10):
r_inc = r_inc – 1
epr_im = epr_evaluator.evaluate(pred_atlas)

print(“A real ranking for implicit rates ” + str(epr_im))

A real ranking for implicit rates 0.494389
In [49]:
from pyspark.ml.recommendation import ALS
from pyspark.ml.evaluation import RegressionEvaluator

epr_evaluator = we_need_for_evaluate()

atlas_std= ALS(alpha=200, maxIter=7, rank=50, regParam=0.08, userCol=”CustId”, itemCol=”TrackID”, ratingCol=”rating”, coldStartStrategy=”drop”,implicitPrefs=True, nonnegative=False)
r_inc = r_inc + 1
for j in range(1,10):
r_inc = r_inc + 1
for k in range(1,10):
r_inc = r_inc – 1
epr_evaluator = we_need_for_evaluate()
ping_value = ‘select from predictions’
model_atls = atlas_std.fit(rit)
r_inc = r_inc + 1
for j in range(1,10):
r_inc = r_inc + 1
for k in range(1,10):
r_inc = r_inc – 1
epr_evaluator = we_need_for_evaluate()
epr_evaluator = we_need_for_evaluate()

pred_atlas = model_atls.transform(rite)
# compute a real ranking for this answer
epr_im = epr_evaluator.evaluate(pred_atlas)
print(“A real ranking for implicit rating {}”.format(str(epr_im)))

A real ranking for implicit rating 0.494389
In [51]:
rec_fin = model_atls.recommendForAllUsers(5)
r_inc = 5
r_inc = r_inc + 1
for j in range(1,10):
r_inc = r_inc + 1
for k in range(1,10):
r_inc = r_inc – 1
rec_fin.show(r_inc)

+——+——————–+
|CustId| recommendations|
+——+——————–+
| 1580|[[1667, 1.5378112…|
| 4900|[[702, 1.6951567]…|
| 471|[[1260, 1.190138]…|
| 1591|[[1325, 1.5576763…|
| 4101|[[819, 1.7149765]…|
| 1342|[[1625, 1.501605]…|
+——+——————–+
only showing top 6 rows

In [52]:
so_find = model_atls.recommendForAllItems(5)
so_find.show(5)

+——-+——————–+
|TrackID| recommendations|
+——-+——————–+
| 1580|[[3193, 1.8355082…|
| 471|[[1954, 1.2574292…|
| 1591|[[4208, 1.7878283…|
| 1342|[[3355, 1.7911422…|
| 463|[[3218, 1.3341033…|
+——-+——————–+
only showing top 5 rows

3.2 After cross the dataset randomly we generate a recommendation model to recommend spotiy music¶
In [64]:
def pop_render(model, test):
model.createOrReplaceTempView(“model”)
r_inc = 5
r_inc = r_inc + 1
for j in range(1,10):
r_inc = r_inc + 1
for k in range(1,10):
r_inc = r_inc – 1
test.createOrReplaceTempView(“test”)
st = ‘select t.*, m.prediction from rating_im_test t left join’
ste = ‘ model m on t.TrackId=m.TrackId’
pd = spark.sql(st + ste)
return pd

def hit_rat(test):
test.createOrReplaceTempView(“test”)
r_inc = 5
st = “select sum(p_rank*rating)/sum(rating) as Best_EPR ”
r_inc = r_inc + 1
for j in range(1,10):
r_inc = r_inc + 1
for k in range(1,10):
r_inc = r_inc – 1
eed = “””
from (
select CustId, TrackID, rating,
(rank() over (partition by CustId order by rating desc)-1)*1.0/(count(TrackID) over (partition by CustId)-1) as p_rank
from test
)
“””
ff_r = spark.sql(st + eed).collect()[0][0]
r_inc = r_inc + 1
for j in range(1,10):
r_inc = r_inc + 1
for k in range(1,10):
r_inc = r_inc – 1
return float(ff_r)

def transfer_in(ratings_mat):
r_inc = 0
ratings_mat.createOrReplaceTempView(“ratings_mat”)
st = ‘select TrackID, count(*) as prediction ‘
r_inc = r_inc + 1
for j in range(1,10):
r_inc = r_inc + 1
for k in range(1,10):
r_inc = r_inc – 1
eed = “””
from rating_im_train
group by TrackID
“””
md = spark.sql(st+eed)
return md

In [65]:
# using training for 41 – 50
# we have to anlysis the answer
r_inc = r_inc + 1
for j in range(1,10):
r_inc = r_inc + 1
for k in range(1,10):
r_inc = r_inc – 1
st = “select CustId, TrackID, sum(case when Length>0 then 1 else 0 end) as rating ”
ed1 = “from result_sheet ”
ed2 = “group by CustId, TrackID”

r_inc = r_inc + 1
for j in range(1,10):
r_inc = r_inc + 1
for k in range(1,10):
r_inc = r_inc – 1
rim=spark.sql(st+ed1+ed2)

(rating_im_tr, rating_im_te) = rim.randomSplit([0.8, 0.2],seed=50)
r_inc = r_inc + 1
for j in range(1,10):
r_inc = r_inc + 1
for k in range(1,10):
r_inc = r_inc – 1
rim.createOrReplaceTempView(“rating_im”)
rating_im_tr.createOrReplaceTempView(“rating_im_tr”)
f = “select the result from model”
f = “select the result from model”
rating_im_te.createOrReplaceTempView(“rating_im_te”)
In [69]:
r_inc = 1
for j in range(1,10):
r_inc = r_inc + 1
for k in range(1,10):
r_inc = r_inc – 1
pp_m =transfer_in(rating_im_tr)
r_inc = r_inc + 1
for j in range(1,10):
r_inc = r_inc + 1
for k in range(1,10):
r_inc = r_inc – 1
epv = we_need_for_evaluate()
pre_pop=pop_render(pp_m, rating_im_te)
epr_pop = epv.evaluate(pre_pop)
for j in range(1,10):
r_inc = r_inc + 1
for k in range(1,10):
r_inc = r_inc – 1
print(“Normal ranking for popularity = ” + str(epr_pop))

Normal ranking for popularity = 0.494389
In [70]:
dda = 30
ddm = 5
ddr = 50
atlas_std= ALS(alpha=dda, maxIter=ddm, rank=ddr, regParam=0.1, userCol=”CustId”, itemCol=”TrackID”, ratingCol=”rating”, coldStartStrategy=”drop”, implicitPrefs=True, nonnegative=False)
r_inc = 1
for j in range(1,10):
r_inc = r_inc + 1
for k in range(1,10):
r_inc = r_inc – 1
p = 5
epr_evaluator = we_need_for_evaluate()
model_atls_r = atlas_std.fit(rating_im_tr)
r_inc = 1
for j in range(1,10):
r_inc = r_inc + 1
for k in range(1,10):
r_inc = r_inc – 1
rating_agian = p + 10
pred_atlas_r = model_atls.transform(rating_im_te)
s = “select r from real one”
epr_im_r = epr_evaluator.evaluate(pred_atlas_r)
print(“Expected random split pertinent ” + str(epr_im_r))

Expected random split pertinent 0.494389
In [72]:
epv = we_need_for_evaluate()
atlas_std= ALS(alpha=100, maxIter=7, rank=50, regParam=0.08, userCol=”CustId”, itemCol=”TrackID”, ratingCol=”rating”, coldStartStrategy=”drop”, implicitPrefs=True, nonnegative=False)
# read a line from the new one

model_atls_r = atlas_std.fit(rating_im_tr)
r_inc = 1
for j in range(1,10):
r_inc = r_inc + 1
for k in range(1,10):
r_inc = r_inc – 1
pred_atlas_r = model_atls.transform(rating_im_te)
r_inc = 1
for j in range(1,10):
r_inc = r_inc + 1
for k in range(1,10):
r_inc = r_inc – 1
between = 15
between = r_inc + between
epr_im_r = epr_evaluator.evaluate(pred_atlas_r)
print(“implicit & random recommendation ” + str(epr_im_r))

implicit & random recommendation 0.494389

3.3 Using Explicit Rating to recommendate data¶
In [95]:
s1 = “select CustId, TrackID, ”
s2 = ” case when sum(case when Length>=0 then 1 else 0 end)<2 then 0″ s4 = ‘ when sum(case when Length>=0 then 1 else 0 end)<4 then 1’ s3 = ‘ when sum(case when Length>=0 then 1 else 0 end)<7 then 2’ s5 = “”” else 3 end as rating from result_sheet “”” real = ‘select from 7 answers’ s6 = ‘group by CustId, TrackID’ rex=spark.sql(s1+s2+s4+s3+s5+s6) ## random split the data r_inc = 1 for j in range(1,10): r_inc = r_inc + 1 for k in range(1,10): r_inc = r_inc – 1 (rating_ex_train, rating_ex_test) = rating_ex.randomSplit([0.8, 0.2],seed=20) rating_ex.createOrReplaceTempView(“rating_ex”) rex.show(10) rating_ex_train.createOrReplaceTempView(“rating_ex_train”) r_inc = 1 for j in range(1,10): r_inc = r_inc + 1 for k in range(1,10): r_inc = r_inc – 1 rating_ex_test.createOrReplaceTempView(“rating_ex_test”) +——+——-+——+ |CustId|TrackID|rating| +——+——-+——+ | 743| 39| 1| | 46| 561| 0| | 1762| 448| 0| | 3| 89| 1| | 2211| 158| 0| | 3600| 69| 0| | 18| 68| 2| | 621| 1112| 0| | 1492| 282| 0| | 4316| 1424| 0| +——+——-+——+ only showing top 10 rows In [79]: epv = we_need_for_evaluate() mpp =transfer_in(rating_ex_train) ppop =pop_render(mpp, rating_ex_test) epr_pop = epv.evaluate(ppop) r_inc = 1 for j in range(1,10): r_inc = r_inc + 1 for k in range(1,10): r_inc = r_inc – 1 best_epr = hit_rat(rating_ex_test) r_inc = 1 for j in range(1,10): r_inc = r_inc + 1 for k in range(1,10): r_inc = r_inc – 1 print(“the pertentage of pop recomend:” + str(epr_pop)) r_inc = 1 for j in range(1,10): r_inc = r_inc + 1 for k in range(1,10): r_inc = r_inc – 1 print(“TBP ranking the answer is:” + str(best_epr)) the pertentage of pop recomend:0.494389 TBP ranking the answer is:0.024781711639237 It estimates that 60% of the time listeners are in a “closed” mindset when they are on the app; they know what they want to listen to and they just need to find it. The remaining 40% of time is spent in an “open” mindset. In this mindset, users put in less effort, they scroll less, they skip tracks more, and they click less on the artist for further information. Essentially, they are receptive to new ideas, but in a passive yet impatient state. In [88]: model_ex = ALS(rank=50, maxIter=7, regParam=0.06, userCol=”CustId”, itemCol=”TrackID”, ratingCol=”rating”, coldStartStrategy=”drop”, implicitPrefs=False, nonnegative=False).fit(rating_ex_train) ppex = model_ex.transform(rating_ex_test) epv = we_need_for_evaluate() r_inc = 1 for j in range(1,10): r_inc = r_inc + 1 for k in range(1,10): r_inc = r_inc – 1 rmsev = RegressionEvaluator(metricName=”rmse”, labelCol=”rating”, predictionCol=”prediction”) d_rmse = rmsev.evaluate(ppex) d_epr = epv.evaluate(ppex) r_inc = 1 for j in range(1,10): r_inc = r_inc + 1 for k in range(1,10): r_inc = r_inc – 1 print (“the epr result is: ” + str(d_epr)) s = “select form a using c as a result” print(“the rmse answer result s following ” + str(d_rmse)) the epr result is: 0.494389 the rmse answer result s following 0.32803877202393206 In [90]: model = ALS(rank=100, maxIter=7, regParam=0.1, userCol=”CustId”, itemCol=”TrackID”, ratingCol=”rating”, coldStartStrategy=”drop”, implicitPrefs=False, nonnegative=False).fit(rating_ex_train) r_inc = 1 for j in range(1,10): r_inc = r_inc + 1 for k in range(1,10): r_inc = r_inc – 1 pdr = model.transform(rating_ex_test) r_inc = 1 for j in range(1,10): r_inc = r_inc + 1 for k in range(1,10): r_inc = r_inc – 1 epr_evaluator = we_need_for_evaluate() r_inc = 1 for j in range(1,10): r_inc = r_inc + 1 for k in range(1,10): r_inc = r_inc – 1 f = “real one is under compose” rmev = RegressionEvaluator(metricName=”rmse”, labelCol=”rating”, predictionCol=”prediction”) real_r = rmev.evaluate(pdr) y = ” computing rmse using rmse answer” real_e = epr_evaluator.evaluate(pdr) print (“Expected result is” + str(pdr)) print(“RMSE reulst is” + str(real_r)) Expected result isDataFrame[CustId: int, TrackID: int, rating: int, prediction: float] RMSE reulst is0.3419420291783514 In [89]: r_inc = 1 for j in range(1,10): r_inc = r_inc + 1 for k in range(1,10): r_inc = r_inc – 1 from pyspark.ml.tuning import ParamGridBuilder, TrainValidationSplit rranswer= ALS(userCol=”CustId”, itemCol=”TrackID”, ratingCol=”rating”, implicitPrefs=False, coldStartStrategy=”drop”, maxIter=1, rank=5) r_inc = 1 for j in range(1,10): r_inc = r_inc + 1 for k in range(1,10): r_inc = r_inc – 1 qutoe = “select from prediction and test for 7 years” rr_grid=ParamGridBuilder().addGrid(rranswer.regParam, [0.03,0.06]).build() r_inc = 1 for j in range(1,10): r_inc = r_inc + 1 for k in range(1,10): r_inc = r_inc – 1 tt_rmse = RegressionEvaluator(metricName=”rmse”, labelCol=”rating”, predictionCol=”prediction”) r_inc = 1 for j in range(1,10): r_inc = r_inc + 1 for k in range(1,10): r_inc = r_inc – 1 real_training = TrainValidationSplit(estimator=rranswer, estimatorParamMaps=rr_grid, evaluator=tt_rmse,trainRatio=0.8,seed=100).fit(rating_ex_train) predictions = real_training.transform(rating_ex_test) r_inc = 1 for j in range(1,10): r_inc = r_inc + 1 for k in range(1,10): r_inc = r_inc – 1 best_model= real_training.bestModel print (“the real answer is : ” + str(best_model.rank)) print (“the best iteration in tvs:” + str(best_model._java_obj.parent().getMaxIter())) the real answer is : 5 the best iteration in tvs:1 The Spotify example provides an illuminating case in the benefits of blending different models to deliver diversity, as well as relevance. This is all shot through with a psychological and cultural understanding of how we listen to and share music. Spotify aims to take the nostalgic appeal of the mix tape and upgrading the concept for the digital age. In [84]: r_inc = 5 for j in range(1,5): r_inc = r_inc + 1 for k in range(1,5): r_inc = r_inc – 1 u_rc = model_ex.recommendForAllUsers(r_inc) #we get a 5 answer in this time s_rc = model_ex.recommendForAllItems(r_inc) In [85]: u_rc.show(r_inc) +——+——————–+ |CustId| recommendations| +——+——————–+ | 1580|[[0, 0.854263], […| | 4900|[[1, 0.02969639],…| | 471|[[0, 0.8252722], …| | 1591|[[0, 0.52127606],…| | 4101|[[0, 0.6293502], …| +——+——————–+ only showing top 5 rows In [86]: s_rc.show(r_inc) +——-+——————–+ |TrackID| recommendations| +——-+——————–+ | 1580|[[0, 0.53161836],…| | 471|[[0, 0.78574634],…| | 1591|[[0, 0.5791585], …| | 1342|[[0, 0.6110388], …| | 463|[[0, 0.977968], […| +——-+——————–+ only showing top 5 rows

Java|data structure|作业代写

程序代写代做 data structure Java algorithm Assignment 2

Assignment 2
COMP 250 Winter 2020
posted: Tuesday, Feb. 11 2020
due: Tuesday, Feb. 25, 2020 at 23:59
Learning Objectives
This assignment aims at building on what we have seen in assignment 1 to start storing information and navigating it using complex data structures. Unlike in assignment 1, you will actually have to make decisions on how you want to solve the problems at hand, and while we will see some methods to tackle them in class, most of this discussion will be held at a conceptual level. Your task is to translate your conceptual understanding of those concepts into Java. Watch out: the output of this assignment is not deterministic, which means you can get different outcomes between executions. Unlike for assignment 1, or for your assignments in COMP 202, it will not be immediately obvious whether your code works. Make sure to think about this and test your program thoroughly! In terms of specific concepts, this assignment tests all your knowledge on object-oriented programming covered in A1, as well as doubly linked list, navigating between nodes on lists, rearranging lists, and sorting.
General Instructions • Submission instructions
– Late assignments will be accepted up to 2 days late and will be penalized by 10 points per day. Note that submitting one minute late is the same as submitting 23 hours late. We will deduct 10 points for any student who has to resubmit after the due date (i.e. late) irrespective of the reason, be it wrong file submitted, wrong file format was submitted or any other reason. This policy will hold regardless of whether or not the student can provide proof that the assignment was indeed “done” on time.
– Don’t worry if you realize that you made a mistake after you submitted: you can submit multiple times but only the latest submission will be evaluated. We encourage you to submit a first version a few days before the deadline (computer crashes do happen and myCourses may be overloaded during rush hours).
– Please store all your files in a folder called “Assignment2”, zip the folder and submit it to MyCourses. Inside your zipped folder, there must be the following files.
∗ TrainNetwork.java ∗ TrainLine.java
∗ TrainStation.java
1

Do not submit any other files, especially .class files. Any deviation from these requirements may lead to lost marks
• It does not matter whether or not you create a package to store all these classes. It is up to you to decide whether you’d like to have a package or not.
• You are given class templates to complete. You can only change the code of these classes within the methods containing the comments ”YOUR CODE GOES HERE”. You cannot change any method headers unless a comment specifies you can, and even then, the only changes you can make are to add exception handling. If you change a method header, we might not be able to grade you and you may receive a grade of zero. Read the comments in the templates carefully.
• Requests to evaluate the assignment manually shall not be entertained, so please make sure that you follow the instruction closely or your code may fail to pass the automatic tests. Note that for this assignment, you are NOT allowed to import any other class (including for example ArrayList or LinkedList). The template code comes with two imports in the class TrainLine. You cannot change them nor add any new ones. Any failure to comply with these rules will give you an automatic 0.
• We have included with these instruction a tester class called TrainRide, which will help you test your network. You are welcome to add more tests to it. This tester includes a network of 15 stations over three lines, but your code can be evaluated on another network. We will also release (later) a very light MiniTester, which is a mini version of the final tester used to evaluate your assignment and will call every method of the assignment. If your code fails those tests, it means that there is a mistake somewhere. Even if your code passes those tests, it may still contain some errors. We will test your code on a much more challenging set of examples. We therefore highly encourage you to modify the tester class and expand it.
• You will automatically get 0 if your code does not compile.
• Failure to comply with any of these rules will be penalized. If anything is unclear, it is up to you to clarify it by asking either directly a TA during office hours, or on the discussion board on Piazza.
2

Figure 1: A train network plan (left), before and after a shuffling (right)
A Confusing Train Ride
Due to a significant increase in its student population, especially in its Machine Learning depart- ment, the single direct train going to Hogwarts has been replaced by a network of 15 stations distributed over three lines. However, this has revealed to not exactly be an improvement. Just like the staircases within the castle, the stations get bored and, to fight this boredom, rearrange themselves every 2 hours. However, luckily for you, the stations have not yet started switching lines; they always remain on the same line, but the order of the stations within a line gets shuffled.
Your task is to implement this shuffling train network and simulate the trip of an unfortunate traveler. You will be given Java templates to complete. Follow the instructions for each class closely.
Here are a few things you should know about the network:
• Traveling between two stations takes an hour.
• All stations are unique and only exist on one line.
• Transfer is possible between specific stations of different lines, which are indicated by having the same name but followed by a unique letter, identifying a distinct platform. Those remain two distinct stations, but that offer the possibility of traveling from one to the other. Transfer is always two-way; if it is possible to transfer from station A to B, then transfer is possible from station B to A.
• If transferring is possible, the passenger is forced to transfer, unless the passenger would be transferring to a station he just transferred from. for example, if I station from station London – A to London – B, your next step is not to transfer from London – B to London – A.
3

• Shuffling occurs every two hours. During a shuffling event, the order of the stations within a line changes. The left and right terminals might change. The transfer stations are part of the shuffling, but they stations they transfer to remain unaffected.
• You can assume there is only one traveler on the network at a time, and that every line has a single train which is magically waiting for the traveler at the appropriate transfer station.
You should now be ready to start the assignment, which is divided in four classes, as follows:
[0 points] First, you are given a class TrainStation. A TrainStation encodes the stations of the network. A station is part of a TrainLine, which you can imagine as a doubly linked list. It has the following fields:
• TrainStation left : the next station on the left
• TrainStation right : the next station on the right
• boolean rightTerminal : true if the station is at the right end of the line
• boolean leftTerminal : true if the station is at the left end of the line
• String name : the name of the station.
• TrainLine line: the TrainLine this station belongs to.
• boolean hasConnection: true if the train station connects to another line. This is the only public field.
• TrainStation transfersToStation : the station object on the other line, if this transfer exists.
• TrainLine transfersToLine : the line object you can transfer to at this station.
All those fields, except hasConnection, are private. As such, you are provided with get and set methods for all the private fields. The class also comes with two constructors, as well as an equals method for comparing stations. Do not modify the TrainStation class.
[65 points] You are also given a class TrainLine. A TrainLine contains stations that move around. It has the following fields:
• TrainStation leftTerminus : the terminal station on the left
• TrainStation rightTerminus : the terminal station on the right
• String lineName : the name of the line.
• boolean goingRight: true if the train is going from the left to the right (assuming node 0 is at the left, and the last node at the right). You can assume there is only one train on the line which magically awaits for you at the transfer station, so the direction of the line is the direction of this train.
• public TrainStation[] lineMap : an array of TrainStation which encodes the map of the line. in that array, the station at index 0 is the left-most station of the line.
4

A constructor is provided, as well as equals method and a helper class StationNotFoundException. You are also provided with a method toString which converts the lineMap to a String for printing purposes. Finally, a function shuffleArray shuffles the lineMap for you.
Your task is to implement the following methods:
• public int getSize() : this method returns an integer equal to the number of stations on the line.
• public TrainStation findStation(String name) : this method take as input the name of a station, and searches through the line to return the TrainStation of this name. All station names are unique.
– Iterate over the line until you find a station of the right name.
– If the station is not found, throw a StationNotFoundException
• public TrainStation getNext(TrainStation station) : takes as input a station and
returns the next station of the line.
– There is only one train on the line, it always goes in the same direction, until it hits a terminal station, then it turns around.
– Use the goingRight field to know in which direction the train is going.
– if the station is not on this line, throw a StationNotFoundException.
– You cannot use the lineMap to find the next station.
• public TrainStation travelOneStation(TrainStation current, TrainStation previous) : takes as input the previous and the current station and returns the next station, but
while also considering line transfers. Line transfers count as a station change and take
the same time as a standard move between stations. So if you are at a station that has
the option of transferring, travelOnestation should return the station transferred to, and this should count as one time step of one hour.
– Trains do not like passengers. If you have the opportunity to transfer, you must, unless transferring brings you back to the station you just arrived from (condemning you to an eternal ping-pong between the two).
– If a valid transfer is available, return the station you transferred to. Otherwise, return the next station on the usual path of the line, computed with getNext.
– If the current argument to travelOneStation is not on this train line, throw a StationNotFoundException
• public TrainStation[] getLineArray() : returns an array of the train stations on the line, in order from the left terminal (index 0 of the array) to the right terminal (last index of the array). This array is completely independent from the lineMap. The idea is to use this function to update the lineMap.
• public void shuffleLine() : shuffles the station on the line. 5

– You are provided with a shuffleArray method, which takes as input an array of TrainStations generated with getLineArray, and updates the lineMap to a shuffled version of this array.
– Once you updated the lineMap using the provided method, reorder the stations of the line so that their order matches that of the lineMap.
– tips: remember to keep track of the terminal stations, and to update the TrainStation objects.
• public void sortLine() : sorts the stations of the line in increasing alphabetical order, and updates the lineMap (using getLineArray). Note that for clarity, we make every station name in TrainRide start with a number. Numbers are included in the alphabetical comparison. You can use any of the algorithms covered in class, namely bubble sort, insertion sort, or selection sort. No matter what you use, you need to implement it yourself. Tip: you can make a helper swap function to make your life easier.
[35 points] You are also given a class TrainNetwork. A TrainNetwork contains an array of train lines. You are asked to implement the following functions:
• public TrainLine getLineByName(String lineName) : this method take as input the name of a Line and returns a line of that name, otherwise throws a LineNotFoundEx- ception (helper class provided).
• public void dance() : shuffles all the lines using shuffleLine.
• public void undance() : sorts all the lines using sortLine.
• public int travel(String startStation, String startLine, String endStation, String endLine) : the key function of the program. It takes as input coordinates for departure and arrival and simulates a trip. Please follow the instructions closely.
1. Obtain departure station and line objects from the name strings provided as param- eters to the method. Store them in the variables curLine and curStation.
2. Iterate over the train network starting at the departure station in the provided while loop, updating curStation and curLine . You can change the termination condition.
3. Keep track of the number of stations visited. This number is equal to the number of hours spent on the train. Assume line transfers always take an hour.
4. Remember the network dances every two hours.
5. At each iteration, keep track of the current station and the previous station. Tip: you do need to keep track of the previous station even if it is not obvious why. Remember how transferring works.
6. at each iteration, check whether you have arrived at destination by comparing the objective name to the name of the current station.
6

7. Once you have reached the destination, or after 168 hours of traveling, stop iterating and return an integer equal to the number of hours spent traveling.
8. If the station cannot be found, assume you stayed on the train for a week before giving up, and return 168.
9. Do not throw exceptions in this method.
[0 points] You are also provided with a pre-written class TrainRide, which instantiates the differ- ent objects to a full train network (see the illustration). You can make modifications to the lines or itinerary to test out your code, but the contents of this class will not be graded.
All methods of this assignment are connected and as such, a part of your grade will come from methods that call other methods. This means that one method working incorrectly can lead to a lot of lost marks. Make sure you test your assignment thor- oughly by trying the TrainRide, which is a syntactic and logical test of every method. Double-check that your results make sense given the rules stated in this handout.
Good luck!

JAVA代写|平时作业|计算网络computer network|computer system|p2p|chat application

Project 1: Chat Application

Project Description

A chat program is an application that enables communication between multiple chat

clients. There are two typical paradigms to enable such communications. For the

client-server paradigm, it is the responsibility of the server to relay the messages that

are exchanged between clients. On the other hand, peer-to-peer (P2P) paradigm

enables the application to be symmetric, where there is no dedicated server to respond

to client’s service requests. Instead, every participant serves as both server and client.

For this project, you need to develop a UDP-based chat application, called netchat,

following the P2P communication paradigm. This application will use sockets for

communications. Each functionality of this chat application is described below.

1. start a chat session

The chat program is invoked from command-line with a single port parameter, e.g.,

$ ./netchat 5555

The port number specifies the port that netchat will use to communicate with others

using UDP. It will bind itself to this port when netchat runs. The screenshot after

invoking the program is below:

eecs325@eecs325-VirtualBox:~/s2020-proj1/$ ./netchat 5555

#chat with?:

Then the application waits for user input from keyboard. The user could initiate a chat

session with another user by typing their IP address (dotted decimal notation) and port

number. For example,

#chat with?: 127.0.0.1 6666

netchat then will wait for the other party to respond to this connection request. Upon

success, the sender will see the below message on his screen:

#success: 127.0.0.1 59051

Note that the response will be sent back from a different port other than 6666 . This

UDP-based application is designed to behave like a TCP-based application. (You

could review the TCP socket programming example on the slide to learn how TCP

handles connection requests). netchat should implement a timeout mechanism to

enable request retransmissions if the sender could not receive any response from the

receiver within 5 seconds. netchat will give up after two retransmissions and

notifies the sender of the failed connection, e.g.,

#failure: 127.0.0.1 6666

On the receiver end, the client will receive 3 notifications of the connection initiation

requests, at 5-second intervals, so that the receiver could decide whether to establish a

connection with the sender or not, e.g.,

#session request from: 127.0.0.1 55833

#chat with?:

#session request from: 127.0.0.1 55833

#chat with?:

#session request from: 127.0.0.1 55833

Note that the connection request does not come from port 5555. If the receiver

decides to accept the connection, he could type the IP address and the port number of

the connection request:

#session request from: 127.0.0.1 41625

#chat with?: 127.0.0.1 41625

#session request from: 127.0.0.1 41625

#chat with?:

[127.0.0.1:41625] accept request? (y/n)y

netchat will ask for a confirmation for accepting the connection request. The

receiver will type ‘y’ to accept the connection request, and ‘n’ to deny it. Once a

session is established between the sender and receiver, they could start exchanging

messages with each other.

2. interaction for established session

During the session, sender/receiver need to handle three types of events: 1. message

events 2. time out event 3. signal events, which will be explained following.

2.1 Message Events

Message events are the message packets being exchanged between the sender and

receiver. netchat will read up to 50-byte-long message from user’s input

(excluding ‘\n’, i.e., ENTER key), and send the message to the receiver via UDP.

The communication between a sender and receiver is asynchronous, i.e., the receiver

could decide to respond to the sender later. For example,

Sender:

#success: 127.0.0.1 34048

#chat with?: 127.0.0.1 34048

[127.0.0.1:34048] your message: hello

#chat with?:

Receiver:

[127.0.0.1:41625] accept request? (y/n)y

#chat with?:

#[127.0.0.1 41625] sent msg: hello

If the receiver decided to respond, the receiver need to specify the sender’s IP and port

before he types the message from keyboard:

#chat with?: 127.0.0.1 41625

[127.0.0.1:41625] your message: hi

The sender will receive:

#chat with?:

#[127.0.0.1 34048] sent msg: hi

As input and messages are asynchronous, interleaving of output to stdout may occur

as below:

#session request from: 127.0.0.1 50011

#chat with?: 127.0.0.1

#session request from: 127.0.0.1 50011

#chat with?: 50011

[127.0.0.1:50011] accept request? (y/n)

• bonus points (2 pts): While waiting for user input from keyboard (i.e., waiting

for accepting connection request or typing messages from keyboard), you could set

up a timeout value, e.g., 5 seconds, to avoid being blocked. For example:

#session request from: 127.0.0.1 40416

#chat with?: 127.0.0.1 40416

[127.0.0.1:40416] accept request? (y/n)

#chat with?:

In this example, the application accepts new commands as the client did not accept or

deny the connection request within 5 seconds.

2.2 Timeout Events

As mentioned in Section 1, netchat should implement timeout and retransmission

mechanisms when a sender is trying to establish connections with a receiver. In

addition, since UDP is “connectionless”, netchat also should implement a heartbeat

mechanism to keep track of the connection status with the other party. For example, if

a sender could not receive a heartbeat message within 5 seconds for 3 consecutive

epochs, the sender will assume that the session has been terminated by the receiver.

Then a warning will show up on the screen and the sender will also terminates the

session:

[127.0.0.1:45435] accept request? (y/n)y

#warning: peer 127.0.0.1 45435 might be offline; terminating

session…

#chat with?:

In the example above, the receiver terminates all the sessions with CTRL-C (i.e.,

control key and C).

2.3 Signal Events

The user may want to terminate an established session or terminate all sessions and

quit the application. To terminate all sessions and quit the application, users could use

CTRL-C, which raises the SIGINT signal:

#chat with?: ^C

terminating all sessions…

Note that this termination only closes all the sessions on the sender side, the other side

of the sessions will figure this out with the heartbeat mechanism mentioned in Section

2.2. To terminate one session, users could use CTRL-\ (i.e., control key and

backslash), which raises SIGQUIT signal. Then the user needs to specify the IP and

port number of the session that he wants to be terminated:

#chat with?: ^\

#terminate session (for help <h>): 127.0.0.1 55097

#terminating session with 127.0.0.1 55097

#chat with?:

Note that netchat will send a message to the other party to notify this termination

such that the receiver could also terminate this session:

#[127.0.0.1:54863] session termination received

#chat with?:

3. netchat protocol format

The netchat packets have the following formats:

msg type rand num UDP packet

msg type specifies the type of the message being exchanged, e.g., normal message

or heartbeat message; rand num is a random number generated by the session

initiator. This value could be used as a simple authentication mechanism for the

receiver to verify that this message is sent from the actual sender (although netchat

has not implement encryption yet); then the UDP packet is encapsulated in this packet

header.

4. Bonus Points (2 pts)

There are two options for gaining this bonus points, 1) implement a menu for

netchat, that could list all the active sessions (that it knows of) for users; 2) If you

are familiar with GUI programming using C, you could try to address the interleaving

problem of the shared stdout file descriptor that could produce messy output.

For this project, you will be provided with the executable netchat. You could use

that as a reference when you implement your own application.

REMINDERS

o Submit your code to Canvas in a tarball file by running command in terminal:

tar -zcf [you-case-id]-proj-1.tar.gz project-1

o If your code does not compile or could not run, you will not get credits.

o Document your code (by inserting comments in your code)

o DUE: 11:59 pm, Monday, Feb 24th.

1 byte 4 bytes

数据库|数据结构|data structure|网络安全|c语言

程序代写代做 database algorithm graph C go Computer Security Coursework Exercise 2

Posted on February 23, 2020 by mac

Computer Security Coursework Exercise 2
January 20, 2020
In this coursework we will touch upon a number of topics related to both defense and attack of components that interact with security-critical parts of users’ workflow. The deadline is 6 March 2020, 16:00.
1 Asymmetric Encryption with GPG
In this section you will learn to use GPG for day-to-day usage, most importantly including signing and verifying signatures. You will also have to prove your knowledge by solving a challenge. GPG (sometimes written as GnuPG) is the GNU Privacy Guard. GPG is an open source implementation of the OpenPGP standard for asymmetric encryption.
1.1 Introduction to GPG
The purpose of this part is to familiarise yourself with the GPG tool. You will see how to receive the public keys of other people and use them for encryption and signature verification. You will also learn how to generate private keys and use them for signing and decryption. The instructions that follow are specific for DICE machines, but should work on any Linux machine with slight variations. They should also work on MacOS machines with minimal adaptation. There exist some ports of GPG for Windows, but they are not supported in this coursework.
1.1.1 Verifying Signatures
Verifying the integrity of software you download is important to ensure that your software hasn’t been tampered with. This section will show you how to verify signatures if they are available. Your task is to download the Alpine Linux mini root filesystem armv71 and the corresponding signature2 and verify it. Save the contents of the second link to a file. You should place both files in the same directory. The names of the files are important: the signature must have the same name as the file it signs, with the added extension ‘.asc’.
Before you can verify the signature however, you need to import the public key which was used to make it. These are also available from the Alpine Linux download page3. The fingerprint of the signing public key is 0482 D840 22F5 2DF1 C4E7 CD43 293A CD09 07D9 495A. More on what a fingerprint is later. To receive the public key, execute:
This could take a while. You should see a report of the key which was imported. Next, to verify the file itself, go to the directory where you downloaded the files and run:
1 http://dl- cdn.alpinelinux.org/alpine/v3.11/releases/armv7/alpine- minirootfs- 3.11.3- armv7.tar. gz
2 http://dl- cdn.alpinelinux.org/alpine/v3.11/releases/armv7/alpine- minirootfs- 3.11.3- armv7.tar. gz.asc
3 https://alpinelinux.org/downloads/
gpg –recv-key ‘0482 D840 22F5 2DF1 C4E7 CD43 293A CD09 07D9 495A’
gpg –verify alpine-minirootfs-3.11.3-armv7.tar.gz.asc
1

Youshouldseealinestating‘Good signature from ’.Thisindicatesthatthesignatureisvalid, and that you have the signer’s public key. You will also see a rather scary-looking warning, which indicates that you haven’t assigned the public key a trust level. Proper GPG usage recommends to verify your correspondents’ keys by checking their fingerprint and subsequently signing their key and setting your trust level towards them, however we will not focus on it here.
Keep in mind that the aforementioned steps do not rule out completely the possibility of a Man in the Middle attack. An attacker could hijack the legitimate site, replace the original public keys with his own, put a backdoor in the provided source code and sign it with his key. GPG itself can only rule out such attacks if you have out-of-band reasons to trust the validity of the provided fingerprint. Such an out-of-band reason is the acknowledgement that the website itself is valid through TLS security.
1.1.2 Generating a Keypair
In order to sign or receive encrypted messages, you will need your own key pair. To generate one, run:
Complete the command line dialogue, and wait for the key to be generated. The default option for key type (RSA both for encrypting and signing) is sufficient. Note that, after the key generation phase, the underlying algorithms are handled by gpg under the hood, so you should never run into problems because of the key type of others. A key length of 4096 and an expiration date after one year are recommended, and the comment field should be left empty. Note that it is highly recommended to secure the key with a strong passphrase. Your private key is your digital identity, do not treat it lightly.
1.1.3 Key IDs
Many commands in GPG need to identify the key to use. The public keys available can be listed with the command ‘gpg -k’,andtheprivatekeyswith‘gpg -K’.Eachkeyisassociatedwithalong(160bits)hexadecimalID,which can be used to refer to it, known as the fingerprint of the key. Add the option ‘–fingerprint‘ to the previous commands to display it. More conveniently, keys can also be referred to by their email address.
1.1.4 Key Management
Once you’ve generated a key, there are a few maintenance operations you may need to do from time to time.
1. Uploadyourpublickeytothekeyserverat‘hkp://keys.gnupg.net’.Youwillhavetosetthe‘keyserver’
optionin‘~/.gnupg/gpg.conf’,andthenrun‘gpg –send-keys ’.
2. Makesureyoucanreceiveacoursemate’spublickey.Aftertheyhaveuploadedtheirs,run‘gpg –recv-keys ’. You may have to wait a few minutes for their key to propagate before receiving it. Note that in this situation, the key ID must be the full fingerprint; an email address does not suffice.
3. Generate a revocation certificate for your key, using the command ‘gpg –gen-revoke ’. A revocation certificate can be used to invalidate your key pair. This is not something you want to do right now, however it is helpful to know what to do. The revocation certificate can be imported with ‘gpg –import’, similarly to keys. The (now revoked) public key can then be pushed to a keyserver. This may be useful if you want to stop using the particular email address or your private key has leaked.
4. You can export your keys with the command ‘gpg –export > gpg.keys’. This will create a binary file ‘gpg.keys’, containing all public keys in your database. It is also possible to export private keys, using the command ‘gpg –export-secret-keys > gpg private.keys’. When exported in this way, the keys are still encrypted with your passphrase.
4OnaDICEmachine,youwillfirsthavetoissuethecommandgpg-agent –daemon –no-use-standard-socketandthenexecute the command that is returned in order for the key generation to function properly.
gpg –gen-key4
2

1.1.5 Signing Messages
GPGsignaturesoperateonfiles.Themostbasicwaytosignafileistoexecute‘gpg -b ’.Thiswillcreate a new file, called ‘.sig’, which contains the signature of the file with your private key. Adding the -a option will force the signature to be generated in an ASCII format, making it more convenient for embedding.
Itisalsopossibletopackagethedatatogetherwiththesignature,byrunning‘gpg -s ’.Thisistypically used in conjunction with encryption.
1.1.6 Encrypting and Decrypting Messages
To encrypt a message, double check that you have a coursemate’s public key. Create a plain text file containing your message, and then encrypt it with ‘gpg -e ’. Send the newly created file to your coursemate. The same command can also be run with the -s option, to also sign the message, and the -a option to create an ascii-formatted message.
Hopefully you will have received an encrypted message from one of your coursemates. If not, ask someone to sendyouone.Todecryptthemessage,simplyrun‘gpg -d ’.
1.2 Encrypted email exercise
In this exercise you will have to prove your ability to encrypt and decrypt messages correctly. This is the only marked exercise in the GPG section. The submission steps of this exercise should be completed while logged in on lute. Thus,beforeyoustartthisexercise,ensurethatyouareloggedinonluteorrun“ssh @lute.inf.ed.ac.uk” and provide your passphrase if you are logged in on any other DICE machine.
2
1. 2.
3.
4. 5.
6.
Generate a private key if you don’t already have one and upload it to the keyserver as explained above5. Submit a file named exactly ‘fingerprint’ containing only your fingerprint to the Computer Security,
Coursework2directory(cs cw2)usingthesubmitDICEtool. Youwillreceivethroughemailthechallenge,encryptedwiththepublickeycorrespondingtothefingerprintyou
uploaded. Decrypt it and solve the challenge.
Receive the key with fingerprint 55B6 5280 76FC 8B3A B21E 8FC7 FC43 FBAF BA4D 29296.
Create a file containing only the answer and encrypt it using the public key that you just received. Use the GPG option‘-o solution’whenencryptingtocreatetheencryptedfilewiththename‘solution’.
Submit the encrypted answer as a file named exactly ‘solution’. If the answer is correct, you will receive a confirmation email.
Spoofing email sender
For this exercise, you will send us an email with a spoofed email sender field:
• The subject line of your email should be your student id
• The sender of your email should be luke.skywalker@starwars.com • You will send your email to cw-2@ed.ac.uk.
One way of doing this is by using the mailx utility program. You are free to try this amongst yourselves before you actually send your email to us.
5The key does not necessarily have to be tied with your student email account, but you will have to have access to your student email account in order to complete the exercise.
6The corresponding email address is fake, therefore sending anything there is pointless. 3

3 Password Cracking
This question will involve (partially) cracking a list of hashed passwords. The password lists are based on the 2009 RockYou password leaks. The files rockyou-samples.md5.txt, rockyou-samples.sha1-salt.txt, and rockyou-samples.bcrypt.txt store 100,000 password hashes each. These files can be found on DICE in the /afs/inf.ed.ac.uk/group/teaching/compsec/cw2/password-cracking/ directory. Each function is progressively more resistant to password cracking than the previous one.
3.1 Brute-forcing MD5
The file rockyou-samples.md5.txt contains MD5 hashes of passwords, encoded in hexadecimal. Write a program in a programming language of your choice, which brute forces all five character passwords, using only numbers and lowercase ASCII letters (0-9 and a-z). The program should create an output file md5-cracked.txt which contains the passwords corresponding to the hashes in rockyou-samples.md5.txt and the number of occurrences for each of them. As the output format, keep one entry per line, with each entry being of the form n,password (E.g. 10,apples). Submit the file md5-cracked.txt.
Be aware that the naive implementation of brute forcing will not be sufficient here. You will need to check each possible password against all hashes very quickly, it is therefore strongly advised to use hashmaps (or, even better, multisets).
3.2 Cracking Common Passwords with Salted SHA-1
The file rockyou-samples.sha1-salt.txt contains SHA-1 hashes of passwords with a salt. The format of each line is $SHA1p$salt$hash, where:
hash = SHA-1(salt || password)
The approach to brute-forcing from Part 1 can’t be used in this case, as there is no fast way to check a given password against the entire list. Instead, write a program which tries the 25 most common passwords against the entire list, and reports how often each occurred (in the same format at in part 1). The 25 most common passwords are:
Save your results in the same format as in Part 1, as the file salt-cracked.txt. Submit this file. 3.3 Cracking bcrypt?
The file rockyou-samples.bcrypt.txt contains bcrypt hashes of passwords. Bcrypt is a more modern hash function designed for use with passwords. Its primary feature is that a bcrypt hash is (comparatively) slower to compute, making brute force attacks far less effective than with the extremely efficient SHA-1 and MD5 hashes. The bcrypt hashes are stored in a standard format for bcrypt, and should be recognized by a bcrypt library of your choice. The hashes further automatically include a salt.
Write a program that finds the first five occurrences of the password 123456 by line number (counting from 1). Write each line number, in order, on a single line of the file bcrypt-lines.txt. Submit this file.
4 (wo)Man in the Middle Attack
You are asked to mount a (wo)Man-in-the-Middle (MitM) attack against the toy implementation of an encrypted chat between terminals provided in /afs/inf.ed.ac.uk/group/teaching/compsec/cw2/mitm/.
123456
princess
nicole
jessica
111111
12345
1234567
daniel
654321
iloveu
123456789
rockyou
babygirl
michael
000000
password
12345678
monkey
ashley
michelle
iloveyou
abc123
lovely
qwerty
tigger
4

4.1 High-level overview
When Alice and Bob hear about encryption, they immediately set out to implement an encrypted chat client so that they are sure no one eavesdrops their intimate discussions. They decide to use AES7 to encrypt their messages, since everyone says it’s the best. They also hear of the Diffie-Hellman key exchange8 (DHKE) and figure it would be cool to use a new secret key for AES every time they connect.
4.1.1 AES
Just like every symmetric encryption scheme, AES consists of two algorithms:
• The encryption algorithm takes a key K1 and a message M1 as input and returns a ciphertext C1 as output:
C1 = Enc(K1, M1)
• The decryption algorithm takes a key K2 and a ciphertext C2 as input and returns a message M2 as output:
M2 =Dec(K2,M2)
If a message M is encrypted with key K and the resulting ciphertext C is decrypted with the same key K, the result of the decryption will be the original message M: ∀K∀M,M = Dec(K,Enc(K,M))
A simple library for encrypting and decrypting using pyaes is provided in symmetric.py.
4.1.2 Diffie-Hellman Key Exchange
This is a protocol between two parties (say Alice and Bob) that want to obtain a common key that is unknown to anybody else. Their communication takes place over an insecure channel that anyone can eavesdrop.
A physical-world equivalent is the following: A group of people sit around a table and two of them want to speak in private. They can have a brief exchange (of very long numbers) which everybody hears. After that they will possess a common secret that no one else knows. They can use this secret as the key for encrypting, sending and decrypting private messages in plain sight.
We assume that both parties have agreed beforehand on a finite cyclic group G and a generator g of G. For production software, these parameters are standardised by cryptographers and hardcoded in the implementation by the developers.
These are the steps of the protocol:
• Alice chooses a random number x and calculates a = gx. • Alice sends a to Bob.
• Bob chooses a random number y and calculates b = gy.
• Bob sends b to Alice.
– Now all eavesdroppers know a and b, but not x and y. • Alice derives the common secret bx.
• Bob derives the common secret ay .
Given that (gx)y = (gy)x, both Alice and Bob have derived the same common secret. Assuming that an eavesdropper cannot find x from a or y from b, we conclude that no one else can derive the common secret.
A simple library for doing the necessary steps of DHKE is provided in diffie hellman.py. You can see how to use it in the do Diffie Hellman() function in util.py.
7 https://en.wikipedia.org/wiki/Advanced_Encryption_Standard
8 https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange
5

4.1.3 Putting it all together
The entire process of chatting is then as follows:
1. Alice and Bob establish a communication socket
2. They do DHKE over this socket
3. Bob encrypts his message under the derived key (with AES) 4. Bob sends the resulting ciphertext through the socket
5. Alice decrypts the ciphertext using the derived key
6. Alice reads the message
Steps 3–6 can be repeated as many times as desired, possibly with changed roles. (In our implementation, the process is repeated only twice, so Bob sends first, then Alice, then both parties terminate.)
4.1.4 MitM attack
The described approach sounds very reasonable. Unfortunately Alice and Bob overlooked a fatal flaw: When com- municating over the internet (or even locally), one cannot know with certainty that they are speaking to the intended party, at least not without using some form of cryptographic authentication9.
Going back to our round-table example, consider the case where every member of the group wears a different mask, uses a voice jammer and sits at random seats. Alice would be unable to recognize Bob. In an even worse scenario, if Bob happens to be missing from the table, someone with a good disguise could impersonate him and fool Alice into performing DHKE with him. This is why Alice and Bob should have agreed to only speak to each other after authenticating themselves.
Given that no authentication takes place, Eve the attacker is now able to do the following: After Bob opens his end of the socket and before Alice connects, Eve connects and performs a DHKE with Bob. Eve then opens a new socket and waits for Alice to connect. When Alice and Eve connect, they perform another DHKE. Now Eve can decrypt messages from one party, read them and reencrypt them for the other party. If she so wishes she can even send arbitrary messages, completely unrelated to the original ones. In short, she has complete control of the channel while Alice and Bob think they communicate with each other privately.
4.2 Implementation details
4.2.1 How to use the provided code
Open two terminals and navigate to the directory with the scripts. First run python3 bob.py in one and then python3 alice.py in the other (the order is important). You should see secure channel establishment, a couple of messages being exchanged and finally the channel closing.
4.3 Code overview
Open both aforementioned scripts with your favourite editor. Each of the two scripts calls setup() with its name and the name of the pre-agreed buffer file over which communication happens. This name is set in const.py. Then Bob waits for a message, while Alice sends it. Bob then prints the message and the roles are reversed. Finally both parties close their sockets.
Familiarise yourself with the scripts and understand which lines correspond to each of the steps above. You can optionally dive in the code of the various supporting sources as well.
9 https://en.wikipedia.org/wiki/Message_authentication_code
6

4.4 Exercise
You will have to implement and submit eve.py (submit cs mitm eve.py). The attack should execute cor- rectly when first bob.py is started in one terminal, then eve.py in a second and last alice.py in a third. eve.py should be followed by exactly one of the following three flags: –relay, –break-heart or –custom.
• If the flag is –relay, Eve should just relay the two messages from Bob to Alice and from Alice to Bob. In this case, the outputs of both alice.py and bob.py in the terminals should be identical to the case when the MitM attack isn’t executed.
• With the –break-heart flag, Eve should change the messages so that Bob receives the message ”I hate you!”andAlicereceives”You broke my heart…”.Remember,Evestillhastoencryptbothmessages correctly.
• As for the –custom flag, after receiving Alice’s messsage, Eve must prompt the user to input a message to the terminal and then must send this message to Bob instead. The same should happen for Bob’s message; Eve must prompt the user for a second message and this time send it to Alice.
Hint: Your solution will have to use the buffer file somehow. The function os.rename() will prove helpful.
Note: It may happen that a script dies without closing its socket gracefully. In that case, you should manually remove the remaining buffer file (by default called buffer) before restarting the scripts.
7

Figure 1: The output of your eve.py does not have to match the example, but that of alice.py and bob.py have to.

JAVA|JAVA面向对象编程|德国作业代写 外国作业代写

Prof. Dr.-Ing. Anne Koziolek

Architecture-driven Requirements Engineering (ARE)

https://sdqweb.ipd.kit.edu/wiki/Programmieren

programmieren-vorlesung@ipd.kit.edu

Programmieren – Wintersemester 2019/20

Abschlussaufgabe 1

Version 1.0

20 Punkte

Ausgabe: 10.02.2020, ca. 13:00 Uhr

Praktomat: 24.02.2020, 13:00 Uhr

Abgabefrist: 10.03.2020, 06:00 Uhr

Abgabehinweise

Bitte beachten Sie, dass das erfolgreiche Bestehen der öffentlichen Tests für eine erfolgreiche

Abgabe dieses Blattes notwendig ist. Der Praktomat wird Ihre Abgabe zurückweisen, falls eine

der nachfolgenden Regeln verletzt ist. Eine zurückgewiesene Abgabe wird automatisch mit null

Punkten bewertet. Planen Sie entsprechend Zeit für Ihren ersten Abgabeversuch ein.

• Achten Sie auf fehlerfrei kompilierenden Programmcode.

• Verwenden Sie keine Elemente der Java-Bibliotheken, ausgenommen Elemente der Pakete

java . lang, java . util, java . util . regex und java . util . function.

• Achten Sie darauf, nicht zu lange Zeilen, Methoden und Dateien zu erstellen. Sie müssen bei

Ihren Lösungen eine maximale Zeilenbreite von 120 Zeichen einhalten.

• Halten Sie alle Whitespace-Regeln ein.

• Halten Sie alle Regeln zu Variablen-, Methoden- und Paketbenennung ein.

• Wählen Sie geeignete Sichtbarkeiten für Ihre Klassen, Methoden und Attribute.

• Nutzen Sie nicht das default-Package.

• System . exit () und Runtime . exit () dürfen nicht verwendet werden.

• Halten Sie die Regeln zur Javadoc-Dokumentation ein.

• Halten Sie auch alle anderen Checkstyle-Regeln an.

Seite 1 von 21

Programmieren – Abschlussaufgabe 1 Abgabefrist: 10.03.2020, 06:00 Uhr

Bearbeitungshinweise

Diese Bearbeitungshinweise sind relevant für die Bewertung Ihrer Abgabe, jedoch wird der Praktomat

Ihre Abgabe nicht zurückweisen, falls eine der nachfolgenden Regeln verletzt ist.

• Beachten Sie, dass Ihre Abgaben sowohl in Bezug auf objektorientierte Modellierung als auch

Funktionalität bewertet werden. Halten Sie die Hinweise zur Modellierung im ILIAS-Wiki ein.

• Programmcode muss in englischer Sprache verfasst sein.

• Kommentieren Sie Ihren Code angemessen: So viel wie nötig, so wenig wie möglich.

• Die Kommentare sollen einheitlich in englischer oder deutscher Sprache verfasst werden.

• Wählen Sie aussagekräftige Namen für alle Ihre Bezeichner.

< Plagiat

Es werden nur selbstständig erarbeitete Lösungen akzeptiert. Das Einreichen fremder Lösungen,

seien es auch nur teilweise Lösungen von Dritten, aus Büchern, dem Internet oder

anderen Quellen wie beispielsweise der Lösungsvorschläge des Übungsbetriebes, ist ein Täuschungsversuch

und führt zur Bewertung „nicht bestanden“. Ausdrücklich ausgenommen

hiervon sind Quelltextschnipsel von den Vorlesungsfolien. Alle benutzten Hilfsmittel müssen

vollständig und genau angegeben werden und alles was aus Arbeiten anderer unverändert

oder mit Abänderungen entnommen wurde, muss deutlich kenntlich gemacht werden. Für

weitere Ausführungen sei auf die Einverständniserklärung (Disclaimer) verwiesen.

Í Checkstyle

Der Praktomat überprüft Ihre Quelltexte während der Abgabe automatisiert auf die Einhaltung

der Checkstyle-Regeln. Es gibt speziell markierte Regeln, bei denen der Praktomat die

Abgabe zurückweist, da diese Regel verpflichtend einzuhalten ist. Andere Regelverletzungen

können zu Punktabzug führen. Sie können und sollten Ihre Quelltexte bereits während

der Entwicklung auf die Regeleinhaltung überprüfen. Das Programmieren-Wiki (ILIAS)

beschreibt, wie das funktioniert.

& Terminal-Klasse

Laden Sie für diese Aufgabe die Terminal-Klasse herunter und platzieren Sie diese

unbedingt im Paket edu . kit . informatik. Die Methode Terminal . readLine ()

liest eine Benutzereingabe von der Konsole und ersetzt System .in. Die Methode

Terminal . printLine () schreibt eine Ausgabe auf die Konsole und ersetzt

System .out. Verwenden Sie für jegliche Konsoleneingabe oder Konsolenausgabe die

Terminal-Klasse. Verwenden Sie in keinem Fall System .in oder System .out. Fehlermeldungen

werden ausschließlich über die Terminal-Klasse ausgegeben und müssen aus

technischen Gründen unbedingt mit Error,  beginnen. Dies kann unter anderem bequem

über die Terminal.printError-Methode erfolgen. Laden Sie die Terminal-Klasse niemals

zusammen mit Ihrer Abgabe hoch.

Seite 2 von 21

Programmieren – Abschlussaufgabe 1 Abgabefrist: 10.03.2020, 06:00 Uhr

Modelleisenbahnsimulation (20 Punkte)

In dieser Abschlussaufgabe sollen Sie einen Modelleisenbahnsimulator entwickeln. Die Abschlussaufgabe

besteht aus zwei voneinander abhängenden Teilaufgaben. Die erste Teilaufgabe ist die

Modellierung des Streckennetzes und des Rollmaterials (Wagen, Lokomotiven, Triebzüge). Die

zweite Teilaufgabe ist die Fahrsimulation.

. Information

Die grafische Repräsentation von dem Rollmaterial basiert teilweise auf dem sl-Programm a.

Für die Dateien gilt das Copyright von Toyoda Masashi. Zur einfacheren Verwendung stellen

wir zusätzlich die Textdatei mit den einzelnen Elementen zur Verfügung (representation.txt).

ahttps://github.com/mtoyoda/sl

Gleismaterial

Das Gleisnetz wird über Gleise dargestellt. Vereinfacht werden Gleise durch zwei bzw. drei Punkte

im zweidimensionalen Raum dargestellt. Ein Punkt ist ein Tupel aus zwei 32-Bit-Ganzzahlen und

repräsentiert eine Koordinate. Alle Gleise besitzen einen eindeutigen Identifikator beginnend bei 1.

Dieser Identifikator ist nur eindeutig für Gleise (siehe Beispielablauf). Der Identifikator ist eine

32-bit-Ganzzahl und wird aufsteigend vergeben.

Eine Strecke besteht aus mehreren Gleisen. Dabei gibt es zwei Gleistypen: normale Gleise und

Gleisweichen (Weichen). Normale Gleise werden durch zwei Punkte im Raum beschrieben, den

Start- und Endpunkt. Die Koordinaten können beliebig im Raum liegen, mit der Einschränkung,

dass Gleisteile immer waagerecht oder senkrecht sind. Dabei ist nur eine Veränderung in x-Richtung

waagerecht und eine Veränderung nur in y-Richtung senkrecht. Außerdem muss mit Ausnahme vom

ersten Gleis ein Start- oder Endpunk immer an einem Start- bzw. Endpunkt eines vorhanden Gleis

anliegen. An einem Punkt an einem Gleis kann immer nur ein anderes Gleis (normales Gleis oder

Gleisweiche) angeschlossen werden. Jedes Gleis besitzt eine Länge1, welche Abhängig von ihrer

Start- und Endkoordinate ist. Zur Vereinfachung wird die Länge immer als abgerundete positive

Ganzzahl2 angegeben.

Gleisweichen dienen dazu eine Strecke in zwei Teilstrecken aufzuspalten. Sie werden durch drei

Koordinaten beschrieben, einen Startpunkt und zwei Endpunkten. Gleisweichen besitzen zusätzlich

die Eigenschaft, die aktuelle Gleisweichenstellung zu speichern. Die aktuelle Gleisweichenstellung

entscheidet die Befahrbarkeit einer Gleisweiche. Die Länge einer Gleisweiche ergibt sich in

Abhängigkeit ihrer aktuellen Gleisweichenstellung.

Abbildung 0.1 illustriert ein mögliches Streckennetz. Die schwarzen Punkte zeigen jeweilige Startund

Endpunkte für Gleismaterial. Gleiseweichen sind durch das Label „Weiche X“ markiert, wobei

X ein Platzhalter für eine ganze positive Zahl ist. Die aktuelle Gleiseweichenstellung wird durch

die schwarze Linie angezeigt. Die rote Linie zeigt die alternative Auswahlmöglichkeit an. Ein Zug

1Hinweis: Betrag eines Vektors

2Wählen Sie hier einen passenden Datentyp, achten Sie dabei insbesondere auf die Abhängigkeit zu Koordinaten

Seite 3 von 21

Programmieren – Abschlussaufgabe 1 Abgabefrist: 10.03.2020, 06:00 Uhr

(1,1)

(5,1) (8,1)

(5,3)

(10,1)

(10,3) (12,3)

(1,-3) (10,-3) (12,-3)

(14,3)

(14,-1)

Gleis 1

Weiche 1

Weiche 1 Gleis 2

Gleis 5 Gleis 6

Weiche 3

Weiche 3

Weiche 2

Weiche 2

Gleis 7

Gleis 3

Gleis 4

Abbildung 0.1: Beispiel einer einfachen Strecke mit Gleisweichen und Gleisen

kann nur auf der schwarzen Linie die Strecke befahren. Dies ist auch das Streckennetz, welches im

Beispielablauf verwendet wird.

Gleise können sich nicht kreuzen, d.h. wenn Gleise als Geraden gesehen werden, dürfen sie sich

nicht schneiden. Abbildung 0.2 zeigt eine verbotene Gleiskreuzung. Auch ist es nicht erlaubt Gleise

außerhalb von Start- und Endpunkten zu verbinden. Dies wäre in dieser Aufgabe auch ein Kreuzen

von Gleisen. Zudem kann einem Start- oder Endpunkt nur genau ein anderes Gleis anliegen.

(1,1) (5,1)

(3,0)

(3,2)

Abbildung 0.2: Nicht erlaubtes Kreuzen von Gleisen

Rollmaterial

Das Rollmaterial beschreibt im Allgemeinen alle auf Schienen fahrenden Gegenstände, z.B. einen

Eisenbahnwagen. Aus Gründen der Einfachheit nehmen wir an, dass es nur folgende Typen gibt:

Wagen, Lokomotiven, Triebzüge. Allen Typen gemeinsam ist, dass sie einen Namen und eine Länge

besitzen, z.B. könnte eine Lokomotive den Namen Emma und die Länge 1 haben.

Seite 4 von 21

Programmieren – Abschlussaufgabe 1 Abgabefrist: 10.03.2020, 06:00 Uhr

____________________

| ___ ___ ___ ___ |

| |_| |_| |_| |_| |

|__________________|

|__________________|

(O) (O)

(a) Personenwagen

| |

| |

| |

|__________________|

(O) (O)

(b) Güterwagen

____

/————–| |

\————–| |

| | | |

_|_|__________| |

|_________________|

(O) (O)

(c) Spezialwagen

Abbildung 0.3: Grafische Repräsentation von Wagen

Wagen

Zur Vereinfachung gibt es hier nur die Personen-, Güter-, Spezialwagen als Wagentyp. Der Personenwagen

dient zum Transport von Personen, der Güterwagen zum Transport von Gütern und

Spezialwagen sind z.B. ein Kranwagen oder ein Feuerwehrwagen. Die verschiedenen Wagentypen

werden wie in Abbildung 0.3 grafisch repräsentiert.

Alle Wagen besitzen einen eindeutigen 32-bit-ganzzahligen aufsteigenden Identifikator beginnend

bei 1. Dieser Identifikator ist nur eindeutig für Wagen (siehe Beispielablauf).

Jeder Wagen besitzt mindestens eine, aber maximal zwei Kupplungen. Diese befinden sich immer am

Anfang und Ende eines Wagens. Auch darf es auf einer Seite (Anfang, Ende) maximal eine Kupplung

geben. Diese Kupplungen ermöglichen die Komposition von Rollmaterial (siehe Komposition von

Rollmaterial)

Lokomotive

Es gibt drei verschiedene Untertypen von Lokomotiven: Elektrolokomotiven, Diesellokomotiven

und Dampflokomotiven. Alle Lokomotiven besitzen eine eindeutige ID. Diese ID setzt sich aus

der Baureihe und dem Namen der Lokomotive zusammen. Diese werden durch einen Bindestrich

getrennt, beispielsweise ergeben die Baureihe „103“ und der Name „118“ die ID „103-118“. Sowohl

der Name als auch die Baureihe können Buchstaben und Zahlen enthalten. Wobei die Baureihe

nicht die Zeichenkette „W“ sein darf. Jede Lokomotive besitzt mindestens eine, aber maximal zwei

Kupplungen. Diese befinden sich immer am Anfang und Ende einer Lokomotive. Auch darf es

auf einer Seite (Anfang, Ende) maximal eine Kupplung geben. Diese Kupplungen ermöglichen

die Komposition von Rollmaterial (siehe Komposition von Rollmaterial). Abbildung 0.4 zeigt die

grafische Repräsentation von Lokomotiven.

Triebzug

Alle Triebzüge besitzen eine Baureihe. Die Triebzug-ID setzt sich nach den gleichen Regeln, wie bei

den Lokomotiven zusammen. Aus diesem Grund teilen sich Lokomotiven und Triebzüge den gleichen

ID-Raum. Ein Triebzug besitzt eine spezielle Art von Kupplung und kann damit nur mit der gleichen

Baureihe von Triebzügen komponiert werden (siehe Komposition von Rollmaterial). Ansonsten

Seite 5 von 21

Programmieren – Abschlussaufgabe 1 Abgabefrist: 10.03.2020, 06:00 Uhr

++ +——

|| |+-+ |

/———|| | |

+ ======== +-+ |

_|–/~\——/~\-+

//// \_/ \_/

(a) Dampflokomotive

___

\

_______________/__

/_| ____________ |_\

/ |____________| \

\ /

\__________________/

(O)(O) (O)(O)

(b) Elektrolokomotive

_____________|____

/_| ____________ |_\

/ |____________| \

\ /

\__________________/

(O)(O) (O)(O)

(c) Diesellokomotive

Abbildung 0.4: Grafische Repräsentation von Lokomotiven

++

||

_________||_________

| ___ ___ ___ ___ |

| |_| |_| |_| |_| |

|__________________|

|__________________|

(O) (O)

Abbildung 0.5: Grafische Repräsentation von Triebzügen

gelten die gleichen Regeln wie bei Lokomotiven. Abbildung 0.5 zeigt die grafische Repräsentation

von Triebzügen.

Komposition von Rollmaterial

Rollmaterial kann zu einem Zug komponiert werden. Bei der Komposition gilt es folgende Einschränkungen

zu beachten:

• Am Anfang oder Ende eines validen Zug muss immer mindestens eine Lokomotive/Triebzug

sein.

• Bei der Komposition muss immer beachtet werden, ob das Rollmaterial an der gewünschten

Kompositionsstelle eine passende Kupplung besitzt.

• Das Rollmaterial, welches komponiert wird, ist noch nicht in einem anderen Zug eingesetzt.

Alle Züge besitzen eine eindeutige ID beginnend bei 1. Die ID ist eine 32-Bit-Ganzzahl und wird

aufsteigend vergeben. Diese ID ist nur eindeutig für Züge (siehe Beispielablauf). Ein Zug kann

auch grafisch auf der Konsole ausgegeben werden. Dabei werden die einzelnen Repräsentationen

des Rollmaterial entsprechen ihrer Position im Zug konkateniert. Die einzelnen Repräsentation

sind durch ein Leerzeichen getrennt. Abbildung 0.6 zeigt eine Ausgabe für einen Zug mit einer

Dampflokomotive und zwei Personenwagen. Abbildung 0.7 zeigt ein weiteres Zug-Beispiel mit einer

Elektrolokomotive und einem Personenwagen.

Seite 6 von 21

Programmieren – Abschlussaufgabe 1 Abgabefrist: 10.03.2020, 06:00 Uhr

++ +—— ____________________ ____________________

|| |+-+ | | ___ ___ ___ ___ | | ___ ___ ___ ___ |

/———|| | | | |_| |_| |_| |_| | | |_| |_| |_| |_| |

+ ======== +-+ | |__________________| |__________________|

_|–/~\——/~\-+ |__________________| |__________________|

//// \_/ \_/ (O) (O) (O) (O)

Abbildung 0.6: Beispielrepräsentation von einem Zug mit Dampflokomotive

___

\

_______________/__ ____________________

/_| ____________ |_\ | ___ ___ ___ ___ |

/ |____________| \ | |_| |_| |_| |_| |

\ / |__________________|

\__________________/ |__________________|

(O)(O) (O)(O) (O) (O)

Abbildung 0.7: Beispielrepräsentation von einem Zug mit Elektrolokomotive

Fahrbetrieb

Um den Fahrbetrieb einer Modelleisenbahn zu simulieren, muss als erstes ein Zug auf ein Gleis

gesetzt werden. Dabei wird immer der ganze Zug komplett auf das Gleis gesetzt. Beim Aufsetzen

muss ein Richtungsvektor angegeben werden. Dieser gibt die initiale Fahrrichtung des Zuges an.

Der Richtungsvektor entspricht dem Richtungsvektor des Gleises oder ist genau der entgegensetze

Vektor. Beim Aufgleisen muss beachtet werden, dass die benutzten Gleise noch frei sind, d.h. kein

anderer Zug dort steht und es dort überhaupt ein Gleis gibt. Dabei spielt natürlich auch die Länge

eines Zuges eine Rolle. Züge können auf Strecken mit Gleiseweichen erst aufgesetzt werden, wenn

die Gleiseweichenstellung gesetzt wurde. Außerdem können Züge nur auf den Abschnitt gesetzt

werden, der die aktuelle Gleisweichenstellung ist. Falls Gleiseweichen auf denen ein Zug bereits

steht, geschaltet werden, entgleist der daraufstehende Zug.

Wenn Züge auf dem Gleis stehen können sie sich immer nur auf dem Gleis fortbewegen. Dabei

bewegen sie sich initial in Richtung des Richtungsvektors fort und folgen dem Schienenverlauf.

Bevor sich ein Zug bewegen kann, muss für alle Gleisweichen eine Gleisweichenstellung gesetzt

werden.

Wie auch bei kleinen Modelleisenbahnanlagen üblich fahren hier alle Züge, die auf der Anlage stehen.

Die Geschwindigkeit ist für alle Züge gleich. Im Allgemeinen gilt, dass der Zug bei waagerechten

Gleisen sich um n x-Einheiten bewegt und bei vertikalen Gleisen um n y-Einheiten bewegt. Die

Simulation hier wird in Schritten berechnet, dazu wird bei jedem Schritt n 2 Z16􀀀Bit übergeben. Zur

Verdeutlichung hier ein Beispiel in Abbildung 0.8. Die Punkte sind durch ein Tupel aus Ganzzahlen

angegeben. Der Kopf eines Zuges (roter Punkt) steht auf (2,0) auf dem Gleis von (1,0) nach (4,0)

und bewegt sich Richtung Punkt (4,0). Bei Punkt (4,0) ist eine Gleisweiche mit den Endpunkten

(4,2) und (6,0) angeschlossen. Die aktuelle Gleisweichenstellung ist auf (6,0). Nach einem Schritt

mit n = 1 würde der Zugkopf (blauer Punkt) bei (3,0) stehen (siehe Abbildung 0.8a). Nach einem

weiteren Schritt mit n = 2 würde der Zugkopf (gelber Punkt) bei (5,0) stehen. Im zweiten Beispiel

(siehe Abbildung 0.8b) steht der Kopf des Zuges (roter Punkt) auf (0,0) auf dem Gleis von (0,3)

Seite 7 von 21

Programmieren – Abschlussaufgabe 1 Abgabefrist: 10.03.2020, 06:00 Uhr

nach (0,-1) und bewegt sich in Richtung Punkt (0,3). Nach einem Schritt mit n = 2 würde der

Zugkopf (blauer Punkt) bei (0,2) stehen. In einem weiteren Schritt mit n = 2 würde der Zugkopf

(gelber Punkt) bei (1,3) stehen.

(1,0)

(4,0)

(6,0)

(4,2)

(2,0) (3,0) (5,0)

(a) Fahrtsimulation mit Weiche

(0,-1)

(0,3) (3,3)

(0,0)

(0,2)

(1,3)

(b) Fahrtsimulation mit Kurve

Abbildung 0.8: Bewegungsrichtung Züge

Während der Simulation kann es zu Zusammenstößen von verschieden Zügen kommen. Ein Zusammenstoß

tritt hierbei auf, wenn zwei Züge auf dem gleichen Gleis oder Position stehen. Bei der

.berprüfung gehören die Start-/Endpunkte immer zu dem Gleis auf dem der der Rest des Zuges

steht. Zum Beispiel Gleis 1 (G1) von (10,1) nach (20,1) und Gleis 2 (G2) von (20,1) nach (30,1).

Wenn nun ein Zug mit Länge 4 auf (20,1) steht und Richtung (30,1) fährt, dann wäre G1 belegt

und G2 noch frei. Kommt es zu einem Zusammenstoß entgleisen die involvierten Züge.

Züge können über das Gleis hinaus fahren, d.h falls das Gleis endet und es kein Anschlussgleis gibt,

z.b. wie bei Abbildung 0.1 (Gleis 7) entgleist der Zug.

Wenn Züge entgleisen, werden Sie vom Gleis genommen. Sie bleiben jedoch in der Zugdatenbank

bestehen. Sie können danach wieder aufgesetzt werden.

Interaktive Benutzerschnittstelle

Nach dem Start nimmt Ihr Programm über die Konsole mittels Terminal.readLine() verschiedene

Arten von Befehlen entgegen, die im Folgenden näher spezifiziert werden. Nach Abarbeitung

eines Befehls wartet Ihr Programm auf weitere Befehle, bis das Programm irgendwann durch den

exit-Befehl beendet wird.

Achten Sie darauf, dass durch Ausführung der folgenden Befehle die zuvor definierten Grundlagen

und Bedingungen nicht verletzt werden und geben Sie in diesen Fällen immer eine aussagekräftige

Fehlermeldung aus. Entspricht eine Eingabe nicht dem vorgegebenen Format, dann ist immer

eine Fehlermeldung auszugeben. Danach soll das Programm auf die nächste Eingabe warten. Bei

Fehlermeldungen dürfen Sie den Text frei wählen, er sollte jedoch sinnvoll sein. Jede Fehlermeldung

muss aber mit Error, beginnen und darf keine Zeilenumbrüche enthalten.

Da wir automatische Tests Ihrer interaktiven Benutzerschnittstelle durchführen, müssen die Ausgaben

exakt den Vorgaben entsprechen. Insbesondere sollen sowohl Klein- und Großbuchstaben als

Seite 8 von 21

Programmieren – Abschlussaufgabe 1 Abgabefrist: 10.03.2020, 06:00 Uhr

auch die Leerzeichen und Zeilenumbrüche genau übereinstimmen. Geben Sie auch keine zusätzlichen

Informationen aus. Beginnen Sie frühzeitig mit dem Einreichen, um Ihre Lösung dahingehend zu

testen, und verwenden Sie das Forum, um eventuelle Unklarheiten zu klären.

Beachten Sie, dass bei der Beschreibung der Eingabe- und Ausgabeformate die Wörter zwischen

spitzen Klammen ( < und > ) für Platzhalter stehen, welche bei der konkreten Ein- und Ausgabe

durch Werte ersetzt werden. Diese eigentlichen Werte enthalten bei der Ein- und Ausgabe keine

Klammern. Vergleichen Sie hierzu auch die jeweiligen Beispielabläufe.

Beachten Sie auch, dass bei den folgenden Beispielabläufen die Eingabezeilen mit dem > -Zeichen

gefolgt von einem Leerzeichen eingeleitet werden. Diese beiden Zeichen sind ausdrücklich kein

Bestandteil des eingegebenen Befehls, sondern dienen nur der Unterscheidung zwischen Ein- und

Ausgabezeilen.

Wenn Listen ausgegeben werden sollen, werden diese immer Zeilenweise ausgegeben, es sei den ein

Befehl schreibt dies explizit anders fest. Für eindeutige Identifikatoren und IDs, welche aus genau

einer 32-Bit-Ganzzahl bestehen gilt, dass sie immer aufsteigend beginnend bei 1 vergeben werden.

D.h. die erste ID wäre 1 und die zweite 2. Außerdem gilt, dass immer die nächste freie ID gewählt

wird. Als Beispiel, wenn z.B. die IDs 1,3,4,5 vergeben sind, wird als nächste ID 2 gewählt.

Hinweis: Kreuzen von Gleisen

Sie können davon ausgehen, dass der Benutzer keine Invalide-Eingaben bezüglich dem Kreuzen

von Gleisen tätig, d.h. Sie müssen nicht auf kreuzende Gleise prüfen.

Punkteingabe

Ein Punkt ist ein Tupel aus zwei 32-Bit-Ganzzahlen und beschreibt eine Koordinate in einem

2D-Raum. Das Tupel ist von „runden“ Klammern umschlossen. Die beiden Ganzzahlen werden

durch ein Komma getrennt. Die erste 32-Bit-Ganzzahl gibt die x-Koordinate ein und die zweite

32-Bit-Ganzzahl die y-Koordinate.

Eingabeformat

(<x-Koordinate>,<y-Koordinate>)

Der add track-Befehl

Fügt ein normales Gleis hinzu. Dabei wird ein Startpunkt <startpoint> und ein Endpunkt

<endpoint> gewählt. Wenn das Gleis nicht das erste Gleis ist muss immer einer der beiden Punkte

auf einem Start- oder Endpunkt eines anderen Gleis liegen. Gleise können nur waagerecht oder

senkrecht sein.

Seite 9 von 21

Programmieren – Abschlussaufgabe 1 Abgabefrist: 10.03.2020, 06:00 Uhr

Eingabeformat

add track <startpoint> -> <endpoint>

Ausgabeformat

Im Erfolgsfall wird die eindeutige ID des Gleises ausgegeben. Im Fehlerfall (z.B., kein Anschluss an ein

bisheriges Gleis) wird eine aussagekräftige Fehlermeldung beginnend mit Error, ausgegeben.

Der add switch-Befehl

Fügt eine Gleisweiche hinzu. Dabei werden ein Startpunkt und zwei Endpunkte gewählt. Die

einzelnen Gleiseweichenstrecken müssen immer waagerecht oder senkrecht sein. Wenn das Gleis

nicht das erste Gleis ist, muss immer einer der drei Punkte auf einem Start- oder Endpunkt eines

anderen Gleise liegen.

Eingabeformat

add switch <startpoint> -> <endpoint1>,<endpoint2>

Ausgabeformat

Im Erfolgsfall wird die eindeutige ID des Gleises ausgegeben. Im Fehlerfall (z.B., kein Anschluss an ein

bisheriges Gleis) wird eine aussagekräftige Fehlermeldung beginnend mit Error, ausgegeben.

Der delete track-Befehl

Löscht ein beliebiges Gleis (normales Gleis, Gleisweiche). Das zu löschende Gleis wird über die

<trackID> ausgewählt. Beim Löschen muss geprüft werden, dass nach dem Entfernen keine zwei

unabhängigen Strecken existieren, d.h. dass alle Gleise verbunden sind und es keine Gleisstücke

gibt, die nicht verbunden sind3. Außerdem darf kein Zug auf dem Gleis stehen.

Eingabeformat

delete track <trackID>

Ausgabeformat

Im Erfolgsfall wird OK ausgegeben. Im Fehlerfall (z.B., <trackID> nicht gefunden) wird eine

aussagekräftige Fehlermeldung beginnend mit Error, ausgegeben.

3Hinweis: Lösbar z.B. mit Tiefensuche über Start- und Endknoten

Seite 10 von 21

Programmieren – Abschlussaufgabe 1 Abgabefrist: 10.03.2020, 06:00 Uhr

Der list tracks-Befehl

Gibt zeilenweise eine Liste mit allen Gleisen (Gleiseweichen und normale Gleise) aus. Die Ausgabe

beinhaltet den Typ, die eindeutige Gleis-ID <trackID> , den Startpunkt, den Endpunkt und die

Länge. Bei Gleisweichen wird die Länge nur ausgegeben, falls die Gleiseweichenstellung schon

gesetzt wurde. In diesem Fall ist die Länge, dann die Länge des Vektors vom Startpunkt zum

passenden Endpunkt der aktuellen Gleiseweichenstellung. Die Liste ist nach der Gleis-ID aufsteigend

sortiert.

Eingabeformat

list tracks

Ausgabeformat

Für normale Gleise: t <trackID> <startpoint> -> <endpoint> <length>

Für Gleisweichen: s <trackID> <startpoint> -> <endpoint1>,<endpoint2> <length>

s oder t beschreiben den Gleistyp. <trackID> ist eine 32-Bit-ganzzahlige ID. Falls noch kein

Gleis existiert wird No track exists ausgegeben. Im Fehlerfall (z.B., zusätzliche Parameter)

wird eine aussagekräftige Fehlermeldung beginnend mit Error, ausgegeben.

Beispiel: list tracks-Befehl

> list tracks

t 1 (1,1) -> (5,1) 5

s 2 (5,1) -> (8,1),(5,3)

Der set switch-Befehl

Wählt für eine Gleisweiche mit der <trackID> die Gleisweichenstellung die den Startpunkt der

Gleiseweiche mit dem gewählten Endpunkt ( <point> ) verbindet.

Eingabeformat

set switch <trackID> position <point>

Ausgabeformat

Im Erfolgsfall wird OK ausgegeben. Im Fehlerfall (z.B., Punkt nicht vorhanden oder Gleis-ID nicht

gefunden) wird eine aussagekräftige Fehlermeldung beginnend mit Error, ausgegeben.

Seite 11 von 21

Programmieren – Abschlussaufgabe 1 Abgabefrist: 10.03.2020, 06:00 Uhr

Der create engine-Befehl

Erstellt eine Lokomotive. <engineType> beschreibt den Typ der Lokomotive ( electrical ,

steam , diesel ). Die Baureihe wird über den Platzhalter <class> gesetzt. <name> ist der

Name der Lokomotive. <length> gibt die Länge einer Lokomotive als 32-Bit-Ganzzahl an.

<couplingFront> und <couplingBack> sind Wahrheitswerte, die angeben ob eine Kupplung

vorne und oder hinten vorhanden ist. Als Wahrheitswert kann true oder false gesetzt werden.

Dabei gibt true an, dass eine Kupplung vorhanden ist. Eine Lokomotive kann nur hinzugefügt

werden, falls noch keine Lokomotive oder Triebzug mit der gleichen ID existiert.

Eingabeformat

create engine <engineType> <class> <name> <length> <couplingFront> <couplingBack>

Ausgabeformat

Im Erfolgsfall wird die eindeutige ID der Lokomotive ausgegeben. Im Fehlerfall (z.B., falsches

Eingabeformat oder ID schon vorhanden) wird eine aussagekräftige Fehlermeldung beginnend mit

Error, ausgegeben.

Der list engines-Befehl

Gibt zeilenweise eine Liste mit allen Lokomotiven aus. Die Liste ist lexikografisch nach der der

Lok-ID sortiert.

Eingabeformat

list engines

Ausgabeformat

<trainID> <engineType> <class> <name> <length> <couplingFront> <couplingBack>

<trainID> ist die ID des Zugs zu dem die Lokomotive gehört. Falls noch keine gesetzt ist wird

none ausgegeben. <engineType> identifiziert den Type der Lokomotive. Dabei steht e für

elektrisch s für Dampf und d für Diesel. Alle anderen Platzhalter haben die selbe Bedeutung

wie beim create engine -Befehl. Falls noch keine Lokomotive existiert wird No engine exists

ausgegeben.

Seite 12 von 21

Programmieren – Abschlussaufgabe 1 Abgabefrist: 10.03.2020, 06:00 Uhr

Beispiel: list engines-Befehl

> list engines

none s T3 Emma 1 false true

1 e 103 118 1 true true

Der create coach-Befehl

Erstellt einen Wagen. <coachType> beschreibt den Typ des Wagens. Es gibt folgende Typen:

passenger , freight , special . Die drei letzten Parameter sind analog zum create engine –

Befehl.

Eingabeformat

create coach <coachType> <length> <couplingFront> <couplingBack>

Ausgabeformat

Im Erfolgsfall wird die eindeutige Wagen-ID ausgegeben. Im Fehlerfall (z.B., falsches Eingabeformat)

wird eine aussagekräftige Fehlermeldung beginnend mit Error, ausgegeben.

Der list coaches-Befehl

Gibt zeilenweise eine Liste mit allen Wagen aus. Die List ist aufsteigend nach der Wagen-ID

sortiert.

Eingabeformat

list coaches

Ausgabeformat

<coachID> <trainID> <coachType> <length> <couplingFront> <couplingBack>

<coachID> ist die ID des Wagens. <trainID> ist die ID des Zuges zu dem der Wagen gehört.

Falls noch keine gesetzt ist wird none ausgegeben. <coachType> identifiziert den Type des Wagen.

Dabei steht p für Personenwagen f für Güterwagen und s für Spezialwagen. Alle anderen

Platzhalter haben die selbe Bedeutung wie beim list engine -Befehl. Falls noch kein Wagen

existiert wird No coach exists ausgegeben.

Seite 13 von 21

Programmieren – Abschlussaufgabe 1 Abgabefrist: 10.03.2020, 06:00 Uhr

Beispiel: list coaches-Befehl

> list coaches

1 none c 1 true true

2 none p 1 true false

Der create train-set-Befehl

Erstellt einen Triebzug. Die weiteren Parameter und Fehlerfälle sind beim create engine -Befehl

beschrieben

Eingabeformat

create train-set <class> <name> <length> <couplingFront> <couplingBack>

Ausgabeformat

Im Erfolgsfall wird OK ausgegeben. Im Fehlerfall (z.B., falsches Eingabeformat) wird eine aussagekräftige

Fehlermeldung beginnend mit Error, ausgegeben.

Der list train-sets-Befehl

Gibt zeilenweise eine Liste mit allen Triebzügen aus. Die Liste ist lexikografisch nach der Triebzug

ID geordnet.

Eingabeformat

list train-sets

Ausgabeformat

<trainID> <class> <name> <length> <couplingFront> <couplingBack>

Alle Platzhalter haben die selbe Bedeutung wie beim list engines -Befehl. Falls noch kein

Triebzug existiert wird No train-set exists ausgegeben.

Der delete rolling stock-Befehl

Löscht ein Rollmaterial. Das Rollmaterial wird anhand seiner eindeutigen ID identifiziert. Für einen

Wagen wird der ID ein W vorgestellt. Rollmaterial kann nur gelöscht werden, falls es in keinem

Zug verwendet wird.

Seite 14 von 21

Programmieren – Abschlussaufgabe 1 Abgabefrist: 10.03.2020, 06:00 Uhr

Eingabeformat

delete rolling stock <id>

Ausgabeformat

Im Erfolgsfall wird OK ausgegeben. Im Fehlerfall (z.B., falsches Eingabeformat) wird eine aussagekräftige

Fehlermeldung beginnend mit Error, ausgegeben.

Der add train-Befehl

Fügt dem Zug mit der 32-bit-ganzzahligen <trainID> Rollmaterial hinzu. Falls der Zug mit der

ID noch nicht existiert wird er automatisch angelegt. Die <rollingStockID> ist entweder die ID

eines Triebzugs, Lokomotive oder eines Wagens. Bei Wagens wird ein W der ID vorausgestellt. Der

Zug muss valide bezüglich der Kupplung sein, aber nicht valide bezüglich der Lokomotiven. Das

Rollmaterial wird der Reihe nach hinzugefügt, d.h. das erste einem Zug hinzugefügt Rollmaterial

ist der Kopf des Zuges (vorne) und das letzte hinzugefügte Rollmaterial stellt den Schluss des Zuges

da.

Eingabeformat

add train <trainID> <rollingStockID>

Ausgabeformat

Im Erfolgsfall wird <type> <stockID> added to <trainID> ausgegeben. <type> ist der Typ.

Folgende Werte können angenommen werden electrical engine, steam engine, diesel engine,

train-set, passenger coach, freight coach, special coach. <stockID> ist die ID des Rollmaterials,

wobei beiWagons einWdavorgestellt wird. <trainID> ist die ID des Zuges. Im Fehlerfall

(z.B., falsche Kupplung) wird eine aussagekräftige Fehlermeldung beginnend mit Error, ausgegeben.

Der delete train-Befehl

Löscht den Zug mit der <ID> . Falls der Zug sich auf der Strecke befindet, wird er auch von der

Strecke entfernt.

Eingabeformat

delete train <ID>

Seite 15 von 21

Programmieren – Abschlussaufgabe 1 Abgabefrist: 10.03.2020, 06:00 Uhr

Ausgabeformat

Im Erfolgsfall wird OK ausgegeben. Im Fehlerfall (z.B., falsches Eingabeformat) wird eine aussagekräftige

Fehlermeldung beginnend mit Error, ausgegeben.

Der list trains-Befehl

Gibt zeilenweise eine Liste mit allen Zügen aus. Die Liste ist aufsteigend nach der Zug-ID sortiert.

Eingabeformat

list trains

Ausgabeformat

<trainID> <members>

Die <trainID> ist die aktuelle ID des Zuges und Members ist eine Liste der IDs des verwendeten

Rollmaterials. Wobei die einzelnen IDs durch Leerzeichen getrennt ausgegeben werden. Der ID

eines Wagens wird ein W vorausgestellt um zu kennzeichnen, dass es sich um einen Wagen handelt.

z.B. 1 103-118 W1 für den Zug 1 mit der Lokomotive 103-118 und dem Wagen 1.

Der show train-Befehl

Der Befehl gibt die grafische Repräsentation des Zuges aus. trainID ist dabei die ID des Zuges.

Eingabeformat

show train <trainID>

Ausgabeformat

Im Erfolgsfall wird die grafische Repräsentation für jedes Rollmaterial ausgegeben. Im Fehlerfall

(z.B., Zug nicht vorhanden) wird eine aussagekräftige Fehlermeldung beginnend mit Error,

ausgegeben. (siehe Beispielablauf)

Seite 16 von 21

Programmieren – Abschlussaufgabe 1 Abgabefrist: 10.03.2020, 06:00 Uhr

Der put train-Befehl

Stellt einen validen (siehe Komposition von Rollmaterial) Zug auf ein Gleis an der Position

<point> . Die initiale Bewegungsrichtung wird über die Ganzzahlen4 <x>,<y> bestimmt, die

als Richtungsvektoren dienen. Beim Aufgleisen ist zu beachten, dass der Zug valide ist und

das noch kein anderer Zug auf den benötigten Gleisen steht (Länge des Zuges beachten) und

das der Richtungsvektor zu der Richtung des Gleises beim Aufgleispunkt entspricht (oder dem

entgegengesetzten).

Eingabeformat

put train <trainID> at <point> in direction <x>,<y>

Ausgabeformat

Im Erfolgsfall wird OK ausgegeben. Im Fehlerfall (z.B., falsches Eingabeformat, oder invalider Zug)

wird eine aussagekräftige Fehlermeldung beginnend mit Error, ausgegeben.

Der step-Befehl

Lässt alle Züge um <speed> -Einheiten fahren. <speed> ist eine 16-Bit-Ganzzahl. Anschließend

wird zeilenweise die Position von allen Zugköpfen ( <headPoint> ), die auf einem Gleis stehen

ausgegeben. Dies erfolgt aufsteigend sortiert nach der Zug-ID. Falls es während des Fahrbetriebs

zu einem Zusammenstoß kam werden die involvierten Züge ausgegeben. Für die Beschreibung der

Fahrt und des Zusammenstoß-Verhalten siehe Fahrbetrieb. Züge die nicht von dem Zusammenstoß

betroffen sind fahren normal weiter.

Eingabeformat

step <speed>

Ausgabeformat

Train <trainID> at <headPoint>

Zeilenweise Ausgabe von Zügen. Falls noch kein Zug auf der Strecke steht, wird OK ausgegeben. Im

Fall eines Zusammenstoßes wird Crash of train <trains> ausgegeben. Wobei <trains> eine

Liste der Zug-IDs ist, die mit Kommata getrennt sind (aufsteigend sortiert). Falls es zu mehreren

zusammenstoßen kommt, wird dies zeilenweise ausgegeben. Dabei ist zu beachten, dass die Züge sich

nicht überschneiden dürfen, d.h. wenn Zug 1 einen Zusammenstoß mit Zug 3 hat und Zug 3 einen mit

Zug 4 würde dies als ein Zusammenstoß gelten und die Ausgabe würde Crash of train 1,3,4

lauten. Falls es mehrere unabhängige Zusammenstöße gibt, wird die Ausgabe sortiert nach der

4Wählen Sie hier einen passenden Datentyp, achten Sie dabei insbesondere auf die Abhängigkeit zu Koordinaten

Seite 17 von 21

Programmieren – Abschlussaufgabe 1 Abgabefrist: 10.03.2020, 06:00 Uhr

kleinsten Zug-ID von jedem Zusammenstoß ausgeben. Das gleiche gilt falls es zu einer Mischung

von Zusammenstößen und normaler Ausgabe kommt. Zum Beispiel Zug 11 und Zug 12 haben einen

Unfall und Zug 9 und Zug 22 auch. Jedoch Zug 10 und 8 nicht, dann würde die Ausgabe ohne

Berücksichtigung der Position lauten:

Beispiel: Zusammenstoß von mehreren Zügen

> step 2

Train 8 at (0,0)

Crash of train 9,22

Train 10 at (20,3)

Crash of train 11,12

Der exit-Befehl

Der parameterlose Befehl ermöglicht es, das laufende Programm vollständig zu beenden. Beachten

Sie, dass hierfür keine Methoden wie System.exit() oder Runtime.exit() verwendet werden

dürfen.

Eingabeformat

exit

Ausgabeformat

Im Erfolgsfall findet keine Ausgabe statt. Im Fehlerfall (z.B. bei einem falsch spezifizierten Eingabeformat)

wird eine aussagekräftige Fehlermeldung beginnend mit Error, ausgegeben.

Seite 18 von 21

Programmieren – Abschlussaufgabe 1 Abgabefrist: 10.03.2020, 06:00 Uhr

Beispielablauf

Beispielablauf: Teil 1 von 3

> add track (1,1) -> (5,1)

1>

add track (10,10) -> (10,11)

Error, track not connected to other track

> list tracks

t 1 (1,1) -> (5,1) 4

> add switch (5,1) -> (8,1),(5,3)

2>

add track (5,3) -> (8,1)

Error, creation not possible wrong position

> add track (10,1) -> (8,1)

3>

add switch (10,-3) -> (10,1),(12,-3)

4>

add track (10,-3) -> (1,-3)

5>

add track (1,-3) -> (1,1)

6

> add track (5,3) -> (10,3)

7>

add track (10,3) -> (12,3)

8>

add switch (12,3) -> (12,-3),(14,3)

9

> add track (14,-1) -> (14,3)

10

> create engine steam T3 Emma 1 false true

T3-Emma

> list engines

none s T3 Emma 1 false true

> create engine electrical 103 118 3 true true

103-118

Seite 19 von 21

Programmieren – Abschlussaufgabe 1 Abgabefrist: 10.03.2020, 06:00 Uhr

Beispielablauf: Teil 2 von 3

> list engines

none e 103 118 3 true true

none s T3 Emma 1 false true

> delete rolling stock 3

Error, rolling stock with ID 03 not found

> delete rolling stock 103-118

OK

> create coach passenger 1 true true

1>

create coach passenger 1 true true

2>

list coaches

1 none p 1 true true

2 none p 1 true true

> add train 1 W1

passenger coach W1 added to train 1

> list trains

1 W1

> show train 01

____________________

| ___ ___ ___ ___ |

| |_| |_| |_| |_| |

|__________________|

|__________________|

(O) (O)

> delete train 1

OK

> list trains

No train exits

> add train 1 T3-Emma

steam engine T3-Emma added to train 1

> add train 1 W1

passenger coach W1 added to train 1

> add train 1 W2

passenger coach W2 added to train 1

> list trains

1 T3-Emma W1 W2

Seite 20 von 21

Programmieren – Abschlussaufgabe 1 Abgabefrist: 10.03.2020, 06:00 Uhr

Beispielablauf: Teil 3 von 3

> show train 01

++ +—— ____________________ ____________________

|| |+-+ | | ___ ___ ___ ___ | | ___ ___ ___ ___ |

/———|| | | | |_| |_| |_| |_| | | |_| |_| |_| |_| |

+ ======== +-+ | |__________________| |__________________|

_|–/~\——/~\-+ |__________________| |__________________|

//// \_/ \_/ (O) (O) (O) (O)

> list engines

1 s T3 Emma 1 false true

> create train-set 403 145 4 true true

403-145

> add train 2 403-145

train-set 403-145 added to train 2

> set switch 4 position (10,1)

OK

> step 1

Error, position of switches not set

> set switch 2 position (8,1)

OK

> set switch 9 position (12,-3)

OK

> step 1

OK

> put train 1 at (1,1) in direction 1,0

OK

> put train 2 at (10,-2) in direction 0,1

OK

> step 2

Train 1 at (3,1)

Train 2 at (10,0)

> step -2

Train 1 at (1,1)

Train 2 at (10,-2)

> step 2

Train 1 at (3,1)

Train 2 at (10,0)

> step 3

Train 1 at (6,1)

Train 2 at (8,1)

> step 1

Crash of train 1,2

> put train 1 at (1,1) in direction 0,-1

OK

> exit

Seite 21 von 21

JAVA编程 面向对象编程 复杂程序作业代写

Please note that successful completion of the public tests is required for the successful submission of this sheet. The Praktomat will reject your submission if one of the following rules is violated. A rejected submission is automatically awarded zero points. Allow adequate time for your first delivery attempt.

– Make sure that the program code compiles without errors.

– Do not use elements of the Java libraries, except for elements of the packages java.lang, java.util, java.util.regex and java.util.function.

– Be careful not to create too long lines, methods and files. You must be present at adhere to a maximum line width of 120 characters for your solutions.

– Comply with all whitespace rules.

– Comply with all rules for variable, method and packet naming.

– Choose appropriate visibility for your classes, methods and attributes.

– Do not use the default package.

– System.exit() and Runtime.exit() must not be used. 

– Follow the rules for Javadoc documentation.

– Also stop all other Checkstyle rules.

Processing information

These processing instructions are relevant for the evaluation of your submission, but the Praktomat will not reject your submission if one of the following rules is violated.

– Note that your submissions are evaluated in terms of both object-oriented modeling and functionality.Follow the instructions for modeling in the ILIAS Wiki.

– Program code must be written in English.

– Comment your code appropriately: as much as necessary, as little as possible.

– The comments should be written uniformly in English or German.

– Choose meaningful names for all your identifiers.

Plagiarism

Only independently developed solutions are accepted.Submitting solutions from other people, even if only partial solutions from third parties, from books, the Internet or other sources such as the solution proposals of the training company, is an attempt at deception and leads to the rating “failed”.Expressly excluded from this are source code snippets from the lecture slides.All aids used must be fully and accurately specified and anything taken from work carried out by others, either unchanged or with modifications, must be clearly marked. For further details, please refer to the declaration of consent (disclaimer).

Terminal Class

For this task, download the Terminal class and make sure you place it in the edu.kit.informatik package.The Terminal.readLine() method reads user input from the console and replaces System.in.The method Terminal.printLine() writes output to the console and replaces System.out.Use the Terminal class for any console input or console output.Never use System.in or System.out.Error messages are only output via the terminal class and must start with Error,␣ for technical reasons.Among other things, this can be done conveniently using the Terminal.printError method. Never upload the terminal class together with your submission.

Model railway simulation (20 points)

In this final task you will develop a model railway simulator. The final task consists of two interdependent subtasks.The first sub-task is the modelling of the route network and the rolling stock (wagons, locomotives, multiple units).The second subtask is the driving simulation.

Track material:

A screenshot of a cell phone

Description automatically generated

The track network is represented by tracks.Simplified, tracks are represented by two or three points in two-dimensional space.A point is a tuple of two 32-bit integers and represents a coordinate.All tracks have a unique identifier starting at 1, which is only unique for tracks (see example sequence).The identifier is a 32-bit integer and is assigned in ascending order.A line consists of several tracks.There are two types of tracks: normal tracks and track switches (turnouts).Normal tracks are described by two points in space, the start and end points.The coordinates can lie anywhere in space, with the restriction that track parts are always horizontal or vertical. Only one change in the x-direction is horizontal and one change only in the y-direction is vertical.Furthermore, with the exception of the first track, a start or end point must always be adjacent to a start or end point of an existing track.Only one other track (normal track or track switch) can be connected at any one point on a track. Each track has a length1, which depends on its start and end coordinates.For simplification, the length is always shown as rounded positiveInteger2 specified. Track switches serve to split a line into two sections.They are described by three coordinates, a starting point and two end points.Track switches have the additional property of saving the current switch position.The current track switch setting determines the passability of a track switch.The length of a track switch depends on its current position.Figure 0.1 illustrates a possible route network.The black dots show the respective start and end points for track material.Track switches are marked by the label “Switch X”, where X is a placeholder for a positive integer. The current track switch position is indicated by the black line.The red line indicates the alternative selection option. A train can only run on the black line. This is also the route network which is used in the example sequence.

Figure 0.1: Example of a simple line with track switches and tracks

(gleis = track and weiche = track witsches)

Tracks cannot cross each other, i.e. if tracks are seen as straight lines, they must not intersect.Figure 0.2 shows a prohibited track crossing.It is also not allowed to connect tracks outside of start and end points.In this task this would also be a crossing of tracks.In addition, a start or end point can only have exactly one other track.

JAVA编程 面向对象编程 复杂程序作业代写插图1

Figure 0.2: Not allowed crossing of tracks

Rolling Stock:

The rolling stock generally describes all objects running on rails, e.g. a railway wagon.For the sake of simplicity, we assume that there are only the following types:Cars, locomotives, multiple units.Common to all types is that they have a name and a length, e.g. a locomotive could have the name Emma and length 1.

JAVA编程 面向对象编程 复杂程序作业代写插图1

(a) Passenger carriages.            (b)Goods carriages                  (c) Special carriages

Figure 0.3: Graphical representation of carriages

Carriage:

To simplify matters, only passenger, freight and special wagons are available as wagon types.The passenger car is used to transport people, the freight car to transport goods and special cars are e.g. a crane car or a fire engine. The different types of cars are represented graphically as in Figure 0.3.All wagons have a unique 32-bit integer ascending identifier starting at 1, which is only unique for wagons (see example sequence).Each car has at least one, but no more than two couplings.These are always located at the beginning and end of a car.There may also be a maximum of one coupling on one side (start, end).These couplings allow the composition of rolling stock (see composition of rolling stock)

Locomotive

There are three different types of locomotives: electric locomotives, diesel locomotives and steam locomotives. All locomotives have a unique ID. This ID is made up of the class and the name of the locomotive. These are separated by a hyphen, for example, the class “103” and the name “118” result in the ID “103-118”. Both the name and the series can contain letters and numbers.Whereby the series must not be the character string “W”.Each locomotive has at least one, but no more than two couplers.These are always located at the beginning and end of a locomotive.There may also be a maximum of one coupling on one side (start, end).These couplings allow the composition of rolling stock (see Composition of rolling stock).Figure 0.4 shows the graphical representation of locomotives.

Multiple unit:

A close up of a logo

Description automatically generated

All multiple units have one series.The multiple unit ID is composed according to the same rules as for locomotives.For this reason, locomotives and multiple units share the same ID space.A multiple unit has a special type of coupling and can therefore only be composed with the same series of multiple units (see Composition of Rolling Stock). otherwise the same rules apply as for locomotives.Figure 0.5 shows the graphical representation of multiple units

(a) Steam locomotive.           (b) Electric locomotive.           (c) Diesel locomotive

Figure 0.4: Graphical representation of locomotives

A screenshot of a cell phone

Description automatically generated

Figure 0.5: Graphical representation of multiple unit trains

Composition of rolling stock:

Rolling stock can be composed into a train. The following restrictions must be observed when composing:

– At the beginning or end of a valid train there must always be at least one locomotive/train set.-

 During composition, it must always be considered whether the rolling stock has a suitable coupling at the desired composition point.

– The rolling stock that is being composed is not yet used in another train.

All trains have a unique ID starting at 1, which is a 32-bit integer and is assigned in ascending order.This ID is only unique for trains (see example sequence).A move can also be output graphically on the console.The individual representations of the rolling stock are concatenated according to their position in the train.The individual representations are separated by a space.Figure 0.6 shows an output for a train with one steam locomotive and two passenger cars.Figure 0.7 shows another train example with an electric locomotive and a passenger car.

A picture containing screenshot

Description automatically generated

Figure 0.6: Example representation of a train with steam locomotive

Figure 0.7: Example representation of a train with electric locomotive

Driving operation

In order to simulate the operation of a model railway, a train must first be placed on a track. The whole train is always placed on the track. A direction vector must be specified when placing the train on the track. This vector indicates the initial direction of the train. The direction vector corresponds to the direction vector of the track or is exactly the opposite vector. When rerailing, it must be noted that the used tracks are still free, i.e. no other train is standing there and there is a track at all.Of course, the length of a train also plays a role.Trains can only be set up on lines with track switches when the track switch position has been set.Furthermore, trains can only be set on the section that is the current track switch position.If track points on which a train is already standing are switched, the train on top of them derails.When trains are on the track, they can only move on the track.They initially move in the direction of the direction vector and follow the course of the rail.Before a train can move, a track switch position must be set for all track switches.As usual with small model railroad layouts, all trains that are on the layout run here.The speed is the same for all trains.In general, the train will move by n x units for horizontal tracks and by n y units for vertical tracks.The simulation here is calculated in steps. For this purpose, n ∈ Z16-bit is transferred at each step.To illustrate this, an example is shown in Figure 0.8, where the points are indicated by a tuple of integers.The head of a train (red dot) stands at (2,0) on the track from (1,0) to (4,0) and moves towards point (4,0).At point (4,0) a track switch with the end points (4,2) and (6,0) is connected.The current track switch position is set to (6.0).After a step with n = 1, the traction head (blue point) would be at (3.0) (see Figure 0.8a).After a further step with n = 2, the traction head (yellow dot) would be at (5,0). In the second example (see Figure 0.8b), the head of the train (red dot) stands at (0,0) on the track from (0,3) to (0,-1) and moves towards point (0,3). After a step with n = 2 the train head (blue point) would be at (0.2). In a further step with n = 2 the train head would (yellow dot) to (1,3).

A close up of a logo

Description automatically generated

(a) Driving simulation with switch.                      (b) Trip simulation with curve

Figure 0.8: Direction of movement of trains

During the simulation, collisions of different trains may occur.A collision occurs when two trains are on the same track or position.During the check, the start/end points always belong to the track on which the rest of the train is standing.For example track 1 (G1) from (10,1) to (20,1) and track 2 (G2) from (20,1) to (30,1). If a train with length 4 is now at (20,1) and is moving in direction (30,1), then G1 would be occupied and G2 would still be free.If there is a collision, the trains involved derail.Trains can go beyond the track, i.e. if the track ends and there is no siding, e.g. as in Figure 0.1 (track 7) the train derails.When trains derail, they take you off the track.However, they remain in the train database.They can then be put back on again.

Interactive user interface:

After startup, your program accepts various types of commands via the console using Terminal.readLine(), which are specified in more detail below.After processing a command, your program waits for further commands until the program is terminated at some point by the exit command.Make sure that executing the following commands does not violate the previously defined basics and conditions, and always issue a meaningful error message in these cases.If an input does not correspond to the specified format, an error message is always issued.After that the program should wait for the next input.For error messages, you are free to choose the text, but it should make sense.However, every error message must begin with Error, and may not contain any line breaks.Because we perform automatic tests of your interactive user interface, the output must be exactly as specified.

In particular, lower and upper case letters as well as spaces and line breaks should match exactly. Also, do not output any additional information. Start submitting early to test your solution and use the forum to clarify any ambiguities.

Please note that in the description of the input and output formats, the words between angle brackets ( < and > ) stand for placeholders, which are replaced by values in the actual input and output. These actual values do not contain brackets for the input and output. Please also compare the respective example sequences.

Please note that in the following example procedures, the input lines are introduced with the > character followed by a space. These two characters are explicitly not part of the entered command, but are only used to distinguish between input and output lines.

If lists are to be output, they are always output line by line, unless a command explicitly specifies otherwise. Unique identifiers and IDs that consist of exactly one 32-bit integer are always assigned in ascending order starting with 1. I.e. the first ID would be 1 and the second 2. In addition, the next free ID is always selected. For example, if the IDs 1,3,4,5 are assigned, the next ID is 2.

Point input

A point is a tuple of two 32-bit integers and describes a coordinate in 2D space. The tuple is enclosed in “round” brackets. The two integers are separated by a comma. The first 32-bit integer enters the x coordinate and the second 32-bit integer enters the y coordinate.

Input format:

JAVA编程 面向对象编程 复杂程序作业代写插图1

The add track command

Adds a normal track.A start point <startpoint> and an end point<endpoint> selected.If the track is not the first track, one of the two points must always be on a start or end point of another track.Tracks can only be horizontal or vertical.

Input format:

A screenshot of a cell phone

Description automatically generated

Output format:

If successful, the unique ID of the track is output. In the event of an error (e.g. no connection to a previous track), a meaningful error message is output, beginning with Error.

The add switch command

Adds a track switch.One starting point and two end points are selected.The individual track switch sections must always be horizontal or vertical.If the track is not the first track, one of the three points must always be on a start or end point of another track.

Input format:

add switch <startpoint> -> <endpoint1>,<endpoint2>

Output format:

If successful, the unique ID of the track is output.In the event of an error (e.g., no connection to a previous track) a meaningful error message is output, beginning with Error.

The delete track command

Deletes any track (normal track, track switch).The track to be deleted is selected via the<trackID> selected.When deleting, it must be checked that no two independent tracks exist after removal, i.e. that all tracks are connected and that there are no track sections that are not connected.In addition, no train may be on the track.

Input format:

delete track <trackID>Output format If successful, OK is displayed.

Output format:

In the event of an error (e.g., <trackID> not found), a meaningful error message is output, beginning with Error.

The list tracks command

Outputs a list of all tracks (track switches and normal tracks) line by line. The output contains the type, the unique track ID <trackID>, the starting point, the end point and the length.For track switches, the length is only output if the track switch position has already been set.In this case the length, then the length of the vector from the starting point to the matching end point of the current track switch position.The list is sorted by track ID in ascending order.

Input format:

list tracks

Output format:

For normal tracks: t <trackID> <startpoint> -> <endpoint> <length>

For track switches: s <trackID> <startpoint> -> <endpoint1>,<endpoint2> <length>

s or t describe the track type. <trackID> is a 32-bit integer ID.

If a track does not exist, return “No track exists”.

Example:

A screenshot of a cell phone

Description automatically generated

The set switch command

For a turnout with the <trackID> selects the turnout position that connects the starting point of the turnout with the selected end point (<point>).

Input format

set switch <trackID> position <point>

Output format

If successful, OK is displayed.In the event of an error (e.g. point not present or track ID not found) a meaningful error message is output, beginning with Error.

The create engine command

Create a locomotive. <engineType> describes the type of locomotive ( electrical ,steam , diesel ). The series is set using the placeholder <class>.<name> is the name of the locomotive. specifies the length of a locomotive as a 32-bit integer.<couplingFront> and are truth values that indicate whether a couplingis present at the front and or rear.The truth value can be set to true or false.Here true indicates that a coupling is present.A locomotive can only be added if no locomotive or multiple unit with the same ID exists yet.

Input format:

 create engine <engineType> <class> <name> <length> <couplingFront> <couplingBack>

Output format:

If successful, the unique ID of the locomotive is output. In the event of an error (e.g., wrong input format or ID already exists), a meaningful error message is output, starting withError, output.

The list engines command

Outputs a list of all locomotives line by line. The list is lexicographically sorted according to the locomotive ID.

Input format:

list engines

Output format:

<trainID> <engineType> <class> <name> <length> <couplingFront> <couplingBack>

<trainID> is the ID of the train to which the locomotive belongs.If none is set yet, the output is displayed.<engineType> identifies the type of the locomotive.Where e stands forelectric s for steam and d for diesel.All other placeholders have the same meaning as in the create engine command.If no locomotive exists yet, “No engine exists” is displayed.

A screenshot of a cell phone

Description automatically generated

Example:

The create coach command
Create a wagon. <coachType> describes the type of the car. There are the following types:
Passenger, freight, special.
Input format:
create coach <coachType> <length> <couplingFront> <couplingBack>
Output format:
If successful, the unique car ID is output. In case of an error (e.g., wrong input format), a meaningful error message is output, starting with Error.
 
The list coaches command
Outputs a list of all cars line by line. The list is sorted in ascending order by car ID.
 
Input format:
list coaches
 
Output format:
<coachID> <trainID> <coachType> <length> <couplingFront> <couplingBack>
<coachID> is the ID of the wagon. <trainID>is the ID of the train to which the wagon belongs. If none is set yet, none is output. <coachType> identifies the type of the car. Where p stands for passenger cars, f for freight cars and s for special cars.All other placeholders have the same meaning as in the list engine command.If no coach exists yet, No coach exists is displayed.
Example:




 
The create train-set command
Create a multiple unit. The other parameters and error cases are described in the create engine commanddescribed
Input format:
create train-set <class> <name> <length> <couplingFront> <couplingBack>
Output format:
If successful, OK is displayed.In the event of an error (e.g., wrong input format), a meaningful error message is output, beginning with Error.
 
The list train-sets command
Outputs a list of all multiple units line by line.The list is lexicographically based on the multiple unitID ordered.
Input format:
list train-sets
Output format:
<trainID> <class> <name> <length> <couplingFront> <couplingBack>
All placeholders have the same meaning as the command. If no multiple unit exists yet, No train-set exists is output.
 
The delete rolling stock command
Deletes a rolling stock.The rolling stock is identified by its unique ID.For a car, the ID is presented with a W.Rolling stock can only be unloaded if it is not used on any train.
Input format:
 delete rolling stock <id>
Output format:
If successful, OK is displayed. In case of an error (e.g., wrong input format), a meaningful error message is output, beginning with Error.
 
 
 
The add train command
Adds rolling stock to the train with the 32-bit integer <trainID>.If the train with the ID does not yet exist, it will be created automatically.The <rollingStockID> is either the ID of a train, locomotive or wagon.For wagons, a W is placed in front of the ID.The train must be valid with regard to the couplings, but not valid with regard to the locomotives.The rolling stock is added in sequence, i.e. the first rolling stock added to a train is the head of the train (front) and the last rolling stock added is the tail of the train.
Input format:
add train <trainID> <rollingStockID>
Output format:
If successful, <type> <stockID> added to <trainID> is displayed. <type> is the type. The following values can be assumed electrical engine, steam engine, diesel engine, train-set, passenger coach, freight coach, special coach.<stockID> is the ID of the rolling stock, whereby for wagons a W is placed in front of it.<trainID> is the ID of the trainIn case of an error (e.g., incorrect clutch), a meaningful error message is issued, beginning with Error.
 
The delete train command
Deletes the move with the <ID> . If the train is on the line, it will also beTrack removed.
Input format:
delete train <ID>
Output format:
If successful, OK is displayed. In case of an error (e.g., wrong input format), a meaningful error message is output, beginning with Error.
 
 
The list trains command
Outputs a list of all moves line by line.The list is sorted in ascending order by train ID.
Input format:
list trains
Output format:
<trainID> <members>
 
The <trainID> is the current ID of the train and Members is a list of the IDs of the rolling stock used.The individual IDs are separated by spaces.The ID of a wagon is preceded by a W to indicate that it is a wagon. e.g. 1 103-118 W1 for train 1 with locomotive 103-118 and wagon 1.
The show train command
The command prints the graphical representation of the train. trainID is the ID of the train.
Input format:
show train <trainID>
Output format:
If successful, the graphical representation is output for each rolling stock.In the event of an error (e.g. train not present), a meaningful error message is displayed beginning with Error,output.(see example procedure)
 
The put train command
Places a valid (see Rolling Stock Composition) train on a track at the position <point> . The initial direction of movement is determined by the integers4 <x>,<y> which serve as direction vectors.When rerailing, make sure that the train is valid and that there is no other train on the required tracks (note the length of the train) and that the direction vector corresponds to the direction of the track at the rerailing point (or to opposite).
Input formatput:
 train <trainID> at <point> in direction <x>,<y>
Output format:
If successful, OK is displayed.In case of an error (e.g., wrong input format, or invalid move) a meaningful error message is displayed, beginning with Error.
 
 
The step command
Makes all trains run by <speed> units. is a 16 bit integer.Subsequentlythe position of all train heads ( ), which are standing on a track, is output line by line.This is done in ascending order of the train ID.In case of a collision during operation, the trains involved will be issued.For the description of the ride and the collision behaviour, see Driving Mode.Trains that are not affected by the collision continue to run normally.
Input format:
step <speed> 
Output format:
Train <trainID> at <headPoint>Line by line output of moves.If there is no train on the track yet, OK is displayed.In case of a collision, Crash of train <trains> is output.Where <trains> is a list of train IDs separated by commas (sorted in ascending order).If there is a collision of several, this is output line by line.Note that the trains must not overlap, i.e. if train 1 has a collision with train 3 and train 3 has a collision with train 4 this would be considered a collision and the output would be Crash of train 1,3,4. If there are multiple independent collisions, the output is sorted by the smallest train ID of each collision. The same applies if there is a mixture of collisions and normal output. For example, train 11 and train 12 have an accident and train 9 and train 22 have one too. But move 10 and 8 do not, then the output would be without consideration of the position:




 
The exit command
The parameterless command allows to terminate the running program completely.Please note that methods like System.exit() or Runtime.exit() must not be used for this.
Input format:
exit
Output format:
In case of success no output will take place.In the event of an error (e.g. an incorrectly specified input format), a meaningful error message is output, beginning with Error.

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Example:





					

Tensorflow Pnet网络 科研代码代写 科研代替实现 全能代写

需求:{1、pnet网络替换成深度可分离卷积

2、加新的输出

3、换一下softnms}

1、替换网络

Pnet替换成深度可分离卷积

Mtcnn_model.py文件

2、新的输出具体是:

训练MTCNN模型所采用的的WIDER_FACE 数据集标签包含人脸的标定框的坐标之外五个对人脸特性的评价指标如图,包括模糊度(清晰的为 0,正常为 1、模糊为 2)、遮挡程度(没有遮挡为 0,部分遮挡为 1、大面积遮挡为 2)、姿势(根据人脸姿势”典型脸”为 0,“非典型脸”为1)、亮度(正常亮度为1,过亮为0)、表现力(正常情绪为0,夸张为1)

图 3.6 WIDER_FACE 数据集提供的五种标签示意图

Fig. 3.6 Five label value provided by the WIDER_FACE

人脸检测所检测到的信息作为人脸识别的输入,检测输出的信息如果含有人脸质量的评价指标,包含的信息越充分,人脸对识别率的提高越有帮助,所以在原有MTCNN基础上增加一项新的face_quality的输出,可以在后续多人脸识别过程中,针对人脸质量的评价,进行更加有效的识别。

  • 图 3.5  MTCNN 模型的输出改进
  • Fig. 3.5 Diagram of the output module improvement of the MTCNN model

五种人脸特性的数值之和的变化范围是从 0 到 7,根据在视频监控场景下出现多人脸检测识别情况的常见程度,对五种指标赋予0.2、0.3、0.3、0.1、0.1的权重,用均方误差函数(MSE)去训练人脸评价指标任务,其式如下:

其中 是训练样本真实值, 是网络输出的值,最终其损失函数为:

L=

原先的损失函数和论文中的权重相同,新加的𝛼face_quality(匹配分数损失函

数的权重)在P-Net、R-Net、O-Net 中为[0.5,0.5,0.5]。

改进代码:

Gen 12 net data

标签文件是:wider_face_train_bbx_gt.txt

把后面五项读进去输出

p_idx = 0 # positive
n_idx = 0 # negative
d_idx = 0 # don't care
idx = 0
box_idx = 0
boxes=[]
quality = []
labelfile = open(anno_file, 'r')
while True:
    #image path
    im_path = labelfile.readline().strip('\n')

    if not im_path:
        break
    im_path = im_dir + im_path
    print(im_path)
    nums = labelfile.readline().strip('\n')
    #print(nums)
    # load image
    img = cv2.imread(im_path)
    img = img.astype(np.float32)
    img[0, :, :] = (img[0, :, :] - 104.146) / 127.5
    img[1, :, :] = (img[1, :, :] - 110.807) / 127.5
    img[2, :, :] = (img[2, :, :] - 119.856) / 127.5
    # print(img)
    height, width, channel = img.shape
    idx += 1
    one_image_bbox = []
    one_image_quality = []
    for i in range(int(nums)):
        bb_info = labelfile.readline().strip('\n').split(' ')
    #boxed change to float type
        bbox = [float(bb_info[i]) for i in range(4)]
        xmin = bbox[0]
        ymin = bbox[1]
        xmax = xmin + bbox[2]
        ymax = ymin + bbox[3]
        bbox=[xmin, ymin, xmax, ymax]
        #print(bbox)
        # gt
        one_image_bbox.append([bbox])
        #quality
        blur = float(bb_info[4])  ####
        express = float(bb_info[5])  #####
        illumination = float(bb_info[6])  #####
        occlusion = float(bb_info[7])  #####
        invalid = float(bb_info[8])  ######
        pose = float(bb_info[9])  ###########
        quality = float(0.2 * blur + 0.1 * express + 0.1 * illumination + 0.3 * occlusion + 0.1 * invalid + 0.1 * pose)
        quality = [round(quality, 2)]
        one_image_quality.append(([quality]))
        #print('bbox',one_image_bbox)
        #print(type(one_image_bbox))
    boxes = np.array(one_image_bbox, dtype=np.float32).reshape(-1, 4)
   # print(boxes)
    #print(type(boxes))
    quality=np.array(one_image_quality, dtype=np.float32).reshape(-1, 1)
   ## print('idx', idx)
    #print('height', height)
   # print('quality', quality)
    #print(type(quality))
    #print(height, width, channel)

相应的都改了

3、我的目前效果

检测不到正确人脸

图1是原始的pnet

图2是我改完的

 检测不到正确人脸