Updating database onclick()
Categories: django
I have some basic functionality working with the schedular app I'm building in django. My most recent task was figuring out how to update an entry in my database at the click of the button so the teachers can mark a lesson timeslot as confirmed, and show the reflected schedule on both the teacher's home page and the student's homepage.
To do so, I had to first create a new view "confirm_timeslot" that would take both the teacher_slug and timeslot_slug as arguments, then updating the boolean "confirmed" field in the database to True, and then return the JsonResponse. I also had to add a new url in urls.py teacher-home/<slug:teacher_slug>/<int:timeslot_id> and point it at the confirm_timeslot view.
views.py:
def confirm_timeslot(request, teacher_slug, timeslot_id):
selected_timeslot = TimeSlot.objects.get(id=timeslot_id)
selected_timeslot.confirmed = True
selected_timeslot.save(update_fields=['confirmed'])
current_teacher = selected_timeslot.teacher_id
return JsonResponse({'result': 'ok'})
urls.py:
path('schedular/teacher-home/<slug:teacher_slug>/<int:timeslot_id>', views.confirm_timeslot, name='confirm-timeslot')
I then had to add a button next to each timeslot entry in the html template for the teacher's homepage and add some data attributes for both the teacher_slug and timeslot_id of the request so I could pass those to my javascript/ajax call, and add the javascript function as an onclick.
teachers-home.html:
<div class="confirm-column">
{% if not timeslot.confirmed %}
{% csrf_token %}
<button id="confirm-btn" onclick="confirm()" data-teacherslug="{{ slug }}" data-timeslotid="{{ timeslot.id }}">Confirm</button>
{% else %}
<span id="checkmark"></span>
{% endif %}
</div>
Lastly, I had to create the confirm() javascript function which takes the passed teacher_slug and timeslot_id and send a request to the appropriate url with the variables inserted, and then update the related confirm-column div's html.
base.js:
function confirm() {
// debugger;
var teacherslug = $('#confirm-btn').data('teacherslug');
var timeslotid = $('#confirm-btn').data('timeslotid')
$.ajax({
url: "/schedular/teacher-home/"+teacherslug+"/"+timeslotid,
success: function(result) {
$(".confirm-column"+timeslotid).load("/schedular/teacher-home/"+teacherslug+" .confirm-column"+timeslotid)
}
})
}
I learned a lot about how django and javascript/ajax can work together when solving this problem, and I'm thankful for my dev friends as well as StackOverflow for helping me when I got stuck. Looking forward to continuning to flesh out this project and will continue to post updates.
Django Project
Categories: django
This weekend I started working on a project in Django which will be a scheduling app for teachers and students. I'm building it to both increase my knowledge and create something that my brother can use for his upcoming music school. I have a basic skeleton completed, and my next steps are to add more functionality as well as work on the design and layout.
0 Comments
3D Surface Area HackerRank
Categories: hackerrank
Challenge:
Given a 2D array representing a square of stacks of blocks, calculate the total surface area of the blocks.
https://www.hackerrank.com/challenges/3d-surface-area/problem
This was a fun problem that sounds more challenging than it actually is. My thought process was that we need to first calculate the height of the stack of blocks at each index as if it had no neighbors, which is 2 + (height of stack x 4), and then subtract the height of any of its neighboring stacks (or just subtract it's own height if the neighboring stack is greater than the current stack). We also need to account for edges and corners, which is handled by making sure the index of each neighboring index is greater than 0 and less than the height/width.
My solution:
def surfaceArea(A):
total_area = 0
for index, row in enumerate(A):
for index2, column in enumerate(row):
column_area = 2 + (column * 4)
if index2 - 1 >= 0:
left = A[index][index2 - 1]
if left > column:
column_area -= column
else:
column_area -= left
if index2 + 1 <= len(A[0]) - 1:
right = A[index][index2 + 1]
if right > column:
column_area -= column
else:
column_area -= right
if index + 1 <= len(A) - 1:
down = A[index + 1][index2]
if down > column:
column_area -= column
else:
column_area -= down
if index - 1 >= 0:
up = A[index - 1][index2]
if up > column:
column_area -= column
else:
column_area -= up
total_area += column_area
return total_area
0 Comments
HackerRank: Matrix Layer Rotation (Part 3)
Categories: hackerrank
I figured out that the reasons my code was failing due to Run Time Errors were (1.) I was creating a new empty matrix with the same dimensions as the given matrix and then appending the rotated arrays to that, instead of simply replacing the elements in the given matrix with the elements from the rotated arrays, and (2.) I was deleting each section from the flat array after adding it to the new matrix, which I found easier at the time, since I wouldn't have to calculate the new index of the next section. This fix was pretty simple, since I just needed to keep an incremental index going while getting the correct slices from the rotated flat array.
It took me a little while to determine the best way to handle the first part, but I finally passed 12 out of 12 test cases with the following code:
def matrixRotation(matrix, r):
# Number of rows in the matrix
rows = len(matrix)
# Number of columns in the matrix
columns = len(matrix[0])
# New list that will contain each slice of the matrix in a new list
matrices = []
# The number of slices in the matrix
matrix_num = int(min(rows, columns) / 2)
i = 0
while i < matrix_num:
single_matrix = [matrix[i][i:columns-i],
[matrix[row][columns-1-i] for row in range(i+1, rows-i-1)],
matrix[rows-i-1][i:columns-i][::-1],
[matrix[row][i] for row in range(i+1, rows-i-1)[::-1]]]
i += 1
# Turn the single_matrix list of lists into a single list
single_matrix = [mat for mat in single_matrix if mat != []]
# Turn into a flat list
single_matrix = list(itertools.chain(*single_matrix))
# Rotate this flat list counter clockwise by r
# If r is more than the length of the matrix it's more efficient to use r % len
new_r = r % len(single_matrix)
# Rotate the list
single_matrix = single_matrix[new_r:] + single_matrix[:new_r]
# Append the rotated list to the matrices list
matrices.append(single_matrix)
flat_matrices = list(itertools.chain(*matrices))
m = 0
rs = rows - 2
cs = columns
index = 0
# Create new matrix from rotated matrix
while m < matrix_num:
# Create new top
matrix[m][m:m+cs] = flat_matrices[index:][:cs]
index += cs
# Create new right side
for k in range(rs):
matrix[k + 1 + m][-1-m] = flat_matrices[index]
index += 1
# Create new bottom
matrix[rows - 1 - m][m:m+cs] = flat_matrices[index:][:cs][::-1]
index += cs
# Create new left side
for k in range(rs):
matrix[rs - k + m][m] = flat_matrices[index]
index += 1
m += 1
rs -= 2
cs -= 2
# Print each row as a string joined by a space
for row in matrix:
print(' '.join(str(num) for num in row))
It took me a bit longer than I expected to solve this problem, but as it was my first "Hard" level HackerRank problem, I'm just glad I was able to complete it. There are definitely ways of rotating each layer in place rather than creating flat arrays from each matrix layer and adding them back in, but I'm happy with my solution.
0 Comments
HackerRank: Matrix Layer Rotation (Part 2)
Categories: hackerrank
Continued from my last post. It looks like I'll need at least one more Blog post related to this problem, since although I found a solution, it is not optimized enough to pass all of the test cases. I'm getting timeouts on 3 of the 10 test cases in HackerRank, and I'm not quite sure where my bottlenecks are yet.
My first try had even more timeouts, but I realized that I can use mod against the number of rotations (rotations % len(array)), since a number of rotations that is more than the length of the array being rotated can be reduced. I implemented this, but am still getting timeouts.
I suspect that one of my bottlenecks is the fact that I'm creating an empty 2d array of the same number of rows and columns before adding my new rows of data to it, so one possible solution would be for me to figure out how to add the data directly to the given matrix, rather than creating a new empty matrix first.
Current (non-optimized) solution:
def matrixRotation(matrix, r):
# Number of rows in the matrix
rows = len(matrix)
# Number of columns in the matrix
columns = len(matrix[0])
# New list that will contain each slice of the matrix in a new list
matrices = []
# The number of slices in the matrix
matrix_num = int(min(rows, columns) / 2)
i = 0
while i < matrix_num:
single_matrix = []
# The top (left to right) of the matrix slice
top = matrix[i][i:columns-i]
# The right side (top to bottom) of the matrix slice
right = [matrix[row][columns-1-i] for row in range(i+1, rows-i-1)]
# The bottom (right to left) of the matrix slice
bottom = matrix[rows-i-1][i:columns-i]
bottom.reverse()
# The left side (bottom to top) of the matrix slice
left = [matrix[row][i] for row in range(i+1, rows-i-1)]
left.reverse()
i += 1
# Append each side of the matrix slice to the single_matrix list, with each side in its own list
single_matrix.extend([top, right, bottom, left])
# Turn the single_matrix list of lists into a single list
single_matrix = [x for x in single_matrix if x != []]
# Turn into a flat list
single_matrix = list(itertools.chain(*single_matrix))
# Rotate this flat list counter clockwise by r
# If r is more than the length of the matrix it's more efficient to use r % len
new_r = r % len(single_matrix)
for _ in range(new_r):
single_matrix.append(single_matrix.pop(0))
# Append the rotated list to the matrices list
matrices.append(single_matrix)
flat_matrices = list(itertools.chain(*matrices))
new_matrix = [[] for i in range(rows)]
i = 0
rs = rows
cs = columns
# Create new matrix from rotated matrix
while i <= matrix_num:
# Create new top
new_matrix[i][i:i] = flat_matrices[:cs]
del flat_matrices[:cs]
# Create new right side
for k in range(rs - 2):
new_matrix[k + 1 + i].insert(i, flat_matrices[k])
del flat_matrices[:rs - 2]
# Create new bottom
new_matrix[rows - 1 - i][i:i] = flat_matrices[:cs][::-1]
del flat_matrices[:cs]
# Create new left side
for k in range(rs - 2):
new_matrix[rs - 2 - k + i].insert(i, flat_matrices[k])
del flat_matrices[:rs - 2]
i += 1
rs -= 2
cs -= 2
# Print each row as a string joined by a space
for row in new_matrix:
print(' '.join(str(x) for x in row))
Here is the problem I'm working on, if anybody is interested:
https://www.hackerrank.com/challenges/matrix-rotation-algo/problem
Hopefully I will have a Part 3 with an optimized solution soon.
0 Comments
0 Comments