Showing posts sorted by relevance for query R language. Sort by date Show all posts
Showing posts sorted by relevance for query R language. Sort by date Show all posts

Sunday, September 13, 2015

What is a good way to learn R language?

There are many ways one can learn as Internet provides a whole lot of options from free sites to sites where you can
pay and register to learn.
R language has come to focus because it can be used to carry out Data Analysis as it has strong statistical basis.
Using R one can work with graphics as well. This means the analyzed data can be pictorially displayed in terms of
graphs and charts for data visualization.
Microsoft SQL Server 2016 will have built-in support for R language and it goes without saying that learning R
programming has great value.
One way, I can think of,  is to download the R programming interface on to your computer and start from there.

Downloading and Installing R language executable for Windows 7?

While it is available for Unix/Linux, it is also available for Windows (both x32bit and x64bit). You can download the latest version here (R-3.2.2-win.exe) . The version you will be downloading is R 3.2.2 for Windows (32/64) 62MB. A small file for the complicated things it does.

Here are some download/install screen shots for those who like:

If you are installing for the first time choose that option after you access the download link above.

Rforwindows01
 
The set up for R on Windows needs to be selected:


Rforwindows04

Complete the Installation wizard screens and you are done.

You can invoke it from the desktop shortcut as shown here and the R-GUI will be displayed as shown:

Rforwindows08

It can also be invoked from Command Line and it will be easier if add the directory of the R installation (C:\Program Files\R\R-3.2.2\bin;) to the Path in your environment variables set up.

After adding the above directory to the Path in environmental variables, you can launch R as shown here:

Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.
C:\Users\mysorian>R
R version 3.2.2 (2015-08-14) -- "Fire Safety"
Copyright (C) 2015 The R Foundation for Statistical Computing
Platform: x86_64-w64-mingw32/x64 (64-bit)

R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type 'license()' or 'licence()' for distribution details.

  Natural language support but running in an English locale
R is a collaborative project with many contributors.
Type 'contributors()' for more information and
'citation()' on how to cite R or R packages in publications.

Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.

> q()
Save workspace image? [y/n/c]: n

Now you are ready to rock and roll. You could also use the GUI shown previously (previous image).

If you enter help.start() either from GUI as shown here.

R_helpstart.png

You can also do this from command line. Note that as shown above help.Start() would produce an error as R language happens to be case sensitive, it has to be help.start().

In both cases help appears in a browser window hosted on your local IIS as shown.


This is all for today. Visit here again for more on R programming.



 

Saturday, December 30, 2017

Show me how to write R Code for Hello World web page?

 R language is open source with a huge number of developers. It has a great arsenal of great stuff already accomplished. It is a language that you should get exposed to yourself. You just install R Gui and you are ready.


Shiny is an enterprise-grade web application framework targeted for those who want to develop with R using the familiar HTML5, CSS and JavaScript. Using R you can turn terrific analytic solutions you have developed/developing into interactive web applications.

Go to this site (https://shiny.rstudio.com/) directly and learn more.

 
Rshiny-00

If you have R Studio you have Shiny because Shiny is a package that you can download.

In this first part we only talk about the very basics.

I assume you have read my previous hands-on R examples in my blogs.


Here I just show a very basic (aka Hello World) example of creating content for a web page using R GUI. More will come later in my blogs.

Launch R Gui as shown and provide reference to the shiny "library" as shown by typing in the three lines of code (The four lines of code in red).


 HelloWorld_00

When you hit Enter after the third line where you define the shiny app, a browser window will open as shown displaying the apps output as shown at a port of the local host.



HelloWorld_01

You also get a response (the last line) in the R GUI as shown.




HelloWorld_02
That is all there is to create a content.

The ui summarizes your user interface, the server is something like a web server and shinyApp is your web response. No fuss, very simple.

Saturday, June 11, 2016

What R language items are installed when you install SQL Server 2016?

R langugage support featured in SQL Server the  first time in SQL Server 2016. There were items  at isntallation time that explicitly shows the items.


Ritems_00 in help

The following items (RServer and R Services) were installed according to the above choice.

When you install SQL Server 2016 Developer you will be able to use the following:



SQL@2K16_defaultInstall


Also in the SQL Server Installation Center you can install a stand-alone Microsoft R Server by clicking the link in the installation center, if for some reason you do not find the Microsoft R Server in your search.

RServer_00

After installing SQL Server 2016 Developer edition you should be able to find the R Server related folders/files here:

R_Folder

R is Power full.
 
R is supposed to be the most powerful language when it comes to statistical processing of a large amount of data; machine learning and graphics. It is open, that means world is the player. Microsoft got into R for these strengths but still there were challenges when it comes to volume of data and deployment scenarios. The open software was further tuned for SQL Server to include in Microsoft R Server.

The Microsoft R product consists of the following:
  • Microsoft R Server
  • Microsoft R Client
  • Microsoft R Open
  • SQL Server R Services
You should jump into R if you are going to work with databases and specially analytics. Analytics is the future! believe me.

Monday, February 20, 2017

What is Shiny?

You started learning the Statistics/Analysis focused language R and you want to do more. You want to build apps with it and host them on the Internet. All this is possible using Shiny.

It is an enterprise-grade web application framework targeted for those who want to develop with R using the familiar HTML5, CSS and JavaScript. Using R you can turn terrific analytic solutions you have developed/developing into interactive web applications.

Go to this site (https://shiny.rstudio.com/) directly and learn more.

 
Rshiny-00

If you have R Studio you have Shiny because Shiny is a package that you can download.

In this first part we only talk about the very basics.

I assume you have read my previous hands-on R examples in my blogs.

http://hodentekhelp.blogspot.com/2015/09/what-is-good-way-to-learn-r-language.html
http://hodentekhelp.blogspot.com/search?q=R+language

Here I just show a very basic (aka Hello World) example of creating content for a web page using R GUI. More will come later in my blogs.

Launch R Gui as shown and provide reference to the shiny "library" as shown by typing in the three lines of code (The four lines of code in red).


 HelloWorld_00

<-fluidpage br="" ello="" world=""><-function br="" input="" output="">When you hit Enter after the third line where you define the shiny app, a browser window will open as shown displaying the apps output as shown at a port of the local host.
 


<-fluidpage br="" ello="" world=""><-function br="" input="" output="">HelloWorld_01

You also get a response (the last line) in the R GUI as shown.
<-fluidpage br="" ello="" world=""><-function br="" input="" output="">
<-fluidpage br="" ello="" world=""><-function br="" input="" output="">
<-fluidpage br="" ello="" world=""><-function br="" input="" output="">
<-fluidpage br="" ello="" world=""><-function br="" input="" output="">
HelloWorld_02
<-fluidpage br="" ello="" world=""><-function br="" input="" output="">That is all there is to create a content.
<-fluidpage br="" ello="" world=""><-function br="" input="" output="">
The ui summarizes your user interface, the server is something like a web serve rand shinyApp is your web response. No fuss, very simple.

Tuesday, September 22, 2015

How are numerical quantites handled in R language?

Numeric is the basic data type to represent numbers n the R language. Decimal is the  default computational data type in R.

You assign a decimal value using the following:
> x=3.1429  Assigns a value 3.1429 to a variable x

> x               Print to screen the value of x

[1] 3.1429     Value is printed
>
Arithmetic Operations:

> 2*x          -What is 2 times x?
[1] 6.2858

> 2+x        -What is 2 added to x?
[1] 5.1429

> x-1         -What is 1 taken away from x?
[1] 2.1429

> x/2         -What is x divided into two?
[1] 1.57145

> x=3.1419
> x^2            -What is x raised to power 2
[1] 9.871536

> x^x            -What is x raised to itself
[1] 36.4862
>
>
> sqrt (x^x)  -Square root of x raised to itself
[1] 6.040381
This is a screen shot of how you use the GUI to carry out the above computations:

RGUI.png

So how would you assign an integer value to a varible y?

You do so by using the integer function as shown in the following:

> y=as.integer(6)    Assign an integer value of 6 to y
> y                          Print y to screen
[1] 6

> class(y)                Print the class name for y
[1] "integer"

> is.integer(y)          test whether y is an integer
[1] TRUE
>
Another way to declare a integer constant is to use an L after the integer you want to declare:

> z=4L       -using L after the number declares it as an integer

> class(z)   -test the data type of z
[1] "integer"

You can force a decimal value to an integer but cannot force a string to an integer!

> y=as.integer("John")  Trying to make "John" to an integer
Warning message:
NAs introduced by coercion   Message from R. R does not like it.
>
R can handle all the mathematical functions you have used in your highschool maths like trgnometric, logarthmic fucntions as well.

Find more about numeric constants in your library that gets  installed with R installation by issuing the command in R as shown here:
>NumericConstants

Which opens up (https://127.0.0.1:xxx/library/base/html/NumericConstatns.html

Can R handle complex numbers?

Yes it can handle complex numbers. Complex numbers can have real and imaginary parts like in,
1+2i, where 1 is the real part and 2i is imaginary

Here is how it is used

> x=1+2i  -x is a complex number with real and imaginary parts (it hasto be 2i and not i2)
> y=1-2i  -y is another complex number with real and imaginary parts

> x*y        -What happens when you multiply them?
[1] 5+0i    -you get a real number (real part is 5 and imaginary component is zero
>

Monday, October 5, 2015

How do you import data in an Excel spreadsheet into R?

MS Excel is an excellent data cruncher which also has statistics related tools to process data in the sheets. R language has package can do staitstical processing of data. Once the data is processed it can be exported so as to create reports. This import and export can be frustrating in some cases taking more time than the statistical processing. R language is language of choice for statistical processing but for not for large scale data.

The easiest type of data that can be imported is the data on a text file. Text file based data is for small and medium amount of data.
I will describe three methods of importing data from a Excel spreadsheet.

First method:
Let us take an example of data on a Excel spreadsheet as shown here:


ExcelOri

Save it as text file as shown in a previous post.

Launch R and in the prompt type as shown:
Enter the location of your .CSV file as shown and clilc Enter


You get an error:
Error: '\U' used without hex digits in character string starting ""C:\U"

We need to change the slash character as shown. Click Enter
Now you get the second error which shows all the needed attributes for calling reading a text file:
Error in scan(file, what, nmax, sep, dec, quote, skip, nlines, na.strings,  :
  line 2 did not have 3 elements


Just like Read.table(), Scan() is another function. In fact Read.table() calls Scan() to do the job. The sep in the list refers to what kind of a separator was used. In the .CSV file it is a comma.

Modify the statement to indicate that the separator is a comma and click enter.
Now the result is displayed. Row numbers and Column heading are added.

Use sep = " "  spaces or newlines
Use sep ="\t" for tab

Second method:
 
Open the Excel file shown at the top and copy the column heading and the data as shown:


R_clip
The contents are now in the "Clipboard".

Now in R enter the code as shown. After the error modify the separator (tab instead of comma)
-----------
> mydat <-read .table="" br="" file="clipboard" sep=",">> mydat
                             V1
1 First Name\tLast Name\tAGE\tRent
2         Chris \tLanger\t40\t2500
3          Jean\tSimmons\t80\t1200
4          Tom \tHiggins\t35\t4000
> mydat <-read .table="" br="" file="clipboard" sep="\t">> mydat
          V1        V2  V3   V4
1 First Name Last Name AGE Rent
2     Chris     Langer  40 2500
3       Jean   Simmons  80 1200
4       Tom    Higgins  35 4000
>

-------------------------------
Third method:

You can also use a statement like the following to display the contents of a .CSV file:
> read.csv("C:/Users/mysorian/Desktop/R_Related/names.csv")
  First.Name Last.Name AGE Rent
1     Chris     Langer  40 2500
2       Jean   Simmons  80 1200
3       Tom    Higgins  35 4000
>
=============================

Tuesday, March 28, 2017

Are there tools to look at financial information of the stock market in R?

I read a very illuminating article on R-Bloggers which was originally published on R-Curtiss Miller's Personal Website (https://ntguardian.wordpress.com/2017/03/27/introduction-stock-market-data-r-1/).

Ever since Microsoft SQL Server began supporting R in its 2016 version, I got interested in R language. It is extremely rich with wide applicability from Astronomy(http://www.astro.umd.edu/~harris/r/index.html) to Zoology(https://www.zoology.ubc.ca/~schluter/R/data/) and everything in between.

Financial information from Yahoo as the source, the packgae 'quantmod' brings with it most of the useful financial information about stocks. quantmod gets data from Yahoo Finance and Google Finance plus from other sources.

In order to work with financial data you should download the package which can done as shown:
------------
> # Get quantmod
> if (!require("quantmod")) {
+     install.packages("quantmod")
+     library(quantmod)
+ }
Loading required package: quantmod
Installing package into ‘C:/Users/Jayaram/Documents/R/win-library/3.2’
(as ‘lib’ is unspecified)
--- Please select a CRAN mirror for use in this session ---
also installing the dependencies ‘xts’, ‘zoo’, ‘TTR’
[ I chose the CRAN site in California ]
trying URL 'https://cran.cnr.berkeley.edu/bin/windows/contrib/3.2/xts_0.9-7.zip'
Content type 'application/zip' length 662188 bytes (646 KB)
downloaded 646 KB

trying URL 'https://cran.cnr.berkeley.edu/bin/windows/contrib/3.2/zoo_1.7-14.zip'
Content type 'application/zip' length 905140 bytes (883 KB)
downloaded 883 KB

trying URL 'https://cran.cnr.berkeley.edu/bin/windows/contrib/3.2/TTR_0.23-1.zip'
Content type 'application/zip' length 432456 bytes (422 KB)
downloaded 422 KB

trying URL 'https://cran.cnr.berkeley.edu/bin/windows/contrib/3.2/quantmod_0.4-7.zip'
Content type 'application/zip' length 473601 bytes (462 KB)
downloaded 462 KB

package ‘xts’ successfully unpacked and MD5 sums checked
package ‘zoo’ successfully unpacked and MD5 sums checked
package ‘TTR’ successfully unpacked and MD5 sums checked
package ‘quantmod’ successfully unpacked and MD5 sums checked

The downloaded binary packages are in
        C:\Users\Jayaram\AppData\Local\Temp\RtmpOIHqF6\downloaded_packages
Loading required package: xts
Loading required package: zoo

Attaching package: ‘zoo’

The following objects are masked from ‘package:base’:

    as.Date, as.Date.numeric

Loading required package: TTR
Version 0.4-0 included new data defaults. See ?getSymbols.
Warning messages:
1: In library(package, lib.loc = lib.loc, character.only = TRUE, logical.return = TRUE,  :
  there is no package called ‘quantmod’
2: package ‘quantmod’ was built under R version 3.2.5
3: package ‘xts’ was built under R version 3.2.5
4: package ‘zoo’ was built under R version 3.2.5
5: package ‘TTR’ was built under R version 3.2.5
---------------
Once it is installed. You can set up start and end dates variables for viewing your stocks like in:
start<- as.date="" br="">end <- as.date="" br="">
With these defined, you can get the Apple's stock price using its ticker symbol AAPL using the functions in the package as shown obtaining data from the Yahoo source.
> getSymbols("AAPL", src="yahoo", from=start, to=end)
To view the data just run the statement
head(AAPL)

Sunday, July 24, 2016

What is Microsoft R Open and how do you get it?

Are you interested in doing statistical analysis of data on a SQL Server? If you say yes, you need to use the most developed statistical ananlysis language R to go with it.

Microsoft R Open is the enhanced distribution of R from Microsoft. It is complete and open source platform. The version R Open 3.3.0 is 100% based on the R-3.3.0 statistical language (R Foundation for Statistical Computing). It is available for 64-bit acrchitecture only.

Its features are:
  • Improved performance
  • Reproducibility
  • Support for Windows and Linux-based Platforms
You may download it from here: https://mran.revolutionanalytics.com/download/

However, if you have already installed SQL Server 2016 and you want to use the R 3.3.0 features then
https://mran.revolutionanalytics.com/download/mro-for-mrs/

Note that R Open is automatically installed for you during installation of R Server.

Tuesday, October 6, 2015

How do you access data using ODBC data connectivity in R?

R language is well suited for statistics and graphics. R is also good at handling data, perhaps not in large-scale. In order to connect to an ODBC source, it needs an ODBC connector which is found in a library called RODBC.

When you install a number of packages are available out of the box shown here:
 

Installed Packages.png

However you may not find the RODBC in the list. You need to install this library.
You can find RODBC library download here for WIndows.
https://cran.r-project.org/web/packages/RODBC/index.html

You will be downloading a zip file named RODBC_1.3-12.zip

You can download it to a location of your choice but move this file to the( library folder) in the folder created by the R installation.
 

The zip file from the download location(desktop) was moved to the folder C:\Program Files\R\R-3.2.2\library.

librarywithRODBC

 

 
Now if you bring up the installed packages from R-GUI you will see RODBC as shown.

LoadPackages2

Now you are ready to use the RODBC library in working with R.
In the RGUI(64-bit) just type library (RODBC) at the prompt as shown. You get another prompt but nothing else.
--------
> library(RODBC)
>
---------
For help with RODBC you can type the following at R prompt:
----------
>help(package=RODBC)
---------
This will open up the help file in HTML at : http://127.0.0.1:27629/library/RODBC/html/00Index.html as shown:


RODBCDoc.png

Now you can use this help file to explore RODBC further.

There are two groups of functions in RODBC, The internet odbc* commands implement low-level access to ODBC functions and the sql* functions operate at a higher level to read, save, copy etc. You can connect to hosts or DSNs.

Happy data hunting!

Thursday, August 9, 2018

What programming language do you want to learn?


Of course, you want the most popular and the most valuable.

According to the Institute of Electrical and Electronics Engineers (IEEE) , it is Python, the clear winner.

Here are the top ten in its rankings:


Why Python?

The answer appears to the fact that it iss now used for embedded applications and because it has beefed up its repertoire related to AI and Machine learning. It is for this reason R language (somewhat specialized) has seen some decline.

Microsoft C# is still standing there at 5 and probably its place will be solid 5 for all types of programming - Web, desktop and Mobile. SQL is also there but does not show up as top 10 which is understandable given its area of usage.

Well here is the first 20. Find if your favorite is here



Well, you may want to know the basis for the ranking. You can get to know here.

You can find a lot of posts on R and Python on this site.



You can find a lot of Python and R posts in my blogs.

Tuesday, September 22, 2015

How do I know a file exists (in R programming)?

If you access the help file on your computer on which you installed R then you can find the information at this link here:

http://127.0.0.1:12506/library/base/html/list.files.html

File information can be found here:
http://127.0.0.1:12506/library/base/html/file.info.html

I had a file names.csv (I had mistaken about its extension being .CSV, it was actually names.xls.csv) which I wanted to know if it exists. Then I used the following commands:

> file.exists("C:/")                Does C:\ folder exists (you should not use the backward slash)?
[1] TRUE

> file.exists("C:/eula.3082")  I know eula.3082 exists but... The reason is perhaps permissions
[1] FALSE

> file.exists("C:/inetpub")     Does C:\inetpub exist?
[1] TRUE

> file.exists("C:/USERS")       Does C:\Users exist?
[1] TRUE

> file.exists("C:/USERS/names.csv")  Does C:\Users\names.csv exist?
[1] FALSE
oops!
> file.exists("C:/USERS/JFA.jpg")       Does C\USERS/JFA.jpg exist?
[1] TRUE

I created a CSV file in EXCEL and made sure it was saved as a CSV by opening it in Notepad.

> file.exists("C:/USERS/mysorian/Documents/names2.csv")  Does C:\USERS\names2.csv?
[1] TRUE

> file.info("C:/USERS/mysorian/Documents/names2.csv")   Provide info on the file C:/USERS/mysorian/Documents/names2.csv
                                       size isdir mode               mtime               ctime
C:/USERS/mysorian/Documents/names2.csv   98 FALSE  666 2015-09-22 16:42:20 2015-09-22 16:42:20
                                                     atime exe
C:/USERS/mysorian/Documents/names2.csv 2015-09-22 16:42:20  no

Listing files in a directory

Also,  if you know the directory you can list all the files as in the following:
--------
Error: could not find function "List.files"  -- R language is case sensitive
> list.files("C:/USERS/mysorian/documents") List the files in the directory in quotes

  [1] "__VSDeploymentFailure__.txt"                     
  [2] "~$ADI_gREETINGS.dotx"                            
  [3] "~$TrustRelated.xlsx"                             
  [4] "04092013 ConsolidatedDetails.xls"                
  [5] "3rd beneficiary details_sept15_2014.dotx"        
  [6] "4mysorian.xlsx"                                  
  [7] "Advanced SQL TOP.dot"                            
  [8] "AdvisoryMichiko.xlsx"                            
  [9] "AdvWksCustomer.rdl"                              
 [10] "Allow connections to this computer.pdf"          
 [11] "Ameritrade2014.csv"                              
 [12] "ApnStub.exe"                                     
 [13] "ArcGIS Explorer"  

Friday, May 30, 2025

Ready to Code Your Own Sudoku Solver?

 

Even if you've never played, you've likely seen a Sudoku puzzle. At its core, Sudoku is a logic-based number placement puzzle set on a 9x9 grid. The grid is further divided into nine 3x3 smaller squares. To solve it, you simply need to place numbers from 1 to 9 into the empty cells. The catch? Each number can only appear once in each row, once in each column, and once in each of the nine 3x3 blocks. It's an addictive challenge that relies solely on deduction. For an in-depth look at its origins and variations, check out its Wikipedia page. 

Now that you understand the game, this post will take you behind the scenes. We'll provide the complete Python code for building your own Sudoku puzzle generator and solver, followed by a step-by-step annotation of how it all works.

This code was run on PyCharm and there are a number of posts in this blog for you to get acquainted. Here is the complete code that you could copy and paste.

from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.properties import ListProperty, ObjectProperty, StringProperty
from kivy.graphics import Color, Line
from kivy.lang import Builder
import random
import time


class Sudoku(object):
def __init__(self, size=9):
self.size = size
self.grid = [[0 for _ in range(size)] for _ in range(size)]
self.original_grid = None
self.original_solution = None

def generate_puzzle(self, difficulty):
self._solve()
self.original_solution = [row[:] for row in self.grid]

squares_to_remove = 0
if difficulty == "easy":
squares_to_remove = 45
elif difficulty == "medium":
squares_to_remove = 55
elif difficulty == "hard":
squares_to_remove = 65

self.grid = [row[:] for row in self.original_solution]
cells = list((r, c) for r in range(self.size) for c in range(self.size))
random.shuffle(cells)

removed_count = 0
for r, c in cells:
if self.grid[r][c] != 0:
temp = self.grid[r][c]
self.grid[r][c] = 0
if not self._has_unique_solution(self.grid):
self.grid[r][c] = temp
else:
removed_count += 1
if removed_count >= squares_to_remove:
break
self.original_grid = [row[:] for row in self.grid] # Corrected line

def _solve(self):
find = self._find_empty()
if not find:
return True
else:
row, col = find

for num in range(1, self.size + 1):
if self._is_valid(row, col, num):
self.grid[row][col] = num
if self._solve():
return True
self.grid[row][col] = 0
return False

def _find_empty(self):
for i in range(self.size):
for j in range(self.size):
if self.grid[i][j] == 0:
return i, j
return None

def _is_valid(self, row, col, num):
if num in self.grid[row]:
return False
if num in [self.grid[i][col] for i in range(self.size)]:
return False
start_row, start_col = 3 * (row // 3), 3 * (col // 3)
for i in range(3):
for j in range(3):
if self.grid[start_row + i][start_col + j] == num:
return False
return True

def _find_all_solutions(self, current_grid):
solutions = []

def solve_recursive(grid, solutions):
find = self._find_empty_in_grid(grid)
if not find:
solutions.append([row[:] for row in grid])
return
row, col = find
for num in range(1, self.size + 1):
if self._is_valid_in_grid(grid, row, col, num):
grid[row][col] = num
solve_recursive(grid, solutions)
if len(solutions) > 1:
return
grid[row][col] = 0

solve_recursive(current_grid, solutions)
return solutions

def _has_unique_solution(self, puzzle_grid):
solutions = self._find_all_solutions([row[:] for row in puzzle_grid])
return len(solutions) == 1

def _find_empty_in_grid(self, grid):
size = len(grid)
for i in range(size):
for j in range(size):
if grid[i][j] == 0:
return i, j
return None

def _is_valid_in_grid(self, grid, row, col, num):
size = len(grid)
if num in grid[row]:
return False
if num in [grid[i][col] for i in range(size)]:
return False
start_row, start_col = 3 * (row // 3), 3 * (col // 3)
for i in range(3):
for j in range(3):
if grid[start_row + i][start_col + j] == num:
return False
return True

def is_complete(self):
for row in self.grid:
if 0 in row or len(set(row)) != self.size:
return False
for col in range(self.size):
if len(set(self.grid[i][col] for i in range(self.size))) != self.size:
return False
for i in range(0, self.size, 3):
for j in range(0, self.size, 3):
block = [self.grid[row][col] for row in range(i, i + 3) for col in range(j, j + 3)]
if len(set(block)) != 9:
return False
return True


class SudokuCell(TextInput):
def __init__(self, **kwargs):
super(SudokuCell, self).__init__(**kwargs)
self.multiline = False
self.input_filter = 'int'
self.halign = 'center'
self.valign = 'middle'
self.font_size = 40
self.foreground_color = (0, 0, 0, 1)
self.bind(focus=self.on_focus) # Added self.on_focus

def on_text(self, instance, value):
if len(value) > 1:
self.text = value[-1]
if value and not (1 <= int(value) <= 9):
self.text = ""

def on_focus(self, instance, focused): # Added this method
if self.parent:
self.parent.on_cell_focus(self, focused)


class SudokuBlock(GridLayout):
"""
Represents a 3x3 sub-grid within the Sudoku grid.
"""
block_row = ObjectProperty(None) # 0, 1, or 2
block_col = ObjectProperty(None) # 0, 1, or 2
cells = ListProperty([])

def __init__(self, **kwargs):
super().__init__(cols=3, rows=3, **kwargs)
self.block_row = kwargs.get('block_row', 0) # Get block row and col
self.block_col = kwargs.get('block_col', 0)
self.cells = []
for i in range(3):
for j in range(3):
cell = SudokuCell()
cell.row =
self.block_row * 3 + i
cell.col =
self.block_col * 3 + j
# cell.bind(focus=self.on_cell_focus) # Removed this line
self.add_widget(cell)
self.cells.append(cell)

def get_block_values(self):
"""Returns the values of the cells in this block."""
values = []
for cell in self.cells:
text = cell.text
if text.isdigit():
values.append(
int(text))
else:
values.append(
0)
return values

def set_block_values(self, values):
"""Sets the values of the cells in this block."""
if len(values) != 9:
raise ValueError("Must provide 9 values for a 3x3 block")
for i, cell in enumerate(self.cells):
cell.text =
str(values[i]) if values[i] != 0 else ""


class SudokuGrid(GridLayout):
grid_data = ListProperty([[
0 for _ in range(9)] for _ in range(9)])
selected_cell = ObjectProperty(
None)
blocks = ListProperty([])
block_line_color = ListProperty([
0, 0, 0, 1]) # Default to black

def __init__(self, **kwargs):
super().__init__(cols=3, rows=3, **kwargs) # 3x3 grid of blocks
self.blocks = []
self.block_line_color = kwargs.get('block_line_color', [0, 0, 0, 1])
for i in range(3):
block_row_list = []
for j in range(3):
block = SudokuBlock(
block_row=i, block_col=j)
self.add_widget(block)
block_row_list.append(block)
self.blocks.append(block_row_list)
self.bind(size=self.on_size, pos=self.on_size)
self.on_size()

def on_size(self, *args):
self.draw_grid()

def on_grid_data(self, instance, value):
for i in range(9):
for j in range(9):
block_row = i //
3
block_col = j // 3
cell_index_in_block = (i % 3) * 3 + (j % 3)
self.blocks[block_row][block_col].cells[cell_index_in_block].text = str(value[i][j]) if value[i][
j] != 0 else ""
j] != 0 else ""

def get_grid_values(self):
values = [[
0 for _ in range(9)] for _ in range(9)]
for i in range(9):
for j in range(9):
block_row = i //
3
block_col = j // 3
cell_index_in_block = (i % 3) * 3 + (j % 3)
text =
self.blocks[block_row][block_col].cells[cell_index_in_block].text
if text.isdigit():
values[i][j] =
int(text)
else:
values[i][j] =
0
return values

def on_cell_focus(self, instance, focused):
"""Handles cell focus and stores the selected cell"""
if focused:
self.selected_cell = (instance.row, instance.col)
else:
if self.selected_cell == (instance.row, instance.col):
self.selected_cell = None

def draw_grid(self, *args):
self.canvas.before.clear()
size =
min(self.width, self.height)
block_size = size /
3
grid_x, grid_y = self.pos
with self.canvas.before:
Color(*
self.block_line_color) # Use the block_line_color
for i in range(4):
line_width =
3
x1 = grid_x + i * block_size
y1 = grid_y
x2 = grid_x + i * block_size
y2 = grid_y + size
Line(
points=[x1, y1, x2, y2], width=line_width)

x1 = grid_x
y1 = grid_y + i * block_size
x2 = grid_x + size
y2 = grid_y + i * block_size
Line(
points=[x1, y1, x2, y2], width=line_width)


class SudokuCreatorApp(App):
grid_widget = ObjectProperty(
None)
message = StringProperty(
"")

def build(self):
main_layout = BoxLayout(
orientation='vertical')
# Pass the color to the grid widget
self.grid_widget = SudokuGrid(block_line_color=[1, 0, 0, 1])
# Example: Red color
main_layout.add_widget(self.grid_widget)

button_layout = BoxLayout(size_hint_y=None, height=50)
generate_easy_button = Button(text="Generate Easy", on_press=lambda btn: self.generate_puzzle("easy"))
generate_medium_button = Button(text="Generate Medium", on_press=lambda btn: self.generate_puzzle("medium"))
generate_hard_button = Button(text="Generate Hard", on_press=lambda btn: self.generate_puzzle("hard"))
check_button = Button(text="Check", on_press=self.check_puzzle)

solve_button = Button(
text="Solve", on_press=self.solve_puzzle)
clear_button = Button(
text="Clear", on_press=self.clear_grid)

button_layout.add_widget(generate_easy_button)
button_layout.add_widget(generate_medium_button)
button_layout.add_widget(generate_hard_button)
button_layout.add_widget(check_button)
button_layout.add_widget(solve_button)
button_layout.add_widget(clear_button)

message_label = Label(
text=self.message, size_hint_y=None, height=30)

main_layout.add_widget(button_layout)
main_layout.add_widget(message_label)

return main_layout

def generate_puzzle(self, difficulty):
sudoku = Sudoku()
sudoku.generate_puzzle(difficulty)
self.grid_widget.grid_data = sudoku.grid
self.message = f"Generated {difficulty} puzzle."

def check_puzzle(self, event):
current_grid =
self.grid_widget.get_grid_values()
sudoku = Sudoku()
sudoku.grid = current_grid
if sudoku.is_complete():
self.message = "Sudoku is complete and valid!"
else:
self.message = "Sudoku is not complete or contains errors."

def solve_puzzle(self, event):
current_grid =
self.grid_widget.get_grid_values()
sudoku = Sudoku()
sudoku.grid = [row[:]
for row in current_grid]
if sudoku._solve():
self.grid_widget.grid_data = sudoku.grid
self.message = "Puzzle solved!"
else:
self.message = "This puzzle has no solution."

def clear_grid(self, event):
self.grid_widget.grid_data = [[0 for _ in range(9)] for _ in range(9)]
self.message = "Grid cleared."


if __name__ == '__main__':
SudokuCreatorApp().run()

The code is long and should you be wanting some explanation, it is here:

You've created a fascinating Sudoku puzzle maker! Let's break down your code step-by-step to understand how each part contributes to the overall application.


1. Importing Libraries

At the beginning of your code, you import all the necessary modules:

  • Kivy Modules: These are the core components for building your graphical user interface (GUI).
    • kivy.app.App: The base class for all Kivy applications.
    • kivy.uix.gridlayout.GridLayout: Arranges widgets in a grid.
    • kivy.uix.boxlayout.BoxLayout: Arranges widgets in a box, either horizontally or vertically.
    • kivy.uix.button.Button: Creates interactive buttons.
    • kivy.uix.label.Label: Displays static text.
    • kivy.uix.textinput.TextInput: Allows users to input text (for the Sudoku cells).
    • kivy.properties.ListProperty, ObjectProperty, StringProperty: These are Kivy properties used for data binding and making attributes observable.
    • kivy.graphics.Color, kivy.graphics.Line: Used for drawing shapes and lines on the canvas, specifically for the Sudoku grid lines.
    • kivy.lang.Builder: Allows you to load Kivy language (KV) files, although you're not explicitly using a KV file in this specific code.
  • Standard Python Modules:
    • random: Used for generating random numbers, crucial for shuffling cells during puzzle generation.
    • time: Although imported, it's not explicitly used in the provided code snippet. It could be used for timing operations, if needed.

2. Sudoku Logic (Sudoku Class)

This class encapsulates all the backend logic for generating, solving, and validating Sudoku puzzles.

  • __init__(self, size=9):
    • Initializes a Sudoku object with a given size (defaulting to 9x9).
    • self.grid: Represents the current state of the Sudoku grid, initialized with zeros.
    • self.original_grid: Stores the puzzle as it was originally generated (with empty cells).
    • self.original_solution: Stores the complete, solved grid that was used to create the puzzle.
  • generate_puzzle(self, difficulty):
    • This is the heart of your puzzle creation.
    • It first calls self._solve() to create a completely filled (solved) Sudoku grid.
    • self.original_solution is then set to this newly solved grid.
    • Based on the difficulty ("easy", "medium", "hard"), it determines how many squares_to_remove (i.e., how many cells to clear) from the solved grid.
    • It shuffles a list of all cell coordinates (cells).
    • It then iterates through the shuffled cells:
      • It temporarily removes a number from a cell.
      • It calls self._has_unique_solution() to check if the puzzle still has only one solution after removing the number.
      • If it doesn't have a unique solution, the number is put back.
      • If it does have a unique solution, the removal is kept, and removed_count is incremented.
    • This process stops once enough squares have been removed for the chosen difficulty.
    • Finally, self.original_grid is set to the puzzle state after removing cells.
  • _solve(self):
    • This is a recursive backtracking algorithm to solve the Sudoku grid.
    • It finds the next empty cell using self._find_empty(). If no empty cells are found, the puzzle is solved, and it returns True.
    • For each number from 1 to 9, it checks if placing that number in the empty cell is _is_valid().
    • If valid, it places the number and recursively calls _solve() again.
    • If the recursive call returns True (meaning a solution was found), it propagates True back up.
    • If the recursive call returns False (meaning that number didn't lead to a solution), it backtracks by setting the cell back to 0.
  • _find_empty(self):
    • Iterates through the self.grid to find the first cell with a value of 0 (empty).
    • Returns the (row, col) of the empty cell or None if no empty cells are found.
  • _is_valid(self, row, col, num):
    • Checks if placing num at (row, col) is valid according to Sudoku rules.
    • It verifies:
      • No duplicate num in the row.
      • No duplicate num in the col.
      • No duplicate num in the 3x3 block that contains (row, col).
  • _find_all_solutions(self, current_grid):
    • This function is crucial for ensuring the generated puzzle has a unique solution.
    • It uses a nested solve_recursive helper function, similar to _solve, but designed to find all possible solutions.
    • It stops searching for solutions as soon as more than one solution is found to optimize performance (if len(solutions) > 1: return).
  • _has_unique_solution(self, puzzle_grid):
    • Takes a puzzle_grid (which might have empty cells).
    • Calls _find_all_solutions() on a copy of the puzzle_grid.
    • Returns True if len(solutions) is exactly 1, indicating a unique solution.
  • _find_empty_in_grid(self, grid):
    • Similar to _find_empty, but operates on an arbitrary grid passed as an argument.
  • _is_valid_in_grid(self, grid, row, col, num):
    • Similar to _is_valid, but operates on an arbitrary grid passed as an argument.
  • is_complete(self):
    • Checks if the current self.grid represents a complete and valid Sudoku solution.
    • It verifies:
      • No zeros (empty cells) in any row.
      • All rows contain unique numbers from 1 to 9.
      • All columns contain unique numbers from 1 to 9.
      • All 3x3 blocks contain unique numbers from 1 to 9.

3. Sudoku Cell (SudokuCell Class)

This Kivy widget represents a single input cell in the Sudoku grid.

  • __init__(self, **kwargs):
    • Initializes the TextInput properties:
      • multiline = False: Ensures only single-line input.
      • input_filter = 'int': Allows only integer input.
      • halign = 'center', valign = 'middle': Centers the text horizontally and vertically.
      • font_size = 40: Sets a large font size for readability.
      • foreground_color = (0, 0, 0, 1): Sets text color to black.
    • self.bind(focus=self.on_focus): Binds the on_focus event to the on_focus method, allowing the parent to track which cell is selected.
  • on_text(self, instance, value):
    • This method is called whenever the text in the TextInput changes.
    • It ensures that only the last character entered is kept if the user types multiple characters quickly.
    • It also clears the text if the entered value is not between 1 and 9.
  • on_focus(self, instance, focused):
    • This method is called when the cell gains or loses focus.
    • It calls the on_cell_focus method of its parent (the SudokuBlock), passing itself and the focus status.

4. Sudoku Block (SudokuBlock Class)

This Kivy widget represents a 3x3 sub-grid of Sudoku cells.

  • block_row, block_col: Kivy ObjectProperty to store the row and column index of the block within the larger 3x3 grid of blocks (e.g., top-left block is block_row=0, block_col=0).
  • cells: Kivy ListProperty to hold references to the nine SudokuCell instances within this block.
  • __init__(self, **kwargs):
    • Initializes a GridLayout with 3 columns and 3 rows.
    • It sets block_row and block_col from the passed keyword arguments.
    • It creates nine SudokuCell instances, assigns their absolute row and col values within the 9x9 grid, adds them to the block's layout, and stores them in self.cells.
  • get_block_values(self):
    • Retrieves the current numerical values (or 0 for empty) from all cells within this block and returns them as a list.
  • set_block_values(self, values):
    • Takes a list of 9 values and updates the text of the cells in the block accordingly. An empty string is used for 0 to represent an empty cell.

5. Sudoku Grid (SudokuGrid Class)

This Kivy widget represents the entire 9x9 Sudoku grid, composed of nine SudokuBlock instances.

  • grid_data: Kivy ListProperty to hold the 2D list representing the Sudoku puzzle data. When this property changes, the Kivy framework automatically updates the UI.
  • selected_cell: Kivy ObjectProperty to store the (row, col) of the currently focused cell.
  • blocks: Kivy ListProperty to hold a 2D list of SudokuBlock instances.
  • block_line_color: Kivy ListProperty to define the color of the major 3x3 block lines.
  • __init__(self, **kwargs):
    • Initializes as a GridLayout with 3 columns and 3 rows (to hold the SudokuBlock instances).
    • It creates nine SudokuBlock instances, arranging them in a 3x3 grid, and adds them as widgets.
    • It binds the size and pos properties to on_size to redraw grid lines when the widget is resized or moved.
  • on_size(self, *args):
    • Called when the size or position of the SudokuGrid changes.
    • It triggers self.draw_grid() to redraw the grid lines.
  • on_grid_data(self, instance, value):
    • This is a Kivy property observer method. Whenever grid_data is updated, this method is called.
    • It iterates through the 9x9 value (the new grid data) and updates the text property of the corresponding SudokuCell widgets.
  • get_grid_values(self):
    • Retrieves the current numerical values (or 0 for empty) from all SudokuCell widgets in the entire 9x9 grid and returns them as a 2D list.
  • on_cell_focus(self, instance, focused):
    • This method is called by a SudokuCell (via its SudokuBlock parent) when its focus state changes.
    • It updates self.selected_cell to the (row, col) of the focused cell or None if focus is lost.
  • draw_grid(self, *args):
    • This method uses Kivy's graphics instructions to draw the thick lines that delineate the 3x3 blocks.
    • It clears previous drawings (self.canvas.before.clear()).
    • It uses Color(*self.block_line_color) to set the drawing color.
    • It draws four vertical and four horizontal lines with a specified line_width to create the block boundaries.

6. Sudoku Application (SudokuCreatorApp Class)

This is the main Kivy application class that brings everything together.

  • grid_widget: Kivy ObjectProperty to hold the instance of SudokuGrid.
  • message: Kivy StringProperty to display messages to the user (e.g., "Generated Easy puzzle.").
  • build(self):
    • This method is called by Kivy to construct the application's user interface.
    • It sets up a BoxLayout as the main_layout with vertical orientation.
    • It creates an instance of SudokuGrid (self.grid_widget) and adds it to the main_layout, passing a red color for the block lines.
    • It creates another BoxLayout for the buttons (button_layout).
    • It creates "Generate Easy", "Generate Medium", "Generate Hard", "Check", "Solve", and "Clear" buttons, each with an on_press event handler that calls the appropriate method.
    • It adds a Label to display the message to the user.
    • Finally, it adds the button_layout and message_label to the main_layout.
    • It returns the main_layout which becomes the root widget of the application.
  • generate_puzzle(self, difficulty):
    • Creates a Sudoku object.
    • Calls the sudoku.generate_puzzle() method with the specified difficulty.
    • Updates self.grid_widget.grid_data with the generated puzzle, which automatically updates the UI.
    • Updates the self.message label.
  • check_puzzle(self, event):
    • Retrieves the current grid values from the grid_widget.
    • Creates a Sudoku object and sets its grid to the current user input.
    • Calls sudoku.is_complete() to check the validity and completeness.
    • Updates the self.message label based on the result.
  • solve_puzzle(self, event):
    • Retrieves the current grid values from the grid_widget.
    • Creates a Sudoku object and sets its grid.
    • Calls sudoku._solve() to find a solution.
    • If a solution is found, it updates self.grid_widget.grid_data with the solved grid.
    • Updates the self.message label.
  • clear_grid(self, event):
    • Resets self.grid_widget.grid_data to an empty 9x9 grid of zeros, effectively clearing the UI.
    • Updates the self.message label.

7. Application Entry Point (if __name__ == '__main__':)

This standard Python construct ensures that SudokuCreatorApp().run() is called only when the script is executed directly (not when it's imported as a module).

  • SudokuCreatorApp().run(): Starts the Kivy application event loop, displaying the GUI.

Running the code:

The result of running the code is an empty Sudoku grid with 4 buttons at the bottom with their functionality as their names.

When you click Generate Hard this is displayed. This populates only a couple of cells in the grid leading to a 'hard' to solve problem.

When you hit Solve in the generated grid, this will be displayed.

The game is still under testing and development.