Login

Welcome, Guest. Please login or register.

March 28, 2024, 07:36:48 pm

Author Topic: Softdev: What programming language?  (Read 11121 times)  Share 

0 Members and 1 Guest are viewing this topic.

Aaron

  • Honorary Moderator
  • ATAR Notes Legend
  • *******
  • Posts: 3932
  • Respect: +1536
Softdev: What programming language?
« on: May 12, 2016, 12:47:26 pm »
+5
Hi to all students past and present who have or are currently completing Software Development.

I'd like to get a general idea of what programming language your class is focusing on for this subject - please comment below with a post containing what language you are using (or have used, for past students) and your thoughts (e.g. was it easy to learn? were you forced to learn it all yourself or did your teacher help you with learning it?)

Please note: To discuss pros/cons of programming languages or to debate for/against another person's programming language suggestion please direct your comments to this thread: https://atarnotes.com/forum/index.php?topic=183589.0 - This thread is for you to state what language you are doing and your thoughts ONLY.

« Last Edit: January 20, 2019, 12:09:04 am by Aaron »
Experience in teaching at both secondary and tertiary levels.

website // new forum profile

MightyBeh

  • Forum Leader
  • ****
  • Posts: 629
  • Beth(x)
  • Respect: +91
Re: Softdev: What programming language?
« Reply #1 on: May 12, 2016, 04:04:05 pm »
+1
My class is working with vb.net. We only really covered the basics in class (creating variables, if statements, loops, arrays, records and stuff like that) so anything that I personally know other than 'okay copy this' is based on messing around with stuff and some ancient resources that I've managed to find through googling things. Despite that though, it is a pretty easy language to pick up other than some weird quirks (a fair number of which originate within Windows itself) and a general lack of support.

If I'd been given a choice of languages I probably wouldn't have picked it, but I'm not upset that it's what we have to use in class, so it can't really be that bad. ::)
VCE: Further Maths | Methods | Specialist | Literature | Software Development | Classics
2017: making some dolla

Aaron

  • Honorary Moderator
  • ATAR Notes Legend
  • *******
  • Posts: 3932
  • Respect: +1536
Re: Softdev: What programming language?
« Reply #2 on: May 12, 2016, 04:47:08 pm »
+1
My class is working with vb.net. We only really covered the basics in class (creating variables, if statements, loops, arrays, records and stuff like that) so anything that I personally know other than 'okay copy this' is based on messing around with stuff and some ancient resources that I've managed to find through googling things. Despite that though, it is a pretty easy language to pick up other than some weird quirks (a fair number of which originate within Windows itself) and a general lack of support.

If I'd been given a choice of languages I probably wouldn't have picked it, but I'm not upset that it's what we have to use in class, so it can't really be that bad. ::)

How much of the programming would you say you had to learn outside of class in order to fulfil the requirements of the SAC's and work?

I don't think I mentioned it in this one (did so in the Informatics thread I made), but I really value these replies to the threads I post, as this helps me understand learning, attitudes etc. in VCE Computing (since i'm a pre-service teacher in IT/Computing). If you're a Softdev student, please feel free to post and share your thoughts.
« Last Edit: May 12, 2016, 04:55:13 pm by Aaron »
Experience in teaching at both secondary and tertiary levels.

website // new forum profile

MightyBeh

  • Forum Leader
  • ****
  • Posts: 629
  • Beth(x)
  • Respect: +91
Re: Softdev: What programming language?
« Reply #3 on: May 12, 2016, 05:31:01 pm »
+1
How much of the programming would you say you had to learn outside of class in order to fulfil the requirements of the SAC's and work?

I don't think I mentioned it in this one (did so in the Informatics thread I made), but I really value these replies to the threads I post, as this helps me understand learning, attitudes etc. in VCE Computing (since i'm a pre-service teacher in IT/Computing). If you're a Softdev student, please feel free to post and share your thoughts.
All of the stuff we learned in class is specifically for SACs and class work. Occasionally, tasks couldn't be properly completed without using some stuff learned outside of class, mostly because our teacher uses a lot of legacy code to teach with without checking that it actually still works. So I'd say I've only had to learn about 5-10% outside of class, but I've definitely willingly learned more than that because I've wanted to be able to produce solutions that are above average. I'd say that what we're taught is enough to get a decent mark, but to do really well we have to learn some things independently of class.
VCE: Further Maths | Methods | Specialist | Literature | Software Development | Classics
2017: making some dolla

kev18

  • Adventurer
  • *
  • Posts: 9
  • Respect: 0
  • School: crcsyd
  • School Grad Year: 2016
Re: Softdev: What programming language?
« Reply #4 on: May 22, 2016, 07:34:11 pm »
0
Yes, we also use VB net, our teacher assisted us with the basics. This helped in our first sac. Now we our making our own programs for a world need, and need a bit more personal research in vb is needed.

Aaron

  • Honorary Moderator
  • ATAR Notes Legend
  • *******
  • Posts: 3932
  • Respect: +1536
Re: Softdev: What programming language?
« Reply #5 on: May 23, 2016, 11:07:59 pm »
0
Yes, we also use VB net, our teacher assisted us with the basics. This helped in our first sac. Now we our making our own programs for a world need, and need a bit more personal research in vb is needed.

Awesome, thanks for sharing! Feel free to let us know via this Softdev board if you run into any problems or simply want to discuss/share thoughts.
Experience in teaching at both secondary and tertiary levels.

website // new forum profile

has400

  • Victorian
  • Adventurer
  • *
  • Posts: 8
  • Respect: 0
  • School: Wesley college
Re: Softdev: What programming language?
« Reply #6 on: September 28, 2016, 08:56:50 pm »
+2
Class learned java through anrdoid studio, and I made a application using information from http://www.champion.gg to create build info for a league of legends application! Teacher gave it 100%! Was pretty easy to learn the language, I did all the learning out of class as well I also made a video releasing the files to the public - https://www.youtube.com/watch?v=EmufzHsQDnY

Aaron

  • Honorary Moderator
  • ATAR Notes Legend
  • *******
  • Posts: 3932
  • Respect: +1536
Re: Softdev: What programming language?
« Reply #7 on: September 28, 2016, 09:03:31 pm »
0
Class learned java through anrdoid studio, and I made a application using information from http://www.champion.gg to create build info for a league of legends application! Teacher gave it 100%! Was pretty easy to learn the language, I did all the learning out of class as well I also made a video releasing the files to the public - https://www.youtube.com/watch?v=EmufzHsQDnY

Awesome mate - looks great!
Experience in teaching at both secondary and tertiary levels.

website // new forum profile

illuminati_confirmed

  • Adventurer
  • *
  • Posts: 10
  • Respect: 0
Re: Softdev: What programming language?
« Reply #8 on: May 25, 2017, 02:07:52 pm »
+2
This thread is old, but for this year, our class has decided to use Visual Basic for our SACs and SAT
year 12 2017
2016: Systems Engineering [43]
2017: Specialist Maths, Mathematical Methods, English Language, Physics, IT Software Development

Aaron

  • Honorary Moderator
  • ATAR Notes Legend
  • *******
  • Posts: 3932
  • Respect: +1536
Re: Softdev: What programming language?
« Reply #9 on: May 25, 2017, 02:27:06 pm »
+1
This thread is old, but for this year, our class has decided to use Visual Basic for our SACs and SAT

No problems at all, you are definitely welcome to post. What are your thoughts about the language and how much do you have to learn by yourself?
Experience in teaching at both secondary and tertiary levels.

website // new forum profile

kiwikoala

  • Trailblazer
  • *
  • Posts: 37
  • Respect: +19
Re: Softdev: What programming language?
« Reply #10 on: January 06, 2018, 06:28:55 pm »
+1
Hiya,
In my class our teacher gave us the choice to do any language from the list vcaa approved. Whilst the resources and tutorials were in Visual Basic. The teacher was pretty hands off about teaching how to program himself. About half the class of 15 did VB, 4 went Python, a few did C# and I believe someone did web stuff.

Worked out fine. I did Python cause I wanted to learn it and had GREAT fun with tkinter (HA, decent intro to OOP tho) Python + tkinter was alright to learn by yourself. The hard parts is finding relevant code examples with a consistent style (hmu for the best documentation websites, and my particular setup/templates I ended up with). Most documentation for it was pre 2010 which is pretty sad. One of my friends decided to do Python + qt and their stuff looked really nice compared to old style defaults of tkinter.

Python is a great general language, just that there are much better ones to make GUIs which is what you are concerned about in Software Development. You want to do VB almost everytime due to the ease of the drag and drop separates the 2 parts into 2 problems and makes it easier to visualise the layouts, Python can be picked up in not much time at all especially if it's your second language.

I recall a time when I learnt that I could store those abstract Button widgets in an array and access them from that instead of calling them btnA, btnB, btnC... looping through them with string manipulation + the exec() function in Python haha.

First folio task, no idea about objects, arrays, pointers etc.
Spoiler
# Children's game 2

from tkinter import *

root = Tk()

feedback = StringVar()
feedback.set('Harro')

# Iterative buttons
button_names = [['a',0], ['b',1], ['c', 2]]
listy = []
listy2 = []
for name, num in button_names:
    # Generates the buttons and assigns to iterative names
    exec("photo%s = PhotoImage(file=name+'.png')" % (name))
    exec("%s = Button(root, image=photo%s, command= lambda: \
change_colour(%s))" % (name, name, name))
    eval(name).grid(row=1, column=num)
    # Creates a multi-dimensional array of the variable name and the string of the variable name
    listy += [[eval(name), name]]

button_names_pic = [['e',0], ['f',1], ['d', 2]]
function_list_pic = []
for name, num in button_names_pic:
    # Generates the buttons and assigns to iterative names
    exec("photo%s = PhotoImage(file=name+'.png')" % (name))
    exec("%s = Button(root, image=photo%s, command= lambda: \
change_colour_pic(%s))" % (name, name, name))
    eval(name).grid(row=2, column=num)
    # Creates a list of variable name and the string of the variable name
    listy2 += [[eval(name), name]]

butReset = Button(root, text="Reset", command=lambda: reset(), width=60)
butReset.grid(row=3, columnspan=3)

check_list = [['a', 'd'], ['b', 'e'], ['c', 'f']]
nice = PhotoImage(file='nice.png')

def reset():
    for butname, picname in (check_list):
        eval(butname).config(bg='blue')
        eval(butname).config(image=eval('photo'+butname))
        eval(picname).config(bg='blue')
        eval(picname).config(image=eval('photo'+picname))

                 
def check_active():
    '''Checks whether the 2 buttons in row 1 and 2 are correct'''
    first = 'poop'
    second = 'poop'
    first_but = None
    second_but = None
    for i, j in listy:
        if i.cget("bg") == 'red':
            first = j
            first_but = i
    for i, j in listy2:
        if i.cget("bg") == 'red':
            second = j
            second_but = i
    for i, j in check_list:
        if first == i and second == j:
            first_but.config(image=nice, bg='blue')
            second_but.config(image=nice, bg='blue')
            feedback.set('Noise')

def change_colour(name):
    ''' Changes pressed button to red but everything else to blue'''
    name.config(bg='red')
    for i, j in listy:
        if i == name:
            pass
        else:
            i.config(bg='blue')
    feedback.set('Hmmm')
    check_active()

def change_colour_pic(name):
    ''' changes pressed button to red but everything else to blue'''
    name.config(bg='red')
    for i, j in listy2:
        if i == name:
            pass
        else:
            i.config(bg='blue')
    feedback.set('Okeh')
    check_active()

title = Label(textvariable = feedback)
title.grid(row=0, columnspan=3)
   
mainloop()

Here is the main.py file for my SAT, still a monstrosity, no drag and drop remember.
Spoiler
"""Tkinter application to graphically plot your gains.

------------------------------------------------------
Steven Nguyen
21/08/16
------------------------------------------------------

This program is designed to be able to take workout data
and store it digitally. With the data and using the
tkinter, ttk and matplotlib libraries graphically
displays the information in a meaningful way for the user.
"""

import tkinter as tk
import tkinter.ttk as ttk

import pickle
import datetime
import ttkcalendar

from matgraph import MatGraph
from inputtab import InputTab
from sumpage import SumPage
from popupobj import Popup
from gainscontainer import work, workout

class Main(tk.Frame):

    def __init__(s, m):
        tk.Frame.__init__(s, m)
        s.config(background='gray20')

        # Initliase Data
        s.dicExercise = s.loadData()
        for key, value in s.dicExercise.items():
            value.chronoSort()
        s.ordKeyExercise = sorted(list(s.dicExercise.keys()))
       
        # Lamba dictionary of all modes
        s.dicMode = {'Avg Weight': lambda x: x.avgWeight(),
                     'Total Weight': lambda x: x.sumWeight(),
                     'Median Weight': lambda x: x.medWeight(),
                     'Highest Weight': lambda x: x.highestWeight()}

        s.initialiseWidgets()

    def initialiseWidgets(s):
        # Expansion
        s.grid_rowconfigure(0, weight=1)
        s.grid_rowconfigure(1, weight=1)
        s.grid_rowconfigure(2, weight=1)

        s.grid_columnconfigure(0, weight=0)
        s.grid_columnconfigure(1, weight=1)

        # Icon Loading
        iconPlus = tk.PhotoImage(file='icons\plus.png')
        iconGraph = tk.PhotoImage(file='icons\graph.png')
        iconSum = tk.PhotoImage(file='icons\sum.png')

        # Buttons
        s.btnInp = ttk.Button(s, image=iconPlus)
        s.btnInp.config(command=lambda: s.switch(s.tabInp))
        s.btnInp.image = iconPlus

        s.btnMat = ttk.Button(s, image=iconGraph)
        s.btnMat.config(command=lambda: s.switch(s.tabMat))
        s.btnMat.image = iconGraph

        s.btnSum = ttk.Button(s, image=iconSum)
        s.btnSum.config(command=lambda: s.switch(s.tabSum))
        s.btnSum.image = iconSum

        s.btnInp.grid(row=0, column=0, sticky='news')
        s.btnMat.grid(row=1, column=0, sticky='news')
        s.btnSum.grid(row=2, column=0, sticky='news')

        # Initialising tabs
        s.initInp()
        s.initMat()
        s.initSum()

        # Initilaised first tab to be the graph
        s.currentTab = s.tabSum
        s.switch(s.tabMat)
        s.updatePlot(event=None)

    def initInp(s):
        """
        Initiates the InputTab object's widgets and data.
        """
        s.tabInp = InputTab(s)
        s.tabInp.chkExercise.config(values=s.ordKeyExercise)
        if s.ordKeyExercise == []:
            pass
        else:
            s.tabInp.varExercise.set(s.ordKeyExercise[0])
        s.tabInp.btnDone.config(command=s.doneSesh)
        s.tabInp.btnNew.config(command=s.callPop)

    def initMat(s):
        """
        Initiates the  MatGraph object's widgets and data.
        """
        s.tabMat = MatGraph(s)
        if s.ordKeyExercise == []:
             pass
        else:
            s.tabMat.varExercise.set(s.ordKeyExercise[0])
        s.tabMat.chkExercise.config(values=s.ordKeyExercise)
        s.tabMat.chkMode.config(values=list(s.dicMode.keys()))
        s.tabMat.chkExercise.bind('<<ComboboxSelected>>', s.updatePlot)
        s.tabMat.chkMode.bind('<<ComboboxSelected>>', s.updatePlot)

    def initSum(s):
        """
        Initiates the SumPage object's widgets and data.
        """
        s.tabSum = SumPage(s)
        s.tabSum.tree.bind('<Delete>', s.deleteSum)
        s.tabSum.btnEdit.config(command=s.editSum)
        s.tabSum.btnDelete.config(command=lambda: s.deleteSum(None))
        s.updateSum()

    def switch(s, chosenFrame):
        """
        Function used to switch between tabs.
        """
        if chosenFrame == s.currentTab:
            return
        else:
            s.currentTab.grid_remove()
            s.updatePlot(event=None)
            chosenFrame.grid(row=0, column=1, rowspan=3, sticky='news')
            s.currentTab = chosenFrame
            s.updateDict()

    def addNewInp(s, event):
        """
        Adds a new, empty workout object to the dictionary while updating all widgets related.
        """
        s.dicExercise[s.pop.add()] = workout(s.pop.add(), [])
        s.pop.top.destroy()
        s.updateDict()
        s.initMat()
        s.updatePlot(event=None)


    def deleteSum(s, event):
        """
        Deletes all selected in the tree and their respective entries in the dictionary.
        """
        for i in reversed(list(s.tabSum.tree.selection())):
            txt = s.tabSum.tree.item(i, 'text')
            tags = s.tabSum.tree.item(i, 'tags')
            if tags != '':
                objWorkout = s.dicExercise[s.tabSum.tree.item(i, 'tags')[0]]
                obj = s.tabSum.tree.item(i, 'tags')[1]
                for i, objWork in reversed(list(enumerate(objWorkout.data))):
                    # Linear search, backwards to maintain indexing
                    if obj == str(objWork):
                        objWorkout.data.pop(i)
                        break
            else:
                s.dicExercise.pop(txt, None)
       
        s.ordKeyExercise = sorted(list(s.dicExercise.keys()))
        s.tabSum.delete()

        s.updateDict(sumPage=False) # So the tree does not get collapsed

    def editSum(s):
        """
        Determines selected item and edits their name or data
        for either workout or work object respectively
        """
        if len(s.tabSum.tree.selection()) != 1:
            return
        item = s.tabSum.tree.selection()
        itemDict = s.tabSum.tree.item(item)

        # Determines object type and then proceeds
        if itemDict['tags'] == '':
            # Workout object
            # Prompts user to rename
            workoutName = itemDict['text']
            s.callPop()
            s.pop.btnAccept.config(command=lambda event=None: s.renameWorkout(event, workoutName))
            s.pop.ent.bind("<Return>", lambda event: s.renameWorkout(event, workoutName))
        else:
            # Work object
            # Switches tab to input page with details filled in
            workoutName = itemDict['tags'][1]
            workoutObj = s.dicExercise[itemDict['tags'][0]]
            for workObj in workoutObj.data:
                # Linear search through object data to compare strings
                if str(workObj) == workoutName:
                    s.deleteSum(event=None)
                    s.switch(s.tabInp)
                    s.tabInp.tree.delete(*s.tabInp.tree.get_children())
                    s.tabInp.varDate.set(workObj.date.strftime('%d/%m/%y'))
                    s.tabInp.varExercise.set(itemDict['tags'][0])
                    for rep, weight in zip(workObj.reps, workObj.weight):
                        s.tabInp.tree.insert('', tk.END, value=[rep, weight])
                    break
   
    def renameWorkout(s, event, oldname):
        """
        Renames workout object by replacing the original and copying.

        oldname:    Current name of exercise selected to be edited.
        """
        newname = s.pop.add()
        s.pop.onEsc(event=None)
        # Dictionary pop method returns the value
        s.dicExercise[newname] = s.dicExercise.pop(oldname)
        s.updateDict(sumPage=True)

       
    def updatePlot(s, event):
        """
        Updates plots to current dictionary.
        """
        if s.ordKeyExercise == []: # Existence Check
            s.tabMat.mainplot.clear()
            s.tabMat.fig.autofmt_xdate()
            s.tabMat.canvas.show()
            return
       
        exercise = s.tabMat.varExercise.get()
        mode = s.tabMat.varMode.get()
   
        x = s.dicExercise[exercise].dates()
        y = s.dicMode[mode](s.dicExercise[exercise])

        s.tabMat.mainplot.clear()
        s.tabMat.mainplot.plot(x, y)
        s.tabMat.mainplot.scatter(x, y)
        s.tabMat.fig.autofmt_xdate()
        s.tabMat.canvas.show()

    def updateDict(s, sumPage=True):
        """
        Updates all checkboxes linked to the s.dicExercise to the current.

        sumPage:    Boolean option to choose if summary page is to be
                    specifically updated or not. Used exactly once.
        """
        s.ordKeyExercise = sorted(list(s.dicExercise.keys()))
        if s.ordKeyExercise == []:
            setter = ''
        else:
            setter = s.ordKeyExercise[0]
       
        s.tabInp.chkExercise.config(values=s.ordKeyExercise)
        s.tabInp.varExercise.set(setter)

        s.tabMat.chkExercise.config(values=s.ordKeyExercise)
        s.tabMat.varExercise.set(setter)
             
        if sumPage == True:
            # To allow for deletion in the sumpage without resetting the tree
            s.updateSum()

    def updateSum(s):
        """
        Puts all the data from s.dicExercise into the tree in a sorted order.
        """
        s.tabSum.tree.delete(*s.tabSum.tree.get_children())
       
        for strEx in s.ordKeyExercise:
            objEx = s.dicExercise[strEx]
            id = s.tabSum.tree.insert('', tk.END, text=strEx)
            for date, objWork in zip(objEx.dates(), objEx.data):
                id2 = s.tabSum.tree.insert(
                    id, tk.END, values=(objWork.weight, objWork.reps),
                    text=str(date),  tags=(strEx, objWork))

    def doneSesh(s):
        """
        Updates the s.dicExercise with the current entries of tabInp.tree into s.dixExercise.
        """
        selectedDate = s.tabInp.selectedDate
       
        lstReps = [float(s.tabInp.tree.item(i)['values'][0])
                   for i in s.tabInp.tree.get_children()]
        lstWeight = [float(s.tabInp.tree.item(i)['values'][1])
                     for i in s.tabInp.tree.get_children()]

        if lstReps == [] or lstWeight == []:
            return

        new = work(lstReps, lstWeight, selectedDate)

        s.dicExercise[s.tabInp.varExercise.get()].data.append(new)
        s.dicExercise[s.tabInp.varExercise.get()].chronoSort()

        s.tabInp.tree.delete(*s.tabInp.tree.get_children()) # Clears the tree
        s.updateDict()
        s.save()

    def onClose(s):
        """
        Procedure to run before closing the app, saves all data.
        """
        s.save()
        root.destroy()

    def loadData(s):
        """
        Returns the save data within data.pkl.
        """
        with open('data.pkl', 'rb') as file:
            return pickle.load(file)

    def save(s):
        """
        Saves any changes to data.pkl.

        Currently only connected to s.onClose.
        """
        with open('data.pkl', 'wb') as output:
            pickle.dump(s.dicExercise, output)
       

    def callPop(s):
        """
        Calls a general popup with an entry and accept button.
        """
        try:
            s.pop.top.destroy()
        except:
            None
        s.pop = Popup(s)
        s.pop.btnAccept.config(command=lambda: s.addNewInp(event=None))
        s.pop.ent.bind("<Return>", s.addNewInp)

if __name__ == '__main__':
    root = tk.Tk()
    app = Main(root)
    app.pack(expand=1, fill='both')
    root.geometry('825x450')
    root.protocol("WM_DELETE_WINDOW", app.onClose)
    root.iconbitmap('icons\icon.ico')
    root.title('Gains Grapher')
    root.mainloop()

:/ unable to combine spoiler and code tags.
« Last Edit: January 06, 2018, 07:20:21 pm by stevenhuyn »

Aaron

  • Honorary Moderator
  • ATAR Notes Legend
  • *******
  • Posts: 3932
  • Respect: +1536
Re: Softdev: What programming language?
« Reply #11 on: January 06, 2018, 08:13:25 pm »
0
Thanks for contributing your thoughts steven. Did you have any prior knowledge re: programming before coming into Softdev or did you learn all of this during the subject?

They look like great programs you've provided, thanks for the share :)
Experience in teaching at both secondary and tertiary levels.

website // new forum profile

kiwikoala

  • Trailblazer
  • *
  • Posts: 37
  • Respect: +19
Re: Softdev: What programming language?
« Reply #12 on: January 06, 2018, 08:16:47 pm »
0
I had attempted a few languages (namely c++ on youtube) before but did not get very far at alI. I did syntax basics for Python during the holiday period to prepare. GUI library was all learnt during the year. Python was the first language to stick and will forever have a special place in my heart.

The code snippets were meant to show how bad it looks actually haha.
« Last Edit: January 06, 2018, 08:21:02 pm by stevenhuyn »

Aaron

  • Honorary Moderator
  • ATAR Notes Legend
  • *******
  • Posts: 3932
  • Respect: +1536
Re: Softdev: What programming language?
« Reply #13 on: January 06, 2018, 08:20:01 pm »
+1
I did syntax basics during the holiday period but that's all.

The code snippets were meant to show how bad it looks actually haha.

I'm aware, but the fact you're using all these different libraries and functions together to create a solution is fantastic. I am attempting to visualise this for complete beginners so even though it's messy and looks bad, you've still done a great job and shows you have an interest in this area. Kudos :)

That's great then, from syntax basics to multiple solutions! Fair year's effort. :)
Experience in teaching at both secondary and tertiary levels.

website // new forum profile

MJDeeks

  • Adventurer
  • *
  • Posts: 7
  • Respect: 0
Re: Softdev: What programming language?
« Reply #14 on: March 26, 2018, 01:15:30 pm »
0
My class uses python and it was fairly easy to learn for someone who was very new to the subject