Friday, June 23, 2017

Learning Aikido

Forty years ago I started learning Aikido. I practiced for a few months and passed a practical exam.

Last year, I started practicing again.

I was a beginner forty years ago, now I am less than a beginner.

Many resources are available on the web. Actually, too many are available. It is difficult to know where to start.

My current teacher is Rene Canabate, a 5th Dan, in the tradition of Morihei Ueshiba and Morihiro Saito.

Before class we stretch and then practice ukemi (falls), both forward and backward.

We begin each class with Tae No Henko. It can be done two ways, Ki No Nagare (flowing) or Awase (blending). Basic techniques are known as kihon.

The attacker is the uke and the defender is the nage, but most important is the relationship between uke and nage.

The uke attacks in several ways:
Morote Dori - two hand grab on one wrist
Shomen Uchi - overhead attack with edge of hand, like a sword attack
Munetski - punch to stomach

The nage has several responses to each attack:
Ikkyo
Nikyo
Sankyo
Yankyo
Gokyo
Kokyu Ho - breath technique
Kotegaeshi

Place the attack with the defense to name the relationship between the uke and nage:
Shomen Uchi Ikkyo
Shomen Uchi Omote Waza
Munetsuki Kotegaeshi 
Munetsuki Omote Waza

The above techniques are the requirements for the 6th kyu exam.

Sensei recommends that students practice 13 jo and 31 jo when not in class. He recommends the teachers Saito Sensei and Yamata.

Saito Sensei Videos

  1. Demonstration
  2. Japanese Promotion 
  3. Demonstration Iriminage
  4. Shomen Uchi
  5. Shomen Uchi Ikkyo with translation. 
  6. Shomen Uchi Sankyo
  7. Shomen Uchi (5th form)
  8. Shomen Uchi Shiho Nage
  9. 20 Jo Suburi
The Aikido glossary is helpful.

There are several Aikido schools that publish kyu requirements.

Aikikai

6th Kyu (Rokukyu) 20 practice days since beginning

  • Seiza (sitting) (a) Rei (bowing) (b) Rise from seiza
  • Shikko* (walking on knees) (mae and ushiro [forward and backward])
  • Hanmi (standing) (a) Migi Hanmi [right foot forward] (b) Hidari Hanmi [left foot forward]
  • Ukemi (rolls) (a) Ushiro ukemi (1) back fall (2) back roll* (b) Mae ukemi* (forward)
  • Kokyu undo (a) Funakogi undo (b) Ikkyo undo
  • Tai sabaki (body movement) (a) Tenkan (b) Irimi (c) Irimi tenkan (d) Tenshin
  • Hanmi (w/partner) (a) Ai hanmi (reversed) (b) Gyaku hanmi (mirrored)
  • Atemi (w/partner) (a) Tsuki (b) Yokomenuchi (c) Shomenuchi
  • Tai no henko (w/partner) as both uke and nage
  • Kokyudosa
* Instructor's option - depending on age and ability.

5th Kyu (Gokyu) 40 days after 6th Kyu, or 60 practice days

Monday, April 24, 2017

Trying Spring Framework

I am following the Spring tutorial at Tutorials Point. The site uses the Eclipse IDE. I am using NetBeans.

First, I created a Java Web application and selected the Spring MVC Framework. I confirmed the choice to include JSTL.

The Spring Framework JAR files and the JSTL JAR files are included.





















The web.xml file includes a reference to a local configuration file, a context listener for the Spring Framework, a servlet that implements the Spring dispatcher, a mapping that sends all .htm files to the dispatcher servlet, a session timeout of 30 minutes, and the name of the welcome file as redirect.jsp.






















The local configuration file is for beans that access a database.

An additional config file is added for the dispatcher servlet. It adds a mapping that refers the index page to the index controller. All other controllers will use the default mappings for Spring. The file also adds rules to transform names into pages. The last tag declares the index controller with its default view.


The redirect.jsp uses embedded java to call the sendRedirect method from the response. The welcome file is redirect.jsp.

The index.htm is significant, since the dispatcher servlet is mapping the file name index.htm to the index controller. If the name in the redirect.jsp is changed, then the key for the property for the indexController must be changed, too.

The index controller sets the view name as index, which forces the viewResolver to create the URL /WB-INF/jsp/index.jsp. Change the prefix to change the path to the JSPs, change the suffix to map to a different type of file.

Normal controllers will use a different naming convention to resolve views. The index controller is different. Any path can be used to map to the index controller, then the index controller will present its view.

Application Context


ApplicationContext is used to create beans. BeanFactory is used to create beans, too. BeanFactory is simpler and its functionality is included in ApplicationContext.

AbstractApplicationContext allows registration of a callback for the destruction of a bean. The destruction callback is not called if scope is set to prototype, since Spring does not manage the entire life cycle of the bean. The initialization and destruction callback names can be set in the opening beans tag in the Beans.xml file. This will set the name of the callbacks for all beans.

To see how the destroy method works, save the application context as an AbstractApplicationContext and call the registerShutdownHook() before closing the application.

BeanPostProcessor


Adding a bean that implements BeanPostProcessor allows for callbacks before and after initialization and destruction.

Injection with XML 

package com.tutorialspoint;

public class TextEditor {
   private SpellChecker spellChecker;
   private GrammarChecker grammarChecker;

    public TextEditor(GrammarChecker grammarChecker) {
        this.grammarChecker = grammarChecker;
    }
  
   // a setter method to inject the dependency.
   public void setSpellChecker(SpellChecker spellChecker) {
      System.out.println("Inside setSpellChecker." );
      this.spellChecker = spellChecker;
   }
  
   // a getter method to return spellChecker
   public SpellChecker getSpellChecker() {
      return spellChecker;
   }
  
   public void spellCheck() {
      spellChecker.checkSpelling();
   }
  
   public void grammarCheck() {
      grammarChecker.checkGrammar();
   }

}


Injection is handled with XML using property and constructor-arg. Use ref when a constructor arg is to a bean. For a setter/getter configuration, use a property that contains an inner bean.

 Autowiring

TutorialsPoint does not go into details about autowiring with XML. Here is another resource: Autowiring with XML

When wiring by name, use the name of the property in the bean, not the name of the variable that the property encapsulates. 

When wiring by type, only one bean of the given type can be a property in the enclosing bean.

Wiring by constructor is wiring byType, but limited to the constructor arguments, not the bean properties.

Annotations

To use annotations to configure Spring, modify the Beans.xml file:
  1. Add xmlns:context
  2. Add schema locations for context and spring-context
  3. Add a tag for context annotation-config
  4. Define the beans in Java, not in the XML.

Java Source Code

Use @Configuration to indicate that Spring should read this class for bean configuration.

Use @Bean on the constructor of the bean class. The annotation indicates that the return from the method is a bean to be registered with Spring. It is equivalent to a bean declaration in the Beans.xml file with the id and class attributes set. All other attributes will have default values. The id must be unique, but is not relevant to retrieving the bean. The class is used to retrieve the bean.

package com.tutorialspoint.annotation;

import org.springframework.context.annotation.*;

@Configuration
public class BeanConfig {
   
   @Bean
   public HelloWorld helloWorld(){
      return new HelloWorld();
   }
 
}


Injection


To implement Dependency Injection, create two methods that return the two classes and annotate them with @Bean. Call the constructor of the dependence class from the constructor of the dependent class.

package com.tutorialspoint.annotation.inject;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class TextEditorConfig {
   @Bean
   public TextEditor textEditor(){
      return new TextEditor( spellChecker() );
   }

   @Bean
   public SpellChecker spellChecker(){
      return new SpellChecker( );
   }
}


Import


The @Import annotation allows one config file to be used in another.

Lifecycle Callbacks


The @Bean annotation supports initMethod and destroyMethod attributes to register callback methods.

Bean Scope


Bean scope is controlled with the @Scope annotation. Use it along with the @Bean annotation. The annotation only has one attribute named value, so the attribute name may be omitted.

MVC


Use @Controller to indicate that a class is a controller.

Use @RequestMapping to set the URL to use to access the controller from the web. The annotation can be used multiple times. It can set the URL and also the method to use. The default parameter is the URL, the method is set with the method attribute.

The return value from the method is the name of the view to use to display the response.

package com.tutorialspoint.annotation.mvc;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
@RequestMapping("/hello")
public class HelloController {
   @RequestMapping(method = RequestMethod.GET)
   public String printHello(ModelMap model) {
      model.addAttribute("message", "Hello Spring MVC Framework!");
      return "hello";
   }
}


I was able to run all the examples.




Friday, November 18, 2016

Using Task Instead of BackgroundWorker to Update UI

The BackgroundWorker component allows for convenient access to a thread. It supports
  • Reporting Progress
  • Error Handling
  • Returning a Result
  • Cancellation
Updating the UI is a common action in GUI applications that perform a time consuming task. A background worker allows for a simple implementation of updating the UI thread and for the UI thread to control the background worker.

A Task is another way to implement a separate worker thread. I will demonstrate how to transform all the actions performed in a background worker into the context of a Task.

I have used the following resources for Tasks
The example I am using is from the Windows Forms 2.0 book by Chris Sells.

Calculate Pi Example

 The calculations for Pi are a mystery, but they take time.

    void CalcPi(int digits) {
      StringBuilder pi = new StringBuilder("3", digits + 2);

      if( digits > 0 ) {
        pi.Append(".");
     
        for( int i = 0; i < digits; i += 9 ) {
          int nineDigits = NineDigitsOfPi.StartingAt(i + 1);
          int digitCount = Math.Min(digits - i, 9);
          string ds = string.Format("{0:D9}", nineDigits);
          pi.Append(ds.Substring(0, digitCount));
      }
    }

A method encapsulates access to the UI.

    void ShowProgress(string pi, int totalDigits, int digitsSoFar) {
      // Display progress in UI
      this.resultsTextBox.Text = pi;
      this.calcToolStripProgressBar.Maximum = totalDigits;
      this.calcToolStripProgressBar.Value = digitsSoFar;
    }
 
A custom class is used to encapsulate data that is passed to the UI.

    class CalcPiUserState {
      public readonly string Pi;
      public readonly int TotalDigits;
      public readonly int DigitsSoFar;

      public CalcPiUserState(string pi, int totalDigits, int digitsSoFar) {
        this.Pi = pi;
        this.TotalDigits = totalDigits;
        this.DigitsSoFar = digitsSoFar;
      }
    }

Helper methods are used to control modify the appearance of the UI.

        void SetUIReady()
        {
            // Reset progress UI
            this.calcToolStripStatusLabel.Text = "Ready";
            this.calcToolStripProgressBar.Visible = false;
        }

        void SetUIBusy()
        {
            // Set calculating UI
            this.calcToolStripProgressBar.Visible = true;
            this.calcToolStripStatusLabel.Text = "Calculating...";
        }

Starting a Worker Thread that Reports Progress

BackgroundWorker

Handle the DoWork event

    void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) {
        CalcPi((int)e.Argument);
    }

Set  WorkerSupportsProgress property
Handle ReportProgress event

    void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) {
      // Show progress
      CalcPiUserState progress = (CalcPiUserState)e.UserState;
      ShowProgress(
        progress.Pi, progress.TotalDigits, progress.DigitsSoFar);
    }

Call RunWorkerAsync

    void calcButton_Click(object sender, EventArgs e) {
      SetUIBusy();

      // Begin calculating pi asynchronously
      this.backgroundWorker.RunWorkerAsync(
        (int)this.decimalPlacesNumericUpDown.Value);
    }

 Handle RunWorkerCompleted event

    void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
   {
       SetUIReady();  
   }

Modify the CalcPi method so that it reports progress regularly.

    void CalcPi(int digits) {
      StringBuilder pi = new StringBuilder("3", digits + 2);

      CalcPiUserState state = new CalcPiUserState(pi.ToString(), digits, 0);
      // Report initial progress
      this.backgroundWorker.ReportProgress(0, state);

      if( digits > 0 ) {
        pi.Append(".");

        for( int i = 0; i < digits; i += 9 ) {
          int nineDigits = NineDigitsOfPi.StartingAt(i + 1);
          int digitCount = Math.Min(digits - i, 9);
          string ds = string.Format("{0:D9}", nineDigits);
          pi.Append(ds.Substring(0, digitCount));

          // Report continuing progress
          state = new CalcPiUserState(pi.ToString(), digits, i + digitCount);
          this.backgroundWorker.ReportProgress(0, state);

          // Check for cancelation
          if (this.backgroundWorker.CancellationPending) { return; }         
        }
      }
    }

Task

Create a helper method to update the UI from the custom state class.

        void ShowProgressState(CalcPiUserState state)
        {
            try
            {
                // Display progress in UI
                this.resultsTextBox.Text = state.Pi;
                this.calcToolStripProgressBar.Maximum = state.TotalDigits;
                this.calcToolStripProgressBar.Value = state.DigitsSoFar;
            }
            catch (Exception e)
            {
                Console.WriteLine("{0} in ShowProgressState", e.Message);
                throw e;
            }
        }

Create a method with return type Task that encapsulates the work. In order to report progress, create an Progress delegate with an Action that reports progress. CalcPiWithProgress is CPU-bound, so call it with Task.Run. The async keyword in the signature means that await is a keyword in the body of the method.

        async Task DoWork()
        {
            //Any method that is an Action, has one parameter of the gerenic type and returns void.
            Action actionProgress = ShowProgressState;
            //The Action and the Progress must have the same generic type.
            IProgress progress = new Progress(actionProgress);
            await Task.Run(() => CalcPiWithProgress(
                  (int)this.decimalPlacesNumericUpDown.Value, progress)
                );

        }


Start task. The await keyword causes the method to start asynchronously. When the thread completes, the code after the await will be run in the same thread context. The handler does not block: SetUIReady is called, but only after the thread completes, and well after the handler completes.

        async void calcButton_Click(object sender, EventArgs e)
        {
            SetUIBusy();

            // Begin calculating pi asynchronously
            await DoWork();

            SetUIReady();
        }

A special method is not needed to catch the completion of the thread, as with a background worker.

Modify the CalcPi method so it reports progress.

    void CalcPiWithProgress(int digits, IProgress progress,) {
      StringBuilder pi = new StringBuilder("3", digits + 2);

      CalcPiUserState state = new CalcPiUserState(pi.ToString(), digits, 0);
      // Report initial progress
      if (progress != null)
                progress.Report(state);

      if( digits > 0 ) {
        pi.Append(".");

        for( int i = 0; i < digits; i += 9 ) {
          int nineDigits = NineDigitsOfPi.StartingAt(i + 1);
          int digitCount = Math.Min(digits - i, 9);
          string ds = string.Format("{0:D9}", nineDigits);
          pi.Append(ds.Substring(0, digitCount));

          // Report continuing progress
          state = new CalcPiUserState(pi.ToString(), digits, i + digitCount);
          if (progress != null)
                progress.Report(state);  
        }
      }
    }

Catch Exceptions

Background Worker

Test the Error property in the RunWorkerCompletedEventArgs in the RunWorkerCompleted handler.

void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
  
      SetUIReady();

      // Was there an error?
      if( e.Error != null ) {
        this.resultsTextBox.Text = e.Error.Message;
        return;
      }

    }

Task 

With Task, the code after the await is run on the UI thread. The code after the await is executed after the thread completes. The handler would have completed long ago.

Catch the exception and reset the UI.

        async void calcButton_Click(object sender, EventArgs e)
        {
            try
            {
                SetUIBusy();

                // Begin calculating pi asynchronously
                await DoWork();

            }
            catch (Exception ex)
            {
                this.resultsTextBox.Text = ex.Message;
            }
            finally
            {
                SetUIReady();
            }
        }

Return a Result from the Thread 

Background Worker

Set the result of the thread in the DoWorkEventArgs in the DoWork handler.

  void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) { 
      // Track start time
      DateTime start = DateTime.Now;

      CalcPi((int)e.Argument);     

      // Return elapsed time
      DateTime end = DateTime.Now;
      TimeSpan elapsed = end - start;
      e.Result = elapsed;
  }

Retrieve the result from the RunWorkerCompletedEventArgs in the RunWorkerCompleted handler.

void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
  
      SetUIReady();

      // e.Result will cause an error if the thread threw an exception
      if( e.Error != null ) {
        this.resultsTextBox.Text = e.Error.Message;
        return;
      }

      // Show elapsed time
      TimeSpan elapsed = (TimeSpan) e.Result;
      MessageBox.Show("Elapsed: " + elapsed.ToString());
}

Task 

Instead of using Task, use Task. The async command  changes the meaning of the method signature. It does not mean that the method returns Task, it means that the method has a call to await and returns type T.

        async Task DoWork()
        {
            // Track start time
            DateTime start = DateTime.Now;

            //Any method that is an Action, has one parameter of the gerenic type and returns void.
            Action actionProgress = ShowProgressState;
            //The Action and the Progress must have the same generic type.
            IProgress progress = new Progress(actionProgress);
            await Task.Run(() => CalcPiWithProgress(
                  (int)this.decimalPlacesNumericUpDown.Value, progress)
                );

            // Return elapsed time
            DateTime end = DateTime.Now;
            TimeSpan elapsed = end - start;
            return elapsed;
        }


The result will be assigned from the await command.

        async void calcButton_Click(object sender, EventArgs e)
        {
            try
            {
                SetUIBusy();

                // Begin calculating pi asynchronously
                TimeSpan elapsed = await DoWork();

                // Show elapsed time
                MessageBox.Show("Elapsed: " + elapsed.ToString());

            }
            catch (Exception ex)
            {
                this.resultsTextBox.Text = ex.Message;
            }
            finally
            {
                SetUIReady();
            }
        }

Adding the Ability to Cancel

Background Worker


Set the WorkerSupportsCancellation property

Signal that the thread should stop.

void calcButton_Click(object sender, EventArgs e) {
      // Don't process if cancel request pending
      // (Should not be called, since we disabled the button...)
      if( this.backgroundWorker.CancellationPending ) { return; }

      // If worker thread currently executing, cancel it
      if( this.backgroundWorker.IsBusy ) {
        this.calcButton.Enabled = false;
        this.backgroundWorker.CancelAsync();
        return;
      }

      SetUIBusy();

      // Begin calculating pi asynchronously
      this.backgroundWorker.RunWorkerAsync(
        (int)this.decimalPlacesNumericUpDown.Value);
    }

The thread monitors the flag for cancellation. When requested, the thread stops working.

  void CalcPi(int digits)
  {
      StringBuilder pi = new StringBuilder("3", digits + 2);

      CalcPiUserState state = new CalcPiUserState(pi.ToString(), digits, 0);
      // Report initial progress
      this.backgroundWorker.ReportProgress(0, state);

      // Check for cancelation
      if (this.backgroundWorker.CancellationPending) { return; }

      if( digits > 0 ) {
        pi.Append(".");

        for( int i = 0; i < digits; i += 9 ) {
          int nineDigits = NineDigitsOfPi.StartingAt(i + 1);
          int digitCount = Math.Min(digits - i, 9);
          string ds = string.Format("{0:D9}", nineDigits);
          pi.Append(ds.Substring(0, digitCount));

          // Report continuing progress
          state = new CalcPiUserState(pi.ToString(), digits, i + digitCount);
          this.backgroundWorker.ReportProgress(0, state);

          // Check for cancelation
          if (this.backgroundWorker.CancellationPending) { return; }         
        }
      }
    }

In the RunWorkerCompleted handler check the Cancelled property in the event args.

void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
      // Reset progress UI
      this.calcButton.Text = "Calculate";
      this.calcButton.Enabled = true;
      this.calcToolStripStatusLabel.Text = "Ready";
      this.calcToolStripProgressBar.Visible = false;

      // Was the worker thread cancelled?
      if (e.Cancelled)
      {
          this.resultsTextBox.Text = "Cancelled";
      }
      else
      {
          // Show elapsed time
          TimeSpan elapsed = (TimeSpan)e.Result;
          MessageBox.Show("Elapsed: " + elapsed.ToString());
      }

Task


As the thread is asked to respond in more ways, it is useful separate the actions performed when the thread ends. As part of the Task class, use the Continue with to specify a method that has the format for Action. Action, Func and Func can also be configured. If the UI will be accessed, then continue from the current context.

        async void calcButton_Click(object sender, EventArgs e)
        {

            SetUIBusy();

            // Begin calculating pi asynchronously
            await DoWork().ContinueWith(WorkCompleted,
                TaskScheduler.FromCurrentSynchronizationContext());

        }




Many states of the task can be inspected. This version does the same as the earlier version of the application. Next, cancellation will be added.

        private void WorkCompleted(Task task)
        {
            switch (task.Status)
            {
                case TaskStatus.Canceled:
                    break;
                case TaskStatus.Faulted:
                    this.resultsTextBox.Text = task.Exception.ToString();
                    break;
                case TaskStatus.RanToCompletion:
                    MessageBox.Show("Elapsed: " + task.Result.ToString());
                    break;
                default:
                    break;
            }
            SetUIReady();
        }


For cancellation, CancellationTaskSource is used. It contains a token that can be set. The token can be monitored by the thread.

        CancellationTokenSource tokenSource;
        CancellationToken token;

        public MainForm() {
            InitializeComponent();
            tokenSource = new CancellationTokenSource();
            token = tokenSource.Token;
            SetUIReady();
        }

A new helper will be added to report progress and check for cancellation, with the ThrowIfCancellationRequested() method of the token.

        void ProgressTestCancel(
            IProgress progress, CancellationToken token, CalcPiUserState state)
        {
            // Report progress
            if (progress != null)
                progress.Report(state);
            token.ThrowIfCancellationRequested();    
        }


The worker thread reports progress and tests for cancellation at regular intervals.

    void CalcPiWithProgress(
          int digits, IProgress progress, CancellationToken token) 
   {
      StringBuilder pi = new StringBuilder("3", digits + 2);

      CalcPiUserState state = new CalcPiUserState(pi.ToString(), digits, 0);
      // Report initial progress
      ProgessTestCancel(progess, token, state);

      if( digits > 0 ) {
        pi.Append(".");

        for( int i = 0; i < digits; i += 9 ) {
          int nineDigits = NineDigitsOfPi.StartingAt(i + 1);
          int digitCount = Math.Min(digits - i, 9);
          string ds = string.Format("{0:D9}", nineDigits);
          pi.Append(ds.Substring(0, digitCount));

          // Report continuing progress
          state = new CalcPiUserState(pi.ToString(), digits, i + digitCount);
          ProgessTestCancel(progess, token, state); 
        }
      }
    }

Pass the token into the method that does the asynchronous work. The task will be needed in other parts of the application to improve the interaction of the UI, so the task is added as an instance variable. Does this remind you of background worker???

         //Needed in order to test if Task is busy in other methods
        Task piTask = null;
        async Task DoWork()
        {
            // Track start time
            DateTime start = DateTime.Now;

            //Any method that is an Action, has one parameter of the gerenic type and returns void.
            Action actionProgress = ShowProgressState;
            //The Action and the Progress must have the same generic type.
            IProgress progress = new Progress(actionProgress);
            piTask = new Task(() =>
                 TimePiThread(
                    (int)this.decimalPlacesNumericUpDown.Value, progress, tokenSource.Token)
                 , tokenSource.Token);
            piTask.Start();
            return await piTask;
         
        }


The button handler will have two possible states: ready to run, ready to cancel. Update the UI based on the state of the task. If the task is running, cancel it on click.

        async void calcButton_Click(object sender, EventArgs e)
        {
            // Don't process if cancel request pending
            // Should not happen, since button will be disabled
            if (this.tokenSource.IsCancellationRequested) { return; }

            if (piTask != null && !piTask.IsCompleted)
            {
                this.calcButton.Enabled = false;
                tokenSource.Cancel();
            }
            else
            {

                SetUIBusy();

                // Begin calculating pi asynchronously
                await DoWork().ContinueWith(WorkCompleted,
                    TaskScheduler.FromCurrentSynchronizationContext());
            }

        }

The helpers for updating the UI need modification, too:

        void SetUIReady()
        {
            // Reset progress UI
            this.calcToolStripStatusLabel.Text = "Ready";
            this.calcToolStripProgressBar.Visible = false;
            this.calcButton.Text = "Calculate";
            this.calcButton.Enabled = true;
        }

        void SetUIBusy()
        {
            // Set calculating UI
            this.calcToolStripProgressBar.Visible = true;
            this.calcButton.Text = "Cancel";
            this.calcToolStripStatusLabel.Text = "Calculating...";
        }

Conclusion

For updating the UI, I still like background worker. In large part, this is due to my understanding of background worker. Task is new to me. It has more power than background worker for other tasks, but background worker is tailored for interacting with the UI. While writing this article, I was frustrated multiple times with the syntax of lambda functions and the .NET delegates. Background worker hides the details, but allows all the necessary features for interacting with the UI.

Wednesday, September 14, 2016

Using GitHub for Homework Submissions

I teach a course in Windows programming. I use Visual Studio. All programming projects are team projects. I have eight teams, with a repository for each team.

Each group in my class has four or five students. Four seems to be the best number, since it is harder to arrange a meeting for five people. For each group, I created a team in GitHub.

Each student must create a GitHub account and send it to me, then I invite them to the team.

I created eight private repositories in GitHub, so only an authorized team has access. The repository is for all the homework assignments. Each repository has one team assigned to it.

The master branch in the repository only has a README file. The file indicates that each homework assignment will be in a separate branch. I populate the branch with a Visual Studio solution.

Once the student, X, has accepted the invitation to the team, X will be able to view the repository in GitHub. The repository has a button for "Clone or Download". Clone is the preferred method. The URL to use to clone the repository is displayed. X should copy the URL and open Visual Studio.

In Visual Studio, X should open Team Explorer. Look for the icon that looks like a plug. It is for Connections. Open it and look under Local Git Repositories. Click the Clone drop-down indicator. Paste the URL from GitHub and click Clone.

After the repository has been downloaded, click the Home icon to go the home screen. On the home screen, click the Branches link. Near the bottom of the screen are the Active Git Repositories. Open the remotes/origin link. Select the branch for the current homework.

Once the correct branch is selected, return to the Home screen. At the bottom, under solutions, should be the homework solution. Double click it and the solution files will be opened in Visual Studio. Open Solution Explorer and start modifying the file.

After making edits, return to Team Explorer and select Changes. Commit All the changes and Push at the same time.

Before starting a new editing session, open Team Explorer, select the solution, and Sync to the remote server.

To populate with an existing solution,
In GitHub,
  1. Create a branch for the assignment in the repo on GitHub
In VS,
  1. Create a new local repo. 
  2. In the local repo settings, set the remote address to the clone address for the remote repo.
  3. Return to Home and select Sync
  4. Perform a fetch to get the hw branch.

The Open solution option in the local repo will only work if the repo is empty. To circumvent,
  1. Open File Explorer and navigate to the repo folder. 
  2. Copy the initial folder that contains the solution into the folder.

Back in VS, the solution will now appear in the local repo.
  1. From Home, select Changes and Commit and Push to commit the .git files
  2. Double-click the solution to open it.
  3. From Home, select Changes and Commit and Push to commit the .git files

Later, I wanted to update the repository with the next version of the submitted homework, since not all students chose to use the repository. Many changes had been made since the initial contents.

I created a branch in GitHub for me from the initial state and sync'd it in VS. Then I opened the new solution in VS. From Home I viewed Changes and committed and pushed to GitHub. In GitHub, I performed a pull request into the original branch from the new branch. No conflicts were present, so the merge was possible. 

Monday, August 29, 2016

Yii User Setting isAdmin

The Yii framework has CUserIdentity as the basis for logging into an application.

It is possible to add state to the class, so an identity can be tested easily; for example, testing if a menu option should displayed for the current user.

array(
    'label'=>'List OfficeVisit', 
    'url'=>array('index'), 
    'visible'=>yii::app()->user->isAdmin)

The CUserIdentity class has support for adding state with setState. The state can be retrieved with getState, or by accessing the state directly as a property.

In the UserIdentity class in the application, which extends CUserIdentity, add the following in the authenticate method, after authenticating:

if ($this->username==='dbadmin') {
     $this->setState('isAdmin', true);

}

The state can be accessed later with either:

yii::app()->user->getState('isAdmin')

or

yii::app()->user->isAdmin

Refer to http://www.yiiframework.com/wiki/6/how-to-add-more-information-to-yii-app-user/ for more information.

 

Thursday, February 4, 2016

New Roulette

Here is a new roulette game.
  1. Everyone has an initial stake that can be any amount of money.
  2. For each spin, you can play or you can watch.
  3. If you play, you must wager 1% of your stake. Watching is free.
  4. A number is chosen for each player and watcher; no two players or watchers have the same number.
  5. The roulette wheel has exactly enough numbers for all the players and watchers.
  6. After each spin, all players and watchers win %100 of their stake.
Here is how you increase your stake:
  1. The roulette wheel is spun.
  2. If the ball lands on the number of a watcher, no ones stake increases.
  3. If the ball lands on the number of a player, then the stake for each player and watcher is raised by an amount between 1% and 2.5%.
  4. Any increase is to the stake for all players and watchers for this spin and all future spins. The longer you play or watch, the bigger your stake becomes.
Would you play or watch?

The name of the game is The Power of a Union in a Right-to-work State.

Friday, January 22, 2016

Installing Python3 on Mac OSX

I have python 2.6 installed on my Mac.

I already had homebrew installed for perl.

I used the command

brew install python

and python 2.7 was installed. The bash profile command was altered to include the new python path at the start of the path command.

PATH="/Library/Frameworks/Python.framework/Versions/2.7/bin:${PATH}"

Install Python 3

Next, I tried to install python 3.

brew search

The name of the package is python3.

brew install python3

This was the first error:


C compiler cannot create executables

I had read a comment earlier about installing Xcode. I already had Xcode. Another comment was to enable command line tools. I did not know if they were already enabled. They weren't.

xcode-select --install

After this command and install, I was able to get further, but the install failed. After error

Need 'brew link xz'

Typed the command

brew link xz

and received an error. So, I ran

brew doctor

I changed the permission on a file. I was able to continue. python 3 is now installed in /usr/local/bin/python3

Install Virtual Environment 

I accessed Python Virtual Environment and learned about virtual environments.
 

Next, I created a virtual environment with the new python.

virtualenv -p python3 python3env

After installing, switch to the folder and activate the environment.

source bin/activate

Now, the path has the local python as the default python.

The virtual environment is alright, but I am limited to a text editor and console window.

Install Eclipse IDE

An IDE with code completion and syntax highlighting is preferable. 

Next, I installed Eclipse and added the PyDev plugin. I installed Eclipse for Java, since no option existed for python.

I followed the instructions at http://www.pydev.org/manual_101_install.html. I was required to accept a certificate that was not mentioned in the instructions.

For Mac, the preferences are not under the window menu, but in the usual preferences under Eclipse in the menu strip.

Next, I followed the instructions for creating a project. The interpreter was the default 2.7, not the new 3.5. I added the new interpreter to the preferences.

The tutorial is for 2. I am using 3, so tutorial code must be modified.

Install NetBeans IDE


Next, I checked to see if NetBeans had a plugin for python. NetBeans 8.1 has a python package that can be installed easily, 8.02 requires some worked. I upgraded to 8.1.

The default python was for jython in NetBeans. I added a reference to my python 3.

The default template for creating a module used python 2 syntax. The template for creating a package used python 3 syntax. 

Update

https://opensource.com/article/19/5/python-3-default-mac

use pip to install modules







 



More Blogs

Followers