Saturday, February 20, 2021

Attempt to reproduce "Django 3 Tutorial & CRUD Example with MySQL and Bootstrap" on Fedora 33 KVM Guest

Regardless I've spent some time to overcome several issues (typos) in Original Howto

https://www.techiediaries.com/django/django-3-tutorial-and-crud-example-with-mysql-and-bootstrap/

I strongly believe that mentioned article is one of the best for beginners to test the taste of Django 3.1.16

To accomplish the task  following issues have to be fixed :-

The core fix in views.py  :-
 
def edit(request, pk, template_name='crudapp/edit.html'):
    contact = get_object_or_404(Contact, pk=pk)
    form = ContactForm(instance=contact)
    if request.method == 'POST':
        form = ContactForm(request.POST, instance=contact)
    # form = ContactForm(request.POST or None, instance=post)
    if form.is_valid():
        form.save()
        return redirect('index')
    return render(request, template_name, {'form':form})
 
Original code provided
def edit(request, pk, template_name='crudapp/edit.html'):
    contact = get_object_or_404(Contact, pk=pk)
    form = ContactForm(request.POST or None, instance=post)
    if form.is_valid():
        form.save()
        return redirect('index')
    return render(request, template_name, {'form':form})
The code above doesn't allow edit records in mariadb database ( OS Linux Fedora 33 Server ) 

Another fix add import to urls.py 

from django.contrib import admin 
from django.urls import path 
from crudapp import views

************************
Update as of 02/24/2021
************************

Overall files layout
 
(.env) [boris@fedora33srv djangoCrudExample]$ ls -CRl
.:
total 4
drwxr-xr-x. 6 boris boris 187 Feb 20 17:58 crudapp
drwxr-xr-x. 3 boris boris 108 Feb 20 18:09 djangoCrudExample
-rwxr-xr-x. 1 boris boris 673 Feb 18 21:16 manage.py
./crudapp:
total 24
-rw-r--r--. 1 boris boris   63 Feb 18 21:26 admin.py
-rw-r--r--. 1 boris boris   89 Feb 18 21:26 apps.py
-rw-r--r--. 1 boris boris  157 Feb 18 21:32 forms.py
-rw-r--r--. 1 boris boris    0 Feb 18 21:26 __init__.py
drwxr-xr-x. 3 boris boris   67 Feb 18 21:30 migrations
-rw-r--r--. 1 boris boris  604 Feb 18 21:30 models.py
drwxr-xr-x. 2 boris boris  150 Feb 20 17:34 __pycache__
drwxr-xr-x. 3 boris boris   21 Feb 18 22:19 templates
-rw-r--r--. 1 boris boris   60 Feb 18 21:26 tests.py
-rw-r--r--. 1 boris boris 1470 Feb 20 17:34 views.py
./crudapp/migrations:
total 4
-rw-r--r--. 1 boris boris 1043 Feb 18 21:30 0001_initial.py
-rw-r--r--. 1 boris boris    0 Feb 18 21:26 __init__.py
drwxr-xr-x. 2 boris boris   72 Feb 18 21:31 __pycache__
./crudapp/migrations/__pycache__:
total 8
-rw-r--r--. 1 boris boris 982 Feb 18 21:31 0001_initial.cpython-39.pyc
-rw-r--r--. 1 boris boris 151 Feb 18 21:30 __init__.cpython-39.pyc
./crudapp/__pycache__:
total 20
-rw-r--r--. 1 boris boris  181 Feb 18 21:30 admin.cpython-39.pyc
-rw-r--r--. 1 boris boris  569 Feb 18 22:03 forms.cpython-39.pyc
-rw-r--r--. 1 boris boris  140 Feb 18 21:30 __init__.cpython-39.pyc
-rw-r--r--. 1 boris boris  801 Feb 18 21:30 models.cpython-39.pyc
-rw-r--r--. 1 boris boris 1834 Feb 20 17:34 views.cpython-39.pyc
 
./crudapp/templates:
total 0
drwxr-xr-x. 2 boris boris 104 Feb 19 00:15 crudapp
./crudapp/templates/crudapp:
total 20
-rw-r--r--. 1 boris boris  895 Feb 18 21:43 base.html
-rw-r--r--. 1 boris boris  749 Feb 18 21:46 confirm_delete.html
-rw-r--r--. 1 boris boris 2653 Feb 18 21:45 create.html
-rw-r--r--. 1 boris boris 2455 Feb 18 21:46 edit.html
-rw-r--r--. 1 boris boris 2157 Feb 18 21:44 index.html
 
./djangoCrudExample:
total 16
-rw-r--r--. 1 boris boris  411 Feb 18 21:16 asgi.py
-rw-r--r--. 1 boris boris    0 Feb 18 21:16 __init__.py
drwxr-xr-x. 2 boris boris  122 Feb 19 00:38 __pycache__
-rw-r--r--. 1 boris boris 3271 Feb 18 21:52 settings.py
-rw-r--r--. 1 boris boris 1120 Feb 19 00:34 urls.py
-rw-r--r--. 1 boris boris  411 Feb 18 21:16 wsgi.py
./djangoCrudExample/__pycache__:
total 16
-rw-r--r--. 1 boris boris  150 Feb 18 21:21 __init__.cpython-39.pyc
-rw-r--r--. 1 boris boris 2391 Feb 18 21:52 settings.cpython-39.pyc
-rw-r--r--. 1 boris boris 1262 Feb 19 00:38 urls.cpython-39.pyc
-rw-r--r--. 1 boris boris  573 Feb 18 22:03 wsgi.cpython-39.pyc

Server Console


























































































Database status verification










Initial setup on Server F33 already running mariadb-server :-

$ python3 -m venv .env

$ source .env/bin/activate

$ sudo dnf install mariadb-connector-c-devel
$ sudo dnf groupinstall "C Development Tools and Libraries"
$ sudo dnf install python-devel
$ pip3 install mariadb
$ pip install mysqlclient

Tuesday, February 9, 2021

Refactoring one Java CRUD Application via adding two constructors to Bean class

The original application   https://www.javatpoint.com/crud-in-jsp  is using bean without any explicitly declared  constructor . To be able invoke different constructors first one for "Update","Insert", "Delete" and another one for "Select" which is supposed to be invoked explicitly we've done following updates to bean User.java. The more intensively we start to use JSP when developing applications, the more imperceptible we come to JSF technology .

package com.javatpoint.bean;

public class User {

private int id;

private String name,password,email,sex,country;

public User() {}

public User(String name, String password, String email, String sex, String country) {

        super();

        this.name = name;

        this.password = password;

        this.email = email;

        this.sex = sex;

        this.country = country;

    }

public User(int id, String name, String password, String email, String sex, String country) {

        super();

        this.id = id;

        this.name = name;

        this.password = password;

        this.email = email;

        this.sex = sex;

        this.country = country;

   }

public int getId() {

        return id;

}

public void setId(int id) {

        this.id = id;

}

public String getName() {

        return name;

}

public void setName(String name) {

        this.name = name;

}

public String getPassword() {

        return password;

}

.  .  .  .  .  .  .  .   .

}
public void setCountry(String country) {
        this.country = country;
  }

}

Due to changes to User.java class UserDao.java requires two explicit calls of second constructor to perform properly the "Select" statements

package com.javatpoint.dao;  

import java.sql.*;  

import java.util.ArrayList;  

import java.util.List;  

import com.javatpoint.bean.User;  

public class UserDao {  

public static Connection getConnection(){  

    Connection con=null;  

    try{  

        Class.forName("com.mysql.jdbc.Driver");  

        con=DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root","*******");  

    }catch(Exception e){System.out.println(e);}  

    return con;  

}  

//  For instance adduser.jsp would call static method                     

//  UserDao.save() utilizing default constructor

public static int save(User u)  {  

    int status=0;  

    try{  

        Connection con=getConnection();  

        PreparedStatement ps=con.prepareStatement(  

"insert into register(name,password,email,sex,country) values(?,?,?,?,?)");  

        ps.setString(1,u.getName());  

        ps.setString(2,u.getPassword());  

        ps.setString(3,u.getEmail());  

        ps.setString(4,u.getSex());  

        ps.setString(5,u.getCountry());  

        status=ps.executeUpdate();  

    }catch(Exception e){System.out.println(e);}  

    return status;  

}  

public static int update(User u){  

    int status=0;  

    try{  

        Connection con=getConnection();  

        PreparedStatement ps=con.prepareStatement(  

"update register set name=?,password=?,email=?,sex=?,country=? where id=?");  

        ps.setString(1,u.getName());  

        ps.setString(2,u.getPassword());  

        ps.setString(3,u.getEmail());  

        ps.setString(4,u.getSex());  

        ps.setString(5,u.getCountry());  

        ps.setInt(6,u.getId());  

        status=ps.executeUpdate();  

    }catch(Exception e){System.out.println(e);}  

    return status;  

}  

public static int delete(User u){  

    int status=0;  

    try{  

        Connection con=getConnection();  

        PreparedStatement ps=con.prepareStatement("delete from register where id=?");  

        ps.setInt(1,u.getId());  

        status=ps.executeUpdate();  

    }catch(Exception e){System.out.println(e);}  

  return status;  

}  

public static List<User> getAllRecords(){  

    List<User> list=new ArrayList<User>();  

    try{  

        Connection con=getConnection();  

        PreparedStatement ps=con.prepareStatement("select * from register");  

        ResultSet rs=ps.executeQuery();  

        while(rs.next()){ 

            int id = rs.getInt("id");

            String name = rs.getString("name");

            String password = rs.getString("password");

            String email = rs.getString("email");

            String sex = rs.getString("sex");

            String country = rs.getString("country");

            User u=new User(id, name, password, email, sex, country);

            list.add(u);  

        }  

    }catch(Exception e){System.out.println(e);}  

    return list;  

}  

public static User getRecordById(int id){  

    User u = null;  

    try{  

        Connection con=getConnection();  

        PreparedStatement ps=con.prepareStatement("select * from register where id=?");  

        ps.setInt(1,id);  

        ResultSet rs=ps.executeQuery();  

        while(rs.next()){  

             int id1 = rs.getInt("id");

            String name1 = rs.getString("name");

            String password1 = rs.getString("password");

            String email1 = rs.getString("email");

            String sex1 = rs.getString("sex");

            String country1 = rs.getString("country");

            u = new User(id1, name1, password1, email1, sex1, country1); 

        }  

    }catch(Exception e){System.out.println(e);}  

    return u;  

}  

}  

Starting JSP :-

[tomcat@fedora33server Newstuff]$ cat index.jsp
<!DOCTYPE html>  
<html>  
<head>  
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">  
<title>JSP CRUD Example</title>  
</head>  
<body bgcolor="C0C0C0">  
<h1>JSP CRUD Example</h1>  
<a href="adduserform.jsp">Add User</a>  
<a href="viewusers.jsp">View Users</a>  
 </body>  
</html>  

HTML table below would be displayed via call static method UserDao.getAllRecords() which builds strings utilizing  instances of User Bean provided by second constructor.


[tomcat@fedora33server Newstuff]$ cat viewusers.jsp
<!DOCTYPE html>  
  <html>  
<head>  
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">  
<title>View Users</title>  
</head>  
<body bgcolor="C0C0C0">  
<%@page import="com.javatpoint.dao.UserDao,com.javatpoint.bean.*,java.util.*"%>  
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>  
<h1>Users List</h1>  
<%  
List<User> list=UserDao.getAllRecords();  
request.setAttribute("list",list);  
%>  
 <table border="1" width="90%">  
<tr><th>Id</th><th>Name</th><th>Password</th><th>Email</th>  
<th>Sex</th><th>Country</th><th>Edit</th><th>Delete</th></tr>  
<c:forEach items="${list}" var="u">  
<tr><td>${u.getId()}</td><td>${u.getName()}</td><td>${u.getPassword()}</td>  
<td>${u.getEmail()}</td><td>${u.getSex()}</td><td>${u.getCountry()}</td>  
<td><a href="editform.jsp?id=${u.getId()}">Edit</a></td>  
<td><a href="deleteuser.jsp?id=${u.getId()}">Delete</a></td></tr>  
</c:forEach>  
</table>  
<br/><a href="adduserform.jsp">Add New User</a>  
</body>  
</html>

Insert row into Mariadb table using default constructor:-

[tomcat@fedora33server Newstuff]$ cat adduserform.jsp
<!DOCTYPE html>  
<html>  
<head>  
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">  
<title>Add User Form</title>  
</head>  
<body bgcolor="C0C0C0">  
<jsp:include page="userform.html"></jsp:include>  
</body>  
</html>  

[tomcat@fedora33server Newstuff]$ cat userform.html
<a href="viewusers.jsp">View All Records</a><br/>  
<h1>Add New User</h1>  
<form action="adduser.jsp" method="post">  
<table>  
<tr><td>Name:</td><td><input type="text" name="name"/></td></tr>  
<tr><td>Password:</td><td>  
<input type="password" name="password"/></td></tr>  
<tr><td>Email:</td><td><input type="email" name="email"/></td></tr>  
<tr><td>Sex:</td><td>  
<input type="radio" name="sex" value="male"/>Male   
<input type="radio" name="sex" value="female"/>Female </td></tr>  
<tr><td>Country:</td><td>  
<select name="country" style="width:155px">  
<option>France</option>  
<option>USA</option>  
<option>UK</option>  
<option>Germany</option>  
<option>Other</option>  
</select>  
</td></tr>  
<tr><td colspan="2"><input type="submit" value="Add User"/></td></tr>  
</table>  
</form>  

[tomcat@fedora33server Newstuff]$ cat adduser.jsp
<%@page import="com.javatpoint.dao.UserDao"%>  
<jsp:useBean id="u" class="com.javatpoint.bean.User"></jsp:useBean>  
<jsp:setProperty property="*" name="u"/>  
<%  
int i=UserDao.save(u);  
if(i>0){  
response.sendRedirect("adduser-success.jsp");  
}else{  
response.sendRedirect("adduser-error.jsp");  
}  
%> 

Mariadb's database and table are declared as follows :-

create database test ;

use test ;
 
 create table register (
 id  int NOT NULL AUTO_INCREMENT,
  name varchar(30) NOT NULL,
  password varchar(30) NOT NULL,
  email  varchar(30) NOT NULL,
  sex varchar(10) NOT NULL,
  country varchar(30) NOT NULL ,
  PRIMARY KEY (id) ) ;

No changes have been done  to JSP's from original source.

 





















































































Wednesday, February 3, 2021

Recursion in Python. Having fun writing code to help out unhappy kids

The only purpose of python coding below is to prevent kids from straight forward calculations, which actually are boring rather then difficult. In doing so I intend to teach my students pretty old principle "Just think first"

"Problem" itself :- 

Algorithm for calculating the value of the function F (n), where n is a natural number,

is given by the following relations:

F (n) = 1 for n = 1;

F (n) = n + F (n - 1), if n is even,

F (n) = 2 × F (n - 2) if n> 1 and n is odd.

What is the value of the function F (46)?


Just notice that number 46 could be easily replaced by 56 or 76






















Another samples :-

The algorithm for calculating the function F (n) is given by the following relations:
F (n) = n for n≤3;
F (n) = n ∗ n ∗ n + F (n – 1) if n > 3 and gives remainder 0 when divided by 3
F (n) = 4 + F (n // 3) if n > 3 and gives remainder 1 when divided by 3
F (n) = n ∗ n + F (n – 2) if n  > 3 and gives remainder 2 when divided by 3
Here // stands for integer division. 
Output an answer as binary value of F(100).



Algorithm for calculating functions F (n), where n is a natural number, given;by the following ratios:

F (n) = n - 1 for n < 4 ,

F (n) = n + 2 * F (n - 1) when n  > 3 and a multiple of 3 ,

F (n) = F (n - 2) + F (n - 3) when n > 3 and not a multiple of 3 .

What is the sum of the digits of the value of the function F (65)?



The algorithm for calculating the function F (n) is given by the following relations:

F (n) = n for n≤3;
F (n) = n ∗ n ∗ n + F (n – 1) if n > 3 and gives remainder 0 when divided by 3
F (n) = 4 + F (n // 3) if n > 3 and gives remainder 1 when divided by 3
F (n) = n ∗ n + F (n – 2) if n  > 3 and gives remainder 2 when divided by 3
Here // stands for integer division.
Determine the number of natural values n from the segment [1; 1000], for which the sum of digits the F (n) value is 53.