Microsoft GitHub Copilot For SWE - Hands-On Tutorial
Microsoft GitHub Copilot For SWE - Hands-On Tutorial
Chat 16-25
1
Assignment 1: Promotion Finder
I. Setup Code in VSCode
Please find code at the following link: Hands-on
The following versions of .NET and Angular will be required with access to
MongoDb Atlas.
• .NET Version: .NET 7,
• Angular Version: v16,
• DB: Mongo Atlas.
II. Using Copilot in different versions as CLI, Inline Suggestions, and Chat Based.
Response:
# Explanation:
# To kill processes with open files that have been deleted, you can use the
following command:
fuser -k -u <file_path>
# Explanation:
# - fuser command is used to identify processes using files or sockets.
# - -k option kills processes using the specified files.
# - -u option specifies that processes accessing the file should be killed.
# - <file_path> is the path of the file that has been deleted but is still open by
some process.
2) Purpose: “Seeking clarification on the command "rm *" and its potential
implications in file deletion”
Prompt: gh copilot explain "rm *"
Response:
# Explanation:
2
# rm is used to remove files and directories.
# * is a wildcard that matches any file or directory in the current directory.
Response:
# Explanation:
# • To kill a process by name, you can use the pkill command.
# • pkill <process_name> kills all processes with the specified name.
# • Another option is to use the killall command.
# • killall <process_name> kills all processes with the specified name.
# • If you want to manually find the process ID (PID) of a process by name and
then kill it, you can use the
# following commands:
# • pgrep <process_name> retrieves the PID of the process with the specified
name.
# • kill <PID> kills the process with the specified PID.
3
Prompt: gh copilot suggest "Kill processes holding onto deleted files"
Response:
# Explanation:
# To kill processes holding onto deleted files, you can use the following
command:
# • lsof is used to list open files and the processes that have them open.
# • | grep deleted filters the output to only show files that have been marked
as deleted.
# • | awk '{print $2}' extracts the second column from the output, which
contains the process IDs.
# • | sort | uniq sorts the process IDs and removes duplicates.
# • | xargs kill -9 sends a SIGKILL signal to each process ID to forcefully
terminate it.
1)
Prompts: make one paragraph element with class head displaying Promotion
finder page and make two class called as space with two button and linking them
respectively and also include a router-outlet.(In Dashboard.component.html)
Response:
4
2.
3. <div class="space">
4. <button routerLink="/resp">Button 1</button>
5. <button routerLink="/resp">Button 2</button>
6. </div>
7.
8. <router-outlet></router-outlet>
9.
2)
Purpose: Create heading with Styling.
Prompts: create a welcome heading with good styling align at the centre of screen
in html
Response:
<div class="welcome-heading">Welcome</div>*
1. <style>
2. .welcome-heading {
3. text-align: center;
4. font-size: 36px;
5. font-weight: bold;
6. margin-top: 50vh;
7. transform: translateY(-50%);
8. }
9. </style>
10.
11. <div class="welcome-heading">Welcome</div>
12.
13.
14.
3)
Prompts: write 4 methods one is called as ngOnChanges that will update the total
number of pages based on changes in page size, and second is called as nextPage()
it will increment the currentPage if it is less then total pages and emit the new page
number and third is onPageChanges it will update current page and last 4th one is
prevPage() it is use to decrement the current page of it is greater than 1
Response: 2.
3. @Component({
4. selector: 'app-paginator',
5. templateUrl: './paginator.component.html',
6. styleUrls: ['./paginator.component.css']
5
7. })
8. export class PaginatorComponent implements OnChanges {
9. @Input() pageSize: number = 10;
10. @Input() totalItems: number = 0;
11. @Output() pageChange = new EventEmitter<number>();
12. currentPage: number = 1;
13. totalPages: number = 10;
14.
15. ngOnChanges(): void {
16. this.totalPages = Math.ceil(this.totalItems / this.pageSize);
17. }
18.
19. nextPage(): void {
20. if (this.currentPage < this.totalPages) {
21. this.currentPage++;
22. this.pageChange.emit(this.currentPage);
23. }
24. }
25.
26. onPageChange(pageNumber: number): void {
27. this.currentPage = pageNumber;
28. this.pageChange.emit(this.currentPage);
29. }
30.
31. prevPage(): void {
32. if (this.currentPage > 1) {
33. this.currentPage--;
34. this.pageChange.emit(this.currentPage);
35. }
36. }
37. }
38.
39.
40. }
41.
42.
4)
Purpose: The code implements functionality to navigate through pages and display
current page information for pagination.
Prompts: write a code that implements the prevPage and nextPage functions to
handle pagination. It displays the current page number, total number of pages, and
buttons for navigation.
Response:
2. <p>Page {{ currentPage }} of {{ totalPages }}</p>
3. <button (click)="prevPage()" [disabled]="currentPage === 1">Previous</button>
4. <button (click)="nextPage()" [disabled]="currentPage === totalPages">Next</button>
5. </div>
6.
7.
6
5)
Purpose: Create TypeScript methods for component initialization, value retrieval
and promotion fetching, page navigation, modal opening and closing with data
assignment.
Prompts: write a ts code to create six methods 1st one is ngOnInit, 2nd one is
getValue it will retrieve and log the selected value, then fetch promotions based
on the value from the API. and 3rd one is onPageChange that will update the
currentPage with new page number, 4th is openModal thal will open the modal
and assign the passed data to terms and 5th one is openLocationModal it will use
to Open the location modal and assign the passed data to locations and 6th and
last one is closeModal it will close both modals
Response:
2.
3. @Component({
4. selector: 'app-promotion',
5. templateUrl: './promotion.component.html',
6. styleUrls: ['./promotion.component.css']
7. })
8. export class PromotionComponent implements OnInit {
9. currentPage: number;
10. terms: any;
11. locations: any;
12.
13. ngOnInit(): void {
14. // Initialize component
15. }
16.
17. getValue(selectedValue: any): void {
18. console.log('Selected value:', selectedValue);
19. // Fetch promotions based on the selected value from the API
20. }
21.
22. onPageChange(newPage: number): void {
23. this.currentPage = newPage;
24. // Update the currentPage with the new page number
25. }
26.
27. openModal(data: any): void {
28. // Open the modal and assign the passed data to terms
29. this.terms = data;
30. }
31.
32. openLocationModal(data: any): void {
33. // Open the location modal and assign the passed data to locations
34. this.locations = data;
35. }
36.
37. closeModal(): void {
38. // Close both modals
7
39. this.terms = null;
40. this.locations = null;
41. }
42. }
43.
44.
6)
Purpose: Configure testing module with RouterTestingModule for AppComponent and
declare it for testing.
Prompts: Set up the testing module for the AppComponent with RouterTestingModule
and declare AppComponent.
Response:
1. describe('AppComponent', () => {
2. beforeEach(() => TestBed.configureTestingModule({
3. imports: [RouterTestingModule],
4. declarations: [AppComponent]
5. }));
6.
7)
8)
Prompts: Test that the AppComponent has the correct title 'PromotionFinderPage'.
Response:
8
it(`should have as title 'PromotionFinderPage'`, () => {
2. const fixture = TestBed.createComponent(AppComponent);
3. const app = fixture.componentInstance;
4. expect(app.title).toEqual('PromotionFinderPage');
5. });
9)
Response:
9
35. await _locations.InsertOneAsync(location);
36. }
37. }
10)
Response:
11)
Prompts: Create GetByLocationIds method which fetches a list of LocationDTO objects from
the MongoDB collection based on a provided list of location IDs.
Response:
12)
10
Purpose: To create method that will retrieve list of country name and store it in mongoDB
collection.
Prompts: Create a GetAllCountries method which retrieves a distinct list of country names
from the LocationDTO objects and store it in the MongoDB collection.
Response:
13)
Purpose: To create a method that will insert location objects into collections.
Prompts: Create Add method and insert a LocationDTO object into the MongoDB
collection. If the location doesn't have an ID, a new ObjectId will generate and assign
before insertion.
Response:
14)
Purpose: To create one class that will do all the get, post, put and delete operations.
11
Prompts: Create PromotionService class which manages promotions stored in a
MongoDB database. It offers methods to retrieve all promotions, get a promotion by its
ID, filter promotions by country and validity dates, as well as add, update, and delete
promotions.
12
47. if (existingPromotion != null)
48. {
49. await _promotions.ReplaceOneAsync(p => p.Id == promotion.Id, promotion);
50. }
51. }
52.
53. public async Task Delete(string id)
54. {
55.
56. await _promotions.DeleteOneAsync(p => p.Id == id);
57. }
58. }
15)
Purpose: To create a method that will retrieve all the data that are present in
“Promotions” collection.
Prompts: Create a GetAll method with retrieves all PromotionDTO objects from the
MongoDB "Promotions" collection and returns them as an enumerable list.
Response:
1. public async Task<IEnumerable<PromotionDTO>> GetAll()
2. {
3. return await _promotions.Find(x => true).ToListAsync();
4. }
5.
16)
Purpose: To create a method that will fetch the details by passing the country details.
Prompts: Create a GetByCountry method and retrieve PromotionDTO objects from the
MongoDB "Promotions" collection that match the specified country and are currently
valid based on the current date.
Response:
1. public async Task<IEnumerable<PromotionDTO>> GetByCountry(string country)
2. {
3.
4. var dateNow = DateTime.Now;
5. var promotionFilter = Builders<PromotionDTO>.Filter.And(
6. Builders<PromotionDTO>.Filter.Eq(x => x.Country, country),
7. Builders<PromotionDTO>.Filter.Lte(x => x.ValidityStart, dateNow),
8. Builders<PromotionDTO>.Filter.Gt(x => x.ValidityEnd, dateNow)
9. );
10. return await _promotions.Find(promotionFilter).ToListAsync();
11. }
12.
13
17)
Purpose: To create one method that will add details in database.
Prompts: Create an Add method which adds a PromotionDTO object to the MongoDB
"Promotions" collection. If the promotion doesn't already have an ID, it generates a new
unique ID before inserting the promotion.
Response:
1. public async Task Add(PromotionDTO promotion)
2. {
3. if (promotion.Id == null)
4. {
5. promotion.Id = ObjectId.GenerateNewId().ToString();
6. }
7. await _promotions.InsertOneAsync(promotion);
8. }
9.
18)
Purpose: To create a method that will update details in database.
Response:
1. public async Task Update(PromotionDTO promotion)
2. {
3.
4. var existingPromotion = await _promotions.Find(p => p.Id ==
promotion.Id).FirstOrDefaultAsync();
5. if (existingPromotion != null)
6. {
7. await _promotions.ReplaceOneAsync(p => p.Id == promotion.Id, promotion);
8. }
9. }
19)
Purpose: To create method for connecting the database, storing in database and to
retrieve data from database.
14
Prompts: Create a TermsService class which manages terms stored in a MongoDB
database. It initializes the database connection in the constructor and provides methods
to add new terms, retrieve all terms, and retrieve terms by their IDs.
Response:
1. public class TermsService
2. {
3. private readonly IMongoCollection<TermDTO> _terms;
4. public TermsService(IConfiguration configuration)
5. {
6. var client = new MongoClient(configuration.GetConnectionString("MongoDB"));
7.
8. var database = client.GetDatabase("PromotionFinder");
9. _terms = database.GetCollection<TermDTO>("Terms");
10. }
11.
12. //Add a new term
13. public async Task Add(TermDTO term)
14. {
15. if (term.Id == null)
16. {
17. term.Id = ObjectId.GenerateNewId().ToString();
18. }
19. await _terms.InsertOneAsync(term);
20. }
21. //Get all terms
22. public async Task<IEnumerable<TermDTO>> GetAll()
23. {
24. return await _terms.Find(x => true).ToListAsync();
25. }
26. public async Task<IEnumerable<TermDTO>> GetAllByIds(IEnumerable<string> termIds)
27. {
28. var termsFilter = Builders<TermDTO>.Filter.In(x => x.Id, termIds);
29. var terms = await _terms.Find(termsFilter).ToListAsync();
30. return terms;
31. }
32.
33. }
34.
20)
Purpose: To create a method that will connect to mongoDB database.
Response:
1. public TermsService(IConfiguration configuration)
2. {
3. var client = new MongoClient(configuration.GetConnectionString("MongoDB"));
15
4.
5. var database = client.GetDatabase("PromotionFinder");
6. _terms = database.GetCollection<TermDTO>("Terms");
7. }
8.
21)
Purpose: To create one method that will store data in mongoDB collection.
Prompts: Create an Add method to insert a TermDTO object into the MongoDB _terms
collection, generating a new ID if none is provided.
Response:
22)
Purpose: To create method to get the data by ids.
Prompts: Create GetAllByIds method to fetche TermDTO objects from the MongoDB
_terms collection based on provided IDs and returns them as an enumerable list.
Response:
1. public async Task<IEnumerable<TermDTO>> GetAllByIds(IEnumerable<string> termIds)
2. {
3. var termsFilter = Builders<TermDTO>.Filter.In(x => x.Id, termIds);
4. var terms = await _terms.Find(termsFilter).ToListAsync();
5. return terms;
6. }
7.
1)
Purpose: To generate unit test cases
16
Prompts: @workspace /tests generate unit test case for selected code
Response: => {
2. let component: PaginatorComponent;
3. let fixture: ComponentFixture<PaginatorComponent>;
4.
5. beforeEach(() => {
6. TestBed.configureTestingModule({
7. declarations: [PaginatorComponent]
8. });
9. fixture = TestBed.createComponent(PaginatorComponent);
10. component = fixture.componentInstance;
11. fixture.detectChanges();
12. });
13.
14. it('should create', () => {
15. expect(component).toBeTruthy();
16. });
17.
18. it('should calculate total pages on changes', () => {
19. component.totalItems = 100;
20. component.pageSize = 10;
21. component.ngOnChanges();
22. expect(component.totalPages).toEqual(10);
23. });
24.
25. it('should increment current page by 1 when next page is called', () => {
26. component.currentPage = 1;
27. component.totalPages = 2;
28. component.nextPage();
29. expect(component.currentPage).toEqual(2);
30. });
31.
32. it('should not increment current page when next page is called and current page is last page',
() => {
33. component.currentPage = 2;
34. component.totalPages = 2;
35. component.nextPage();
36. expect(component.currentPage).toEqual(2);
37. });
38.
39. it('should decrement current page by 1 when prev page is called', () => {
40. component.currentPage = 2;
41. component.prevPage();
42. expect(component.currentPage).toEqual(1);
43. });
44.
45. it('should not decrement current page when prev page is called and current page is first
page', () => {
46. component.currentPage = 1;
47. component.prevPage();
48. expect(component.currentPage).toEqual(1);
49. });
50. });
2)
17
Purpose: To generate pagination html code
Prompts: Generate HTML code for a pagination component that displays the
current page number, the total number of pages, and buttons for navigating to
the previous and next pages.
Response:
3)
Prompts: (Provide the code snippet generated by above prompt) in the above
code The previous button should be disabled when the current page is the first
page, and the next button should be disabled when the current page is the last
page.
Response:
2. <button class="prev-btn" id="prev-btn" onclick="prevPage()">Previous</button>
3. <span id="page-num">1</span> / <span id="total-pages">10</span>
4. <button class="next-btn" id="next-btn" onclick="nextPage()">Next</button>
5. </div>
6.
7. <script>
8. var currentPage = 1;
9. var totalPages = 10;
10.
11. document.getElementById('page-num').innerText = currentPage;
12. document.getElementById('total-pages').innerText = totalPages;
13.
14. function updateButtons() {
15. document.getElementById('prev-btn').disabled = currentPage === 1;
16. document.getElementById('next-btn').disabled = currentPage === totalPages;
17. }
18.
19. function prevPage() {
20. if (currentPage > 1) {
21. currentPage--;
22. document.getElementById('page-num').innerText = currentPage;
23. updateButtons();
24. }
25. }
26.
27. function nextPage() {
18
28. if (currentPage < totalPages) {
29. currentPage++;
30. document.getElementById('page-num').innerText = currentPage;
31. updateButtons();
32. }
33. }
34.
35. updateButtons();
36. </script>
37.
4)
Response:
In Visual Studio Code, you can use multi-cursor for various tasks such as editing
multiple lines simultaneously, renaming variables, and more. Here's how you can use it:
1. Add additional cursors to all occurrences of the current selection: Use the Add
Cursors To Top (editor.action.addCursorsToTop) or Add Cursors To Bottom
(editor.action.addCursorsToBottom) commands.
2. Add a new cursor at a specific location: Hold the Alt key and click at the location
where you want to add a new cursor.
3. Add a new cursor to all occurrences of a specific word: Select the word and use the
Add Cursors To Top or Add Cursors To Bottom commands.
5)
Response:
To center align your pagination component, you can use CSS Flexbox. Add the
following CSS properties to your .pagination class:
19
1. pagination {
2. display: flex;
3. justify-content: center;
4. align-items: center;
5. }
6.
6)
Response:
The selected code is a method in C# that fetches promotions for a specific country
from a MongoDB database. The method is part of a service class, likely used in a web
API or similar application. Here's a breakdown:
This line defines the method signature. The method is public, meaning it can be
accessed from outside the class. It's async, which means it's asynchronous and returns
a Task. The Task wraps a collection (IEnumerable) of PromotionDTO objects. The
method takes one parameter, a string representing the country.
);
1. var promotionFilter = Builders<PromotionDTO>.Filter.And(
2. Builders<PromotionDTO>.Filter.Eq(x => x.Country, country),
3. Builders<PromotionDTO>.Filter.Lte(x => x.ValidityStart, dateNow),
4. Builders<PromotionDTO>.Filter.Gt(x => x.ValidityEnd, dateNow)
20
5. );
This block creates a filter for the MongoDB query. It uses the Builders class from the
MongoDB driver to create a compound filter with three conditions:
• The Country property of the PromotionDTO must equal the country parameter.
• The ValidityStart property must be less than or equal to the current date and
time.
• The ValidityEnd property must be greater than the current date and time.
This filter will match promotions that are valid for the specified country and whose
validity period includes the current date and time.
7)
Response:
Based on the structure of your workspace and the existing code in
PromotionService.cs, you can add a method to fetch all promotions by country. Here's
an example of how you can do it:
}
1. public async Task<IEnumerable<PromotionDTO>> GetAllByCountry(string country)
2. {
3. var promotionsByCountryFilter = Builders<PromotionDTO>.Filter.Eq(x => x.Country, country);
4. return await _promotions.Find(promotionsByCountryFilter).ToListAsync();
5. }
6.
21
This method, GetAllByCountry, is asynchronous and returns a Task that wraps a
collection (IEnumerable) of PromotionDTO objects. It takes one parameter, a string
representing the country.
The method creates a filter that matches PromotionDTO objects where the Country
property equals the country parameter. It then uses this filter to find matching
documents in the _promotions collection, converts the result to a list, and returns it.
8)
Response:
To install Angular CLI, you can use the following command in your terminal:
This command installs Angular CLI globally on your system. The -g flag is used to
specify that the package should be installed globally.
After the installation is complete, you should be able to use the ng command. You can
verify the installation by checking the version of Angular CLI:
1. ng --version
Once Angular CLI is installed, you can serve your Angular application using the ng
serve command:
1. ng serve
22
This command starts the development server. By default, the server runs on
http://localhost:4200/.
Please ensure that you're in the correct directory (the root directory of your Angular
project) before running the ng serve command.
9)
Prompts: @workspace /explain how this code works and what is need of using
ngOnInit()
Response:
This code defines an Angular component named PromotionComponent. The
PromotionComponent class is decorated with @Component, which tells Angular that
this class is an Angular component.
countries, terms, and locations: Arrays to store data fetched from APIs.
constructor: The constructor method is where the HttpClient is injected into this
component, and where the component fetches the list of countries from an API.
ngOnInit: This is a lifecycle hook that is called after Angular has initialized all data-
bound properties of a directive. In this code, it's empty and can be removed if not
used.
23
pagedEnergyData: A getter method that returns a slice of the promotions array based
on the current page and items per page.
getValue: A method that fetches promotions based on the selected value from a
dropdown.
onPageChange: A method that updates the current page when the user navigates to a
different page.
The ngOnInit() method is a lifecycle hook in Angular, and it's a good place to put
initialization logic. This method is called just after the constructor call and after the
first ngOnChanges() call (which is another lifecycle hook that is called when an input or
output binding value changes). If you need to fetch data when the component
initializes, ngOnInit() is a good place to do it. In this code, ngOnInit() is not used and
can be removed.
10)
Response:
Here are some of the file names in your workspace:
1. app.component.ts
2. app.module.ts
3. Promotion.ts
4. module-routing.module.ts
5. module.module.ts
6. .gitkeep
7. custom-theme.scss
8. environment.ts
9. index.html
10. main.ts
11. styles.css
12. tsconfig.app.json
13. tsconfig.json
14. tsconfig.spec.json
24
15.
11)
Response:
Here's an outline for a Jupyter notebook that contains all Angular commands:
Create Notebook
DB:
Purpose:
The purpose of the prompt is to design a MongoDB schema for storing states, including a foreign
key reference to countries, state IDs, and state names.
25
Prompts: create State table with Country_id as a foreign key, State_Id, State_Name in
MongoDB.
Response:
json
"_id": ObjectId("..."),
"State_Id": 1,
"State_Name": "California",
• _id is the unique identifier for each document in the State collection. MongoDB
automatically assigns a unique _id to each document if you don't provide one
explicitly.
• State_Id is an identifier for the state.
• State_Name is the name of the state.
• Country_id is a reference to the Country document where this state belongs. It's
typically stored as the ObjectId of the related country document.
To create this structure in MongoDB, you would insert documents into a State collection.
Before creating the State collection, make sure you have a Country collection where each
document represents a country. The Country_id in the State documents would reference
the _id field of the corresponding country document
UI:
Purpose:
The purpose is to enhance the existing schema by enabling filtering of states based on both country
and product type, thereby improving query flexibility and data retrieval capabilities.
Prompts: Add one more filter for showing State based on Country and Product type mentioned below:
Response:
API:
Purpose: The purpose is to develop a .NET 7 API endpoint called "getState" that retrieves
states based on a specified country, facilitating state information retrieval for a given country
in a .NET environment.
Prompts: create a getState api based on country in dotnet 7
26
Response:
1. // Country model
2. public class Country
3. {
4. public int Id { get; set; }
5. public string Name { get; set; }
6. }
7.
8. // State model
9. public class State
10. {
11. public int Id { get; set; }
12. public string Name { get; set; }
13. public int CountryId { get; set; }
14. }
15.
16. // Fake repository for demonstration purposes
17. public interface IStateRepository
18. {
19. IEnumerable<State> GetStatesByCountry(int countryId);
20. }
21.
22. public class StateRepository : IStateRepository
23. {
24. private readonly List<State> _states = new List<State>
25. {
26. new State { Id = 1, Name = "California", CountryId = 1 },
27. new State { Id = 2, Name = "Texas", CountryId = 1 },
28. // Add more states...
29. };
30.
31. public IEnumerable<State> GetStatesByCountry(int countryId)
32. {
33. return _states.Where(s => s.CountryId == countryId);
34. }
35. }
36.
37.
38.
39. [ApiController]
40. [Route("api/[controller]")]
41. public class StateController : ControllerBase
42. {
43. private readonly IStateRepository _stateRepository;
44.
45. public StateController(IStateRepository stateRepository)
46. {
47. _stateRepository = stateRepository;
48. }
49.
50. [HttpGet("getState/{countryId}")]
51. public IActionResult GetStatesByCountry(int countryId)
52. {
53. var states = _stateRepository.GetStatesByCountry(countryId);
54. if (states == null)
55. {
56. return NotFound();
57. }
27
58. return Ok(states);
28