Showing posts with label Programming. Show all posts
Showing posts with label Programming. Show all posts

Thursday, April 14, 2022

Swift Arrays to Dictionaries with indices

The extension below is to facilitate the creation of dictionaries from arrays. In this case, the dictionary has the array element as the key and the index of that element as the value. 

Since I was only working with arrays that held unique values I added a guard statement to enforce that. If you remove it, then your the last duplicated element would have the index as its value.

extension Array where Element: Hashable {

    func toDictionary() -> [Element: Int] {

        guard Set(self).count == self.count else {

            fatalError("\(#function) requires arrays with unique values!")

        }

        return self

            .enumerated()

            .reduce(into: [Element: Int]()) { dict, tup in

                dict[tup.1] = tup.0

            }

    }


["hello", "world"].toDictionary() // ["world": 1, "hello": 0]


Saturday, June 01, 2019

100 Days of Swift

3. For a tougher challenge, take the image generation code out of cellForRowAt: generate all images when the app first launches, and use those smaller versions instead. For bonus points, combine the getDocumentsDirectory() method I introduced in project 10 so that you save the resulting cache to make sure it never happens again.

As a reminder, here’s the code for getDocumentsDirectory():
func getDocumentsDirectory() -> URL {
    let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
    return paths[0]
}

The above is from Day 98 of Paul Hudson's excellent course: 100 Days of Swift. It is Challenge #3 and there is even a "bonus" challenge inside the challenge! In approaching the solution--before coding--I wrote down my thoughts and then gathered snippets of code that I thought would help. My notes are below. I thought it might be helpful for others to share them without giving away the solution.

First, I jotted down the four main things I was concerned with:
  1. Read big images from bundle, see project 1.
  2. Render a image into a rect using CoreGraphics like in project 30. 
  3. Read the thumbnails in like project 10
  4. If a thumbnail does not exist then create it. Also like in project 10.
Next, I gathered the corresponding snippets of the code:

From project 1:
DispatchQueue.global(qos: .userInitiated).async { [weak self] in
    let fm = FileManager.default
    let path = Bundle.main.resourcePath!
    let items = try! fm.contentsOfDirectory(atPath: path)
    
    let pictureNames = items
        .filter { $0.hasPrefix("nssl") }
        .sorted { $0 < $1 }
    
    self?.storms = pictureNames.map {
        Storm(name: $0, imageName: $0) }
    
    DispatchQueue.main.async { [weak self] in
        self?.collectionView.reloadData()
    }
}

From project 30:
        let path = Bundle.main.path(forResource: imageRootName, ofType: nil)!
        let original = UIImage(contentsOfFile: path)!

        let renderRect = CGRect(origin: .zero, size: CGSize(width: 90, height: 90))
        let renderer = UIGraphicsImageRenderer(size: renderRect.size)
        
        let rounded = renderer.image { ctx in
            ctx.cgContext.addEllipse(in: renderRect)
            ctx.cgContext.clip()
            
            original.draw(in: renderRect)
        }

From project 10:

Write:
        let imageName = UUID().uuidString
        let imagePath = getDocumentsDirectory().appendingPathComponent(imageName)
        if let jpegData = image.jpegData(compressionQuality: 0.8) {
            try? jpegData.write(to: imagePath)
        }

Read:
        let path = getDocumentsDirectory().appendingPathComponent(person.imageName)
        cell.imageView.image = UIImage(contentsOfFile: path.path)

Saturday, March 31, 2012

Astra Itinera

My first iPad game, Astra Itinera, is now available on iTunes! Astra Itinera is a turn-based strategy game. Check out the Facebook page.

Astra Itinera grew out of my AS3 Strategy Games tutorial series. If you'd like to learn how to create random terrains, use connected component labeling, A* (a-star) pathfinding, state machines and more, check out the tutorial

Recommended by MacMost.com: "The interface is simple, but the game play is deep."

Mentioned in the CartoonSmart.com blog.

Tuesday, December 06, 2011

Playing with Processing

I've been fascinated with Processing lately. So I decided to port a small part of my terrain generation code from my Strategy Games in AS3 series. I was surprised at how easy it was to port and how fast it runs. An unexpected benefit, I found that rethinking a problem by writing it in a different language gave me better insight into the problem I was originally solving.

Sunday, October 26, 2008

Array Functions in AS3

AS3 Array class has some really handy functions that I never noticed before. They will be very useful (how did I ever NOT notice them?):

every(callback:Function, thisObject:* = null):Boolean
Executes a test function on each item in the array until an item is reached that returns false for the specified function.

filter(callback:Function, thisObject:* = null):Array
Executes a test function on each item in the array and constructs a new array for all items that return true for the specified function.

forEach(callback:Function, thisObject:* = null):void
Executes a function on each item in the array.

map(callback:Function, thisObject:* = null):Array
Executes a function on each item in an array, and constructs a new array of items corresponding to the results of the function on each item in the original array.

some(callback:Function, thisObject:* = null):Boolean
Executes a test function on each item in the array until an item is reached that returns true.

Saturday, July 19, 2008

AS3 vs Java Local Variable Scope

In some languages, you can scope variables within blocks of code, like in different compound statements. For example, the following is legal in Java:
{
int i = 0;
}
{
int i = 1; //Legal in Java
}
But adding those {} to make a compound statement does NOT work in
ActionScript 3 because the AS3 compiler takes all the local variables
(regardless of depth) and declares that right at the beginning of the
function. For example, this is legal in AS3:
    trace(i); // Legal in AS3, default value of int (zero) is output
var i:int = 1;
trace(i);
It appears we're accessing a variable before it is declared. But since the compiler moved our declaration to the beginning of the function, there is no error. The assignment is not moved, the the value of i at that point is zero. This behavior is similar to the way Flash deals with variables
declared later on the timeline, you can reference them before earlier
than the declaration because the compiler moves that declaration to
the beginning.

Friday, July 11, 2008

SWCs and FlashDevelop

I'm thinking my Bits of Blender episodes are really cutting into my blogging time! But I thought I'd put a note out on my latest development approach in FlashDevelop for Flash/ActionScript 3 projects.

Previously, I'd set the main class as the Document class. Then I would set the parent class of Symbols to a corresponding ActionScript 3 class. I'd turn off the automatic declaration of variables so that it would force me to declare them in the class. This was nice because I would have a reminder at the top of the class that there were named instances in the symbol. I'd also add a "//MC" after the declaration as another reminder why I had those members set to "public" (I'd also set "//MC" as one of the tasks so I could quickly find all the named instances on the stage).

But for a recent project, I decided to go with compiling in FlashDevelop instead of Flash. When I'd used FlashDevelop for some Flex work last year, I was always impress with how quickly it compiled. Flash seems to take much longer. I think it may be because FlashDevelop uses the Flex compiler which is doing incremental compiles and Flash is always compiling everything (I'm guessing). So instead of working in Flash, my main Flash class is not running in Flash. Instead, I'm bringing all of my Flash assets in via an SWC. This gives me the advantage of compiling straight in FlashDevelop (and not having it switch to Flash, in fact Flash does not even have to be running). Plus, my compiles are faster. But there is one downside, now instead of my Flash symbol extending an AS3 class, I'm having my AS3 class extend the symbol. This means any named instances in the class are in the symbol instead of in the AS3 class, so I no longer have that reminder of the declaration at the top of the class. The instance is still declared and still appears in the code completion, but it just does not feel quite as good. Overall, though, this approach weighs in feeling like a better way to go.

Sunday, April 13, 2008

Reflection in ActionScript 3

I'm not a big fan of the old eval() function in earlier versions of ActionScript. As of ActionScript 3, it is no longer supported. For the most part, that is a very good thing. My buddy, Jason, is migrating from AS2 to AS3 and he found himself looking for the eval() function. He came to me and asked me about it, I replied "you mean the evil() function?".

The problem with eval() is that you were executing code that was being created at runtime, meaning there's no chance of the complier helping you catch errors. He showed me the code he was working on and --usually-- you can solve the lack of eval() through a better architecture. As I looked at his program, I realized he had a pretty elegant solution. Re-architecting would take a good deal of time and not necessarily yield as elegant result. Java has quite a few classes for dealing with reflection, so I figured (given how similar AS3 is to Java) there must be some similar classes. As it turns out, the pickings are pretty minimal... but there were enough to come up with a nice, dynamic solution to his problem.

In the flash.utils package, there are a number of public functions. The one we were looking for (before we even knew it) was getDefinitionByName(). This function takes a string that is the name of a class, an returns the class object for it. With the class object, you can then create an instance of the class. Here's a simple example you could run in the Flash IDE:
var myClass:Object = getDefinitionByName("Symbol1");
addChild( new myClass() );
It assumes you have a Symbol named "Symbol1" that is exported for ActionScript. If you are doing this in Flex or inside an external class file, remember to import the flash.utils package. The danger of runtime errors still exists, but it is more limited now in that you can create classes and not just execute and arbitrary chunk code on the fly like you could with eval().

Audio Display List?

The Flash 9 player using ActionScript 3 (for Flex or Flash), has an internal structure called a display list. Items in the display list, will be shown, items not in it will not be shown. So if you load an external SWF, it will not be visible until you add it to the display list. Once it is in the display list, it'll receive events (like MouseEvents, KeyboardEvents, ENTER_FRAME, and so on). That's nice, because you can load it and display it at will.

But what about a SWF that also contains audio? As it turns out, there is no audio equivalent to the display list. Once a SWF containing audio is loaded, it will begin to play and you'll hear the audio, whether or not you're displaying it. To stop the audio, listen for Event.INIT on the loaderInfo in the Loader object. Event.INIT fires when the first frame is loaded so you can call stop() it to prevent the playback head from moving forward in the timeline.

Thursday, March 27, 2008

DNA script


After writing the script I posted in the previous blog, it occurred to me that I should be able to create all the nucleotides with a script, not just color them. So I poked around in the Blender Python APIs and came up with the following:
import random, math
import Blender
from Blender import Object, Scene, Material

scn = Scene.GetCurrent()
colors1 = [Material.Get("G_Nucleotide"), Material.Get("C_Nucleotide")]
colors2 = [Material.Get("A_Nucleotide"), Material.Get("T_Nucleotide")]
groups = [colors1, colors2]
for i in range(0, 90):
rot = i*.125*math.pi
o = scn.objects.new(Object.Get("nucleotide").getData())
o.colbits = 1
o.modifiers = Object.Get("nucleotide").modifiers
o2 = scn.objects.new(Object.Get("nucleotide").getData())
o2.colbits = 1
o2.modifiers = Object.Get("nucleotide").modifiers
groupNum = random.choice([0,1])
firstColorNum = random.choice([0,1])
if firstColorNum == 0:
secondColorNum = 1
else:
secondColorNum = 0
firstColor = groups[groupNum][firstColorNum]
secondColor = groups[groupNum][secondColorNum]
o.LocZ = i*.2
o.RotZ = rot
o.setMaterials([firstColor])
o2.LocZ = i*.2
o2.RotZ = rot + math.pi
o2.setMaterials([secondColor])
scn.update()

Python is one of the more unique languages I've worked with. After my initial shock at being forced to indent, I've now found I like it. I'd do it anyway, but now it is sure to be done and done consistently. It makes for reading my code and others' code much nicer. As I get used to syntax and familiar with the Python and Blender APIs, I find I am looking for more excuses to use it. :)

For one of my future courses, I'd like to teach how to program... using Python as the language and Blender as the environment. This would be for folks who want to learn to program, but haven't a clue were to start. It's nice to be able to solve some of the more tedious tasks (like creating and coloring nucleotides) programmatically.

Another course I'd like to teach is one on the Blender Game Engine. With the logic bricks, you can do a lot of programming logic without getting into the syntax issues you get in a language. A cool thing in Blender is you can extend the logic bricks by calling Python scripts.

About the image: The image above has over 1200 objects, but only one mesh. Each object reference the same mesh (making changes easy). I applied the Material color to the object (not the mesh, which is the default). By using a script, I was able to apply the colors randomly but following the rules that the A color had to go with T (or T with A) and the G color had to go with C (or C with G). Since all the nucleotides of the same color share the same Material, color and texture changes are also easy.

Wednesday, March 12, 2008

Blender Materials and Python


I spent some time tonight working with Blender on an illustration of DNA. At first, I thought it would be straightforward... I soon realized there were many challenges. The biggest was setting up the nucleotides. They have to be four different colors, representing the pair A and T, as well as C and G. The pairs need to go together. Since there were so many of them, I thought this was a good time to do a little Python. After poking around in the APIs, I found where I could set the Object's material. I ran my script and nothing seemed to happen. As it turns out, Blender can associate a material with an object or a mesh. By default it associates with a mesh and it seems that the mesh material takes precedence over the object material. A small change to the code and I got it working. Here's the program:

import Blender
from Blender import Material, Mesh

objects = Blender.Object.GetSelected()
mat = Material.Get("T_Nucleotide")

for curObj in objects:
n = curObj.getData()
n.materials = [mat]
n.update()
curObj.layers = [5]

The code starts out with the import statements to use the Blender, Material, and Mesh modules. Next it gets all the selected objects (this way I could click on the ones I want to change). Then it sets a variable to the material I want to use. I loop through the list of objects getting the mesh data, then setting its materials. Note that the materials property is actually a list of materials, so I add the brackets around the material variable. I call update() so the screen is updated. Lastly, all the ones that were changed I move to layer 5. The layers property is list, this is a neat feature of Blender... unlike most graphics programs where an object can only reside on one layer at a time, in Blender you can set the object to appear on multiple layers. Turns out to be very useful.

Monday, March 10, 2008

FlexBuilder vs FlashDevelop

I've been using both FlexBuilder and FlashDevelop at work lately. I'm a long time FlashDevelop user, so I've a little bias towards it. Lately, I've been trying to look at FlexBuilder with regards to its strengths. I've found that if I am doing a lot of MXML coding, FlexBuilder is a better tool. You have a class view of the MXML and it is good about hinting for MXML attributes. If you need to do absolute positioning, FlexBuilder also wins because of it's WYSIWYG editor.

But when it comes to ActionScript 3 coding, I'd much rather be in FlashDevelop. FlashDevelop's code hinting is much more powerful, for example it does NOT require you to type exactly the right characters. It's a breeze to jump around to declarations of code as well as nice features for creating getters/setters, promoting local variable to member variables, and creating event handlers. The look and feel of FlashDevelop is also nice, it launches and runs quickly. It has good defaults, a user-friendly UI, and good choices for fonts (I guess that could fall under "good defaults"). FlashDevelop is also free.

Wednesday, December 05, 2007

Programming Alice 3d

I just downloaded the Alice 3d programming environment Carnegie Mellon University. It is a interesting way to learn programming logic without getting bogged down with dealing with syntax problems. By dragging and dropping you can construct your logic and create stories with 3d characters.

Since I'm back using Blender, I had to see if there was a way to develop 3d models in Blender for Alice. The official site is slim on documentation from a user perspective, so developer documentation is non-existent. In the program, I noticed you can import and .ASE file. I'd never heard of that and didn't see it in the Blender list of export formats. Fortunately, Blender is extensible through Python and someone wrote an import and export script for .ASE.

Just put the exporter script in your Blender scripts folder. I tested it and it works as long as you make sure none of the objects you make sure your object names don't have a "." in them.

Working with Alice set my Java-sense to tingling. I could tell it is a Java app from the look and feel, plus they have all sorts of .JAR files in the application folder. Having spent some time with Java, I started poking around. Knowing Java likes the .JAR format, which is really .ZIP, I renamed an Alice .A2W file with the .ZIP extension instead. Sure enough it popped right open with WinZip. It was very cool to poke around inside. Most of the contents were XML files. It's fun to see how it's put together.

One downside is when I tried to use the "Export Movie" feature and got a "This feature is not implemented yet" dialog box. Why even put the menu item in the menu if it is not implemented? Another problem was when I tried to view it as a web page. It didn't work but there was a link with instructions. Basically, you need to make sure you have Java, Java3d, and the Java Media Framework (which requires a reboot). Those are three separate downloads from three separate pages. Not too user friendly! Lastly, after downloading and installing those, rebooting my machine, I find the applet version does not play back showing the word balloons and opacity changes in my "world". So if you want to show others your work, you'll have to pass around the .A2W file, which is basically the source code and files. Even that has some issues in that supposedly some mail programs recognize that it's really a .ZIP and change the extension. I haven't confirmed that behavior.

Still, Alice is a great tool and it is free. In a short amount of time, my kids were creating short stories using the pre-created characters.

Tuesday, October 09, 2007

Interacting with Flex in Flash

I was trying to bring a Flex 2 SWF into Flash CS3 and interact with it. I was able to load the Flex swf without a problem but when I tried to access a public property or function I'd get the following error:

ReferenceError: Error #1069: Property hello not found on
_Main_mx_managers_SystemManager and there is no default value.

So I did the natural thing and Googled it before spending time figuring it out :)
Unfortunately, my search came up empty :(

Looking into the docs class mx.managers.SystemManager gave me the clue I needed. To get at the actual application, I needed to get to the first child of the loaded content. The compiler was unhappy with calling getChildAt() on the content object, so I cast it into an Object along the lines:

var flexApp:Object = (loader.content as Object).getChildAt(0);
trace(flexApp.hello);

That did the trick!

Saturday, September 08, 2007

Code-behind and States in Flex 2

I've always liked the .NET way of developing web pages, where you have your code separated from your layout. Someone just referred me to this post on using Flex in a .NET code-behind style (thanks Steve!). It's very similar to .NET, you just extend the Application class and use it in your MXML file.

It is very cool but there's a minor error where the package name is left off the screenshot (though the instructions are correct). One of the comments on the post noted that in order to use states with this approach you needed to make a small change from "mx.states" to "app.states" where "app" is the namespace of your application.

I thought I'd post a version of this approach that included the states issue. I hilited where you need to change "mx" to "app" and where you need to add "app" as the namespace. The shots below are of code done in FlashDevelop 3 (beta 3).


UPDATE: September 14, 2007 1:07 PM I've had additional troubles with using the code-behind and states. I'm afraid for now it's best to hold off on using the approach.


Sunday, August 05, 2007

Flex 2 States

I've been learning a little about Flex 2 this weekend while working through O'Reilly's Programming Flex 2 by Chafic Kazoun and Joey Lott. There's always a big gap between working through a book and doing a real project when it comes to technology.

That said, one feature of Flex 2 that I think is implemented quite well is states. From my practice, it seems Adobe has implemented the concept in a straightforward manner. States relate to the view. You create different states for different modes your program is in. A program can only have one current state at a time. I'm impressed at how easy it is to set up a series of states and switch between them. When you do switch between states, the different controls on a state preserves its own state, i.e. a checked CheckBox remains checked whether it is part of the active state or not. I look forward to seeing whether I feel the same in actual practice.

Thursday, August 31, 2006

The Programming Road

I've always considered C to be my first programming language (subsequently I judge all languages against it). I picked up Learn C on the Macintosh in 1991. Technically, I did do Fortran on punch cards in 1983, but that was a different world. It occurred to me today I programmed in HyperCard and its HyperTalk language in 1988-90, I remember writing two small programs for use in our family business. I guess I never thought of it as programming because it seemed very easy to get a result. Maybe that is why HyperCard was so popular, that and it being installed on the early Macs. Nothing like free software that's easy to learn. 

After painfully working through Learn C on the Macintosh, I actually started understanding some of the basics of programming. From there I moved to Prograph CPX at the end of 1993. In early 1994 I took a programming logic course that helped solidify my understanding of what was going on. The course was interesting, you didn't use a computer, just flowcharting and pseudocoding. That same year I picked up AppleScript to script QuarkXPress using Frontmost (later FaceSpan) to have a front end to my scripts, and in the fall I learned Lingo with Director 4.

I actually tried Director in 1993 and made an interactive portfolio for my company. It was with Director 3.1.1 and I was not too impressed. Version 4.0 of Director did impress me. I'd found the joys of Object-Orient Programming (OOP) thanks to Prograph CPX. With version 4.0 of Director, Lingo was now a powerful OO language.

I stayed with Director for several years, dabbling in JavaScript in 1997. That year also marked my first introduction to Java. I was not too impressed (deja vu!). I continued with Director until 2000, co-authoring two books on the subject and tech editing two more. That year I took an instructor job at Sun Microsystems. I taught several Java courses, a shell scripting course using Bourne and Korn, and learned the Vi text editor. I also picked up programming the C Shell in order to teach a course in it. In the shell scripting courses I was introduced to grep, sed, and awk. Awk I loved!

After leaving Sun, I got a job where I got to do a little Director again and was exposed to the classic ASP. I found I did not care much for ASP or VBScript. I learned to program in ActionScript with Flash 6 and the Flash Communication Server APIs. After that I migrated the company from VBscript and ASP to C# and ASP.NET. I learned SQL, I enjoyed pair-programming, and discovered Visual Studio was the best IDE out there. Along the way I got to briefly pick up and program in XSLT and created a .NET Windows Forms application.

After that job I came to StorageTek where I worked with the Docent LMS and CDS. The LMS used a server-side JavaScript that was a step up from classic ASP, but not a big step. I managed to make use of both my ASP.NET and Windows Forms skills. I tinkered a little with JavaScripting Photoshop for a project.

Sun bought StorageTek, so I'm back at Sun. But I'm not back using Java (yet), I'm actually learning Perl and MySQL.